chiark / gitweb /
REORG Delete everything that's not innduct or build system or changed for innduct
authorIan Jackson <ian@liberator.(none)>
Sat, 15 May 2010 16:17:27 +0000 (17:17 +0100)
committerIan Jackson <ian@liberator.(none)>
Sat, 15 May 2010 16:17:27 +0000 (17:17 +0100)
735 files changed:
CONTRIBUTORS [deleted file]
ChangeLog [deleted file]
HACKING [deleted file]
INSTALL [deleted file]
LICENSE [deleted file]
MANIFEST [deleted file]
NEWS [deleted file]
README [deleted file]
TODO [deleted file]
authprogs/Makefile [deleted file]
authprogs/auth_krb5.c [deleted file]
authprogs/auth_smb.c [deleted file]
authprogs/ckpasswd.c [deleted file]
authprogs/domain.c [deleted file]
authprogs/ident.c [deleted file]
authprogs/libauth.c [deleted file]
authprogs/libauth.h [deleted file]
authprogs/radius.c [deleted file]
authprogs/smbval/Makefile [deleted file]
authprogs/smbval/byteorder.h [deleted file]
authprogs/smbval/rfcnb-common.h [deleted file]
authprogs/smbval/rfcnb-error.h [deleted file]
authprogs/smbval/rfcnb-io.c [deleted file]
authprogs/smbval/rfcnb-io.h [deleted file]
authprogs/smbval/rfcnb-priv.h [deleted file]
authprogs/smbval/rfcnb-util.c [deleted file]
authprogs/smbval/rfcnb-util.h [deleted file]
authprogs/smbval/rfcnb.h [deleted file]
authprogs/smbval/session.c [deleted file]
authprogs/smbval/smbdes.c [deleted file]
authprogs/smbval/smbencrypt.c [deleted file]
authprogs/smbval/smblib-common.h [deleted file]
authprogs/smbval/smblib-priv.h [deleted file]
authprogs/smbval/smblib-util.c [deleted file]
authprogs/smbval/smblib.c [deleted file]
authprogs/smbval/smblib.h [deleted file]
authprogs/smbval/valid.c [deleted file]
authprogs/smbval/valid.h [deleted file]
backends/actmerge.in [deleted file]
backends/actsync.c [deleted file]
backends/actsyncd.in [deleted file]
backends/archive.c [deleted file]
backends/batcher.c [deleted file]
backends/buffchan.c [deleted file]
backends/crosspost.c [deleted file]
backends/cvtbatch.c [deleted file]
backends/filechan.c [deleted file]
backends/inndf.c [deleted file]
backends/innxbatch.c [deleted file]
backends/innxmit.c [deleted file]
backends/map.c [deleted file]
backends/map.h [deleted file]
backends/mod-active.in [deleted file]
backends/news2mail.in [deleted file]
backends/ninpaths.c [deleted file]
backends/nntpget.c [deleted file]
backends/nntpsend.in [deleted file]
backends/overchan.c [deleted file]
backends/send-ihave.in [deleted file]
backends/send-nntp.in [deleted file]
backends/send-uucp.in [deleted file]
backends/sendinpaths.in [deleted file]
backends/sendxbatches.in [deleted file]
backends/shlock.c [deleted file]
backends/shrinkfile.c [deleted file]
contrib/Makefile [deleted file]
contrib/README [deleted file]
contrib/archivegz.in [deleted file]
contrib/auth_pass.README [deleted file]
contrib/auth_pass.c [deleted file]
contrib/backlogstat.in [deleted file]
contrib/backupfeed.in [deleted file]
contrib/cleannewsgroups.in [deleted file]
contrib/count_overview.pl [deleted file]
contrib/delayer.in [deleted file]
contrib/expirectl.c [deleted file]
contrib/findreadgroups.in [deleted file]
contrib/fixhist [deleted file]
contrib/innconfcheck [deleted file]
contrib/makeexpctl.in [deleted file]
contrib/makestorconf.in [deleted file]
contrib/mkbuf [deleted file]
contrib/mlockfile.c [deleted file]
contrib/newsresp.c [deleted file]
contrib/pullart.c [deleted file]
contrib/reset-cnfs.c [deleted file]
contrib/respool.c [deleted file]
contrib/sample.init.script [deleted file]
contrib/showtoken.in [deleted file]
contrib/stathist.in [deleted file]
contrib/thdexpire.in [deleted file]
contrib/tunefeed.in [deleted file]
control/Makefile [deleted file]
control/controlbatch.in [deleted file]
control/controlchan.in [deleted file]
control/docheckgroups.in [deleted file]
control/gpgverify.in [deleted file]
control/modules/checkgroups.pl [deleted file]
control/modules/ihave.pl [deleted file]
control/modules/newgroup.pl [deleted file]
control/modules/rmgroup.pl [deleted file]
control/modules/sendme.pl [deleted file]
control/modules/sendsys.pl [deleted file]
control/modules/senduuname.pl [deleted file]
control/modules/version.pl [deleted file]
control/perl-nocem.in [deleted file]
control/pgpverify.in [deleted file]
control/signcontrol.in [deleted file]
debian/changelog [deleted file]
debian/changelog.old [deleted file]
debian/compat [deleted file]
debian/inn2-dev.files [deleted file]
debian/inn2-dev.links [deleted file]
debian/inn2-inews.files [deleted file]
debian/inn2-inews.links [deleted file]
debian/inn2.README.Debian [deleted file]
debian/inn2.cron.d [deleted file]
debian/inn2.docs [deleted file]
debian/inn2.examples [deleted file]
debian/inn2.init [deleted file]
debian/inn2.links [deleted file]
debian/inn2.logcheck.ignore.server [deleted file]
debian/inn2.logcheck.violations.ignore [deleted file]
debian/inn2.postinst [deleted file]
debian/inn2.postrm [deleted file]
debian/inn2.preinst [deleted file]
debian/inn2.prerm [deleted file]
debian/patches/debian-paths [deleted file]
debian/patches/fix_ad_flag [deleted file]
debian/patches/fix_body_regexps [deleted file]
debian/patches/no-makedbz-on-install [deleted file]
debian/patches/nocem-gpg-import [deleted file]
debian/patches/series [deleted file]
debian/patches/typo_inn_conf_man [deleted file]
debian/patches/u_innreport_misc [deleted file]
debian/patches/u_right_length [deleted file]
debian/patches/u_status_init_ip [deleted file]
debian/patches/u_tls_duplicate_reply [deleted file]
debian/patches/u_xhdr_permissions [deleted file]
debian/patches/u_xover_duplicate_reply [deleted file]
debian/rules [deleted file]
debian/watch [deleted file]
doc/GPL [deleted file]
doc/IPv6-info [deleted file]
doc/checklist [deleted file]
doc/compliance-nntp [deleted file]
doc/config-design [deleted file]
doc/config-semantics [deleted file]
doc/config-syntax [deleted file]
doc/external-auth [deleted file]
doc/history [deleted file]
doc/hook-perl [deleted file]
doc/hook-python [deleted file]
doc/hook-tcl [deleted file]
doc/man/Makefile [deleted file]
doc/man/active.5 [deleted file]
doc/man/active.times.5 [deleted file]
doc/man/actsync.8 [deleted file]
doc/man/actsyncd.8 [deleted file]
doc/man/archive.8 [deleted file]
doc/man/auth_krb5.8 [deleted file]
doc/man/auth_smb.8 [deleted file]
doc/man/batcher.8 [deleted file]
doc/man/buffchan.8 [deleted file]
doc/man/buffindexed.conf.5 [deleted file]
doc/man/ckpasswd.8 [deleted file]
doc/man/clientlib.3 [deleted file]
doc/man/cnfsheadconf.8 [deleted file]
doc/man/cnfsstat.8 [deleted file]
doc/man/control.ctl.5 [deleted file]
doc/man/controlchan.8 [deleted file]
doc/man/convdate.1 [deleted file]
doc/man/ctlinnd.8 [deleted file]
doc/man/cvtbatch.8 [deleted file]
doc/man/cycbuff.conf.5 [deleted file]
doc/man/dbz.3 [deleted file]
doc/man/distrib.pats.5 [deleted file]
doc/man/domain.8 [deleted file]
doc/man/expire.8 [deleted file]
doc/man/expire.ctl.5 [deleted file]
doc/man/expireover.8 [deleted file]
doc/man/expirerm.8 [deleted file]
doc/man/fastrm.1 [deleted file]
doc/man/filechan.8 [deleted file]
doc/man/getlist.1 [deleted file]
doc/man/grephistory.1 [deleted file]
doc/man/history.5 [deleted file]
doc/man/ident.8 [deleted file]
doc/man/incoming.conf.5 [deleted file]
doc/man/inews.1 [deleted file]
doc/man/inn.conf.5 [deleted file]
doc/man/inncheck.8 [deleted file]
doc/man/innconfval.1 [deleted file]
doc/man/innd.8 [deleted file]
doc/man/inndcomm.3 [deleted file]
doc/man/inndf.8 [deleted file]
doc/man/inndstart.8 [deleted file]
doc/man/innfeed.1 [deleted file]
doc/man/innfeed.conf.5 [deleted file]
doc/man/innmail.1 [deleted file]
doc/man/innreport.8 [deleted file]
doc/man/innstat.8 [deleted file]
doc/man/innupgrade.8 [deleted file]
doc/man/innwatch.8 [deleted file]
doc/man/innwatch.ctl.5 [deleted file]
doc/man/innxbatch.8 [deleted file]
doc/man/innxmit.8 [deleted file]
doc/man/libauth.3 [deleted file]
doc/man/libinn.3 [deleted file]
doc/man/libinnhist.3 [deleted file]
doc/man/libstorage.3 [deleted file]
doc/man/list.3 [deleted file]
doc/man/mailpost.8 [deleted file]
doc/man/makeactive.8 [deleted file]
doc/man/makedbz.8 [deleted file]
doc/man/makehistory.8 [deleted file]
doc/man/mod-active.8 [deleted file]
doc/man/moderators.5 [deleted file]
doc/man/motd.news.5 [deleted file]
doc/man/news.daily.8 [deleted file]
doc/man/news2mail.8 [deleted file]
doc/man/newsfeeds.5 [deleted file]
doc/man/newslog.5 [deleted file]
doc/man/ninpaths.8 [deleted file]
doc/man/nnrpd.8 [deleted file]
doc/man/nnrpd.track.5 [deleted file]
doc/man/nntpget.1 [deleted file]
doc/man/nntpsend.8 [deleted file]
doc/man/nntpsend.ctl.5 [deleted file]
doc/man/ovdb.5 [deleted file]
doc/man/ovdb_init.8 [deleted file]
doc/man/ovdb_monitor.8 [deleted file]
doc/man/ovdb_server.8 [deleted file]
doc/man/ovdb_stat.8 [deleted file]
doc/man/overchan.8 [deleted file]
doc/man/overview.fmt.5 [deleted file]
doc/man/parsedate.3 [deleted file]
doc/man/passwd.nntp.5 [deleted file]
doc/man/perl-nocem.8 [deleted file]
doc/man/pgpverify.1 [deleted file]
doc/man/prunehistory.8 [deleted file]
doc/man/pullnews.1 [deleted file]
doc/man/putman.sh [deleted file]
doc/man/qio.3 [deleted file]
doc/man/radius.8 [deleted file]
doc/man/radius.conf.5 [deleted file]
doc/man/rc.news.8 [deleted file]
doc/man/readers.conf.5 [deleted file]
doc/man/rnews.1 [deleted file]
doc/man/sasl.conf.5 [deleted file]
doc/man/scanlogs.8 [deleted file]
doc/man/send-nntp.8 [deleted file]
doc/man/send-uucp.8 [deleted file]
doc/man/sendinpaths.8 [deleted file]
doc/man/shlock.1 [deleted file]
doc/man/shrinkfile.1 [deleted file]
doc/man/simpleftp.1 [deleted file]
doc/man/sm.1 [deleted file]
doc/man/startinnfeed.1 [deleted file]
doc/man/storage.conf.5 [deleted file]
doc/man/subscriptions.5 [deleted file]
doc/man/tally.control.8 [deleted file]
doc/man/tdx-util.8 [deleted file]
doc/man/tst.3 [deleted file]
doc/man/uwildmat.3 [deleted file]
doc/man/writelog.8 [deleted file]
doc/pod/Makefile [deleted file]
doc/pod/active.pod [deleted file]
doc/pod/active.times.pod [deleted file]
doc/pod/auth_krb5.pod [deleted file]
doc/pod/auth_smb.pod [deleted file]
doc/pod/checklist.pod [deleted file]
doc/pod/ckpasswd.pod [deleted file]
doc/pod/control.ctl.pod [deleted file]
doc/pod/convdate.pod [deleted file]
doc/pod/cycbuff.conf.pod [deleted file]
doc/pod/distrib.pats.pod [deleted file]
doc/pod/domain.pod [deleted file]
doc/pod/expire.ctl.pod [deleted file]
doc/pod/expireover.pod [deleted file]
doc/pod/external-auth.pod [deleted file]
doc/pod/fastrm.pod [deleted file]
doc/pod/grephistory.pod [deleted file]
doc/pod/hacking.pod [deleted file]
doc/pod/hook-perl.pod [deleted file]
doc/pod/hook-python.pod [deleted file]
doc/pod/ident.pod [deleted file]
doc/pod/inews.pod [deleted file]
doc/pod/inn.conf.pod [deleted file]
doc/pod/innconfval.pod [deleted file]
doc/pod/innd.pod [deleted file]
doc/pod/inndf.pod [deleted file]
doc/pod/inndstart.pod [deleted file]
doc/pod/innmail.pod [deleted file]
doc/pod/innupgrade.pod [deleted file]
doc/pod/install.pod [deleted file]
doc/pod/libauth.pod [deleted file]
doc/pod/libinnhist.pod [deleted file]
doc/pod/list.pod [deleted file]
doc/pod/mailpost.pod [deleted file]
doc/pod/makehistory.pod [deleted file]
doc/pod/motd.news.pod [deleted file]
doc/pod/news.pod [deleted file]
doc/pod/newsfeeds.pod [deleted file]
doc/pod/ninpaths.pod [deleted file]
doc/pod/nnrpd.pod [deleted file]
doc/pod/ovdb.pod [deleted file]
doc/pod/ovdb_init.pod [deleted file]
doc/pod/ovdb_monitor.pod [deleted file]
doc/pod/ovdb_server.pod [deleted file]
doc/pod/ovdb_stat.pod [deleted file]
doc/pod/passwd.nntp.pod [deleted file]
doc/pod/pullnews.pod [deleted file]
doc/pod/qio.pod [deleted file]
doc/pod/radius.conf.pod [deleted file]
doc/pod/radius.pod [deleted file]
doc/pod/rc.news.pod [deleted file]
doc/pod/readers.conf.pod [deleted file]
doc/pod/readme.pod [deleted file]
doc/pod/sasl.conf.pod [deleted file]
doc/pod/sendinpaths.pod [deleted file]
doc/pod/simpleftp.pod [deleted file]
doc/pod/sm.pod [deleted file]
doc/pod/subscriptions.pod [deleted file]
doc/pod/tdx-util.pod [deleted file]
doc/pod/tst.pod [deleted file]
doc/pod/uwildmat.pod [deleted file]
doc/sample-control [deleted file]
expire/Makefile [deleted file]
expire/convdate.c [deleted file]
expire/expire.c [deleted file]
expire/expireover.c [deleted file]
expire/expirerm.in [deleted file]
expire/fastrm.c [deleted file]
expire/grephistory.c [deleted file]
expire/makedbz.c [deleted file]
expire/makehistory.c [deleted file]
expire/prunehistory.c [deleted file]
extra/active [deleted file]
extra/buildinnkeyring [deleted file]
extra/bunbatch [deleted file]
extra/dh_cloneconf [deleted file]
extra/ginpaths2 [deleted file]
extra/newsgroups [deleted file]
extra/sasl.conf [deleted file]
extra/send-uucp.cf [deleted file]
frontends/Makefile [deleted file]
frontends/cnfsheadconf.in [deleted file]
frontends/cnfsstat.in [deleted file]
frontends/ctlinnd.c [deleted file]
frontends/decode.c [deleted file]
frontends/encode.c [deleted file]
frontends/feedone.c [deleted file]
frontends/getlist.c [deleted file]
frontends/inews.c [deleted file]
frontends/innconfval.c [deleted file]
frontends/mailpost.in [deleted file]
frontends/ovdb_init.c [deleted file]
frontends/ovdb_monitor.c [deleted file]
frontends/ovdb_server.c [deleted file]
frontends/ovdb_stat.c [deleted file]
frontends/pullnews.in [deleted file]
frontends/rnews.c [deleted file]
frontends/scanspool.in [deleted file]
frontends/sm.c [deleted file]
frontends/sys2nf.c [deleted file]
history/Make.methods [deleted file]
history/Makefile [deleted file]
history/buildconfig.in [deleted file]
history/his.c [deleted file]
history/hisinterface.h [deleted file]
history/hisv6/hismethod.config [deleted file]
history/hisv6/hisv6-private.h [deleted file]
history/hisv6/hisv6.c [deleted file]
history/hisv6/hisv6.h [deleted file]
include/Makefile [deleted file]
include/acconfig.h [deleted file]
include/clibrary.h [deleted file]
include/conffile.h [deleted file]
include/dbz.h [deleted file]
include/inn/buffer.h [deleted file]
include/inn/confparse.h [deleted file]
include/inn/defines.h [deleted file]
include/inn/hashtab.h [deleted file]
include/inn/history.h [deleted file]
include/inn/innconf.h [deleted file]
include/inn/list.h [deleted file]
include/inn/md5.h [deleted file]
include/inn/messages.h [deleted file]
include/inn/mmap.h [deleted file]
include/inn/qio.h [deleted file]
include/inn/sequence.h [deleted file]
include/inn/timer.h [deleted file]
include/inn/tst.h [deleted file]
include/inn/vector.h [deleted file]
include/inn/wire.h [deleted file]
include/inndcomm.h [deleted file]
include/innperl.h [deleted file]
include/libinn.h [deleted file]
include/nntp.h [deleted file]
include/ov.h [deleted file]
include/paths.h.in [deleted file]
include/portable/mmap.h [deleted file]
include/portable/setproctitle.h [deleted file]
include/portable/socket.h [deleted file]
include/portable/time.h [deleted file]
include/portable/wait.h [deleted file]
include/ppport.h [deleted file]
innd/Makefile [deleted file]
innd/art.c [deleted file]
innd/cc.c [deleted file]
innd/chan.c [deleted file]
innd/icd.c [deleted file]
innd/innd.c [deleted file]
innd/innd.h [deleted file]
innd/inndstart.c [deleted file]
innd/keywords.c [deleted file]
innd/lc.c [deleted file]
innd/nc.c [deleted file]
innd/newsfeeds.c [deleted file]
innd/ng.c [deleted file]
innd/perl.c [deleted file]
innd/proc.c [deleted file]
innd/python.c [deleted file]
innd/rc.c [deleted file]
innd/site.c [deleted file]
innd/status.c [deleted file]
innd/tcl.c [deleted file]
innd/util.c [deleted file]
innd/wip.c [deleted file]
innfeed/Makefile [deleted file]
innfeed/README [deleted file]
innfeed/article.c [deleted file]
innfeed/article.h [deleted file]
innfeed/buffer.c [deleted file]
innfeed/buffer.h [deleted file]
innfeed/config_l.c [deleted file]
innfeed/configfile.h [deleted file]
innfeed/configfile.l [deleted file]
innfeed/configfile.y [deleted file]
innfeed/connection.c [deleted file]
innfeed/connection.h [deleted file]
innfeed/endpoint.c [deleted file]
innfeed/endpoint.h [deleted file]
innfeed/host.c [deleted file]
innfeed/host.h [deleted file]
innfeed/imap_connection.c [deleted file]
innfeed/innfeed-convcfg.in [deleted file]
innfeed/innfeed.h [deleted file]
innfeed/innlistener.c [deleted file]
innfeed/innlistener.h [deleted file]
innfeed/main.c [deleted file]
innfeed/misc.c [deleted file]
innfeed/misc.h [deleted file]
innfeed/procbatch.in [deleted file]
innfeed/startinnfeed.c [deleted file]
innfeed/tape.c [deleted file]
innfeed/tape.h [deleted file]
innfeed/testListener.pl [deleted file]
lib/Makefile [deleted file]
lib/buffer.c [deleted file]
lib/cleanfrom.c [deleted file]
lib/clientactive.c [deleted file]
lib/clientlib.c [deleted file]
lib/concat.c [deleted file]
lib/conffile.c [deleted file]
lib/confparse.c [deleted file]
lib/daemonize.c [deleted file]
lib/date.c [deleted file]
lib/dbz.c [deleted file]
lib/defdist.c [deleted file]
lib/fdflags.c [deleted file]
lib/fdlimit.c [deleted file]
lib/fseeko.c [deleted file]
lib/ftello.c [deleted file]
lib/genid.c [deleted file]
lib/getfqdn.c [deleted file]
lib/getmodaddr.c [deleted file]
lib/getpagesize.c [deleted file]
lib/gettime.c [deleted file]
lib/hash.c [deleted file]
lib/hashtab.c [deleted file]
lib/hstrerror.c [deleted file]
lib/inet_aton.c [deleted file]
lib/inet_ntoa.c [deleted file]
lib/innconf.c [deleted file]
lib/inndcomm.c [deleted file]
lib/list.c [deleted file]
lib/localopen.c [deleted file]
lib/lockfile.c [deleted file]
lib/makedir.c [deleted file]
lib/md5.c [deleted file]
lib/memcmp.c [deleted file]
lib/messages.c [deleted file]
lib/mkstemp.c [deleted file]
lib/mmap.c [deleted file]
lib/parsedate.y [deleted file]
lib/perl.c [deleted file]
lib/pread.c [deleted file]
lib/pwrite.c [deleted file]
lib/qio.c [deleted file]
lib/radix32.c [deleted file]
lib/readin.c [deleted file]
lib/reservedfd.c [deleted file]
lib/resource.c [deleted file]
lib/sendarticle.c [deleted file]
lib/sendpass.c [deleted file]
lib/sequence.c [deleted file]
lib/setenv.c [deleted file]
lib/seteuid.c [deleted file]
lib/setproctitle.c [deleted file]
lib/snprintf.c [deleted file]
lib/sockaddr.c [deleted file]
lib/strcasecmp.c [deleted file]
lib/strerror.c [deleted file]
lib/strlcat.c [deleted file]
lib/strlcpy.c [deleted file]
lib/strspn.c [deleted file]
lib/strtok.c [deleted file]
lib/timer.c [deleted file]
lib/tst.c [deleted file]
lib/uwildmat.c [deleted file]
lib/vector.c [deleted file]
lib/version.c [deleted file]
lib/wire.c [deleted file]
lib/xfopena.c [deleted file]
lib/xmalloc.c [deleted file]
lib/xsignal.c [deleted file]
lib/xwrite.c [deleted file]
nnrpd/Makefile [deleted file]
nnrpd/article.c [deleted file]
nnrpd/cache.c [deleted file]
nnrpd/cache.h [deleted file]
nnrpd/commands.c [deleted file]
nnrpd/group.c [deleted file]
nnrpd/line.c [deleted file]
nnrpd/list.c [deleted file]
nnrpd/misc.c [deleted file]
nnrpd/newnews.c [deleted file]
nnrpd/nnrpd.c [deleted file]
nnrpd/nnrpd.h [deleted file]
nnrpd/perl.c [deleted file]
nnrpd/perm.c [deleted file]
nnrpd/post.c [deleted file]
nnrpd/post.h [deleted file]
nnrpd/python.c [deleted file]
nnrpd/sasl_config.c [deleted file]
nnrpd/sasl_config.h [deleted file]
nnrpd/tls.c [deleted file]
nnrpd/tls.h [deleted file]
nnrpd/track.c [deleted file]
samples/INN.py [deleted file]
samples/Makefile [deleted file]
samples/active.minimal [deleted file]
samples/actsync.cfg [deleted file]
samples/actsync.ign [deleted file]
samples/buffindexed.conf [deleted file]
samples/control.ctl [deleted file]
samples/cycbuff.conf [deleted file]
samples/distrib.pats [deleted file]
samples/expire.ctl [deleted file]
samples/filter.tcl [deleted file]
samples/filter_innd.pl [deleted file]
samples/filter_innd.py [deleted file]
samples/filter_nnrpd.pl [deleted file]
samples/incoming.conf [deleted file]
samples/inn.conf.in [deleted file]
samples/innfeed.conf [deleted file]
samples/innreport.conf.in [deleted file]
samples/innwatch.ctl [deleted file]
samples/moderators [deleted file]
samples/motd.news [deleted file]
samples/news2mail.cf [deleted file]
samples/newsfeeds.in [deleted file]
samples/newsgroups.minimal [deleted file]
samples/nnrpd.py [deleted file]
samples/nnrpd.track [deleted file]
samples/nnrpd_access.pl.in [deleted file]
samples/nnrpd_access.py [deleted file]
samples/nnrpd_access_wrapper.pl.in [deleted file]
samples/nnrpd_access_wrapper.py [deleted file]
samples/nnrpd_auth.pl.in [deleted file]
samples/nnrpd_auth.py [deleted file]
samples/nnrpd_auth_wrapper.pl.in [deleted file]
samples/nnrpd_auth_wrapper.py [deleted file]
samples/nnrpd_dynamic.py [deleted file]
samples/nnrpd_dynamic_wrapper.py [deleted file]
samples/nntpsend.ctl [deleted file]
samples/ovdb.conf [deleted file]
samples/overview.fmt [deleted file]
samples/passwd.nntp [deleted file]
samples/radius.conf [deleted file]
samples/readers.conf [deleted file]
samples/sasl.conf.in [deleted file]
samples/startup.tcl [deleted file]
samples/startup_innd.pl [deleted file]
samples/storage.conf [deleted file]
samples/subscriptions [deleted file]
scripts/Makefile [deleted file]
scripts/inncheck.in [deleted file]
scripts/innmail.in [deleted file]
scripts/innreport.in [deleted file]
scripts/innreport_inn.pm [deleted file]
scripts/innshellvars.in [deleted file]
scripts/innshellvars.pl.in [deleted file]
scripts/innshellvars.tcl.in [deleted file]
scripts/innstat.in [deleted file]
scripts/innupgrade.in [deleted file]
scripts/innwatch.in [deleted file]
scripts/news.daily.in [deleted file]
scripts/rc.news.in [deleted file]
scripts/scanlogs.in [deleted file]
scripts/simpleftp.in [deleted file]
scripts/tally.control.in [deleted file]
scripts/writelog.in [deleted file]
site/Makefile [deleted file]
site/getsafe.sh [deleted file]
storage/Make.methods [deleted file]
storage/Makefile [deleted file]
storage/buffindexed/buffindexed.c [deleted file]
storage/buffindexed/buffindexed.h [deleted file]
storage/buffindexed/ovmethod.config [deleted file]
storage/buffindexed/ovmethod.mk [deleted file]
storage/buildconfig.in [deleted file]
storage/cnfs/cnfs-private.h [deleted file]
storage/cnfs/cnfs.c [deleted file]
storage/cnfs/cnfs.h [deleted file]
storage/cnfs/method.config [deleted file]
storage/expire.c [deleted file]
storage/interface.c [deleted file]
storage/interface.h [deleted file]
storage/ov.c [deleted file]
storage/ovdb/ovdb-private.h [deleted file]
storage/ovdb/ovdb.c [deleted file]
storage/ovdb/ovdb.h [deleted file]
storage/ovdb/ovmethod.config [deleted file]
storage/overdata.c [deleted file]
storage/ovinterface.h [deleted file]
storage/timecaf/README.CAF [deleted file]
storage/timecaf/caf.c [deleted file]
storage/timecaf/caf.h [deleted file]
storage/timecaf/method.config [deleted file]
storage/timecaf/timecaf.c [deleted file]
storage/timecaf/timecaf.h [deleted file]
storage/timehash/method.config [deleted file]
storage/timehash/timehash.c [deleted file]
storage/timehash/timehash.h [deleted file]
storage/tradindexed/ovmethod.config [deleted file]
storage/tradindexed/ovmethod.mk [deleted file]
storage/tradindexed/tdx-cache.c [deleted file]
storage/tradindexed/tdx-data.c [deleted file]
storage/tradindexed/tdx-group.c [deleted file]
storage/tradindexed/tdx-private.h [deleted file]
storage/tradindexed/tdx-structure.h [deleted file]
storage/tradindexed/tdx-util.c [deleted file]
storage/tradindexed/tradindexed.c [deleted file]
storage/tradindexed/tradindexed.h [deleted file]
storage/tradspool/README.tradspool [deleted file]
storage/tradspool/method.config [deleted file]
storage/tradspool/tradspool.c [deleted file]
storage/tradspool/tradspool.h [deleted file]
storage/trash/method.config [deleted file]
storage/trash/trash.c [deleted file]
storage/trash/trash.h [deleted file]
support/config.guess [deleted file]
support/config.sub [deleted file]
support/fixscript.in [deleted file]
support/indent [deleted file]
support/install-sh [deleted file]
support/ltmain.sh [deleted file]
support/makedepend [deleted file]
support/mkchangelog [deleted file]
support/mkmanifest [deleted file]
support/mksnapshot [deleted file]
support/mksystem [deleted file]
support/mkversion [deleted file]
tests/Makefile [deleted file]
tests/TESTS [deleted file]
tests/authprogs/ckpasswd.t [deleted file]
tests/authprogs/domain.t [deleted file]
tests/authprogs/passwd [deleted file]
tests/lib/articles/no-body [deleted file]
tests/lib/articles/strange [deleted file]
tests/lib/articles/truncated [deleted file]
tests/lib/buffer-t.c [deleted file]
tests/lib/concat-t.c [deleted file]
tests/lib/config/errors [deleted file]
tests/lib/config/line-endings [deleted file]
tests/lib/config/no-newline [deleted file]
tests/lib/config/null [deleted file]
tests/lib/config/simple [deleted file]
tests/lib/config/valid [deleted file]
tests/lib/config/warn-bool [deleted file]
tests/lib/config/warn-int [deleted file]
tests/lib/config/warnings [deleted file]
tests/lib/confparse-t.c [deleted file]
tests/lib/date-t.c [deleted file]
tests/lib/fakewrite.c [deleted file]
tests/lib/hash-t.c [deleted file]
tests/lib/hashtab-t.c [deleted file]
tests/lib/hstrerror-t.c [deleted file]
tests/lib/inet_aton-t.c [deleted file]
tests/lib/inet_ntoa-t.c [deleted file]
tests/lib/innconf-t.c [deleted file]
tests/lib/list-t.c [deleted file]
tests/lib/md5-t.c [deleted file]
tests/lib/memcmp-t.c [deleted file]
tests/lib/messages-t.c [deleted file]
tests/lib/mkstemp-t.c [deleted file]
tests/lib/pread-t.c [deleted file]
tests/lib/pwrite-t.c [deleted file]
tests/lib/qio-t.c [deleted file]
tests/lib/setenv-t.c [deleted file]
tests/lib/setenv.t [deleted file]
tests/lib/snprintf-t.c [deleted file]
tests/lib/strerror-t.c [deleted file]
tests/lib/strlcat-t.c [deleted file]
tests/lib/strlcpy-t.c [deleted file]
tests/lib/tst-t.c [deleted file]
tests/lib/uwildmat-t.c [deleted file]
tests/lib/vector-t.c [deleted file]
tests/lib/wire-t.c [deleted file]
tests/lib/xmalloc.c [deleted file]
tests/lib/xmalloc.t [deleted file]
tests/lib/xwrite-t.c [deleted file]
tests/libtest.c [deleted file]
tests/libtest.h [deleted file]
tests/overview/data/basic [deleted file]
tests/overview/data/bogus [deleted file]
tests/overview/data/high-numbered [deleted file]
tests/overview/data/reversed [deleted file]
tests/overview/munge-data [deleted file]
tests/overview/tradindexed-t.c [deleted file]
tests/runtests.c [deleted file]
tests/util/convdate.t [deleted file]

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
deleted file mode 100644 (file)
index 504329f..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-The following is a list of the people (in roughly chronological order)
-who've helped out.  If anyone's name has been left out (probably), or if
-something has been incorrectly attributed to you (ditto), please let us
-know.
-
-Rich Salz:
-        Designed and wrote most of it.
-
-Bob Halley:
-        Did the TCL extension.
-
-Christophe Wolfhugel:
-        Did the Perl extension and provided several other fixes.
-
-Doug Needham:
-        Made nnrpd spool if innd is unavailable.  Made nnrpd handle the
-        LIST SUBSCRIPTIONS command.  Added the rebuilding of control
-        connections to innd (SIGUSR1).  Got inews to ask the nntp peer for
-        moderator info instead of digging it out of a local file.
-
-David Lawrence: 
-        Did the hooks for PGP verificiation of control messages, added
-        actived support for syncing against an active file obtained via
-        ftp.
-
-John Stapleton:
-        Wrote the poison newsgroup code ('@') for newsfeeds(5).  Wrote the
-        too-many-connects support ('-X -H -T' flags to innd).
-        
-Landon Curt Noll:
-        Wrote or co-wrote actsync, nntpsend, shrinkfile, innstat,
-        news.daily, tally.control and various man pages.  He also was the
-        person originally behind the site directory
-        configuration/installation process.
-
-John Levine:
-        Wrote the '-e' support for expire (expire on shortest time).
-
-Matthias Urlichs:
-        Made rnews recognise gzip compression.  Made newsfeeds(5) take the
-        'Wp' flag.
-
-Stefan Petri:
-        Did the original XBATCH support
-
-Russel Street:
-        Did more XBATCH support.
-
-Alan Barrett:
-        Did the work-limiter in the select loop to stop streaming from
-        killing performance.
-
-Greg Patten:
-        Wrote the perl innlog.
-
-Clayton O'Neill:
-        Wrote the articles storage API and implemented the timehash
-        and regular storage mechanisms with it.  He made significant
-        modifications to dbz.  Integrating innfeed, adding Xref slaving,
-        the history cache, the WIP rewrite and various speedups were
-        also his doing.  Provided the tradindexed overview mechanism.
-        Implemented the O flag in newsfeeds.  Did a bunch of early work on
-        the CVS repository, reorganization of the code, and committing
-        patches from others.
-
-Vincent Archer:
-        Wrote the initial autoconf scripts.
-
-Forrest J. Cavalier III:
-        Provided a lot of bug fixes to 1.5.2.  He extended the autoconf
-        setup a lot to work with version 2.0, and has provided a lot of
-        valuable design input and testing.
-
-Scott Fritchie:
-        Wrote the CNFS storage back end.
-
-Fabien Tassin:
-        Wrote the innreport package.  Implemented the new incoming.conf
-        configuration file.  Added support for nested profile timers.
-
-Jeremy Nixon:
-        Wrote the initial patch for Perl filtering of message IDs on IHAVE
-        or CHECK and other patches related to the filtering code.
-
-Karl Kleinpaste:
-        Wrote the experimental code for automatically generating keywords
-        from incoming articles and putting those keywords in the overview
-        for the use of readers.
-
-Dave Hayes:
-        Along with some bugfixes, Dave wrote the posting-backoff code for 
-        nnrpd and the patches to the perl hooks to make the headers
-        modifiable.
-
-Joe Greco:
-        Wrote the code for measuring the timing of various parts of innd
-        and the original actived code.
-
-Sang-yong Suh:
-        Provided the fuzzy offset technique to dbz.
-
-Katsuhiro Kondou:
-        Provided unified overview, the buffindexed overview method, trash
-        storage method, spool translation method, traditional expire
-        policy for articles stored through storage API and expireindex, as
-        well as hundreds of fixes to clean up defects as changes were
-        made.  Did a large amount of man page documentation and clean up.
-        Has also been a major force in the CVS pool maintenace.
-
-Russell Vincent:
-        Expanded inn.conf to make many of the old compile time options
-        into run time variables.  Numerous bug fixes, small feature
-        enhancements and man updates.
-
-Darrell Fuhriman:
-        Provided various bug fixes and contributed to the pre-SM CNFS
-        development.
-
-Steve Carrie:
-        Modified nnrpd to allow detailed client tracking, added the -R
-        flag to nnrpd.
-
-Ed Mooring:
-        Wrote the first Perl filter callbacks into INN.
-
-Aidan Cully:
-        Provided the patches to support the new readers.conf file, and
-        wrote the initial user authenticators and resolvers for the
-        readers.conf.  Provided the patches to support the new
-        storage.conf format.  Added the option to store articles based on
-        the Expires header.  Also added the '@' article exclusion code to
-        incoming.conf.
-
-Andrew Gierth:
-        Contributed improvements to the nnrpd Perl filtering support to
-        give access to message bodies and support the DROP and SPOOL
-        keywords in filter returns.
-
-Russ Allbery:
-        Has done large amounts of clean-up on various pieces of the system
-        (especially the documentation and build system), and has helped
-        with the CVS pool maintenance.  Improved the speed and portability
-        of the Perl filter.  Rewrote the tradindexed overview method for
-        additional robustness.  Has done extensive work on libinn,
-        breaking out common code from other parts of INN.  Lots of other
-        fixes to various parts of INN.
-
-Kai Henningsen:
-        Implemented the C and U flags in newsfeeds.
-
-Julio Sanchez:
-        Wrote the initial libtool support for INN.
-
-Igor Timkin:
-        Added min-queue-connection support to innfeed, added outgoing
-        volume logging and reporting, and provided a variety of bug
-        fixes.
-
-Heath Kehoe:
-        Various portability and bug fixes, wrote the ovdb overview
-        mechanism that uses Berkeley DB.
-
-Richard Todd:
-        Implemented the timecaf and tradspool storage mechanisms, as well
-        as many bug fixes and other contributions.
-
-Brian Kantor:
-        Wrote the news2mail gateway.
-
-Ilya Etingof:
-        Added Python authentication support for nnrpd.
-
-Kenichi OKADA:
-        Added preliminary SSL and SASL support for nnrpd.
-
-Olaf Titz:
-        Implemented MODE CANCEL support, as well as other patches and bug
-        fixes.
-
-Sven Paulus:
-        Wrote the support for variables in newsfeeds, contributed various
-        other patches and bug fixes.
-
-Krischan Jodies:
-        Wrote the SMB authenticator.
-
-Alex Kiernan:
-        Wrote the history API, generalized the timer code in innd and
-        innfeed into a generic timer library, reworked the NEWNEWS code
-       and added a history cache, and contributed various other bug fixes.
-
-Marco d'Itri:
-        Wrote gpgverify and overhauled controlchan and its modules.  Added
-        IPv6 support to innd and inndstart.  Contributed a rewritten
-        send-uucp.  Has also contributed a variety of bug fixes and helped
-        with testing.
-
-Jeffrey M. Vinocur:
-        Broke parts of the interface with nnrpd for authentication programs
-        into a separate library, added various features to readers.conf,
-        and wrote various other fixes and feature improvements,
-        particularly to nnrpd.
-
-Erik Klavon:
-        Significantly reworked nnrpd Perl and Python hooks to be more useful
-        in combination with the readers.conf mechanism.
-
-Nathan Lutchansky:
-        Added IPv6 support to innfeed, nnrpd, and supporting programs.
-
-Also:
-
-Dave Barr:
-        Kept INN alive after Rich Salz didn't have the time any more but 
-        before the ISC took over.  He released 4 unofficial versions that 
-        provided a good boost to what the ISC started with.  Minor work
-        on 2.0, mostly with example files and minor code tweaks.
-
-James Brister:
-        The chief maintainer of INN from when the ISC took over
-        maintenance through the 2.2 release, James is also the original
-        author of innfeed and has made fixes, improvements, and feature
-        additions all over the code.
-
-Marc Fournier:
-        Provided various bug fixes and did a lot of work integrating other
-        peoples patches and looking after the CVS pool.  Helped
-        significantly with the conversion to autoconf.  Added the ability
-        to set connection limits on a per-host basis.
-
-Joshua M. Thompson
-        Wrote the original INSTALL documentation.
-
-The following people helped above and beyond the call of duty with testing
-(provided patches, bug reports, suggestions, documentation improvements,
-and lobbying):
-
-Paul Vixie, Robert Elz, Evan Champion, Robert Keller, Barry Bouwsma,
-markd@mira.net.au, Ollivier Robert, Kevin Jameson, Heiko W. Rupp,
-Fletcher Mattox, Matus Uhlar, Gabor Kiss, Matthias Scheler,
-Richard Michael Todd, Trevor Riley, Alex Bligh, J. Porter Clark,
-Alan Brown, Bert Hyman, Petter Nilsen, Gary E. Miller, Kim Culhan,
-Marc Baudoin, Neal Becker, Bjorn Knutsson, Stephen Marquard,
-Frederick Korz, Benedict Lofstedt, Dan Ellis, Joe Ramey,
-Odd Einar Aurbakken, Jon Lewis, Dan Riley, Peter Eriksson, Ken Lalonde,
-Koichi Mouri, J. Richard Sladkey, Trine Krogstad, Holger Burbach,
-Per Hedeland, Larry Rosenman, Andrew Burgess, Michael Brunnbauer,
-Mohan Kokal, Robert R. Collier, Mark Hittinger, Miquel van Smoorenburg,
-Boyd Lynn Gerber, Yury B. Razbegin, Joe St. Sauver, Heiko Schlichting,
-John P. Speno, Scott Gifford, Steve Parr, Robert Kiessling,
-Francis Swasey, Paul Tomblin, Florian La Roche, Curt Welch,
-Thomas Mike Michlmayr, KIZU Takashi, Michael Hall, Jeff King,
-Edward S. Marshall, Michael Schroeder, George Lindholm, Don Lewis,
-Christopher Masto, Hiroaki Sengoku, Yury July, Yar Tikhiy, Kees Bakker,
-Peter da Silva, Matt McLeod, Ed Korthof, Jan Rychter, Winfried Magerl,
-Andreas Lamrecht, Duane Currie, Ian Dickinson, Bettina Fink,
-Jochen Erwied, Rebecca Ore, Felicia Neff, Antonio Querubin, Bear Giles,
-Christopher P. Lindsey, Winfried Szukalski, Edvard Tuinder,
-Frank McConnell, Ilya Kovalenko, Steve Youngs, Jacek Konieczny,
-Ilya Voronin, Sergey Babitch, WATANABE Katsuhiro, Chris Caputo,
-Thomas Parmelan
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644 (file)
index 397156e..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,238 +0,0 @@
-2008-06-29  iulius
-
-       * lib/perl.c: Use snprintf instead of asprintf.
-
-       * doc/hook-python, doc/pod/hook-python.pod: Use initial capital
-         letters for head titles.
-
-       * NEWS, doc/pod/news.pod, lib/perl.c: Fixed a hang in Perl hooks on
-         (at least) HP/PA since Perl 5.10. On such architectures,
-         pthread_mutex_lock() hangs inside perl_parse() if
-         PERL_SYS_INIT3() hasn't been called.
-         
-         Also rewrite "do" and "eval" calls to use perl_eval_pv().
-
-2008-06-25  iulius
-
-       * samples/innreport.conf.in: For two sections in innreport.conf
-         there is a mismatch between sort function and sorted hash.
-         
-         Thanks to Alexander Bartolich for this patch.
-
-2008-06-24  iulius
-
-       * NEWS, doc/pod/news.pod, scripts/innreport_inn.pm: Fix another
-         long-standing bug in innreport which prevented it from correctly
-         reporting innfeed log messages.
-
-       * scripts/innreport_inn.pm: Suppress a few other nnrpd and
-         controlchan notices in innreport.
-
-2008-06-23  iulius
-
-       * NEWS, doc/pod/news.pod: Add changelog for innreport.
-
-       * NEWS, doc/pod/news.pod: Changelog for INN 2.4.5 :-)
-
-       * doc/hook-python: Update the auto-generated documentation for INN
-         2.4.5.
-
-       * scripts/innreport_inn.pm: Fix a long-standing bug in innreport
-         which prevented it from correctly reporting nnrpd log messages.
-
-       * scripts/innreport_inn.pm: Suppress a few warnings in innreport
-         (especially from Python hooks and nnrpd). Also backport some
-         other improvements made in TRUNK.
-
-       * site, site/.cvsignore, site/Makefile: Install nnrpd.py which
-         previously was not.
-
-       * MANIFEST, samples/nnrpd_access.py, samples/nnrpd_auth.py,
-         samples/nnrpd_dynamic.py, site, site/.cvsignore, site/Makefile:
-         Update the Python nnrpd filter. New samples for access and
-         dynamic hooks.
-
-2008-06-22  iulius
-
-       * samples/filter_innd.py: Update the Python innd filter.
-
-       * doc/pod/hook-python.pod: Typo (canceled -> cancelled).
-
-       * samples/nnrpd_access_wrapper.py, samples/nnrpd_auth_wrapper.py,
-         samples/nnrpd_dynamic_wrapper.py: Update old Python wrappers.
-
-       * samples/INN.py, samples/nnrpd.py: Update stub Python scripts. Fix
-         a compilation problem with INN.py (undefined variable) and add
-         missing methods.
-
-       * doc/hook-python, doc/man/readers.conf.5, doc/pod/hook-python.pod,
-         doc/pod/readers.conf.pod: Update POD documentation for Python
-         hooks. It is a complete proof-reading.
-
-       * nnrpd/python.c: No need to check the existence of methods not
-         used by the hooked script.
-
-       * innd/python.c, nnrpd/python.c: Fix an issue with Python exception
-         handling.
-
-       * nnrpd/python.c: Fix typos.
-
-       * nnrpd/python.c: Fix a segfault when one closes and then reopens
-         Python in the same process. files and dynamic_file are still
-         pointing to the old freed memory and INN blithely tries to write
-         to it. Thanks to Russ Allbery for the patch.
-
-2008-06-21  iulius
-
-       * innd/python.c: Better be more careful when decrementing the
-         reference count for these objects.
-
-2008-06-16  iulius
-
-       * doc/external-auth, doc/hook-perl, doc/hook-python,
-         doc/man/active.5, doc/man/active.times.5, doc/man/auth_krb5.8,
-         doc/man/auth_smb.8, doc/man/ckpasswd.8, doc/man/control.ctl.5,
-         doc/man/convdate.1, doc/man/cycbuff.conf.5,
-         doc/man/distrib.pats.5, doc/man/domain.8, doc/man/expire.ctl.5,
-         doc/man/expireover.8, doc/man/fastrm.1, doc/man/grephistory.1,
-         doc/man/ident.8, doc/man/inews.1, doc/man/inn.conf.5,
-         doc/man/innconfval.1, doc/man/innd.8, doc/man/inndf.8,
-         doc/man/inndstart.8, doc/man/innmail.1, doc/man/innupgrade.8,
-         doc/man/libauth.3, doc/man/libinnhist.3, doc/man/list.3,
-         doc/man/mailpost.8, doc/man/makehistory.8, doc/man/motd.news.5,
-         doc/man/newsfeeds.5, doc/man/ninpaths.8, doc/man/nnrpd.8,
-         doc/man/ovdb.5, doc/man/ovdb_init.8, doc/man/ovdb_monitor.8,
-         doc/man/ovdb_server.8, doc/man/ovdb_stat.8,
-         doc/man/passwd.nntp.5, doc/man/qio.3, doc/man/radius.8,
-         doc/man/radius.conf.5, doc/man/rc.news.8, doc/man/readers.conf.5,
-         doc/man/sasl.conf.5, doc/man/sendinpaths.8, doc/man/simpleftp.1,
-         doc/man/sm.1, doc/man/subscriptions.5, doc/man/tdx-util.8,
-         doc/man/tst.3, doc/man/uwildmat.3: Update version number for INN
-         2.4.5 documentation.
-
-2008-06-11  iulius
-
-       * support/config.guess, support/config.sub: Update support files
-         for autoconf to their last stable version.
-
-2008-06-10  iulius
-
-       * innd/python.c: Fix the name of a variable used in Python filters.
-
-2008-06-09  iulius
-
-       * innd/python.c: Fix a bug when reloading Python filters. They
-         might not be correctly reloaded. They must be reimported before
-         being reloaded.
-
-       * nnrpd/python.c: Fix a segfault when generating access groups with
-         embedded Python filters for nnrpd. Thanks to David Hlacik for the
-         bug report.
-
-2008-06-08  iulius
-
-       * frontends/pullnews.in: Two minor issues resolved with this patch
-         by Geraint Edwards: * an off-by-one error on the limit to the
-         amount of articles to get; * when an article is not available, we
-         may have redundantly retried that article.
-
-2008-06-07  iulius
-
-       * doc/pod/cycbuff.conf.pod, doc/pod/hook-perl.pod,
-         doc/pod/hook-python.pod, innd/python.c, samples/filter_innd.pl:
-         Fix the use of "ctlinnd reload something 'reason'" in
-         documentation.
-
-2008-06-05  iulius
-
-       * doc/hook-perl, doc/hook-python, doc/pod/hook-perl.pod,
-         doc/pod/hook-python.pod, innd/innd.c, innd/innd.h,
-         samples/filter_innd.py: Add access to several new headers within
-         Perl and Python hooks for innd. Thanks to Matija Nalis for the
-         patch.
-         
-         Also update the POD documentation and the Python sample.
-
-       * doc/man/pullnews.1, doc/pod/pullnews.pod, frontends/pullnews.in:
-         A new improved version of pullnews. Great thanks to Geraint A.
-         Edwards for all his work. He added no more than 16 flags, fixed
-         some bugs and integrated the backupfeed contrib script by Kai
-         Henningsen, adding again 6 other flags.
-         
-         A long-standing but very minor bug in the -g option was
-         especially fixed and items from the to-do list implemented.
-         
-         From TODO:
-         
-         + reset highwater mark to match server (-w) + reset highwater
-         mark to zero (also -w) + add group to config (-G) + drop articles
-         with headers matching (or not matching) regexp (-m)
-         
-         From backupfeed:
-         
-         + pull only a proportion (factor) of articles (-f) + sleeps
-         between articles/groups (-z/-Z) + Path: fake hop insert (-F) +
-         NNTP connection timeout (-N) + overall session timeout (-S)
-         
-         Other new flags/features:
-         
-         -l logfile log to logfile (rather than /dev/null when rnews'ing!)
-         -s host:port add local port option (can use -p already) -t
-         retries attempt connect to upstream retries times -T retry_pause
-         wait between retries -k checkpt checkpoint the config file every
-         checkpt arts -C width when writing the progress bar - use width
-         columns -d debug_level self-explanatory -M max_arts only process
-         max_arts articles per run -H headers remove these headers from
-         articles -Q quietness set how quiet we are -R be a reader -n
-         no-op -P paths feed articles depending on number of hops in Path:
-
-2008-05-25  iulius
-
-       * control/modules/newgroup.pl: Fix a Perl warning.
-
-2008-05-24  iulius
-
-       * nnrpd/tls.c: When an article of a size greater than remaining
-         stack is retrieved via SSL, a segmentation fault will occur due
-         to the use of alloca(). The below patch uses heap based realloc()
-         instead of stack based alloca(), with a static buffer growing as
-         needed. It uses realloc() instead of malloc() for performance
-         reasons since this function is called frequently. The caveat is
-         that the memory is never free()'ed, so if more correct code is
-         desired, it should be adjusted.
-         
-         Thanks to Chris Caputo for this patch.
-
-2008-05-19  iulius
-
-       * innd/Makefile, nnrpd/line.c: Implementation of the "alarm signal"
-         around SSL_read so that to prevent dead connections from leading
-         nnrpd processes to wait forever in SSL_read(). "clienttimeout"
-         now also works on SSL connections.
-         
-         Thanks to Matija Nalis for the patch.
-
-       * nnrpd/tls.c: Implementation on systems that support it of
-         SO_KEEPALIVE in SSL TCP connections, allowing system detection
-         and closing the dead TCP SSL connections automatically after
-         system-specified time (usually at least 2 hours as recommended by
-         RFC (on Linux, see /proc/sys/net/ipv4/tcp_keepalive_*).
-         
-         Thanks to Matija Nalis for the patch.
-
-2008-05-18  iulius
-
-       * innfeed/host.c: Fix a problem of undefined constant.
-
-2008-05-14  iulius
-
-       * innfeed/host.c: Fix a bug in ipAddrs which contained thrice the
-         same IPs. Rotating the peer IP addresses was a bit slower than it
-         could be.
-         
-         Thanks, D. Stussy, for having seen that. Miquel van Smoorenburg
-         provided the patch.
-
-       * Makefile.global.in: Bump the revision number to 2.4.5 (in case it
-         is released one day).
-
diff --git a/HACKING b/HACKING
deleted file mode 100644 (file)
index 87a76e3..0000000
--- a/HACKING
+++ /dev/null
@@ -1,708 +0,0 @@
-Hacking INN
-
-    This file is for people who are interested in making modifications to
-    INN.  Normal users can safely skip reading it.  It is intended primarily
-    as a guide, resource, and accumulation of tips for maintainers and
-    contributors, and secondarily as documentation of some of INN's
-    internals.
-
-    This is $Revision: 7736 $ dated $Date: 2006-04-15 04:52:06 +0200 (Sat,
-    15 Apr 2006) $.
-
-    First of all, if you plan on working on INN source, please start from
-    the current development tree.  There may be significant changes from the
-    previous full release, so starting from development sources will make it
-    considerably easier to integrate your work.  You can get nightly
-    snapshots of the current development source from ftp.isc.org in
-    /isc/inn/snapshots (the snapshots named inn-CURRENT-*.tar.gz), or you
-    can get the current CVS tree by using CVSup (see "Using CVSup").
-
-Configuring and Portability
-
-    All INN code should be written expecting ANSI C and POSIX.  There is no
-    need to attempt to support pre-ANSI compilers, and ANSI-only features
-    such as <stdarg.h>, string concatenation, #elif, and token pasting may
-    be used freely.  So far as possible, INN is written to attempt to be
-    portable to any system new enough that someone is likely to want to run
-    a news server on it, but whenever possible this portability should be
-    provided by checking for standard behavior in configure and supplying
-    replacements for standard functions that are missing.
-
-    When there is a conflict between ANSI C and C99, INN code should be
-    written expecting C99 and autoconf used to patch up the differences.
-
-    Try to avoid using #ifdef and the like in the middle of code as much as
-    possible.  Instead, try to isolate the necessary portability bits and
-    include them in libinn or at least in conditional macros separate from
-    the code.  Trying to read code littered with conditional compilation
-    directives is much more difficult.
-
-    The shell script configure at the top level of the source tree is
-    generated by autoconf from configure.in, and include/config.h.in is
-    generated by autoheader from configure.in and include/acconfig.h.  At
-    configure time, configure generates include/config.h and several other
-    files based on options it was given and what it discovers about the
-    target system.
-
-    All modifications to configure should instead be made to configure.in. 
-    Similarly, modifications to include/config.h.in should instead be made
-    to include/acconfig.h.  The autoconf manual (available using info
-    autoconf if you have autoconf and the GNU info utilities installed on
-    your system) is a valuable reference when making any modifications.
-
-    To regenerate configure, just run "autoconf".  To regenerate
-    include/config.h.in, run:
-
-        autoheader -l include
-
-    to tell it where to find acconfig.h.  Please don't include patches to
-    either configure or include/config.h.in when sending patches to INN;
-    instead, note in your patch that those files must be regenerated.
-
-    The generated files are checked into the CVS repository so that people
-    working on INN don't have to have autoconf on their system, and to make
-    packaging easier.
-
-    At the time of this writing, autoconf 2.13 is required.
-
-    The supporting files for autoconf are in the support subdirectory,
-    including the files config.guess and config.sub to determine the system
-    name and and ltmain.sh for libtool support.  The latter file comes from
-    the libtool distribution; the canonical version of the former two are
-    available from ftp.gnu.org in /gnu/config.  In addition, m4/libtool.m4
-    is just a copy of libtool.m4 from the libtool distribution.  (Using
-    libtool without using automake requires a few odd hacks.)  These files
-    used to be on a separate vendor branch so that we could make local
-    modifications, but local modifications have not been necessary for some
-    time.  Now, new versions can just be checked in like any other file
-    modifications.
-
-    INN should not compile with libtool by default, only when requested,
-    since otherwise normal compilations are quite slow.  (Using libtool is
-    not without some cost.)  Basic compilation with libtool works fine as of
-    this writing, with both static and shared compiles, but the dependencies
-    aren't quite right for make -j using libtool.
-
-Documentation
-
-    INN's documentation is currently somewhat in a state of flux.  The vast
-    majority is still in the form of man pages written directly in nroff. 
-    Some parts of the documentation have been rewritten in POD; that
-    documentation can be found in doc/pod.  The canonical source for README,
-    INSTALL, NEWS, doc/hook-perl, doc/hook-python, and this file are also in
-    POD.
-
-    If you're modifying some part of INN's documentation and see that it has
-    a POD version in doc/pod, it's preferred if you can make the
-    modifications to the POD source and then regenerate the derived files. 
-    For a quick introduction to POD, see the perlpod(1) man page on your
-    system (it should be installed if you have Perl installed).
-
-    When writing new documentation, write in whatever format you care to; if
-    necessary, we can always convert it to POD or whatever else we want to
-    use.  Having the documentation exist in *some* form is more important
-    than what language you write it in.  If you really don't have any
-    particular preference, there's a slight preference currently for POD.
-
-    If you use POD or regenerate POD documentation, please install something
-    close to the latest versions of the POD processing utilities to avoid
-    changes to the documentation depending on who generated it last.  You
-    can find the latest version on CPAN (ftp.perl.org or another mirror) in
-    modules/by-module/Pod.  You'll need PodParser (for versions of Perl
-    before 5.6.1; 5.6.1 and later come with a recent enough version) and the
-    latest version of podlators.  For versions of Perl earlier than 5.005,
-    you'll also need File::Spec in modules/by-module/File.
-
-    podlators 1.25 or later will build INN's documentation without
-    significant changes from the versions that are checked into the
-    repository.
-
-    There are Makefile rules in doc/pod/Makefile to build all of the
-    documentation whose master form is POD; if you add additional
-    documentation, please add a rule there as well.  Documentation should be
-    generated by cd'ing to doc/pod and typing "make file" where "file" is
-    the relative path to the documentation file.  This will get all of the
-    various flags right for pod2text or pod2man.
-
-Error Handling
-
-    INN has a set of generic error handling routines that should be used as
-    much as possible so that the same syntax can be used for reporting
-    errors everywhere in INN.  The four basic functions are warn, syswarn,
-    die, and sysdie; warn prints or logs a warning, and die does the same
-    and then exits the current program.  The sys* versions add a colon, a
-    space, and the value of strerror(errno) to the end of the message, and
-    should be used to report failing system calls.
-
-    All of the actual error reporting is done via error handlers, and a
-    program can register its own handlers in addition to or instead of the
-    default one.  The default error handler (error_log_stderr) prints to
-    stderr, prepending the value of error_program_name if it's set to
-    something other than NULL.  Three other error handlers are available,
-    error_log_syslog_crit, error_log_syslog_err, and
-    error_log_syslog_warning, which log the message to syslog at LOG_CRIT,
-    LOG_ERR, or LOG_WARNING priority, respectively.
-
-    There is a different set of error handlers for warn/syswarn and
-    die/sysdie.  To set them, make calls like:
-
-        warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
-        die_set_handlers(2, error_log_stderr, error_log_syslog_err);
-
-    The first argument is the number of handlers, and the remaining
-    arguments are pointers to functions taking an int (the length of the
-    formatted message), a const char * (the format), a va_list (the
-    arguments), and an int that's 0 if warn or die was called and equal to
-    the value of errno if syswarn or sysdie was called.  The length of the
-    formatted message is obtained by calling vsnprintf with the provided
-    format and arguments, and therefore is reliable to use as the size of a
-    buffer to malloc to hold the result of formatting the message provided
-    that vsnprintf is used to format it (warning: the system vsprintf may
-    produce more output under some circumstances, so always use vsnprintf).
-
-    The error handler can do anything it wishes; each error handler is
-    called in the sequence given.  Error handlers shouldn't call warn or die
-    unless great caution is taken to prevent infinite recursion.  Also be
-    aware that sysdie is called if malloc fails in xmalloc, so if the error
-    handler needs to allocate memory, it must not use xmalloc or a related
-    function to do so and it shouldn't call die to report failure.  The
-    default syslog handlers report memory allocation failure to stderr and
-    exit.
-
-    Finally, die and sysdie support an additional handler that's called
-    immediate before exiting, takes no arguments, and returns an int which
-    is used as the argument for exit.  It can do any necessary global
-    cleanup, call abort instead to generate a core dump or the like.
-
-    The advantage of using this system everywhere in INN is that library
-    code can use warn and die to report errors and each calling program can
-    set up the error handlers as appropriate to make sure the errors go to
-    the right place.  The default handler is fine for interactive programs;
-    for programs that run from interactive scripts, adding something like:
-
-        error_program_name = "program";
-
-    to the beginning of main (where program is the name of the program) will
-    make it easier to figure out which program the script calls is failing. 
-    For programs that may also be called non-interactively, like inndstart,
-    one may want to set up handlers like:
-
-        warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
-        die_set_handlers(2, error_log_stderr, error_log_syslog_err);
-
-    Finally, for daemons and other non-interactive programs, one may want to
-    do:
-
-        warn_set_handlers(1, error_log_syslog_warning);
-        die_set_handlers(1, error_log_syslog_err);
-
-    to report errors only via syslog.  (Note that if you use syslog error
-    handlers, the program should call openlog first thing to make sure they
-    are logged with the right facility.)
-
-    For historical reasons, error messages that are fatal to the news
-    subsystem are logged at the LOG_CRIT priority, and therefore die in innd
-    should use error_log_syslog_crit.
-
-Test Suite
-
-    The test suite for INN is located in the tests directory and is just
-    getting started.  The test suite consists of a set of programs listed in
-    tests/TESTS and the scaffolding in the runtests program.
-
-    Adding new tests is very straightforward and very flexible.  Just write
-    a program that tests some part of INN, put it in a directory under tests
-    named after the part of INN it's testing (all the tests so far are in
-    lib because they're testing libinn routines), and have it output first a
-    line containing the count of test cases in that file, and then for each
-    test a line saying "ok n" or "not ok n" where n is the test case number.
-    (If a test is skipped for some reason, such as a test of an optional
-    feature that wasn't compiled into INN, the test program should output
-    "ok n # skip".)  Add any rules necessary to build the test to
-    tests/Makefile (note that for simplicity it doesn't recurse into
-    subdirectories) and make sure it creates an executable ending in .t. 
-    Then add the name of the test to tests/TESTS, without the .t ending.
-
-    One naming convention:  to distinguish more easily between e.g. 
-    lib/error.c (the implementation) and tests/lib/error-t.c (the test
-    suite), we add -t to the end of the test file names.  So
-    tests/lib/error-t.c is the source that compiles into an executable
-    tests/lib/error.t which is run by putting a line in tests/TESTS of just
-    "lib/error".
-
-    Note that tests don't have to be written in C; in fact, lib/xmalloc.t is
-    just a shell script (that calls a supporting C program).  Tests can be
-    written in shell or Perl (but other languages should be avoided because
-    someone who wants to run the test suite may not have it) and just have
-    to follow the above output conventions.
-
-    Additions to the test suite, no matter how simple, are very welcome.
-
-Makefiles
-
-    All INN makefiles include Makefile.global at the top level, and only
-    that makefile is a configure substitution target.  This has the
-    disadvantage that configure's normal support for building in a tree
-    outside of the source tree doesn't work, but it has the significant
-    advantage of making configure run much faster and allowing one to run
-    make in any subdirectory and pick up all the definitions and settings
-    from the top level configuration.
-
-    All INN makefiles should also set $(top) to be the path to the top of
-    the build directory (usually relative).  This path is used to find
-    various programs like fixscript and libtool so that the same macros (set
-    in Makefile.global) can be used all over INN.
-
-    The format of INN's makefiles is mostly standardized; the best examples
-    of the format are probably frontends/Makefile and backends/Makefile, at
-    least for directories with lots of separate programs.  The ALL variable
-    holds all the files that should be generated, EXTRA those additional
-    files that were generated by configure, and SOURCES the C source files
-    for generating tag information.
-
-    There are a set of standard installation commands defined in make
-    variables by Makefile.global, and these should be used for all file
-    installations.  See the comment blocks in Makefile.global.in for
-    information on what commands are available and when they should be used.
-    There are also variables set for each of the installation directories
-    that INN uses, for use in building the list of installed paths to files.
-
-    Each subdirectory makefile should have the targets all (the default),
-    clean, clobber, install, tags, and profiled.  The tags target generates
-    vi tags files, and the profiled target generates a profiling version of
-    the programs (although this hasn't been tested much recently).  These
-    rules should be present and empty in those directories where they don't
-    apply.
-
-    Be sure to test compiling with both static and dynamic libraries and
-    make sure that all the libtool support works correctly.  All linking
-    steps, and the compile steps for all library source, should be done
-    through $(LIBTOOL) (which will be set to empty in Makefile.global if
-    libtool support isn't desired).
-
-Scripts
-
-    INN comes with and installs a large number of different scripts, both
-    Bourne shell and Perl, and also comes with support for Tcl scripts
-    (although it doesn't come with any).  Shell variables containing both
-    configure-time information and configuration information from inn.conf
-    are set by the innshellvars support libraries, so the only
-    system-specific configuration that should have to be done is fixing the
-    right path to the interpretor and adding a line to load the appropriate
-    innshellvars.
-
-    support/fixscript, built by configure, does this.  It takes a .in file
-    and generates the final script (removing the .in) by fixing the path to
-    the interpretor on the first line and replacing the second line,
-    whatever it is, with code to load the innshellvars appropriate for that
-    interpretor.  (If invoked with -i, it just fixes the interpretor path.)
-
-    Scripts should use innshellvars (via fixscript) to get the right path
-    and the right variables whenever possible, rather than having configure
-    substitute values in them.  Any values needed at run-time should instead
-    be available from all of the different innshellvars.
-
-    See the existing scripts for examples of how this is done.
-
-Include Files
-
-    Include files relevant to all of INN, or relevant to the two libraries
-    built as part of INN (the utility libinn library and the libstorage
-    library that contains all storage and overview functions) are found in
-    the include directory; other include files relevant only to a portion of
-    INN are found in the relevant directory.
-
-    Practically all INN source files will start with:
-
-        #include "config.h"
-        #include "clibrary.h"
-
-    The first picks up all defines generated by autoconf and is necessary
-    for types that may not be present on all systems (uid_t, pid_t, size_t,
-    int32_t, and the like).  It therefore should be included before any
-    other headers that use those types, as well as to get general
-    configuration information.
-
-    The second is portably equivalent to:
-
-        #include <sys/types.h>
-        #include <stdarg.h>
-        #include <stdio.h>
-        #include <stdlib.h>
-        #include <stddef.h>
-        #include <stdint.h>
-        #include <string.h>
-        #include <unistd.h>
-
-    except that it doesn't include headers that are missing on a given
-    system, replaces functions not found on the system with the INN
-    equivalents, provides macros that INN assumes are available but which
-    weren't found, and defines some additional portability things.  Even if
-    this is more headers than the source file actually needs, it's generally
-    better to just include clibrary.h rather than trying to duplicate the
-    autoconf-driven hackery that it does to do things portably.  The primary
-    exception is for source files in lib that only define a single function
-    and are used for portability; those may want to include only config.h so
-    that they can be easily used in other projects that use autoconf. 
-    config.h is a fairly standard header name for this purpose.
-
-    clibrary.h does also include config.h, but it's somewhat poor form to
-    rely on this; it's better to explicitly list the header dependencies for
-    the benefit of someone else reading the code.
-
-    There are portable wrappers around several header files that have known
-    portability traps or that need some fixing up on some platforms.  Look
-    in include/portable and familiarize yourself with them and use them
-    where appropriate.
-
-    Another frequently included header file is libinn.h, which among other
-    things defines xmalloc(), xrealloc(), xstrdup(), and xcalloc(), which
-    are checked versions of the standard memory allocation routines that
-    terminate the program if the memory allocation fails.  These should
-    generally always be used instead of the regular C versions.  libinn.h
-    also provides various other utility functions that are frequently used.
-
-    paths.h includes a wide variety of paths determined at configure time,
-    both default paths to various parts of INN and paths to programs.  Don't
-    just use the default paths, though, if they're also configurable in
-    inn.conf; instead, call ReadInnConf() and use the global innconf
-    structure.
-
-    Other files in include are interfaces to particular bits of INN library
-    functionality or are used for other purposes; see the comments in each
-    file.
-
-    Eventually, the header files will be separated into installed header
-    files and uninstalled header files; the latter are those headers that
-    are used only for compiling INN and aren't useful for users of INN's
-    libraries (such as clibrary.h).  All of the installed headers will live
-    in include/inn and be installed in a subdirectory named inn in the
-    configured include directory.  This conversion is still in progress.
-
-    When writing header files, remember that C reserves all identifiers
-    beginning with two underscores and all identifiers beginning with an
-    underscore and a capital letter for the use of the implementation; don't
-    use any identifiers with names like that.  Additionally, any identifier
-    beginning with an underscore and a lower-case letter is reserved in file
-    scope, which means that such identifiers can only be used by INN for the
-    name of structure members or function arguments in function prototypes.
-
-    Try to pay attention to the impact of a header file on the program
-    namespace, particularly for installed header files in include/inn.  All
-    symbols defined by a header file should ideally begin with INN_, inn_,
-    or some other unique prefix indicating the subsystem that symbol is part
-    of, to avoid accidental conflicts with symbols defined by the program
-    that uses that header file.
-
-Coding Style
-
-    INN has quite a variety of coding styles intermixed.  As with all
-    programs, it's preferrable when making minor modifications to keep the
-    coding style of the code you're modifying.  In INN, that will vary by
-    file.  (Over time we're trying to standardize on one coding style, so
-    changing the region you worked on to fit the general coding style is
-    also acceptable).
-
-    If you're writing a substantial new piece of code, the prevailing
-    "standard" INN coding style appears to be something like the following:
-
-    *  Write in regular ANSI C whenever possible.  Use the normal ANSI and
-       POSIX constructs and use autoconf or portability wrappers to fix
-       things up beforehand so that the code itself can read like regular
-       ANSI or POSIX code.  Code should be written so that it works as
-       expected on a modern platform and is fixed up with portability tricks
-       for older platforms, not the other way around.  You may assume an
-       ANSI C compiler.
-
-       Try to use const wherever appropriate.  Don't use register; modern
-       compilers will do as good of a job as you will in choosing what to
-       put into a register.  Don't bother with restrict (at least yet).
-
-    *  Use string handling functions that take counts for the size of the
-       buffer whenever possible.  This means using snprintf in preference to
-       sprintf and using strlcpy and strlcat in preference to strcpy and
-       strcat.  Also, use strlcpy and strlcat instead of strncpy and strncat
-       unless the behavior of the latter is specifically required, as it is
-       much easier to audit uses of the former than the latter.  (strlcpy is
-       like strncpy except that it always nul-terminates and doesn't fill
-       the rest of the buffer with nuls, making it more efficient.  strlcat
-       is like strncat except that it always nul-terminates and it takes the
-       total size of the buffer as its third argument rather than just the
-       amount of space left.)  All of these functions are guaranteed to be
-       available; there are replacements in lib for systems that don't have
-       them.
-
-    *  Avoid #ifdef and friends whenever possible.  Particularly avoid using
-       them in the middle of code blocks.  Try to hide all portability
-       preprocessor magic in header files or in portability code in lib. 
-       When something just has to be done two completely different ways
-       depending on the platform or compile options or the like, try to
-       abstract that functionality out into a generic function and provide
-       two separate implementations using #ifdef; then the main code can
-       just call that function.
-
-       If you do have to use preprocessor defines, note that if you always
-       define them to either 0 or 1 (never use #define without a second
-       argument), you can use the preprocessor define in a regular if
-       statement rather than using #if or #ifdef.  Make use of this instead
-       of #ifdef when possible, since that way the compiler will still
-       syntax-check the other branch for you and it makes it far easier to
-       convert the code to use a run-time check if necessary. 
-       (Unfortunately, this trick can't be used if one branch may call
-       functions unavailable on a particular platform.)
-
-    *  Avoid uses of fixed-width buffers except in performance-critical
-       code, as it's harder to be sure that such code is correct and it
-       tends to be less flexible later on.  If you need a reusable,
-       resizable memory buffer, one is provided in lib/buffer.c.
-
-    *  Avoid uses of static variables whenever possible, particularly in
-       libraries, because it interferes with making the code re-entrant down
-       the road and makes it harder to follow what's going on.  Similarly,
-       avoid using global variables whenever possible, and if they are
-       required, try to wrap them into structures that could later be
-       changed into arguments to the affected functions.
-
-    *  Roughly BSD style but with four-space indents.  This means no space
-       before the parens around function arguments, open brace on the same
-       line as if/while/for, and close and open brace on the same line as
-       else).
-
-    *  Introductory comments for functions or files are generally written
-       as:
-
-           /*
-           **  Introductory comment.
-           */
-
-       Other multiline comments in the source are generally written as:
-
-           /* This is a
-              multiline comment. */
-
-       Comments before functions saying what they do are nice to have.  In
-       general, the RCS/CVS Id tag is on the first line of each source file
-       since it's useful to know when a file was last modified.
-
-    *  Checks for NULL pointers are preferrably written out explicitly; in
-       other words, use:
-
-           if (p != NULL)
-
-       rather than:
-
-           if (p)
-
-       to make it clearer what the code is assuming.
-
-    *  It's better to always put the body of an if statement on a separate
-       line, even if it's only a single line.  In other words, write:
-
-           if (p != NULL)
-               return p;
-
-       and not:
-
-           if (p != NULL) return p;
-
-       This is in part for a practical reason:  some code coverage analysis
-       tools like purecov will count the second example above as a single
-       line and won't notice if the condition always evaluates the same way.
-
-    *  Plain structs make perfectly reasonable abstract data types; it's not
-       necessary to typedef the struct to something else.  Structs are
-       actually very useful for opaque data structures, since you can
-       predeclare them and then manipulate pointers to them without ever
-       having to know what the contents look like.  Please try to avoid
-       typedefs except for function pointers or other extremely confusing
-       data types, or for data types where we really gain some significant
-       data abstraction from hiding the underlying data type.  Also avoid
-       using the _t suffix for any type; all types ending in _t are reserved
-       by POSIX.  For typedefs of function pointer types, a suffix of _func
-       usually works.
-
-       This style point is currently widely violated inside of INN itself;
-       INN originally made extensive use of typedefs.
-
-    *  When noting something that should be improved later, add a comment
-       containing "FIXME:" so that one can easily grep for such comments.
-
-    INN's indentation style roughly corresponds to that produced by GNU
-    indent 2.2.6 with the following options:
-
-        -bad -bap -nsob -fca -lc78 -cd41 -cp1 -br -ce -cdw -cli0 -ss -npcs
-        -ncs -di1 -nbc -psl -brs -i4 -ci4 -lp -ts8 -nut -ip5 -lps -l78 -bbo
-        -hnl
-
-    Unfortunately, indent currently doesn't get everything right (it has
-    problems with spacing around struct pointer arguments in functions,
-    wants to put in a space between a dereference of a function pointer and
-    the arguments to the called function, misidentifies some macro calls as
-    being type declarations, and fouls up long but simple case statements). 
-    It would be excellent if someday we could just run all of INN's code
-    through indent routinely to enforce a consistant coding style, but
-    indent isn't quite ready for that.
-
-    For users of emacs cc-mode, use the "bsd" style but with:
-
-        (setq c-basic-offset 4)
-
-    Finally, if possible, please don't use tabs in source files, since they
-    can expand differently in different environments.  In particular, please
-    try not to use the mix of tabs and spaces that is the default in emacs. 
-    If you use emacs to edit INN code, you may want to put:
-
-        ; Use only spaces when indenting or centering, no tabs.
-        (setq-default indent-tabs-mode nil)
-
-    in your ~/.emacs file.
-
-    Note that this is only a rough guideline and the maintainers aren't
-    style nazis; we're more interested in your code contribution than in how
-    you write it.
-
-Using CVSup
-
-    If you want to get updated INN source more easily or more quickly than
-    by downloading nightly snapshots, or if you want to see the full CVS
-    history, you may want to use CVSup to download the source.  CVSup is a
-    client and server designed for replicating CVS repositories between
-    sites.
-
-    Unfortunately, CVSup is written in Modula-3, so getting a working binary
-    can be somewhat difficult.  Binaries are available in the *BSD ports
-    collection or (for a wide variety of different platforms) available from
-    <ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/binaries/> and its mirrors. 
-    Alternately, you can get a compiler from <http://m3.polymtl.ca/m3/>
-    (this is more actively maintained than the DEC Modula-3 compiler) and
-    the source from <ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/>.
-
-    After you have the CVSup client, you need to have space to download the
-    INN repository and space for CVSup to store its data files.  You also
-    need to write a configuration file (a supfile) for CVSup.  The following
-    supfile will download the latest versions from the mainline source:
-
-        *default host=inn-cvs.isc.org
-        *default base=<data-location>
-        *default prefix=<download-location>
-        *default release=cvs
-        *default tag=.
-        *default delete use-rel-suffix
-        inn
-
-    where <data-location> should be a directory where CVSup can put its data
-    files and <download-location> is where the downloaded source will go (it
-    will be put into a subdirectory named inn).  If you want to pull down
-    the entire CVS repository instead (warning: this is much larger than
-    just the latest versions of the source), delete the "*default tag=."
-    line.  The best way to download the CVS repository is to download it
-    into a portion of a locally-created CVS repository, so that then you can
-    perform standard CVS operations (like cvs log) against the downloaded
-    repository.  Creating your own local CVS repository is outside the scope
-    of this document.
-
-    Note that only multiplexed mode is supported (this mode should be the
-    default).
-
-    For more general information on using CVSup, see the FreeBSD page on it
-    at <http://www.freebsd.org/handbook/mirrors-cvsup.html>.
-
-Making a Release
-
-    This is a checklist that INN maintainers should go through when
-    preparing a new release of INN.
-
-    1.  If making a major release, branch the source tree and create a new
-        STABLE branch tag.  This branch will be used for minor releases
-        based on that major release and can be done a little while before
-        the .0 release of that major release.  At the same time as the
-        branch is cut, tag the trunk with a STABLE-<version>-branch marker
-        tag so that it's easy to refer to the trunk at the time of the
-        branch.
-
-    2.  Update doc/pod/news.pod and regenerate NEWS.  Be more detailed for a
-        minor release than for a major release.  For a major release, also
-        add information on how to upgrade from the last major release,
-        including anything special to be aware of.  (Minor releases
-        shouldn't require any special care when upgrading.)
-
-    3.  Make sure that support/config.sub and support/config.guess are the
-        latest versions (from <ftp://ftp.gnu.org/gnu/config/>).  See the
-        instructions in "Configuring and Portability" for details on how to
-        update these files.
-
-    4.  Make sure that samples/control.ctl is in sync with the master
-        version at <ftp://ftp.isc.org/pub/usenet/CONFIG/control.ctl>.
-
-    5.  Check out a copy of the release branch.  It's currently necessary to
-        run configure to generate Makefile.global.  Then run "make
-        check-manifest".  The only differences should be files that are
-        generated by configure; if there are any other differences, fix the
-        MANIFEST.
-
-    6.  Run "make release".  Note that you need to have a copy of svn2cl
-        from <http://ch.tudelft.nl/~arthur/svn2cl/> to do this; at least
-        version 0.7 is required.  Start the ChangeLog at the time of the
-        previous release.  (Eventually, the script will be smart enough to
-        do this for you.)
-
-    7.  Make the resulting tar file available for testing in a non-listable
-        directory on ftp.isc.org and announce its availability on
-        inn-workers.  Install it on at least one system and make sure that
-        system runs fine for at least a few days.  This is also a good time
-        to send out a draft of the release announcement to inn-workers for
-        proof-reading.
-
-    8.  Generate a diff between this release and the previous release if
-        feasible (always for minor releases, possibly not a good idea due to
-        the length of the diff for major releases).
-
-    9.  Move the release into the public area of the ftp site and update the
-        inn.tar.gz link.  Make an MD5 checksum of the release tarball and
-        put it on the ftp site as well, and update the inn.tar.gz.md5 link. 
-        Put the diff up on the ftp site as well.  Contact the ISC folks to
-        get the release PGP-signed.  Possibly move older releases off into
-        the OLD directory.
-
-    10. Announce the new release on inn-announce and in news.software.nntp.
-
-    11. Tag the checked-out tree that was used for generating the release
-        with a release tag (INN-<version>).
-
-    12. Bump the revision number in Makefile.global.in.
-
-References
-
-    Some additional references that may be hard to find and may be of use to
-    people working on INN:
-
-    <http://www.eyrie.org/~eagle/nntp/>
-        The home page for the IETF NNTP standardization effort, including
-        links to the IETF NNTP working group archives and copies of the
-        latest drafts of the new NNTP standard.  The old archived mailing
-        list traffic contains a lot of interesting discussion of why NNTP is
-        the way it is.
-
-    <http://www.imc.org/ietf-usefor/>
-        The archives for the USEFOR IETF working group, the working group
-        for the RFC 1036 replacement (the format of Usenet articles).  Also
-        contains a lot of references to other relevant work, such as the RFC
-        822 replacement work.
-
-    <http://www.mibsoftware.com/userkt/inn/dev/>
-        Forrest Cavalier provides several tools for following INN
-        development at this page and elsewhere in the Usenet RKT.  Under
-        here is a web-accessible checked-out copy of the current INN source
-        tree and pointers to how to use CVSup.
-
-    <http://www.sas.com/standards/large.file/>
-        The standards for large file support on Unix that are being
-        generally implemented by vendors.  INN sort of partially uses these,
-        but a good full audit of the code to check them should really be
-        done and there are occasional problems.
-
-    <http://v6web.litech.org/ipv6primer/>
-        A primer on IPv6 with pointers to the appropriate places for more
-        technical details as needed, useful when working on IPv6 support in
-        INN.
-
diff --git a/INSTALL b/INSTALL
deleted file mode 100644 (file)
index eceb489..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,1527 +0,0 @@
-Welcome to INN 2.4!
-
-    Please read this document thoroughly before trying to install INN. 
-    You'll be glad you did.
-
-    If you are upgrading from a major release of INN prior to 2.3, it is
-    recommended that you make copies of your old configuration files and use
-    them as guides for doing a clean installation and configuration of 2.4. 
-    Many config files have changed, some have been added, and some have been
-    removed.  You'll find it much easier to start with a fresh install than
-    to try to update your old installation.  This is particularly true if
-    you're upgrading from a version of INN prior to 2.0.
-
-    If you are upgrading from INN 2.3 or later, you may be able to just
-    update the binaries, scripts, and man pages by running:
-
-        make update
-
-    after building INN and then comparing the new sample configuration files
-    with your current ones to see if anything has changed.  If you take this
-    route, the old binaries, scripts, and man pages will be saved with an
-    extension of ".OLD" so that you can easily back out.  Be sure to
-    configure INN with the same options that you used previously if you take
-    this approach (in particular, INN compiled with --enable-largefiles
-    can't read the data structures written by INN compiled without that
-    flag, and vice versa).  If you don't remember what options you used but
-    you have your old build tree, look at the comments at the beginning of
-    config.status.
-
-    If you made ckpasswd setuid root so that you could use system passwords,
-    you'll have to do that again after make update.  (It's much better to
-    use PAM instead if you can.)
-
-    If you use "make update" to upgrade from INN 2.3, also look at the new
-    sample configuration files in samples to see if there are new options of
-    interest to you.  In particular, control.ctl has been updated and
-    inn.conf has various new options.
-
-    For more information about recent changes, see NEWS.
-
-Supported Systems
-
-    As much as possible, INN is written in portable C and should work on any
-    Unix platform.  It does, however, make extensive use of mmap(2) and
-    certain other constructs that may be poorly or incompletely implemented,
-    particularly on very old operating systems.
-
-    INN has been confirmed to work on the following operating systems:
-
-        AIX 4.3
-        FreeBSD 2.2.x and up
-        HP-UX 10.20 and up
-        Linux 2.x (tested with libc 5.4, glibc 2.0 and up)
-        Mac OS X 10.2 and up
-        NetBSD 1.6 and up
-        OpenBSD 2.8 and up
-        SCO 5.0.4 (tested with gcc 2.8.1, cc)
-        Solaris 2.5.x and up
-        UnixWare 7.1
-        UX/4800 R11 and up
-
-    If you have gotten INN working on an operating system other than the
-    ones listed above, please let us know at <inn-bugs@isc.org>.
-
-Before You Begin
-
-    INN requires several other packages be installed in order to be fully
-    functional (or in some cases, to work at all):
-
-    * In order to build INN, you will need a C compiler that understands
-      ANSI C.  If you are trying to install INN on an operating system that
-      doesn't have an ANSI C compiler (such as SunOS), installing gcc is
-      recommended.  You can get it from <ftp://ftp.gnu.org/gnu/gcc/> or its
-      mirrors.  INN is tested with gcc more thoroughly than with any other
-      compiler, so even if you have another compiler available, you may wish
-      to use gcc instead.
-
-    * Currently, in order to build INN, you will need an implementation of
-      yacc.  GNU bison (from <ftp://ftp.gnu.org/gnu/bison/> or its mirrors)
-      will work fine.  We hope to remove this requirement in the future.
-
-    * INN requires at least Perl 5.004_03 to build and to run several
-      subsystems.  INN is tested primarily with newer versions of Perl, so
-      it's generally recommended that you install the latest stable
-      distribution of Perl before compiling INN.  For instructions on
-      obtaining and installing Perl, see
-      <http://www.perl.com/pub/language/info/software.html>.  Note that you
-      may need to use the same compiler and options (particularly largefile
-      support) for Perl and INN.
-
-      If you're using a version of Perl prior to 5.6.0, you may need to make
-      sure that the Perl versions of your system header files have been
-      generated in order for Sys::Syslog to work properly (used by various
-      utility programs, including controlchan).  To do this, run the
-      following two commands:
-
-          # cd /usr/include
-          # h2ph * sys/*
-
-      An even better approach is to install Perl 5.6.1 or later, which have
-      a fixed version of Sys::Syslog that doesn't require this (as well as
-      many other improvements over earlier versions of Perl).
-
-    * The INN Makefiles use the syntax "include FILE", rather than the
-      syntax expected by some BSDish systems of ".include <FILE>".  If your
-      system expects the latter syntax, the recommended solution is to
-      install GNU make from <ftp://ftp.gnu.org/make/>.  You may have GNU
-      make already installed as gmake, in which case using gmake rather than
-      make to build INN should be sufficient.
-
-    * If you want to enable support for authenticated control messages (this
-      is not required, but is highly recommended for systems carrying public
-      Usenet hierarchies) then you will need to install some version of PGP.
-      The recommended version is GnuPG, since it's actively developed,
-      supports OpenPGP, is freely available and free to use for any purpose
-      (in the US and elsewhere), and (as of version 1.0.4 at least) supports
-      the RSA signatures used by most current control message senders.
-
-      Alternately, you can install PGP from <http://www.pgp.com/> or one of
-      the international versions of it.  Be warned, however, that the
-      licensing restrictions on PGP inside the United States are extremely
-      unclear; it's possible that if you are installing INN for a company in
-      the U.S., even if the news server is not part of the business of that
-      company, you would need to purchase a commercial license for PGP.  For
-      an educational or non-profit organization, this shouldn't be a
-      problem.
-
-    * If you want to use either the Python embedded hooks, you'll need to
-      have a suitable versions of Python installed.  See doc/hook-python for
-      more information.
-
-    * Many of INN's optional features require other packages (primarily
-      libraries) be installed.  If you wish to use any of these optional
-      features, you will need to install those packages first.  Here is a
-      table of configure options enabling optional features and the software
-      and versions you'll need:
-
-          --with-perl         Perl 5.004_03 or higher, 5.6.1+ recommended
-          --with-python       Python 1.5.2 or higher
-          --with-berkeleydb   BerkeleyDB 2.0 or higher, 4.2+ recommended
-          --with-openssl      OpenSSL 0.9.6 or higher
-          --with-sasl         SASL 2.x or higher
-          --with-kerberos     MIT Kerberos v5 1.2.x or higher
-
-      If any of these libraries (other than Perl or Python) are built shared
-      and installed in locations where your system doesn't search for shared
-      libraries by default, you may need to encode the paths to those shared
-      libraries in the INN binaries.  For more information on shared library
-      paths, see:
-
-          <http://www.eyrie.org/~eagle/notes/rpath.html>
-
-      For most systems, setting the environment variable LD_RUN_PATH to a
-      colon-separated list of additional directories in which to look for
-      shared libraries before building INN will be sufficient.
-
-Unpacking the Distribution
-
-    Released versions of INN are available from ftp.isc.org in /isc/inn. 
-    New major releases will be announed on <inn-announce@isc.org> (see
-    README) when they're made.
-
-    If you want more a more cutting-edge version, you can obtain current
-    snapshots from from ftp.isc.org in directory /isc/inn/snapshots.  These
-    are snapshots of the INN CVS tree taken daily; there are two snapshots
-    made each night (one of the current development branch, and one of the
-    stable branch consisting of bug fixes to the previous major release). 
-    They are stored in date format; in other words the snapshots from April
-    6th, 2000, would be named inn-CURRENT-20000406.tar.gz and
-    inn-STABLE-20000406.tar.gz.  Choose the newest file of whichever branch
-    you prefer.  (Note that the downloading, configuring, and compiling
-    steps can be done while logged in as any user.)
-
-    The distribution is in gzip compressed tar archive format.  To extract
-    it, execute:
-
-        gunzip -c <inn-src-file> | tar -xf -
-
-    Extracting the source distribution will create a directory named
-    inn-<version> or inn-<BRANCH>-<date> where the source resides.
-
-Installing INN
-
-    Before beginning installation, you should make sure that there is a user
-    on your system named "news", and that this user's primary group is set
-    to a group called "news".  You can change these with the
-    --with-news-user and --with-news-group options to configure (see below).
-    The home directory of this user should be set to the directory under
-    which you wish to install INN (/usr/local/news is the default and is a
-    good choice).  INN will install itself as this user and group.  You can
-    change these if you want, but these are the defaults and it's easier to
-    stick with them on a new installation.
-
-    By default, INN sends reports to the user "usenet".  This account isn't
-    used for any other purposes.  You can change it with the
-    --with-news-master option to configure (see below).
-
-    WARNING: By default, INN installs various configuration files as
-    group-writeable, and in general INN is not hardened from a security
-    standpoint against an attack by someone who is already in the news
-    group.  In general, you should consider membership in the news group as
-    equivalent to access to the news account.  You should not rely on being
-    able to keep anyone with access to the news GID from converting that
-    into access to the news UID.  The recommended configuration is to have
-    the only member of the group "news" be the user "news".
-
-    Installing INN so that all of its files are under a single directory
-    tree, rather than scattering binaries, libraries, and man pages
-    throughout the file system, is strongly recommended.  It helps keep
-    everything involved in the operation of INN together as a unit and will
-    make the installation instructions easier to follow.
-
-    As a side note, whenever doing anything with a running news server,
-    first log in as this user.  That way, you can ensure that all files
-    created by any commands you run are created with the right ownership to
-    be readable by the server.  Particularly avoid doing anything in the
-    news spool itself as root, and make sure you fix the ownership of any
-    created files if you have to.  INN doesn't like files in the news spool
-    owned by a user other than the news user.  However, since certain
-    binaries need to be setuid root, indiscriminate use of "chown news" is
-    not the solution.  (If you don't like to log in to system accounts,
-    careful use of "chmod g+s" on directories and a umask of 002 or 007 may
-    suffice.)
-
-    INN uses GNU autoconf and a generated configure script to make
-    configuration rather painless.  Unless you have a rather abnormal setup,
-    configure should be able to completely configure INN for your system. 
-    If you want to change the defaults, you can invoke the configure script
-    with one or more command line options.  Type:
-
-        ./configure --help
-
-    for a full list of supported options.  Some of the most commonly used
-    options are:
-
-    --prefix=PATH
-        Sets the installation prefix for INN.  The default is
-        /usr/local/news.  All of INN's programs and support files will be
-        installed under this directory.  This should match the home
-        directory of your news user (it will make installation and
-        maintenance easier).  It is not recommended to set this to /usr; if
-        you decide to do that anyway, make sure to point INN's temporary
-        directory at a directory that isn't world-writeable (see
-        --with-tmp-dir below).
-
-    --with-db-dir=PATH
-        Sets the prefix for INN database files.  The default is PREFIX/db,
-        where PREFIX is /usr/local/news unless overridden with the option
-        above.  The history and active files will be stored in this
-        directory, and writes to those files are an appreciable percentage
-        of INN's disk activity.  The history file can also be quite large
-        (requiring up to 2 GB or more during nightly expire), so this is a
-        common portion of INN to move to a different file system.
-
-    --with-spool-dir=PATH
-        Sets the prefix for the news spool (when using any storage method
-        other than CNFS) and the overview spool.  The default is
-        PREFIX/spool.  This is another common portion of INN to move to a
-        different file system (often /news).
-
-    --with-tmp-dir=PATH
-        Sets the directory in which INN will create temporary files.  This
-        should under no circumstances be the same as the system temporary
-        directory or otherwise be set to a world-writeable directory, since
-        INN doesn't take care to avoid symlink attacks and other security
-        problems possible with a world-writeable directory.  This directory
-        should be reserved for the exclusive use of INN and only writeable
-        by the news user.  Usage is generally light, so this is unlikely to
-        need a separate partition.
-
-        It's also possible to set the paths for most other sections of the
-        INN installation independently; see "./configure --help" and look
-        for the --with-*-dir=PATH options.
-
-    --enable-largefiles
-        Enables large file support.  This is not enabled by default, even on
-        platforms that support it, because it changes the format of INN's
-        on-disk databases (making it difficult to upgrade an earlier INN
-        installation) and can significantly increase the size of some of the
-        history database files.  Large file support is not necessary unless
-        your history database is so large that it exceeds 2 GB or you want
-        to use CNFS buffers larger than 2 GB.
-
-        The history, tradindexed and buffindexed overview, CNFS, and timecaf
-        databases written by an INN built with this option are incompatible
-        with those written by an INN without this option.
-
-    --enable-tagged-hash
-        Use tagged hash table for the history database.  The tagged hash
-        format uses much less memory but is somewhat slower.  This option is
-        recommended if you have less than 256 MB of RAM on your news server.
-        If you install INN without tagged hash (the default) and expire
-        takes an excessive amount of time, you should make sure the RAM in
-        your system satisfies the following formula:
-
-            ram > 10 * tablesize
-
-                  ram:  Amount of system RAM (in bytes)
-            tablesize:  3rd field on the 1st line of history.dir (bytes)
-
-        If you don't have at least that much RAM, try rebuilding INN with
-        tagged hash enabled.
-
-        NOTE: --enable-largefiles cannot be used with --enable-tagged-hash.
-
-    --with-perl
-        Enables support for embedded Perl, allowing you to install filter
-        scripts written in Perl.  Highly recommended, because many really
-        good spam filters are written in Perl.  See doc/hook-perl for all
-        the details.
-
-        Even if you do not use this option, INN still requires Perl as
-        mentioned above.
-
-    --with-python
-        Enables support for Python, allowing you to install filter and
-        authentication scripts written in Python.  You will need Python
-        1.5.2 or later installed on your system to enable this option.  See
-        doc/hook-python for all the details.  Note that there is an
-        incompatibility between INN and Python 2.0 when Python is compiled
-        with cycle garbage collection; this problem was reported fixed in
-        Python 2.1a1.
-
-    --with-innd-port=PORT
-        By default, inndstart(8) refuses to bind to any port under 1024
-        other than 119 and 433 for security reasons (to prevent attacks on
-        rsh(1)-based commands and replacing standard system daemons).  If
-        you want to run innd on a different port under 1024, you'll need to
-        tell configure what port you intend to use.  (You'll also still need
-        to set the port number in inn.conf or give it to inndstart on the
-        command line.)
-
-    --with-syslog-facility=FACILITY
-        Specifies the syslog facility that INN programs should log to.  The
-        default is LOG_NEWS unless configure detects that your system
-        doesn't understand that facility, in which case it uses LOG_LOCAL1. 
-        This flag overrides the automatic detection.  Be sure to specify a
-        facility not used by anything else on your system (one of LOG_LOCAL0
-        through LOG_LOCAL7, for example).
-
-    --enable-libtool
-        INN has optional support for libtool to generate shared versions of
-        INN's libraries.  This can significantly decrease the size of the
-        various binaries that come with a complete INN installation.  You
-        can also choose to use libtool even when only building static
-        libraries; a libtool build may be somewhat more portable on weird
-        systems.  libtool builds aren't the default because they take
-        somewhat longer.  See "./configure --help" for the various available
-        options related to libtool builds.
-
-        Please note that INN's shared library interface is not stable and
-        may change drastically in future releases.  For this reason, it's
-        also not properly versioned and won't be until some degree of
-        stability is guaranteed, and the relevant header files are not
-        installed.  Only INN should use INN's shared libraries, and you
-        should only use the shared libraries corresponding to the version of
-        INN that you're installing.
-
-        Also, when updating an existing version of INN, INN tries to save
-        backup copies of all files so that you can revert to the previous
-        installed version.  Unfortunately, when using shared libraries, this
-        confuses ldconfig on some systems (such as Linux) and the symbolic
-        links for the libraries may point to the .OLD versions.  If this
-        happens, you can either fix the links by hand or remove the .OLD
-        versions and re-run ldconfig.
-
-    --enable-uucp-rnews
-        If this option is given to configure, rnews will be installed setuid
-        news, owned by group uucp, and mode 4550.  This will allow the UUCP
-        subsystem to run rnews to process UUCP batches of news articles. 
-        Prior to INN 2.3, installing rnews setuid news was standard; since
-        most sites no longer use UUCP, it is no longer the default as of INN
-        2.3 and must be requested at configure time.  You probably don't
-        want to use this option unless your server accepts UUCP news
-        batches.
-
-    --enable-setgid-inews
-        If this option is given to configure, inews will be installed setgid
-        news and world-executable so that non-privileged users on the news
-        server machine can use inews to post articles locally (somewhat
-        faster than opening a new network connection).  For standalone news
-        servers, by far the most common configuration now, there's no need
-        to use this option; even if you have regular login accounts on your
-        news server, INN's inews can post fine via a network connection to
-        your running news server and doesn't need to use the local socket
-        (which is what setgid enables it to do).  Installing inews setgid
-        was the default prior to INN 2.3.
-
-    --with-berkeleydb=PATH
-        Enables support for Berkeley DB (2.x or 3.x), which means that it
-        will then be possible to use the ovdb overview method if you wish. 
-        Enabling this configure option doesn't mean you'll be required to
-        use ovdb, but it does require that Berkeley DB be installed on your
-        system (including the header files, not just the runtime libraries).
-        If a path is given, it sets the installed directory of Berkeley DB
-        (configure will search for it in some standard locations, but if you
-        have it installed elsewhere, you may need this option).
-
-    --with-openssl=PATH
-        Enables support for SSL for news reading, which means it will be
-        possible to have SSL or TLS encrypted NNTP connections between your
-        server and newsreaders.  This option requires OpenSSL be installed
-        on your system (including the header files, not just the runtime
-        libraries).  If a path is given, it sets the installed directory of
-        OpenSSL.  After compiling and installing INN with this option,
-        you'll still need to make a certificate and private key to use SSL. 
-        See below for details on how to do that.
-
-    --enable-ipv6
-        Enables support for IPv6 in innd, innfeed, nnrpd, and several of the
-        supporting programs.  This option should be considered developmental
-        at present.  For more information see doc/IPv6-info (and if you have
-        any particularly good or bad news to report, please let us know at
-        <inn-bugs@isc.org>).
-
-    For the most common installation, a standalone news server, a suggested
-    set of options is:
-
-        ./configure --with-perl
-
-    provided that you have the necessary version of Perl installed. 
-    (Compiling with an embedded Perl interpretor will allow you to use one
-    of the available excellent spam filters if you so choose.)
-
-    If the configure program runs successfully, then you are ready to build
-    the distribution.  From the root of the INN source tree, type:
-
-        make
-
-    At this point you can step away from the computer for a little while and
-    have a quick snack while INN compiles.  On a decently fast system it
-    should only take five or ten minutes at the most to build.
-
-    Once the build has completed successfully, you are ready to install INN
-    into its final home.  Type:
-
-        make install
-
-    You will need to run this command as root so that INN can create the
-    directories it needs, change ownerships (if you did not compile as the
-    news user) and install a couple of setuid wrapper programs needed to
-    raise resource limits and allow innd to bind to ports under 1024.  This
-    step will install INN under the install directory (/usr/local/news,
-    unless you specified something else to the configure script).
-
-    If you are configuring SSL support for newsreaders, you must make a
-    certificate and private key at least once.  Type:
-
-        make cert
-
-    as root in order to do this.
-
-    You are now ready for the really fun part:  configuring your copy of
-    INN!
-
-Choosing an Article Storage Format
-
-    The first thing to decide is how INN should store articles on your
-    system.  There are four different methods for you to choose from, each
-    of which has its own advantages and disadvantages.  INN can support all
-    four at the same time, so you can store certain newsgroups in one method
-    and other newsgroups in another method.
-
-    The supported storage formats are:
-
-    tradspool
-        This is the storage method used by all versions of INN previous to
-        2.0.  Articles are stored as individual text files whose names are
-        the same as the article number.  The articles are divided up into
-        directories based on the newsgroup name.  For example, article 12345
-        in news.software.nntp would be stored as news/software/nntp/12345
-        relative to the root of the article spool.
-
-        Advantages:  Widely used and well-understood storage mechanism, can
-        read article spools written by older versions of INN, compatible
-        with all third-party INN add-ons, provides easy and direct access to
-        the articles stored on your server and makes writing programs that
-        fiddle with the news spool very easy, and gives you fine control
-        over article retention times.
-
-        Disadvantages:  Takes a very fast file system and I/O system to keep
-        up with current Usenet traffic volumes due to file system overhead. 
-        Groups with heavy traffic tend to create a bottleneck because of
-        inefficiencies in storing large numbers of article files in a single
-        directory.  Requires a nightly expire program to delete old articles
-        out of the news spool, a process that can slow down the server for
-        several hours or more.
-
-    timehash
-        Articles are stored as individual files as in tradspool, but are
-        divided into directories based on the arrival time to ensure that no
-        single directory contains so many files as to cause a bottleneck.
-
-        Advantages:  Heavy traffic groups do not cause bottlenecks, and fine
-        control of article retention time is still possible.
-
-        Disadvantages:  The ability to easily find all articles in a given
-        newsgroup and manually fiddle with the article spool is lost, and
-        INN still suffers from speed degredation due to file system overhead
-        (creating and deleting individual files is a slow operation).
-
-    timecaf
-        Similar to timehash, articles are stored by arrival time, but
-        instead of writing a separate file for each article, multiple
-        articles are put in the same file.
-
-        Advantages:  Roughly four times faster than timehash for article
-        writes, since much of the file system overhead is bypassed, while
-        still retaining the same fine control over article retention time.
-
-        Disadvantages:  Even worse than timehash, and similar to cnfs
-        (below), using this method means giving up all but the most careful
-        manually fiddling with your article spool.  As one of the newer and
-        least widely used storage types, timecaf has not been as thoroughly
-        tested as the other methods.
-
-    cnfs
-        CNFS stores articles sequentially in pre-configured buffer files. 
-        When the end of the buffer is reached, new articles are stored from
-        the beginning of the buffer, overwriting older articles.
-
-        Advantages:  Blazingly fast because no file creations or deletions
-        are necessary to store an article.  Unlike all other storage
-        methods, does not require manual article expiration; old articles
-        are deleted to make room for new ones when the buffers get too full.
-        Also, with CNFS your server will never throttle itself due to a full
-        spool disk, and groups are restricted to just the buffer files you
-        give them so that they can never use more than the amount of disk
-        space you allocate to them.
-
-        Disadvantages:  Article retention times are more difficult to
-        control because old articles are overwritten automatically.  Attacks
-        on Usenet, such as flooding or massive amounts of spam, can result
-        in wanted articles expiring much faster than you intended (with no
-        warning).
-
-    Some general recommendations:  If you are installing a transit news
-    server (one that just accepts news and sends it out again to other
-    servers and doesn't support any readers), use CNFS exclusively and don't
-    worry about any of the other storage methods.  Otherwise, put
-    high-volume groups and groups whose articles you don't need to keep
-    around very long (binaries groups, *.jobs*, news.lists.filters, etc.) in
-    CNFS buffers, and use timehash, timecaf, or tradspool (if you have a
-    fast I/O subsystem or need to be able to go through the spool manually)
-    for everything else.  You'll probably find it most convenient to keep
-    special hierarchies like local hierarchies and hierarchies that should
-    never expire in tradspool.
-
-    If your news server will be supporting readers, you'll also need to
-    choose an overview storage mechanism (by setting *ovmethod* in
-    inn.conf).  There are three overview mechanisms to choose from: 
-    tradindexed, buffindexed, and ovdb.  tradindexed is very fast for
-    readers, but it has to update two files for each incoming article and
-    can be quite slow to write.  buffindexed can keep up with a large feed
-    more easily, since it uses large buffers to store all overview
-    information, but it's somewhat slower for readers (although not as slow
-    as the unified overview in INN 2.2).  ovdb stores overview data in a
-    Berkeley DB database; it's fast and very robust, but requires more disk
-    space.  See the ovdb(5) man page for more information on it.
-
-    Note that ovdb has not been as widely tested as the other overview
-    mechanisms and should be considered experimental.  tradindexed is the
-    best tested and most widely used of the overview implementations.
-
-    If buffindexed is chosen, you will need to create the buffers for it to
-    use (very similar to creating CNFS buffers) and list the available
-    buffers in buffindexed.conf.  See buffindexed.conf(5) for more
-    information.
-
-Configuring INN
-
-    All documentation from this point on assumes that you have set up the
-    news user on your system as suggested in "Installing INN" so that the
-    root of your INN installation is ~news/.  If you've moved things around
-    by using options with "configure", you'll need to adjust the
-    instructions to account for that.
-
-    All of INN's configuration files are located in ~news/etc.  Unless noted
-    otherwise, any files referred to below are in this directory.  When you
-    first install INN, a sample of each file (containing lots of comments)
-    is installed in ~news/etc; refer to these for concrete examples of
-    everything discussed in this section.
-
-    All of INN's configuration files, all of the programs that come with it,
-    and some of its library routines have documentation in the form of man
-    pages.  These man pages were installed in ~news/man as part of the INN
-    installation process and are the most complete reference to how INN
-    works.  You're strongly encouraged to refer to the man pages frequently
-    while configuring INN, and for quick reference afterwards.  Any detailed
-    questions about individual configuration files or the behavior of
-    specific programs should be answered in them.  You may want to add
-    ~news/man to your MANPATH environment variable; otherwise, you may have
-    to use a command like:
-
-        man -M ~news/man inn.conf
-
-    to see the inn.conf(5) man page (for example).
-
-    Before we begin, it is worth mentioning the wildmat pattern matching
-    syntax used in many configuration files.  These are simple wildcard
-    matches using the asterisk ("*") as the wildcard character, much like
-    the simple wildcard expansion used by Unix shells.
-
-    In many cases, wildmat patterns can be specified in a comma-separated
-    list to indicate a list of newsgroups.  When used in this fashion, each
-    pattern is checked in turn to see if it matches, and the last pattern in
-    the line that matches the group name is used.  Patterns beginning with
-    "!" mean to exclude groups matching that pattern.  For example:
-
-        *, !comp.*, comp.os.*
-
-    In this case, we're saying we match everything ("*"), except that we
-    don't match anything under comp ("!comp.*"), unless it is actually under
-    the comp.os hierarchy ("comp.os.*").  This is because non-comp groups
-    will match only the first pattern (so we want them), comp.os groups will
-    match all three patterns (so we want them too, because the third pattern
-    counts in this case), and all other comp groups will match the first and
-    second patterns and will be excluded by the second pattern.
-
-    Some uses of wildmat patterns also support "poison" patterns (patterns
-    starting with "@").  These patterns behave just like "!" patterns when
-    checked against a single newsgroup name.  Where they become special is
-    for articles crossposted to multiple newsgroups; normally, such an
-    article will be considered to match a pattern if any of the newsgroups
-    it is posted to matches the pattern.  If any newsgroup the article is
-    posted to matches an expression beginning with "@", however, that
-    article will not match the pattern even if other newsgroups to which it
-    was posted match other expressions.
-
-    See uwildmat(3) for full details on wildmat patterns.
-
-    In all INN configuration files, blank lines and lines beginning with a
-    "#" symbol are considered comments and are ignored.  Be careful, not all
-    files permit comments to begin in the middle of the line.
-
-  inn.conf
-
-    The first, and most important file is inn.conf.  This file is organized
-    as a series of parameter-value pairs, one per line.  The parameter is
-    first, followed by a colon and one or more whitespace characters, and
-    then the value itself.  For some parameters the value is a string or a
-    number; for others it is true or false.  (True values can be written as
-    "yes", "true", or "on", whichever you prefer.  Similarly, false values
-    can be written as "no", "false", or "off".)
-
-    inn.conf contains dozens of changeable parameters (see inn.conf(5) for
-    full details), but only a few really need to be edited during normal
-    operation:
-
-    allownewnews
-        If set to true then INN will support the NEWNEWS command for news
-        readers.  While this can be an expensive operation, its speed has
-        been improved considerably as of INN 2.3 and it's probably safe to
-        turn on without risking excessive server load.  The default is true.
-        (Note that the *access:* setting in readers.conf overrides this
-        value; see readers.conf(5) for more details.)
-
-    complaints
-        Used to set the value of the X-Complaints-To: header, which is added
-        to all articles posted locally.  The usual value would be something
-        like "abuse@example.com" or "postmaster@example.com".  If not
-        specified, the newsmaster email address will be used.
-
-    hiscachesize
-        The amount of memory (in kilobytes) to allocate for a cache of
-        recently used history file entries.  Setting this to 0 disables
-        history caching.  History caching can greatly increase the number of
-        articles per second that your server is capable of processing.  A
-        value of 256 is a good default choice.
-
-    logipaddr
-        If set to true (the default), INN will log the IP address (or
-        hostname, if the host is listed in incoming.conf with a hostname) of
-        the remote host from which it received an article.  If set to false,
-        the trailing Path: header entry is logged instead.  If you are using
-        controlchan (see below) and need to process ihave/sendme control
-        messages (this is very, very unlikely, so if you don't know what
-        this means, don't worry about it), make sure you set this to false,
-        since controlchan needs a site name, not an IP address.
-
-    organization
-        Set this to the name of your organization as you want it to appear
-        in the Organization: header of all articles posted locally and not
-        already containing that header.  This will be overridden by the
-        value of the ORGANIZATION environment variable (if it exists).  If
-        neither this parameter nor the environment variable or set, no
-        Organization: header will be added to posts which lack one.
-
-    pathhost
-        This is the name of your news server as you wish it to appear in the
-        Path: header of all postings which travel through your server (this
-        includes local posts and incoming posts that you forward out to
-        other sites).  If this parameter is unspecified, the fully-qualified
-        domain name (FQDN) of the machine will be used instead.  Please use
-        the FQDN of your server or an alias for your server unless you have
-        a very good reason not to; a future version of the news RFCs may
-        require this.
-
-    rlimitnofile
-        If set to a non-negative value (the default is -1), INN (both innd
-        and innfeed) will try to raise the maximum number of open file
-        descriptors to this value when it starts.  This may be needed if you
-        have lots of incoming and outgoing feeds.  Note that the maximum
-        value for this setting is very operating-system-dependent, and you
-        may have to reconfigure your system (possibly even recompile your
-        kernel) to increase it.  See "File Descriptor Limits" for complete
-        details.
-
-    There are tons of other possible settings; you may want to read through
-    inn.conf(5) to get a feel for your options.  Don't worry if you don't
-    understand the purpose of most of them right now.  Some of the settings
-    are only needed for very obscure things, and with more experience
-    running your news server the rest will make more sense.
-
-  newsfeeds
-
-    newsfeeds determines how incoming articles are redistributed to your
-    peers and to other INN processes.  newsfeeds is very versatile and
-    contains dozens of options; we will touch on just the basics here.  The
-    manpage contains more detailed information.
-
-    newsfeeds is organized as a series of feed entries.  Each feed entry is
-    composed of four fields separated by colons.  Entries may span multiple
-    lines by using a backslash ("\") to indicate that the next line is a
-    continuation of the current line.  (Note that comments don't interact
-    with backslashes in the way you might expect.  A commented-out line
-    ending in a backslash will still be considered continued on the next
-    line, possibly resulting in more commented out than you intended or
-    bizarre syntax errors.  In general, it's best to avoid commenting out
-    lines in the middle of continuation lines.)
-
-    The first field in an entry is the name of the feed.  It must be unique,
-    and for feeds to other news servers it is usually set to the actual
-    hostname of the remote server (this makes things easier).  The name can
-    optionally be followed by a slash and a comma-separated exclude list. 
-    If the feed name or any of the names in the exclude list appear in the
-    Path line of an article, then that article will not be forwarded to the
-    feed as it is assumed that it has passed through that site once already.
-    The exclude list is useful when a news server's hostname is not the same
-    as what it puts in the Path header of its articles, or when you don't
-    want a feed to receive articles from a certain source.
-
-    The second field specifies a set of desired newsgroups and distribution
-    lists, given as newsgroup-pattern/distribution-list.  The distribution
-    list is not described here; see newsfeeds(5) for information (it's not
-    used that frequently in practice).  The newsgroup pattern is a
-    wildmat-style pattern list as described above (supporting "@").
-
-    The third field is a comma-separated list of flags that determine both
-    the type of feed entry and sets certain parameters for the entry.  See
-    newsfeeds(5) for information on the flag settings; you can do a
-    surprising amount with them.  The three most common patterns, and the
-    ones mainly used for outgoing news feeds to other sites, are "Tf,Wnm"
-    (to write out a batch file of articles to be sent, suitable for
-    processing by nntpsend and innxmit), "Tm" (to send the article to a
-    funnel feed, used with innfeed), and "Tc,Wnm*" (to collect a funnel feed
-    and send it via a channel feed to an external program, used to send
-    articles to innfeed).
-
-    The fourth field is a multi-purpose parameter whose meaning depends on
-    the settings of the flags in the third field.  To get a feel for it
-    using the examples above, for file feeds ("Tf") it's the name of the
-    file to write, for funnel feeds ("Tm") it's the name of the feed entry
-    to funnel into, and for channel feeds ("Tc") it's the name of the
-    program to run and feed references to articles.
-
-    Now that you have a rough idea of the file layout, we'll begin to add
-    the actual feed entries.  First, we'll set up the special ME entry. 
-    This entry is required and serves two purposes:  the newsgroup pattern
-    specified here is prepended to the newsgroup list of all other feeds,
-    and the distribution pattern for this entry determines what
-    distributions (from the Distribution: header of incoming articles) are
-    accepted from remote sites by your server.  The example in the sample
-    newsfeeds file is a good starting point.  If you are going to create a
-    local hierarchy that should not be distributed off of your system, it
-    may be useful to exclude it from the default subscription pattern, but
-    default subscription patterns are somewhat difficult to use right so you
-    may want to just exclude it specifically from every feed instead.
-
-    The ME entry tends to confuse a lot of people, so this point is worth
-    repeating:  the newsgroup patterns set the default subscription for
-    *outgoing* feeds, and the distribution patterns set the acceptable
-    Distribution: header entries for *incoming* articles.  This is confusing
-    enough that it may change in later versions of INN.
-
-    There are two basic ways to feed articles to remote sites.  The most
-    common for large sites and particularly for transit news servers is
-    innfeed(8), which sends articles to remote sites in real time (the
-    article goes out to all peers that are supposed to receive it
-    immediately after your server accepts it).  For smaller sites,
-    particularly sites where the only outgoing messages will be locally
-    posted articles, it's more common to batch outgoing articles and send
-    them every ten minutes or so from cron using nntpsend(8) and innxmit(8).
-    Batching gives you more control and tends to be extremely stable and
-    reliable, but it's much slower and can't handle high volume very well.
-
-    Batching outgoing posts is easy to set up; for each peer, add an entry
-    to newsfeeds that looks like:
-
-        remote.example.com/news.example.com\
-            :<newsgroups>\
-            :Tf,Wnm:
-
-    where <newsgroups> is the wildmat pattern for the newsgroups that site
-    wants.  In this example, the actual name of the remote site is
-    "remote.example.com", but it puts "news.example.com" in the Path:
-    header.  If the remote site puts its actual hostname in the Path:
-    header, you won't need the "/news.example.com" part.
-
-    This entry will cause innd to write out a file in ~news/spool/outgoing
-    named remote.example.com and containing the Message-ID and storage token
-    of each message to send to that site.  (The storage token is INN's
-    internal pointer to where an article is stored; to retrieve an article
-    given its storage token, use sm(8)).  innxmit knows how to read files of
-    this format and send those articles to the remote site.  For information
-    on setting it up to run periodically, see "Setting Up the Cron Jobs"
-    below.  You will also need to set up a config file for nntpsend; see the
-    man page for nntpsend.ctl(5) for more information.
-
-    If instead you want to use innfeed to send outgoing messages
-    (recommended for sites with more than a couple of peers), you need some
-    slightly more complex magic.  You still set up a separate entry for each
-    of your peers, but rather than writing out batch files, they all
-    "funnel" into a special innfeed entry.  That special entry collects all
-    of the separate funnel feeds and sends the data through a special sort
-    of feed to an external program (innfeed in this case); this is a
-    "channel" feed.
-
-    First, the special channel feed entry for innfeed that will collect all
-    the funnel feeds:
-
-        innfeed!\
-            :!*\
-            :Tc,Wnm*:/usr/local/news/bin/startinnfeed -y
-
-    (adjust the path to startinnfeed(1) if you installed it elsewhere). 
-    Note that we don't feed this entry any articles directly (its newsgroup
-    pattern is "!*").  Note also that the name of this entry ends in an
-    exclamation point.  This is a standard convention for all special feeds;
-    since the delimiter for the Path: header is "!", no site name containing
-    that character can ever match the name of a real site.
-
-    Next, set up entries for each remote site to which you will be feeding
-    articles.  All of these entries should be of the form:
-
-        remote.example.com/news.example.com\
-            :<newsgroups>\
-            :Tm:innfeed!
-
-    specifying that they funnel into the "innfeed!" feed.  As in the
-    previous example for batching, "remote.example.com" is the actual name
-    of the remote peer, "news.example.com" is what it puts in the Path:
-    header (if different than the actual name of the server), and
-    <newsgroups> is the wildmat pattern of newsgroups to be sent.
-
-    As an alternative to NNTP, INN may also feed news out to an IMAP server,
-    by using imapfeed(8), which is almost identical to innfeed.  The
-    startinnfeed process can be told to start imapfeed instead of innfeed. 
-    The feed entry for this is as follows:
-
-        imapfeed!\
-            :!*\
-            :Tc,Wnm*,S16384:/usr/local/news/bin/startinnfeed imapfeed
-
-    And set up entries for each remote site like:
-
-        remote.example.com/news.example.com\
-            :<newsgroups>\
-            :Tm:imapfeed!
-
-    For more information on imapfeed, look at the innfeed/imap_connection.c.
-    For more information on IMAP in general, see RFC 2060.
-
-    Finally, there is a special entry for controlchan(8), which processes
-    newsgroup control messages, that should always be in newsfeeds unless
-    you never want to honor any control messages.  This entry should look
-    like:
-
-        controlchan!\
-            :!*,control,control.*,!control.cancel\
-            :Tc,Wnsm:/usr/local/news/bin/controlchan
-
-    (modified for the actual path to controlchan if you put it somewhere
-    else).  See "Processing Control Messages" for more details.
-
-    For those of you upgrading from earlier versions of INN, note that the
-    functionality of overchan(8) and crosspost is now incorporated into INN
-    and neither of those programs is necessary.  Unfortunately, crosspost
-    currently will not work even with the tradspool storage method.  You can
-    still use overchan if you make sure to set *useoverchan* to true in
-    inn.conf so that innd doesn't write overview data itself, but be
-    careful:  innd may accept articles faster than overchan can process the
-    data.
-
-  incoming.conf
-
-    incoming.conf file specifies which machines are permitted to connect to
-    your host and feed it articles.  Remote servers you peer with should be
-    listed here.  Connections from hosts not listed in this file will (if
-    you don't allow readers) be rejected or (if you allow readers) be handed
-    off to nnrpd and checked against the access restrictions in
-    readers.conf.
-
-    Start with the sample incoming.conf and, for each remote peer, add an
-    entry like:
-
-        peer remote.example.com { }
-
-    This uses the default parameters for that feed and allows incoming
-    connections from a machine named "remote.example.com".  If that peer
-    could be connecting from several different machines, instead use an
-    entry like:
-
-         peer remote.example.com {
-            hostname: "remote.example.com, news.example.com"
-         }
-
-    This will allow either "remote.example.com" or "news.example.com" to
-    feed articles to you.  (In general, you should add new peer lines for
-    each separate remote site you peer with, and list multiple host names
-    using the *hostname* key if one particular remote site uses multiple
-    servers.)
-
-    You can restrict the newsgroups a remote site is allowed to send you,
-    using the same sort of pattern that newsfeeds(5) uses.  For example, if
-    you want to prevent "example.com" hosts from sending you any articles in
-    the "local.*" hierarchy (even if they're crossposted to other groups),
-    change the above to:
-
-        peer remote.example.com {
-            patterns: "*, @local.*"
-            hostname: "remote.example.com, news.example.com"
-        }
-
-    Note, however, that restricting what a remote side can send you will
-    *not* reduce your incoming bandwidth usage.  The remote site will still
-    send you the entire article; INN will just reject it rather than saving
-    it to disk.  To reduce bandwidth, you have to contact your peers and ask
-    them not to send you the traffic you don't want.
-
-    There are various other things you can set, including the maximum number
-    of connections the remote host will be allowed.  See incoming.conf(5)
-    for all the details.
-
-    Note for those familiar with older versions of INN:  this file replaces
-    the old hosts.nntp configuration file.
-
-  cycbuff.conf
-
-    cycbuff.conf is only required if CNFS is used.  If you aren't using
-    CNFS, skip this section.
-
-    CNFS stores articles in logical objects called *metacycbuffs*.  Each
-    metacycbuff is in turn composed of one or more physical buffers called
-    *cycbuffs*.  As articles are written to the metacycbuff, each article is
-    written to the next cycbuff in the list in a round-robin fashion (unless
-    "sequential" mode is specified, in which case each cycbuff is filled
-    before moving on to the next).  This is so that you can distribute the
-    individual cycbuffs across multiple physical disks and balance the load
-    between them.
-
-    There are two ways to create your cycbuffs:
-
-    1.  Use a block device directly.  This will probably give you the most
-        speed since it avoids the file system overhead of large files, but
-        it requires your OS support mmap(2) on a block device.  Solaris
-        supports this, as do late Linux 2.4 kernels.  FreeBSD does not at
-        last report.  Also on many PC-based Unixes it is difficult to create
-        more than eight partitions, which may limit your options.
-
-    2.  Use a real file on a filesystem.  This will probably be a bit slower
-        than using a block device directly, but it should work on any Unix
-        system.
-
-    If you're having doubts, use option #2; it's easier to set up and should
-    work regardless of your operating system.
-
-    Now you need to decide on the sizes of your cycbuffs and metacycbuffs. 
-    You'll probably want to separate the heavy-traffic groups
-    ("alt.binaries.*" and maybe a few other things like "*.jobs*" and
-    "news.lists.filters") into their own metacycbuff so that they don't
-    overrun the server and push out articles on the more useful groups.  If
-    you have any local groups that you want to stay around for a while then
-    you should put them in their own metacycbuff as well, so that they don't
-    get pushed out by other traffic.  (Or you might store them in one of the
-    other storage methods, such as tradspool.)
-
-    For each metacycbuff, you now need to determine how many cycbuffs will
-    make up the metacycbuff, the size of those cycbuffs, and where they will
-    be stored.  Some OSes do not support files larger than 2 GB, which will
-    limit the size you can make a single cycbuff, but you can still combine
-    many cycbuffs into each metacycbuff.  Older versions of Linux are known
-    to have this limitation; FreeBSD does not.  Some OSes that support large
-    files don't support direct access to block devices for large partitions
-    (Solaris prior to Solaris 7, or not running in 64-bit mode, is in this
-    category); on those OSes, if you want cycbuffs over 2 GB, you'll have to
-    use regular files.  If in doubt, keep your cycbuffs smaller than 2 GB. 
-    Also, when laying out your cycbuffs, you will want to try to arrange
-    them across as many physical disks as possible (or use a striped disk
-    array and put them all on that).
-
-    In order to use any cycbuff larger than 2 GB, you need to build INN with
-    the --enable-largefiles option.  See "Installing INN" for more
-    information and some caveats.
-
-    For each cycbuff you will be creating, add a line to cycbuff.conf like
-    the following:
-
-        cycbuff:NAME:/path/to/buffer:SIZE
-
-    NAME must be unique and must be at most seven characters long. 
-    Something simple like "BUFF00", "BUFF01", etc. is a decent choice, or
-    you may want to use something that includes the SCSI target and slice
-    number of the partition.  SIZE is the buffer size in kilobytes (if
-    you're trying to stay under 2 GB, keep your sizes below 2097152).
-
-    Now, you need to tell INN how to group your cycbuffs into metacycbuffs. 
-    This is similar to creating cycbuff entries:
-
-        metacycbuff:BUFFNAME:CYCBUFF,CYCBUFF,CYCBUFF
-
-    BUFFNAME is the name of the metacycbuff and must be unique and at most
-    eight characters long.  These should be a bit more meaningful than the
-    cycbuff names since they will be used in other config files as well. 
-    Try to name them after what will be stored in them; for example, if this
-    metacycbuff will hold alt.binaries postings, "BINARIES" would be a good
-    choice.  The last part of the entry is a comma-separated list of all of
-    the cycbuffs that should be used to build this metacycbuff.  Each
-    cycbuff should only appear in one metacycbuff line, and all metacycbuff
-    lines must occur after all cycbuff lines in the file.
-
-    If you want INN to fill each cycbuff before moving on to the next one
-    rather than writing to them round-robin, add ":SEQUENTIAL" to the end of
-    the metacycbuff line.  This may give noticeably better performance when
-    using multiple cycbuffs on the same spindle (such as partitions or
-    slices of a larger disk), but will probably give worse performance if
-    your cycbuffs are spread out across a lot of spindles.
-
-    By default, CNFS data is flushed to disk every 25 articles.  If you're
-    running a small server with a light article load, this could mean losing
-    quite a few articles in a crash.  You can change this interval by adding
-    a cycbuffupdate line to your cycbuff.conf file; see cycbuff.conf(5) for
-    more details.
-
-    Finally, you have to create the cycbuffs.  See "Creating the Article
-    Spool" for more information on how to do that.
-
-  storage.conf
-
-    storage.conf determines where incoming articles will be stored (what
-    storage method, and in the case of CNFS, what metacycbuff).  Each entry
-    in the file defines a storage class for articles.  The first matching
-    storage class is used to store the article; if no storage class matches,
-    INN will reject that article.  (This is almost never what you want, so
-    make sure this file ends in a catch-all entry that will match
-    everything.)
-
-    A storage class definition looks like this:
-
-        method <methodname> {
-            newsgroups: <wildmat>
-            class: <storage_class>
-            size: <minsize>[,<maxsize>]
-            expires: <mintime>[,<maxtime>]
-            options: <options>
-        }
-
-    <methodname> is the name of the storage method to use to store articles
-    in this class ("cnfs", "timehash", "timecaf", "tradspool", or the
-    special method "trash" that accepts the article and throws it away).
-
-    The first parameter is a wildmat pattern in the same format used by the
-    newsfeeds(5) file, and determines what newsgroups are accepted by this
-    storage class.
-
-    The second parameter is a unique number identifying this storage class
-    and should be between 0 and 255.  It can be used to control article
-    expiration, and for timehash and timecaf will set the top-level
-    directory in which articles accepted by this storage class are stored. 
-    The easiest way to deal with this parameter is to just number all
-    storage classes in storage.conf sequentially.  The assignment of a
-    particular number to a storage class is arbitrary but *permanent* (since
-    it is used in storage tokens).
-
-    The third parameter can be used to accept only articles in a certain
-    size range into this storage class.  A <maxsize> of 0 (or a missing
-    <maxsize>) means no upper limit (and of course a <minsize> of 0 would
-    mean no lower limit, because all articles are more than zero bytes
-    long).  If you don't want to limit the size of articles accepted by this
-    storage class, leave this parameter out entirely.
-
-    The fourth parameter you probably don't want to use; it lets you assign
-    storage classes based on the Expires: header of incoming articles.  The
-    exact details are in storage.conf(5).  It's very easy to use this
-    parameter incorrectly; leave it out entirely unless you've read the man
-    page and know what you're doing.
-
-    The fifth parameter is the options parameter.  Currently only CNFS uses
-    this field; it should contain the name of the metacycbuff used to store
-    articles in this storage class.
-
-    If you're using CNFS exclusively, just create one storage class for each
-    metacycbuff that you have defined in cycbuff.conf and set the newsgroups
-    pattern according to what newsgroups should be stored in that buffer.
-
-    If you're using timehash or timecaf, the storage class IDs are used to
-    store articles in separate directory trees, which you can take advantage
-    of to put particular storage classes on different disks.  Also,
-    currently storage class is the only way to specify expiration time, so
-    you will need to divide up your newsgroups based on how long you want to
-    retain articles in those groups and create a storage class for each such
-    collection of newsgroups.  Make note of the storage class IDs you assign
-    as they will be needed when you edit expire.ctl a bit later.
-
-  expire.ctl
-
-    expire.ctl sets the expiration policy for articles stored on the server.
-    Be careful, since the default configuration will expire most articles
-    after 10 days; in most circumstances this deletion is *permanent*, so
-    read this whole section carefully if you want to keep local hierarchies
-    forever.  (See archive(8) for a way to automate backups of important
-    articles.)
-
-    Only one entry is required for all storage classes; it looks like:
-
-        /remember/:10
-
-    This entry says how long to keep the Message-IDs for articles that have
-    already expired in the history file so that the server doesn't accept
-    them again.  Occasionally, fairly old articles will get regurgitated
-    somewhere and offered to you again, so even after you've expired
-    articles from your spool, you want to keep them around in your history
-    file for a little while to ensure you don't get duplicates.
-
-    INN will reject any articles more than a certain number of days old (the
-    *artcutoff* parameter in inn.conf, defaulting to 10); the number on the
-    "/remember/" line should match that.
-
-    CNFS makes no further use of expire.ctl, since articles stored in CNFS
-    buffers expire automatically when the buffer runs out of free space (but
-    see the "-N" option in expireover(8) if you really want to expire them
-    earlier).  For other storage methods, there are two different syntaxes
-    of this file, depending on *groupbaseexpiry* in inn.conf.  If it is set
-    to false, expire.ctl takes entries of the form:
-
-        <storage_class>:<keep>:<default>:<purge>
-
-    <storage_class> is the number assigned to a storage class in
-    storage.conf.  <default> is the number of days to keep normal articles
-    in that storage class (decimal values are allowed).  For articles that
-    don't have an Expires: header, those are the only two values that
-    matter.  For articles with an Expires: header, the other two values come
-    into play; the date given in the Expires: header of an article will be
-    honored, subject to the contraints set by <keep> and <purge>.  All
-    articles in this storage class will be kept for at least <keep> days,
-    regardless of their Expires: headers, and all articles in this storage
-    class will be expired after <purge> days, even if their Expires: headers
-    specify a longer life.
-
-    All three of these fields can also contain the special keyword "never". 
-    If <default> is "never", only articles with explicit Expires: headers
-    will ever be expired.  If <keep> is "never", articles with explicit
-    Expires: headers will be kept forever.  Setting <purge> to "never" says
-    to honor Expires: headers even if they specify dates far into the
-    future.  (Note that if <keep> is set to "never", all articles with
-    Expires: headers are kept forever and the value of <purge> is not used.)
-
-    If the value of "groupbaseexpiry" is true, expire.ctl takes entries of
-    the form:
-
-        <wildmat>:<flag>:<keep>:<default>:<purge>
-
-    <wildmat> is a wildmat expression ("!" and "@" not permitted, and only a
-    single expression, not a comma-separated set of them).  Each expiration
-    line applies to groups matching the wildmat expression.  <flag> is "M"
-    for moderated groups, "U" for unmoderated groups, and "A" for groups
-    with any moderation status; the line only matches groups with the
-    indicated expiration status.  All of the other fields have the same
-    meaning as above.
-
-  readers.conf
-
-    Provided that *noreader* is set to false in inn.conf, any connection
-    from a host that doesn't match an entry in incoming.conf (as well as any
-    connection from a host that does match such an entry, but has issued a
-    MODE READER command) will be handed off to nnrpd(8), the part of INN
-    that supports newsreading clients.  nnrpd uses readers.conf to determine
-    whether a given connection is allowed to read news, and if so what
-    newsgroups the client can read and post to.
-
-    There are a variety of fairly complicated things that one can do with
-    readers.conf, things like run external authentication programs that can
-    query RADIUS servers.  See readers.conf(5) and the example file for all
-    the gory details.  Here's an example of probably the simplest reasonable
-    configuration, one that only allows clients in the example.com domain to
-    read from the server and allows any host in that domain to read and post
-    to all groups:
-
-        auth "example.com" {
-            hosts: "example.com, *.example.com"
-            default: "<user>"
-            default-domain: "example.com"
-        }
-
-        access "all" {
-            users: "*@example.com"
-            newsgroups: "*"
-        }
-
-    If you're running a server for one particular domain, want to allow all
-    hosts within that domain to read and post to any group on the server,
-    and want to deny access to anyone outside that domain, just use the
-    above and change "example.com" in the above to your domain and you're
-    all set.  Lots of examples of more complicated things are in the sample
-    file.
-
-Creating the Article Spool (CNFS only)
-
-    If you are using actual files as your CNFS buffers, you will need to
-    pre-create those files, ensuring they're the right size.  The easiest
-    way to do this is with dd.  For each cycbuff in cycbuff.conf, create the
-    buffer with the following commands (as the news user):
-
-        dd if=/dev/zero of=/path/to/buffer bs=1k count=BUFFERSIZE
-        chmod 664 /path/to/buffer
-
-    Substitute the correct path to the buffer and the size of the buffer as
-    specified in cycbuff.conf.  This will create a zero-filled file of the
-    correct size; it may take a while, so be prepared to wait.
-
-    Here's a command that will print out the dd(1) commands that you should
-    run:
-
-        awk -F: \
-        '/^cy/ { printf "dd if=/dev/zero of=%s bs=1k count=%s\n", $3, $4 }' \
-        ~news/etc/cycbuff.conf
-
-    If you are using block devices, you don't technically have to do
-    anything at all (since INN is capable of using the devices in /dev), but
-    you probably want to create special device files for those devices
-    somewhere for INN's private use.  It s more convenient to keep all of
-    INN's stuff together, but more importantly, the device files used by INN
-    really should be owned by the news user and group, and you may not want
-    to do that with the files in /dev.
-
-    To create the device files for INN, use mknod(8) with a type of "b",
-    getting the major and minor device numbers from the existing devices in
-    /dev.  There's a small shell script in cycbuff.conf(5) that may help
-    with this.  Make sure to create the device files in the location INN
-    expects them (specified in cycbuff.conf).
-
-    Solaris users please note:  on Solaris, do not use block devices that
-    include the first cylinder of the disk.  Solaris doesn't protect the
-    superblock from being overwritten by an application writing to block
-    devices and includes it in the first cylinder of the disk, so unless you
-    use a slice that starts with cylinder 1 instead of 0, INN will
-    invalidate the partition table when it tries to initialize the cycbuff
-    and all further accesses will fail until you repartition.
-
-Creating the Database Files
-
-    At this point, you need to set up the news database directory
-    (~news/db).  This directory will hold the active(5) file (the list of
-    newsgroups you carry), the active.times(5) file (the creator and
-    creation time of newsgroups created since the server was initialized),
-    the newsgroups(5) file (descriptions for all the newsgroups you carry),
-    and the history(5) file (a record of every article the server currently
-    has or has seen in the past few days, used to decide whether to accept
-    or refuse new incoming messages).
-
-    Before starting to work on this, make sure you're logged on as the news
-    user, since all of these files need to be owned by that user.  This is a
-    good policy to always follow; if you are doing any maintenance work on
-    your news server, log on as the news user.  Don't do maintenance work as
-    root.  Also make sure that ~news/bin is in the default path of the news
-    user (and while you're at it, make sure ~news/man is in the default
-    MANPATH) so that you can run INN maintenance commands without having to
-    type the full path.
-
-    If you already have a server set up (if you're upgrading, or setting up
-    a new server based on an existing server), copy active and newsgroups
-    from that server into ~news/db.  Otherwise, you'll need to figure out
-    what newsgroups you want to carry and create new active and newsgroups
-    files for them.  If you plan to carry a full feed, or something close to
-    that, go to <ftp://ftp.isc.org/pub/usenet/CONFIG/> and download active
-    and newsgroups from there; that will start you off with reasonably
-    complete files.  If you plan to only carry a small set of groups, the
-    default minimal active file installed by INN is a good place to start;
-    you can create additional groups after the server is running by using
-    "ctlinnd newgroup".  (Another option is to use actsync(8) to synchronize
-    your newsgroup list to that of another server.)
-
-    "control" and "junk" must exist as newsgroups in your active file for
-    INN to start, and creating pseudogroups for the major types of control
-    messages is strongly encouraged for all servers that aren't standalone. 
-    If you don't want these groups to be visible to clients, do *not* delete
-    them; simply hide them in readers.conf.  "to" must also exist as a
-    newsgroup if you have mergetogroups set in inn.conf.
-
-    Next, you need to create an empty history database.  To do this, type:
-
-        cd ~news/db
-        touch history
-        makedbz -i
-
-    When it finishes, rename the files it created to remove the ".n" in the
-    file names and then make sure the file permissions are correct on all
-    the files you've just created:
-
-        chmod 644 *
-
-    Your news database files are now ready to go.
-
-Configuring syslog
-
-    While some logs are handled internally, INN also logs a wide variety of
-    information via syslog.  INN's nightly report programs know how to roll
-    and summarize those syslog log files, but when you first install INN you
-    need to set them up.
-
-    If your system understands the "news" syslog facility, INN will use it;
-    otherwise, it will log to "local1".  Nearly every modern system has a
-    "news" syslog facility so you can safely assume that yours does, but if
-    in doubt take a look at the output from running "configure".  You should
-    see a line that looks like:
-
-        checking log level for news... LOG_NEWS
-
-    If that says LOG_LOCAL1 instead, change the below instructions to use
-    "local1" instead of "news".
-
-    Edit /etc/syslog.conf on your system and add lines that look like the
-    following:
-
-        news.crit           /usr/local/news/log/news.crit
-        news.err            /usr/local/news/log/news.err
-        news.notice         /usr/local/news/log/news.notice
-
-    (Change the path names as necessary if you installed INN in a different
-    location than /usr/local/news.)  These lines *must* be tab-delimited, so
-    don't copy and paste from these instructions.  Type it in by hand and
-    make sure you use a tab, or you'll get mysterious failures.  You'll also
-    want to make sure that news log messages don't fill your other log files
-    (INN generates a lot of log traffic); so for every entry in
-    /etc/syslog.conf that starts with "*", add ";news.none" to the end of
-    the first column.  For example, if you have a line like:
-
-        *.err               /dev/console
-
-    change it to:
-
-        *.err;news.none     /dev/console
-
-    (You can choose not to do this for the higher priority log messages, if
-    you want to make sure they go to your normal high-priority log files as
-    well as INN's.  Don't bother with anything lower priority than "crit",
-    though.  "news.err" isn't interesting enough to want to see all the
-    time.)  Now, make sure that the news log files exist; syslog generally
-    won't create files automatically.  Enter the following commands:
-
-        touch /usr/local/news/log/news.crit
-        touch /usr/local/news/log/news.err
-        touch /usr/local/news/log/news.notice
-        chown news /usr/local/news/log/news.*
-        chgrp news /usr/local/news/log/news.*
-
-    (again adjusting the paths if necessary for your installation). 
-    Finally, send a HUP signal to syslogd to make it re-read its
-    configuration file.
-
-Setting Up the Cron Jobs
-
-    INN requires a special cron job to be set up on your system to run
-    news.daily(8) which performs daily server maintenance tasks such as
-    article expiration and the processing and rotation of the server logs. 
-    Since it will slow the server down while it is running, it should be run
-    during periods of low server usage, such as in the middle of the night. 
-    To run it at 3am, for example, add the following entry to the news
-    user's crontab file:
-
-        0 3 * * * /usr/local/news/bin/news.daily expireover lowmark
-
-    or, if your system does not have per-user crontabs, put the following
-    line into your system crontab instead:
-
-        0 3 * * * su -c "/usr/local/news/bin/news.daily expireover lowmark" news
-
-    If you're using any non-CNFS storage methods, add "delayrm" to the above
-    option list for news.daily.
-
-    The news user obviously must be able to run cron jobs.  On Solaris, this
-    means that it must have a valid /etc/shadow entry and must not be locked
-    (although it may be a non-login account).  There may be similar
-    restrictions with other operating systems.
-
-    If you use the batching method to send news, also set up a cron job to
-    run nntpsend(8) every ten minutes.  nntpsend will run innxmit for all
-    non-empty pending batch files to send pending news to your peers.  That
-    cron entry should look something like:
-
-        0,10,20,30,40,50 * * * * /usr/local/news/bin/nntpsend
-
-    The pathnames and user ID used above are the installation defaults;
-    change them to match your installation if you used something other than
-    the defaults.
-
-    The parameters passed to news.daily in the above example are the most
-    common (and usually the most efficient) ones to use.  More information
-    on what these parameters do can be found in the news.daily(8) man page.
-
-File Descriptor Limits
-
-    INN likes to use a lot of file descriptors, particularly if you have a
-    lot of peers.  Depending on what your system defaults are, you may need
-    to make sure the default limit is increased for INN (particularly for
-    innd and innfeed).  This is vital on Solaris, which defaults (at least
-    as of 2.6) to an absurdly low limit of 64 file descriptors per process.
-
-    One way to increase the number of file descriptors is to set
-    *rlimitnofile* in inn.conf to a higher value.  This will cause both
-    startinnfeed and inndstart (the setuid root wrapper scripts that start
-    innfeed and innd, respectively) to increase the file descriptor limits
-    before they run the regular INN programs.  Note, however, that INN won't
-    be able to increase the limits above the hard limits set by your
-    operating system; on some systems, that hard limit is normally 256 file
-    descriptors (Linux, for example).  On others, like Solaris, it's 1024. 
-    Increasing the limit beyond that value may require serious system
-    configuration work.  (On some operating systems, it requires patching
-    and recompiling the kernel.  On Solaris it can be changed in
-    /etc/system, but for 2.6 or earlier the limit cannot be increased beyond
-    1024 without breaking select(2) and thereby breaking all of INN.  For
-    current versions of Linux, you may be able to change the maximum by
-    writing to /proc/sys/fs/file-max.)
-
-    256 file descriptors will probably be enough for all but the largest
-    sites.  There is no harm in setting the limits higher than you actually
-    need (provided they're set to something lower than or equal to your
-    system hard limit).  256 is therefore a reasonable value to try.
-
-    If you're installing INN on a Solaris system, particularly if you're
-    installing it on a dedicated news server machine, it may be easier to
-    just increase the default file descriptor limit across the board for all
-    processes.  You can do that by putting the line:
-
-        set rlim_fd_cur = 256
-
-    in /etc/system and rebooting.  You can increase it all the way to 1024
-    (and may need to if you have a particularly large site), but that can
-    cause RPC and some stdio applications to break.  It therefore probably
-    isn't a good idea on a machine that isn't dedicated to INN.
-
-Starting and Stopping the System
-
-    INN is started via the shell script rc.news.  This must be run as the
-    news user and not as root.  To start INN on system boot, you therefore
-    want to put something like:
-
-        su - news -c /usr/local/news/bin/rc.news
-
-    in the system boot scripts.  If innd is stopped or killed, you can
-    restart it by running rc.news by hand as the news user.
-
-    The rc.news script may also be used to shut down INN, with the "stop"
-    option:
-
-        su - news -c '/usr/local/news/bin/rc.news stop'
-
-    In the contrib directory of this source tree is a sample init script for
-    people using System V-style init.d directories.
-
-Processing Newsgroup Control Messages
-
-    Control messages are specially-formatted messages that tell news servers
-    to take various actions.  Cancels (commands to delete messages) are
-    handled internally by INN, and all other control messages are processed
-    by controlchan.  controlchan should be run out of newsfeeds if you want
-    your news server to process any control messages; see "Configuring INN"
-    for specific instructions.
-
-    The actions of controlchan are determined by control.ctl, which lists
-    who can perform what actions.  The primary control messages to be
-    concerned with are "newgroup" (to create a newsgroup), "rmgroup" (to
-    remove a newsgroup), and "checkgroups" (to compare the list of groups
-    carried in a hierarchy to a canonical list).  INN comes with a
-    control.ctl file that processes control messages in most major public
-    hierarchies; if you don't want to act on all those control messages, you
-    should remove from that file all entries for hierarchies you don't want
-    to carry.
-
-    You can tell INN to just authenticate control messages based on the From
-    header of the message, but this is obviously perilous and control
-    messages are widely forged.  Many hierarchies sign all of their control
-    messages with PGP, allowing news servers to verify their authenticity,
-    and checking those signatures for hierarchies that use them is highly
-    recommended.  controlchan knows how to do this (using pgpverify) without
-    additional configuration, but you do have to provide it with a public
-    key ring containing the public keys of all of the hierarchy
-    administrators whose control messages you want to check.
-
-    INN expects the public key ring to either be in the default location for
-    a PGP public key ring for the news user (generally ~news/.gnupg for
-    GnuPG and ~news/.pgp for old PGP implementations), or in pathetc/pgp
-    (/usr/local/news/etc/pgp by default).  The latter is the recommended
-    path.  To add a key to that key ring, use:
-
-        gpg --import --homedir=/usr/local/news/etc/pgp <file>
-
-    where <file> is a file containing the hierarchy key.  Change the homedir
-    setting to point to pathetc/pgp if you have INN installed in a
-    non-default location.  If you're using the old-style PGP program, an
-    equivalent command is:
-
-        env PGPPATH=/usr/local/news/etc/pgp pgp <file>
-
-    You can safely answer "no" to questions about whether you want to sign,
-    trust, or certify keys.
-
-    The URLs from which you can get hierarchy keys are noted in comments in
-    control.ctl.  <ftp://ftp.isc.org/pub/pgpcontrol/PGPKEYS> tries to
-    collect the major hierarchy keys.
-
-    If you are using GnuPG, please note that the first user ID on the key
-    will be the one that's used by INN for verification and must match the
-    key listed in control.ctl.  If a hierarchy key has multiple user IDs,
-    you may have to remove all the user IDs except the one that matches the
-    control.ctl entry using "gpg --edit-key" and the "delkey" command.
-
diff --git a/LICENSE b/LICENSE
deleted file mode 100644 (file)
index 4d0fec5..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,87 +0,0 @@
-INN as a whole and all code contained in it not otherwise marked with
-different licenses and/or copyrights is covered by the following copyright
-and license:
-
-   Copyright (c) 2004, 2005, 2006, 2007, 2008
-       by Internet Systems Consortium, Inc. ("ISC")
-   Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-       2002, 2003 by The Internet Software Consortium and Rich Salz
-
-   This code is derived from software contributed to the Internet Software
-   Consortium by Rich Salz.
-
-   Permission to use, copy, modify, and distribute this software for any
-   purpose with or without fee is hereby granted, provided that the above
-   copyright notice and this permission notice appear in all copies.
-
-   THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-   REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-   MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
-   SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Some specific portions of INN are covered by different licenses.  Those
-licenses, if present, will be noted prominantly at the top of those source
-files.  Specifically (but possibly not comprehensively):
-
-   authprogs/smbval/*, backends/send-uucp.in, and control/perl-nocem.in
-   are under the GNU General Public License.  See doc/GPL for a copy of
-   this license.
-
-   backends/shrinkfile.c, frontends/scanspool.in, lib/concat.c,
-   lib/hstrerror.c, lib/inet_aton.c, lib/inet_ntoa.c, lib/memcmp.c,
-   lib/parsedate.y, lib/pread.c, lib/pwrite.c, lib/setenv.c, lib/seteuid.c,
-   lib/strerror.c, lib/strlcat.c and lib/strlcpy.c are in the public
-   domain.
-
-   lib/snprintf.c may be used for any purpose as long as the author's
-   notice remains intact in all source code distributions.
-
-   control/gpgverify.in, control/pgpverify.in and control/signcontrol.in
-   are under a BSD-style license (with the advertising clause) with UUNET
-   Technologies, Inc. as the copyright holder.  See the end of those files
-   for details.
-
-   control/controlchan.in and control/modules/*.pl are covered by a
-   two-clause BSD-style license (no advertising clause).  See the
-   beginning of those files for details.
-
-   lib/strcasecmp.c, lib/strspn.c, and lib/strtok.c are taken from BSD
-   sources and are covered by the standard BSD license.  See those files
-   for more details.
-
-   lib/md5.c is covered under the standard free MD5 license from RSA Data
-   Security.  See the file for more details.  A clarification is also
-   provided here:  <http://www.ietf.org/ietf/IPR/RSA-MD-all>.
-
-      "Implementations of these message-digest algorithms, including
-      implementations derived from the reference C code in RFC-1319,
-      RFC-1320, and RFC-1321, may be made, used, and sold without
-      license from RSA for any purpose."
-
-   history/his.c and history/hisv6/hisv6.c are under a license very
-   similar to the new BSD license (no advertising clause) but with Thus
-   plc as the copyright holder.  See those files for details.
-
-   lib/tst.c, include/inn/tst.h and doc/pod/tst.pod are derived from
-   <http://www.octavian.org/cs/tst1.3.tar.gz> and are under the new BSD
-   license (no advertising clause), but with Peter A. Friend as the
-   copyright holder.
-
-   tests/runtests.c is covered under a license very similar to the MIT/X
-   Consortium license.  See the beginning of the file for details.
-
-Note that all portions of INN that link with core INN code have to be
-covered by licenses compatible with the license at the top of this file,
-and since INN links with several external libraries if so configured (such
-as OpenSSL), should also be compatible with the licenses of those external
-libraries to be safe.  Some portions of this distribution are covered by
-more restrictive licenses, but all of that code is completely stand-alone,
-either as a standalone script or as code that compiles into a separate
-executable.
-
-Please note that the files in the contrib directory are not properly part
-of INN and may be under widely varying licenses.  Please see each file
-and/or its documentation for license information.
diff --git a/MANIFEST b/MANIFEST
deleted file mode 100644 (file)
index d93dada..0000000
--- a/MANIFEST
+++ /dev/null
@@ -1,745 +0,0 @@
-File Name                             Description
--------------------------------------------------------------------------------
-CONTRIBUTORS                          List of contributors
-HACKING                               Docs for INN coders and maintainers
-INSTALL                               INN installation instructions
-LICENSE                               Legal mumbo-jumbo
-MANIFEST                              This shipping list
-Makefile                              Top-level makefile
-Makefile.global.in                    Make variables for all Makefiles
-NEWS                                  Changes since last version
-README                                Introduction to the INN package
-TODO                                  The list of pending INN projects
-aclocal.m4                            M4 macro for libtool
-authprogs                             The authentication programs (Directory)
-authprogs/Makefile                    Makefile for auth programs
-authprogs/auth_krb5.c                 Authenticator against Kerberos v5
-authprogs/auth_smb.c                  Authenticator against Samba servers
-authprogs/ckpasswd.c                  Check password
-authprogs/domain.c                    Get username from remote user's hostname
-authprogs/ident.c                     Get username from ident
-authprogs/libauth.c                   Library for talking to nnrpd
-authprogs/libauth.h                   Interface for libauth
-authprogs/radius.c                    Authenticator against RADIUS servers
-authprogs/smbval                      The smb auth libraries (Directory)
-authprogs/smbval/Makefile             Libraries for smb auth
-authprogs/smbval/byteorder.h          Libraries for smb auth
-authprogs/smbval/rfcnb-common.h       Libraries for smb auth
-authprogs/smbval/rfcnb-error.h        Libraries for smb auth
-authprogs/smbval/rfcnb-io.c           Libraries for smb auth
-authprogs/smbval/rfcnb-io.h           Libraries for smb auth
-authprogs/smbval/rfcnb-priv.h         Libraries for smb auth
-authprogs/smbval/rfcnb-util.c         Libraries for smb auth
-authprogs/smbval/rfcnb-util.h         Libraries for smb auth
-authprogs/smbval/rfcnb.h              Libraries for smb auth
-authprogs/smbval/session.c            Libraries for smb auth
-authprogs/smbval/smbdes.c             Libraries for smb auth
-authprogs/smbval/smbencrypt.c         Libraries for smb auth
-authprogs/smbval/smblib-common.h      Libraries for smb auth
-authprogs/smbval/smblib-priv.h        Libraries for smb auth
-authprogs/smbval/smblib-util.c        Libraries for smb auth
-authprogs/smbval/smblib.c             Libraries for smb auth
-authprogs/smbval/smblib.h             Libraries for smb auth
-authprogs/smbval/valid.c              Libraries for smb auth
-authprogs/smbval/valid.h              Libraries for smb auth
-backends                              Outgoing feed programs (Directory)
-backends/Makefile                     Makefile for outgoing feed programs
-backends/actmerge.in                  Merge two active files to stdout
-backends/actsync.c                    Poll remote(s) for active file & merge
-backends/actsyncd.in                  Daemon to run actsync periodically
-backends/archive.c                    Simple article archiver
-backends/batcher.c                    Make news batches
-backends/buffchan.c                   Buffered funnel to file splitter
-backends/crosspost.c                  Create links for crossposts (obselete)
-backends/cvtbatch.c                   Add fields to simple batchfile
-backends/filechan.c                   Split a funnel into separate files
-backends/inndf.c                      df used for innwatch
-backends/innxbatch.c                  Send batches using XBATCH to remote
-backends/innxmit.c                    Send articles to remote site
-backends/map.c                        Site name to filename mapping routines
-backends/map.h                        Headers for backends/map.c
-backends/mod-active.in                Batch do active file modifications
-backends/news2mail.in                 News to mail gateway
-backends/ninpaths.c                   Path statistics accumulation program
-backends/nntpget.c                    Get articles from remote site
-backends/nntpsend.in                  Invoke all innxmit's at once
-backends/overchan.c                   Update news overview database
-backends/send-ihave.in                Script to post ihave messages
-backends/send-nntp.in                 Shell script to call innxmit
-backends/send-uucp.in                 Script to call batcher
-backends/sendinpaths.in               Send accumulated Path statistics
-backends/sendxbatches.in              Shell wrapper around innxbatch
-backends/shlock.c                     Program to make lockfiles in scripts
-backends/shrinkfile.c                 Shrink file from beginning
-configure                             Script to configure INN
-configure.in                          Source file for configure
-contrib                               External contributions (Directory)
-contrib/Makefile                      Makefile for contrib programs
-contrib/README                        Contents of the contrib directory
-contrib/archivegz.in                  Compressing version of archive
-contrib/auth_pass.README              README corresponding to auth_pass.c
-contrib/auth_pass.c                   Sample for use with AUTHINFO GENERIC
-contrib/backlogstat.in                Analyze innfeed's backlog status
-contrib/backupfeed.in                 Suck down news via a reading connection
-contrib/cleannewsgroups.in            Script to clean newsgroups file
-contrib/count_overview.pl             Count overview entries
-contrib/delayer.in                    Delay data in a pipe, for innfeed
-contrib/expirectl.c                   Generate expire.ctl from template
-contrib/findreadgroups.in             Track which groups are being read
-contrib/fixhist                       Script to clean history
-contrib/innconfcheck                  Merge inn.conf with its man page
-contrib/makeexpctl.in                 Create expire.ctl from read groups
-contrib/makestorconf.in               Create storage.conf from read groups
-contrib/mkbuf                         Create cycbuff for HP-UX
-contrib/mlockfile.c                   Lock files into memory using mlock
-contrib/newsresp.c                    Measure responsiveness of remote server
-contrib/pullart.c                     Recover articles from cyclic buffers
-contrib/reset-cnfs.c                  Reset the state parts of a CNFS buffer
-contrib/respool.c                     Respool articles in the storage manager
-contrib/sample.init.script            Example SysV-style init.d script
-contrib/showtoken.in                  Decode storage API tokens
-contrib/stathist.in                   Parse history statistics
-contrib/thdexpire.in                  Dynamic expire for timehash and timecaf
-contrib/tunefeed.in                   Tune a feed by comparing active files
-control                               Control message handling (Directory)
-control/Makefile                      Makefile for control programs
-control/controlbatch.in               Batch program for controlchan
-control/controlchan.in                Channel program for control messages
-control/docheckgroups.in              Script to execute checkgroups
-control/gpgverify.in                  Verify control messages with GnuPG
-control/modules                       Modules for controlchan (Directory)
-control/modules/checkgroups.pl        checkgroups controlchan handler
-control/modules/ihave.pl              ihave controlchan handler
-control/modules/newgroup.pl           newgroup controlchan handler
-control/modules/rmgroup.pl            rmgroup controlchan handler
-control/modules/sendme.pl             sendme controlchan handler
-control/modules/sendsys.pl            sendsys controlchan handler
-control/modules/senduuname.pl         senduuname controlchan handler
-control/modules/version.pl            version controlchan handler
-control/perl-nocem.in                 NoCeM on spool implementation
-control/pgpverify.in                  Verify control messages with PGP
-control/signcontrol.in                PGP control message signing program
-doc                                   Documentation (Directory)
-doc/GPL                               The GNU General Public License 2.0
-doc/IPv6-info                         Nathan Lutchansky's IPv6 notes
-doc/Makefile                          Makefile for documentation
-doc/checklist                         Checklist for installing INN
-doc/compliance-nntp                   INN compliance with the NNTP standard
-doc/config-design                     Configuration parser design principles
-doc/config-semantics                  Configuration file semantics
-doc/config-syntax                     Configuration file syntax
-doc/external-auth                     readers.conf external interface notes
-doc/history                           Messages of historical significance
-doc/hook-perl                         Christophe Wolfhugel's Perl hook notes
-doc/hook-python                       Python hook notes
-doc/hook-tcl                          Bob Halley's TCL hook notes
-doc/man                               nroff documentation (Directory)
-doc/man/Makefile                      Makefile for nroff documentation
-doc/man/active.5                      Manpage for active database
-doc/man/active.times.5                Manpage for active.times file
-doc/man/actsync.8                     Manpage for active file synch program
-doc/man/actsyncd.8                    Manpage for active synch daemon
-doc/man/archive.8                     Manpage for archive backend
-doc/man/auth_krb5.8                   Manpage for auth_krb5 authenticator
-doc/man/auth_smb.8                    Manpage for auth_smb authenticator
-doc/man/batcher.8                     Manpage for batcher
-doc/man/buffchan.8                    Manpage for buffchan backend
-doc/man/buffindexed.conf.5            Manpage for buffindexed.conf config file
-doc/man/ckpasswd.8                    Manpage for ckpasswd authenticator
-doc/man/clientlib.3                   Manpage for C News library interface
-doc/man/cnfsheadconf.8                Manpage for cnfsheadconf
-doc/man/cnfsstat.8                    Manpage for cnfsstat
-doc/man/control.ctl.5                 Manpage for control.ctl config file
-doc/man/controlchan.8                 Manpage for controlchan backend
-doc/man/convdate.1                    Manpage for convdate utility
-doc/man/ctlinnd.8                     Manpage for ctlinnd frontend
-doc/man/cvtbatch.8                    Manpage for cvtbatch utility
-doc/man/cycbuff.conf.5                Manpage for cycbuff.conf config file
-doc/man/dbz.3                         Manpage for DBZ database interface
-doc/man/distrib.pats.5                Manpage for distrib.pats config file
-doc/man/domain.8                      Manpage for domain resolver
-doc/man/expire.8                      Manpage for expire
-doc/man/expire.ctl.5                  Manpage for expire.ctl config file
-doc/man/expireover.8                  Manpage for expireover
-doc/man/expirerm.8                    Manpage for expirerm
-doc/man/fastrm.1                      Manpage for fastrm utility
-doc/man/filechan.8                    Manpage for filechan backend
-doc/man/getlist.1                     Manpage for getlist frontend
-doc/man/grephistory.1                 Manpage for grephistory
-doc/man/history.5                     Manpage for history database
-doc/man/ident.8                       Manpage for ident resolver
-doc/man/incoming.conf.5               Manpage for incoming.conf config file
-doc/man/inews.1                       Manpage for inews frontend
-doc/man/inn.conf.5                    Manpage for inn.conf config file
-doc/man/inncheck.8                    Manpage for inncheck utility
-doc/man/innconfval.1                  Manpage for innconfval
-doc/man/innd.8                        Manpage for innd server
-doc/man/inndcomm.3                    Manpage for part of INN library
-doc/man/inndf.8                       Manpage for inndf utility
-doc/man/inndstart.8                   Manpage for inndstart
-doc/man/innfeed.1                     Manpage for innfeed backend
-doc/man/innfeed.conf.5                Manpage for innfeed.conf config file
-doc/man/innmail.1                     Manpage for innmail utility
-doc/man/innreport.8                   Manpage for innreport
-doc/man/innstat.8                     Manpage for innstat utility
-doc/man/innupgrade.8                  Manpage for innupgrade utility
-doc/man/innwatch.8                    Manpage for innwatch
-doc/man/innwatch.ctl.5                Manpage for innwatch.ctl config file
-doc/man/innxbatch.8                   Manpage for innxbatch
-doc/man/innxmit.8                     Manpage for innxmit
-doc/man/libauth.3                     Manpage for authprogs utilty routines
-doc/man/libinn.3                      Manpage for INN library routines
-doc/man/libinnhist.3                  Manpage for history API library routines
-doc/man/libstorage.3                  Manpage for storage API library routines
-doc/man/list.3                        Manpage for list routines
-doc/man/mailpost.8                    Manpage for mailpost frontend
-doc/man/makeactive.8                  Manpage for makeactive
-doc/man/makedbz.8                     Manpage for makedbz
-doc/man/makehistory.8                 Manpage for makehistory
-doc/man/mod-active.8                  Manpage for mod-active
-doc/man/moderators.5                  Manpage for moderators config file
-doc/man/motd.news.5                   Manpage for motd.news config file
-doc/man/news.daily.8                  Manpage for news.daily
-doc/man/news2mail.8                   Manpage for news2mail
-doc/man/newsfeeds.5                   Manpage for newsfeeds config file
-doc/man/newslog.5                     Manpage for log files
-doc/man/ninpaths.8                    Manpage for ninpaths
-doc/man/nnrpd.8                       Manpage for nnrpd daemon
-doc/man/nnrpd.track.5                 Manpage for nnrpd.track config file
-doc/man/nntpget.1                     Manpage for nntpget frontend
-doc/man/nntpsend.8                    Manpage for nntpsend
-doc/man/nntpsend.ctl.5                Manpage for nntpsend.ctl config file
-doc/man/ovdb.5                        Manpage for the ovdb storage module
-doc/man/ovdb_init.8                   Manpage for ovdb_init
-doc/man/ovdb_monitor.8                Manpage for ovdb_monitor
-doc/man/ovdb_server.8                 Manpage for ovdb_server
-doc/man/ovdb_stat.8                   Manpage for ovdb_stat
-doc/man/overchan.8                    Manpage for overchan backend
-doc/man/overview.fmt.5                Manpage for overview.fmt config file
-doc/man/parsedate.3                   Manpage for parsedate library routine
-doc/man/passwd.nntp.5                 Manpage for passwd.nntp config file
-doc/man/perl-nocem.8                  Manpage for perl-nocem
-doc/man/pgpverify.1                   Manpage for pgpverify
-doc/man/prunehistory.8                Manpage for prunehistory
-doc/man/pullnews.1                    Manpage for pullnews
-doc/man/putman.sh                     Install a manpage
-doc/man/qio.3                         Manpage for fast I/O file routines
-doc/man/radius.8                      Manpage for radius authenticator
-doc/man/radius.conf.5                 Manpage for radius.conf config file
-doc/man/rc.news.8                     Manpage for rc.news
-doc/man/readers.conf.5                Manpage for readers.conf config file
-doc/man/rnews.1                       Manpage for rnews frontend
-doc/man/sasl.conf.5                   Manpage for sasl.conf config file
-doc/man/scanlogs.8                    Manpage for scanlogs
-doc/man/send-nntp.8                   Manpage for send-nntp and send-ihave
-doc/man/send-uucp.8                   Manpage for send-uucp
-doc/man/sendinpaths.8                 Manpage for sendinpaths
-doc/man/shlock.1                      Manpage for shlock backend utility
-doc/man/shrinkfile.1                  Manpage for shrinkfile utility
-doc/man/simpleftp.1                   Manpage for simpleftp utility
-doc/man/sm.1                          Manpage for sm
-doc/man/startinnfeed.1                Manpage for startinnfeed
-doc/man/storage.conf.5                Manpage for storage.conf config file
-doc/man/subscriptions.5               Manpage for subscriptions list
-doc/man/tally.control.8               Manpage for tally.control
-doc/man/tdx-util.8                    Manpage for tdx-util
-doc/man/tst.3                         Manpage for ternary search tree routines
-doc/man/uwildmat.3                    Manpage for uwildmat library routine
-doc/man/writelog.8                    Manpage for writelog
-doc/pod                               POD documentation (Directory)
-doc/pod/Makefile                      Maintainer rules for derived files
-doc/pod/active.pod                    Master file for active.5
-doc/pod/active.times.pod              Master file for active.times.5
-doc/pod/auth_krb5.pod                 Master file for auth_krb5.8
-doc/pod/auth_smb.pod                  Master file for auth_smb.8
-doc/pod/checklist.pod                 Master file for doc/checklist
-doc/pod/ckpasswd.pod                  Master file for ckpasswd.8
-doc/pod/control.ctl.pod               Master file for control.ctl.5
-doc/pod/convdate.pod                  Master file for convdate.1
-doc/pod/cycbuff.conf.pod              Master file for cycbuff.conf.5
-doc/pod/distrib.pats.pod              Master file for distrib.pats.5
-doc/pod/domain.pod                    Master file for domain.8
-doc/pod/expire.ctl.pod                Master file for expire.ctl.5
-doc/pod/expireover.pod                Master file for expireover.8
-doc/pod/external-auth.pod             Master file for doc/external-auth
-doc/pod/fastrm.pod                    Master file for fastrm.1
-doc/pod/grephistory.pod               Master file for grephistory.1
-doc/pod/hacking.pod                   Master file for HACKING
-doc/pod/hook-perl.pod                 Master file for doc/hook-perl
-doc/pod/hook-python.pod               Master file for doc/hook-python
-doc/pod/ident.pod                     Master file for ident.8
-doc/pod/inews.pod                     Master file for inews.1
-doc/pod/inn.conf.pod                  Master file for inn.conf.5
-doc/pod/innconfval.pod                Master file for innconfval.1
-doc/pod/innd.pod                      Master file for innd.8
-doc/pod/inndf.pod                     Master file for inndf.8
-doc/pod/inndstart.pod                 Master file for inndstart.8
-doc/pod/innmail.pod                   Master file for innmail.1
-doc/pod/innupgrade.pod                Master file for innupgrade.8
-doc/pod/install.pod                   Master file for INSTALL
-doc/pod/libauth.pod                   Master file for libauth.3
-doc/pod/libinnhist.pod                Master file for libinnhist.3
-doc/pod/list.pod                      Master file for list.3
-doc/pod/mailpost.pod                  Master file for mailpost.8
-doc/pod/makehistory.pod               Master file for makehistory.8
-doc/pod/motd.news.pod                 Master file for motd.news.5
-doc/pod/news.pod                      Master file for NEWS
-doc/pod/newsfeeds.pod                 Master file for newsfeeds.5
-doc/pod/ninpaths.pod                  Master file for ninpaths.8
-doc/pod/nnrpd.pod                     Master file for nnrpd.8
-doc/pod/ovdb.pod                      Master file for ovdb.5
-doc/pod/ovdb_init.pod                 Master file for ovdb_init.8
-doc/pod/ovdb_monitor.pod              Master file for ovdb_monitor.8
-doc/pod/ovdb_server.pod               Master file for ovdb_server.8
-doc/pod/ovdb_stat.pod                 Master file for ovdb_stat.8
-doc/pod/passwd.nntp.pod               Master file for passwd.nntp.5
-doc/pod/pullnews.pod                  Master file for pullnews.1
-doc/pod/qio.pod                       Master file for qio.3
-doc/pod/radius.conf.pod               Master file for radius.conf.5
-doc/pod/radius.pod                    Master file for radius.8
-doc/pod/rc.news.pod                   Master file for rc.news.8
-doc/pod/readers.conf.pod              Master file for readers.conf.5
-doc/pod/readme.pod                    Master file for README
-doc/pod/sasl.conf.pod                 Master file for sasl.conf.5
-doc/pod/sendinpaths.pod               Master file for sendinpaths.8
-doc/pod/simpleftp.pod                 Master file for simpleftp.1
-doc/pod/sm.pod                        Master file for sm.1
-doc/pod/subscriptions.pod             Master file for subscriptions.5
-doc/pod/tdx-util.pod                  Master file for tdx-util.8
-doc/pod/tst.pod                       Master file for tst.3
-doc/pod/uwildmat.pod                  Master file for uwildmat.3
-doc/sample-control                    Sample PGP-signed control message
-expire                                Expiration and recovery (Directory)
-expire/Makefile                       Makefile for expiration
-expire/convdate.c                     Date string conversions
-expire/expire.c                       Expire old articles and history lines
-expire/expireover.c                   Expire news overview data
-expire/expirerm.in                    Remove articles from expire -z
-expire/fastrm.c                       Remove list of files
-expire/grephistory.c                  Find entries in history database
-expire/makedbz.c                      Recover dbz
-expire/makehistory.c                  Recover the history database
-expire/prunehistory.c                 Prune file names from history file
-frontends                             inews, rnews, ctlinnd (Directory)
-frontends/Makefile                    Makefile for frontends
-frontends/cnfsheadconf.in             Setup cycbuff header
-frontends/cnfsstat.in                 Show cycbuff status
-frontends/ctlinnd.c                   Send control request to innd
-frontends/decode.c                    Decode 7-bit data into binary file
-frontends/encode.c                    Encode binary file into 7-bit data
-frontends/feedone.c                   Test rig to feed a single NNTP article
-frontends/getlist.c                   Get active or other list from server
-frontends/inews.c                     Send article to local NNTP server
-frontends/innconfval.c                Get an INN configuration parameter
-frontends/mailpost.in                 Mail to news gateway
-frontends/ovdb_init.c                 Prepare ovdb database for use
-frontends/ovdb_monitor.c              Database maintainance for ovdb
-frontends/ovdb_server.c               Helper server for ovdb
-frontends/ovdb_stat.c                 Display information from ovdb database
-frontends/pullnews.in                 Sucking news feeder
-frontends/rnews.c                     UUCP unbatcher
-frontends/scanspool.in                Scan spool directory for trash
-frontends/sm.c                        Get article or overview data from token
-frontends/sys2nf.c                    Sys file to newsfeeds conversion aid
-history                               History library routines (Directory)
-history/Make.methods                  Makefile for history methods
-history/Makefile                      Makefile for history library
-history/buildconfig.in                Construct history interface
-history/his.c                         History API glue implementation
-history/hisinterface.h                History API interface
-history/hisv6                         History v6 method (Directory)
-history/hisv6/hismethod.config        hisbuildconfig definition
-history/hisv6/hisv6-private.h         Private header file for hisv6
-history/hisv6/hisv6.c                 hisv6 history method
-history/hisv6/hisv6.h                 Header for hisv6 history
-include                               Header files (Directory)
-include/Makefile                      Makefile for header files
-include/acconfig.h                    Master file for config.h.in
-include/clibrary.h                    C library portability
-include/conffile.h                    Header file for reading *.conf files
-include/config.h.in                   Template configuration data 
-include/dbz.h                         Header file for DBZ
-include/inn                           Installed header files (Directory)
-include/inn/buffer.h                  Header file for reusable counted buffers
-include/inn/confparse.h               Header file for configuration parser
-include/inn/defines.h                 Portable defs for installed headers
-include/inn/hashtab.h                 Header file for generic hash table
-include/inn/history.h                 Header file for the history API
-include/inn/innconf.h                 Header file for the innconf struct
-include/inn/list.h                    Header file for list routines
-include/inn/md5.h                     Header file for MD5 digests
-include/inn/messages.h                Header file for message functions
-include/inn/mmap.h                    Header file for mmap() functions
-include/inn/qio.h                     Header file for quick I/O package
-include/inn/sequence.h                Header file for sequence space arithmetic
-include/inn/timer.h                   Header file for generic timers
-include/inn/tst.h                     Header file for ternary search tries
-include/inn/vector.h                  Header file for vectors of strings
-include/inn/wire.h                    Header file for wire-format functions
-include/inndcomm.h                    innd control channel commands
-include/innperl.h                     Header file for embedded Perl
-include/libinn.h                      INN library declarations
-include/nntp.h                        NNTP command and reply codes
-include/ov.h                          Header file for overview
-include/paths.h.in                    Paths to common programs and files
-include/portable                      Portability wrappers (Directory)
-include/portable/mmap.h               Wrapper for <sys/mman.h>
-include/portable/setproctitle.h       Portable setup for setproctitle
-include/portable/socket.h             Wrapper for <sys/socket.h> and friends
-include/portable/time.h               Wrapper for <time.h> and <sys/time.h>
-include/portable/wait.h               Wrapper for <sys/wait.h>
-include/ppport.h                      Header file for Perl support
-include/storage.h                     Header file for storage API
-innd                                  Server (Directory)
-innd/Makefile                         Makefile for server
-innd/art.c                            Process a received article
-innd/cc.c                             Control channel routines
-innd/chan.c                           I/O channel routines
-innd/icd.c                            Read and write the active file
-innd/innd.c                           Main and utility routines
-innd/innd.h                           Header file for server
-innd/inndstart.c                      Open the NNTP port, then exec innd
-innd/keywords.c                       Generate article keywords
-innd/lc.c                             Local NNTP channel routines
-innd/nc.c                             NNTP channel routines
-innd/newsfeeds.c                      Routines to parse the newsfeeds file
-innd/ng.c                             Newsgroup routines
-innd/perl.c                           Perl routines for innd
-innd/proc.c                           Process routines
-innd/python.c                         Python routines for innd
-innd/rc.c                             Remote channel accepting routines
-innd/site.c                           Site feeding routines
-innd/status.c                         Status routines for innd
-innd/tcl.c                            Bob Halley's Tcl hook
-innd/util.c                           Utility functions for innd
-innd/wip.c                            Work-in-progress routines for innd
-innfeed                               innfeed (Directory)
-innfeed/Makefile                      Makefile for innfeed
-innfeed/README                        Assorted notes
-innfeed/article.c                     Implementation of the Article class
-innfeed/article.h                     Public interface to Articles
-innfeed/buffer.c                      Implementation of the Buffer class
-innfeed/buffer.h                      Public interface to the Buffer class
-innfeed/config_l.c                    Lexer for the innfeed config file
-innfeed/configfile.h                  Header file for configfile.y
-innfeed/configfile.l                  Master file for config_l.c
-innfeed/configfile.y                  Parser for innfeed config file
-innfeed/connection.c                  Implementation of the Connection class
-innfeed/connection.h                  Public interface to the Connection class
-innfeed/endpoint.c                    Implementation of the EndPoint class
-innfeed/endpoint.h                    Public interface to the EndPoint class
-innfeed/host.c                        Implementation of the Host class
-innfeed/host.h                        Public interface to the Host class
-innfeed/imap_connection.c             Implementation of IMAP Connection class
-innfeed/innfeed-convcfg.in            Script to convert old innfeed.conf
-innfeed/innfeed.h                     Application configuration values
-innfeed/innlistener.c                 Implementation of the InnListener class
-innfeed/innlistener.h                 Public interface of InnListener class
-innfeed/main.c                        Main routines for the innfeed program
-innfeed/misc.c                        Miscelloneous routines for innfeed
-innfeed/misc.h                        Header file for misc.c
-innfeed/procbatch.in                  Script to process dropped articles
-innfeed/startinnfeed.c                Start innfeed
-innfeed/tape.c                        Implementation of the Tape class
-innfeed/tape.h                        Public interface to the Tape class
-innfeed/testListener.pl               Script to hand articles to innfeed
-lib                                   INN library routines (Directory)
-lib/Makefile                          Makefile for library
-lib/buffer.c                          Reusable counted buffer
-lib/cleanfrom.c                       Clean out a From line
-lib/clientactive.c                    Client access to the active file
-lib/clientlib.c                       Replacement for C News library routine
-lib/concat.c                          Concatenate strings with dynamic memory
-lib/conffile.c                        Routines for reading *.conf files
-lib/confparse.c                       Generic configuration file parser
-lib/daemonize.c                       Code necessary to become a daemon
-lib/date.c                            Date parsing and conversion routines
-lib/dbz.c                             DBZ database library
-lib/defdist.c                         Determine default Distribution header
-lib/fdflags.c                         Set or clear file descriptor flags
-lib/fdlimit.c                         File descriptor limits
-lib/fseeko.c                          fseeko replacement
-lib/ftello.c                          ftello replacement
-lib/genid.c                           Generate a message ID
-lib/getfqdn.c                         Get FQDN of local host
-lib/getmodaddr.c                      Get a moderator's address
-lib/getpagesize.c                     getpagesize replacement
-lib/gettime.c                         Get time and timezone info
-lib/hash.c                            Create hash from message ID
-lib/hashtab.c                         Generic hash table
-lib/hstrerror.c                       Error reporting for resolver
-lib/inet_aton.c                       Extra source for inet_aton routine
-lib/inet_ntoa.c                       Convert inaddr to string (BSD)
-lib/innconf.c                         Parsing and manipulation of inn.conf
-lib/inndcomm.c                        Library routines to talk to innd
-lib/list.c                            List routines
-lib/localopen.c                       Open a local NNTP connection
-lib/lockfile.c                        Try to lock a file descriptor
-lib/makedir.c                         Make directory recursively
-lib/md5.c                             MD5 checksum calculation
-lib/memcmp.c                          memcmp replacement
-lib/messages.c                        Error reporting and debug output
-lib/mkstemp.c                         mkstemp replacement
-lib/mmap.c                            mmap manipulation routines
-lib/parsedate.y                       Date parsing
-lib/perl.c                            Perl hook support for nnrpd and innd
-lib/pread.c                           pread replacement
-lib/pwrite.c                          pwrite replacement
-lib/qio.c                             Quick I/O package
-lib/radix32.c                         Encode a number as a radix-32 string
-lib/readin.c                          Read file into memory
-lib/remopen.c                         Open a remote NNTP connection
-lib/reservedfd.c                      File descriptor reservation
-lib/resource.c                        Get process CPU usage
-lib/sendarticle.c                     Send an article, NNTP style
-lib/sendpass.c                        Send NNTP authentication
-lib/sequence.c                        Sequence space arithmetic routines
-lib/setenv.c                          setenv replacement
-lib/seteuid.c                         seteuid replacement
-lib/setproctitle.c                    setproctitle replacement
-lib/snprintf.c                        snprintf and vsnprintf replacement
-lib/sockaddr.c                        Manipulation of sockaddr structs
-lib/strcasecmp.c                      Case-insenstive string comparison (BSD)
-lib/strerror.c                        String representation of errno
-lib/strlcat.c                         strlcat replacement
-lib/strlcpy.c                         strlcpy replacement
-lib/strspn.c                          Skip bytes in a string (BSD)
-lib/strtok.c                          Split a string into tokens (BSD)
-lib/timer.c                           Generic profile timer
-lib/tst.c                             Ternary search trie implementation
-lib/uwildmat.c                        Pattern match routine
-lib/vector.c                          Manipulate vectors of strings
-lib/version.c                         INN version constants
-lib/wire.c                            Manipulate wire-format articles
-lib/xfopena.c                         Open a FILE in append mode
-lib/xmalloc.c                         Failsafe memory allocation wrapper
-lib/xsignal.c                         signal() wrapper using sigaction
-lib/xwrite.c                          write that handles partial transfers
-nnrpd                                 Reader server (Directory)
-nnrpd/Makefile                        Makefile for nnrpd
-nnrpd/article.c                       Article-related routines
-nnrpd/cache.c                         MessageID cache routines
-nnrpd/cache.h                         MessageID cache interfaces
-nnrpd/commands.c                      Assorted server commands
-nnrpd/group.c                         Group-related routines
-nnrpd/line.c                          Long line-by-line reading routines
-nnrpd/list.c                          The LIST commands
-nnrpd/misc.c                          Miscellaneous support routines
-nnrpd/newnews.c                       The NEWNEWS command
-nnrpd/nnrpd.c                         Main and some utility routines
-nnrpd/nnrpd.h                         Header file for nnrpd
-nnrpd/perl.c                          Perl routines for nnrpd
-nnrpd/perm.c                          Reading readers.conf
-nnrpd/post.c                          Article processing and posting
-nnrpd/post.h                          Article data types
-nnrpd/python.c                        Python routines for nnrpd
-nnrpd/sasl_config.c                   Configuration for SASL
-nnrpd/sasl_config.h                   SASL data types
-nnrpd/tls.c                           Transport layer security
-nnrpd/tls.h                           Transport layer security data types
-nnrpd/track.c                         Track client behavior
-samples                               Prototype INN config files (Directory)
-samples/INN.py                        Stub Python functions
-samples/Makefile                      Makefile for samples
-samples/active.minimal                Minimal starting active file
-samples/actsync.cfg                   Config file for actsync
-samples/actsync.ign                   Ignore file for actsync
-samples/buffindexed.conf              Buffindexed overview config file
-samples/control.ctl                   Access control for control messages
-samples/cycbuff.conf                  Sample cycbuff.conf file
-samples/distrib.pats                  Default values for Distribution header
-samples/expire.ctl                    Expiration config file
-samples/filter.tcl                    Sample Tcl filter for innd
-samples/filter_innd.pl                Sample Perl filter for innd
-samples/filter_innd.py                Sample Python filter for innd
-samples/filter_nnrpd.pl               Sample Perl filter for nnrpd
-samples/incoming.conf                 Permissions for incoming feeds
-samples/inn.conf.in                   General INN configuration
-samples/innfeed.conf                  Outgoing feed configuration
-samples/innreport.conf.in             Log summary configuration
-samples/innwatch.ctl                  INN monitoring configuration
-samples/moderators                    Moderation submission addresses
-samples/motd.news                     Sample MOTD file
-samples/news2mail.cf                  news2mail config file
-samples/newsfeeds.in                  innd feed configuration
-samples/newsgroups.minimal            Minimal starting newsgroups file
-samples/nnrpd.py                      Python hooks for nnrpd
-samples/nnrpd.track                   Reader tracking configuration
-samples/nnrpd_access.pl.in            Sample nnrpd Perl access hooks
-samples/nnrpd_access.py               Sample nnrpd Python access hooks
-samples/nnrpd_access_wrapper.pl.in    Wrapper around old Perl access hooks
-samples/nnrpd_access_wrapper.py       Wrapper around old Python access hooks
-samples/nnrpd_auth.pl.in              Sample nnrpd Perl authorization hooks
-samples/nnrpd_auth.py                 Sample nnrpd Python authorization hooks
-samples/nnrpd_auth_wrapper.pl.in      Wrapper around old Perl auth hooks
-samples/nnrpd_auth_wrapper.py         Wrapper around old Python auth hooks
-samples/nnrpd_dynamic.py              Sample nnrpd Python dynamic access hooks
-samples/nnrpd_dynamic_wrapper.py      Wrapper around old Python dynamic hooks
-samples/nntpsend.ctl                  Outgoing nntpsend feed configuration
-samples/ovdb.conf                     Berkeley DB overview configuration
-samples/overview.fmt                  Format of news overview database
-samples/passwd.nntp                   Passwords for remote connections
-samples/radius.conf                   Sample config for RADIUS authentication
-samples/readers.conf                  Reader connection configuration
-samples/sasl.conf.in                  SASL configuration
-samples/startup.tcl                   Tcl startup code for innd
-samples/startup_innd.pl               Perl startup code for innd
-samples/storage.conf                  Sample storage configuration
-samples/subscriptions                 Sample default subscriptions list
-scripts                               Various utilities (Directory)
-scripts/Makefile                      Makefile for script files
-scripts/inncheck.in                   Syntax-check INN config files
-scripts/innmail.in                    Perl front-end to sendmail
-scripts/innreport.in                  Script to analyze INN logs
-scripts/innreport_inn.pm              Config file for innreport
-scripts/innshellvars.in               Config parameters for shell scripts
-scripts/innshellvars.pl.in            Config parameters for Perl scripts
-scripts/innshellvars.tcl.in           Config parameters for Tcl scripts
-scripts/innstat.in                    Display INN status snapshot
-scripts/innupgrade.in                 Upgrade INN configuration files
-scripts/innwatch.in                   Throttle innd based on load and space
-scripts/news.daily.in                 Front-end script to run expire, etc.
-scripts/rc.news.in                    News boot script
-scripts/scanlogs.in                   Summarize log files
-scripts/simpleftp.in                  Rudimentary ftp client
-scripts/tally.control.in              Count newgroup/rmgroup messages
-scripts/writelog.in                   Write a log entry or mail it
-site                                  Site-local files (Directory)
-site/Makefile                         Makefile for site-local files
-site/getsafe.sh                       Safely get config file from samples
-storage                               Storage library (Directory)
-storage/Make.methods                  Makefile for storage methods
-storage/Makefile                      Makefile for storage library
-storage/buffindexed                   buffindexed overview method (Directory)
-storage/buffindexed/buffindexed.c     buffindexed overview routines
-storage/buffindexed/buffindexed.h     Header file for buffindexed overview
-storage/buffindexed/ovmethod.config   buildconfig definition
-storage/buffindexed/ovmethod.mk       Make rules for buffindexed overview
-storage/buildconfig.in                Construct method interface
-storage/cnfs                          CNFS storage method (Directory)
-storage/cnfs/cnfs-private.h           Private header file for CNFS
-storage/cnfs/cnfs.c                   CNFS storage routines
-storage/cnfs/cnfs.h                   Header file for CNFS
-storage/cnfs/method.config            buildconfig definition
-storage/expire.c                      Overview-drive expire implementation
-storage/interface.c                   Storage API glue implementation
-storage/interface.h                   Storage API interface
-storage/ov.c                          Overview API glue implementation
-storage/ovdb                          ovdb overview method (Directory)
-storage/ovdb/ovdb-private.h           Private header file for ovdb
-storage/ovdb/ovdb.c                   ovdb (Berkeley DB) overview method
-storage/ovdb/ovdb.h                   Header for ovdb (Berkeley DB) overview
-storage/ovdb/ovmethod.config          buildconfig definition
-storage/overdata.c                    Overview data manipulation
-storage/ovinterface.h                 Overview API interface
-storage/timecaf                       timecaf storage method (Directory)
-storage/timecaf/README.CAF            README the CAF file format
-storage/timecaf/caf.c                 CAF file implementation
-storage/timecaf/caf.h                 Header for CAF files
-storage/timecaf/method.config         buildconfig definition
-storage/timecaf/timecaf.c             timecaf storage routines
-storage/timecaf/timecaf.h             Header file for timecaf
-storage/timehash                      timehash storage method (Directory)
-storage/timehash/method.config        buildconfig definition
-storage/timehash/timehash.c           timehash storage routines
-storage/timehash/timehash.h           Header for timehash
-storage/tradindexed                   tradindexed overview method (Directory)
-storage/tradindexed/ovmethod.config   buildconfig definition
-storage/tradindexed/ovmethod.mk       Make rules for tradindexed overview
-storage/tradindexed/tdx-cache.c       Data file cache handling for tradindexed
-storage/tradindexed/tdx-data.c        Data file handling for tradindexed
-storage/tradindexed/tdx-group.c       Group index handling for tradindexed
-storage/tradindexed/tdx-private.h     Private header file for tradindexed
-storage/tradindexed/tdx-structure.h   On disk layout of tradindexed files
-storage/tradindexed/tdx-util.c        Utility program for tradindexed
-storage/tradindexed/tradindexed.c     Interface code for the overview API
-storage/tradindexed/tradindexed.h     Interface for tradindexed
-storage/tradspool                     tradspool storage method (Directory)
-storage/tradspool/README.tradspool    Docs for tradspool storage method
-storage/tradspool/method.config       buildconfig definition
-storage/tradspool/tradspool.c         tradspool storage routines
-storage/tradspool/tradspool.h         Header for tradspool
-storage/trash                         Trash storage method (Directory)
-storage/trash/method.config           buildconfig definition
-storage/trash/trash.c                 Trash storage routines
-storage/trash/trash.h                 Header file for trash storage
-support                               Tools for building INN (Directory)
-support/config.guess                  Determine system type for libtool
-support/config.sub                    Canonicalize system type for libtool
-support/fixscript.in                  Interpreter path fixup script
-support/indent                        A mostly working wrapper around indent
-support/install-sh                    Installation utility
-support/ltmain.sh                     Source for libtool utility
-support/makedepend                    Generate dependencies for C files
-support/mkchangelog                   Generate ChangeLog from CVS
-support/mkmanifest                    Generate a list of files for the manifest
-support/mksnapshot                    Generate a snapshot of the tree
-support/mksystem                      Generate <inn/system.h> from config.h
-support/mkversion                     Generate <inn/version.h> with INN version
-tests                                 Test suite for INN (Directory)
-tests/Makefile                        Makefile for test suite
-tests/TESTS                           List of tests to run
-tests/authprogs                       Test suite for auth programs (Directory)
-tests/authprogs/ckpasswd.t            Tests for authprogs/ckpasswd
-tests/authprogs/domain.t              Tests for authprogs/domain
-tests/authprogs/passwd                Password data for ckpasswd tests
-tests/lib                             Test suite for libinn (Directory)
-tests/lib/articles                    Testing news articles (Directory)
-tests/lib/articles/no-body            An article without a body
-tests/lib/articles/strange            An article with CR and LF in headers
-tests/lib/articles/truncated          An article truncated in the headers
-tests/lib/buffer-t.c                  Tests for lib/buffer.c
-tests/lib/concat-t.c                  Tests for lib/concat.c
-tests/lib/config                      Testing config files (Directory)
-tests/lib/config/errors               Various config files with errors
-tests/lib/config/line-endings         A config file with varied line endings
-tests/lib/config/no-newline           A config file without an ending newline
-tests/lib/config/null                 A config file containing a nul character
-tests/lib/config/simple               A simple config file
-tests/lib/config/valid                Various valid config parameters
-tests/lib/config/warn-bool            Invalid boolean parameters
-tests/lib/config/warn-int             Invalid integer parameters
-tests/lib/config/warnings             Various config files with warnings
-tests/lib/confparse-t.c               Tests for lib/confparse.c
-tests/lib/date-t.c                    Tests for lib/date.c
-tests/lib/fakewrite.c                 Helper functions for xwrite tests
-tests/lib/hash-t.c                    Tests for lib/hash.c
-tests/lib/hashtab-t.c                 Tests for lib/hashtab.c
-tests/lib/hstrerror-t.c               Tests for lib/hstrerror.c
-tests/lib/inet_aton-t.c               Tests for lib/inet_aton.c
-tests/lib/inet_ntoa-t.c               Tests for lib/inet_ntoa.c
-tests/lib/innconf-t.c                 Tests for lib/innconf.c
-tests/lib/list-t.c                    Tests for lib/list.c
-tests/lib/md5-t.c                     Tests for lib/md5.c
-tests/lib/memcmp-t.c                  Tests for lib/memcmp.c
-tests/lib/messages-t.c                Tests for lib/messages.c
-tests/lib/mkstemp-t.c                 Tests for lib/mkstemp.c
-tests/lib/pread-t.c                   Tests for lib/pread.c
-tests/lib/pwrite-t.c                  Tests for lib/pwrite.c
-tests/lib/qio-t.c                     Tests for lib/qio.c
-tests/lib/setenv-t.c                  Tests for lib/setenv.c
-tests/lib/setenv.t                    Wrapper for setenv tests
-tests/lib/snprintf-t.c                Tests for lib/snprintf.c
-tests/lib/strerror-t.c                Tests for lib/strerror.c
-tests/lib/strlcat-t.c                 Tests for lib/strlcat.c
-tests/lib/strlcpy-t.c                 Tests for lib/strlcpy.c
-tests/lib/tst-t.c                     Tests for lib/tst.c
-tests/lib/uwildmat-t.c                Tests for lib/uwildmat.c
-tests/lib/vector-t.c                  Tests for lib/vector.c
-tests/lib/wire-t.c                    Tests for lib/wire.c
-tests/lib/xmalloc.c                   Helper program for xmalloc tests
-tests/lib/xmalloc.t                   Tests for lib/xmalloc.c
-tests/lib/xwrite-t.c                  Tests for lib/xwrite.c
-tests/libtest.c                       Helper library for writing tests
-tests/libtest.h                       Interface to libtest
-tests/overview                        Test suite for overview (Directory)
-tests/overview/data                   Test overview data (Directory)
-tests/overview/data/basic             Basic set of overview test data
-tests/overview/data/bogus             Bad newsgroup name test data
-tests/overview/data/high-numbered     High-numbered article test data
-tests/overview/data/reversed          Same as basic, but in reverse order
-tests/overview/munge-data             Support script to generate test data
-tests/overview/tradindexed-t.c        Tests for storage/tradindexed/*
-tests/runtests.c                      The test suite driver program
-tests/util                            Test suite for utilities (Directory)
-tests/util/convdate.t                 Tests for expire/convdate
diff --git a/NEWS b/NEWS
deleted file mode 100644 (file)
index 2ad3e94..0000000
--- a/NEWS
+++ /dev/null
@@ -1,860 +0,0 @@
-Changes in 2.4.5
-
-    * Fixed the "alarm signal" around "SSL_read" in nnrpd:  it allows a
-      proper disconnection of news clients which were previously hanging
-      when posting an article through a SSL connection.  Moreover, the
-      *clienttimeout* parameter now works on SSL connections.  Thanks to
-      Matija Nalis for the patch.
-
-    * SO_KEEPALIVE is now implemented for SSL TCP connections on systems
-      which support it, allowing system detection and closing the dead TCP
-      SSL connections automatically after system-specified time.  Thanks to
-      Matija Nalis for the patch.
-
-    * Fixed a segmentation fault when an article of a size greater than
-      remaining stack is retrieved via SSL.  Thanks to Chris Caputo for this
-      patch.
-
-    * Fixed a few segfaults and bugs which affected both Python innd and
-      nnrpd hooks.  They no longer check the existence of methods not used
-      by the hooked script.  An issue with Python exception handling was
-      also fixed, as well as a segfault fixed by Russ Allbery which happened
-      whenever one closes and then reopens Python in the same process. 
-      Julien Elie also fixed a bug when reloading Python filters (they were
-      not always correctly reloaded) and a segfault when generating access
-      groups with embedded Python filters for nnrpd.  Many thanks to David
-      Hlacik for its bug reports.
-
-    * The nnrpd.py stub file in order to test Python nnrpd hooks, as
-      mentioned in their documentation, is now installed; only INN.py was
-      previously installed in *pathfilter*.  Also fixed a bug in INN.py and
-      add missing methods to it.
-
-    * Fixed a long-standing bug in innreport which prevented it from
-      correctly reporting nnrpd and innfeed log messages.
-
-    * Fixed a hang in Perl hooks on (at least) HP/PA since Perl 5.10.
-
-    * Fixed a compilation problem on some platforms because of AF_INET6
-      which was not inside a HAVE_INET6 block in innfeed.
-
-    * Fixed a bug in innfeed which contained thrice the same IPs for each
-      peer; it unnecessarily slowed the peer IP rotation for innfeed. 
-      Thanks, D. Stussy, for having seen that.  Miquel van Smoorenburg
-      provided the patch.
-
-    * A new *heavily* improved version of pullnews is shipped with this INN
-      release.  This new version is provided by Geraint Edwards.  He added
-      no more than 16 flags, fixed some bugs and integrated the backupfeed
-      contrib script by Kai Henningsen, adding again 6 other flags.  A
-      long-standing but very minor bug in the -g option was especially fixed
-      and items from the to-do list implemented.  Many thanks again to
-      Geraint Edwards.
-
-    * New headers are accessible through Perl and Python innd filtering
-      hooks.  You will find the exact list in the INN Python Filtering and
-      Authentication Hooks documentation (doc/hook-python) and in Python
-      samples.  Thanks to Matija Nalis for this addition of new useful
-      headers.
-
-    * New samples for Python nnrpd hooks are shipped with INN: 
-      nnrpd_access.py for access control and nnrpd_dynamic.py for dynamic
-      access control.  The nnrpd_auth.py script is now only used for
-      authorization control.  See the readers.conf man page for more
-      information (especially the *python_auth*, *python_access* and
-      *python_dynamic* parameters).  The documention about INN Python
-      Filtering and Authentication Hooks has also been improved by Julien
-      Elie.
-
-Changes in 2.4.4
-
-    * Fixed incomplete checking of packet sizes in the ctlinnd interface in
-      the no-Unix-domain-sockets case.  This is a potential buffer overflow
-      in dead code since basically all systems INN builds on support Unix
-      domain sockets these days.  Also track the buffer size more correctly
-      in the client side of this interface for the Unix domain socket case.
-
-    * Group blocks in incoming.conf are now correctly parsed and no longer
-      cause segfaults when loading this file.
-
-    * Fixed a problem with innfeed continuously segfaulting on amd64
-      hardware (and possibly on lots of 64-bit platforms).  Many thanks to
-      Ollivier Robert for his patch and also to Kai Gallasch for having
-      reported the problem and provided the FreeBSD server to debug it.
-
-    * scanlogs now rotates innfeed's log file, which prevents innfeed from
-      silently dying when its log file reaches 2 GB.
-
-    * Perl 5.10 support has been added to INN thanks to Jakub Bogusz.
-
-    * Some news clients hang when posting an article through a SSL
-      connection: it seems that nnrpd's SSL routines make it wrongly wait
-      for data completion.  In order to fix the problem, the select() wait
-      is now just bypassed.  However, the IDLE timer stat is currently not
-      collected for such connections.  Thanks to Kachun Lee for this
-      workaround.
-
-    * Fixed a bug in the display of the used compressor ("cunbatch" was used
-      if arguments were passed to gzip or bzip2).
-
-    * Fixed a bug in mailpost and pullnews which prevented useful error
-      messages to be seen.  Also add the -x flag to pullnews in order to
-      insert Xref: headers in articles which lack one.
-
-    * If compiling with Berkeley DB, use its ndbm compatibility layer for
-      ckpasswd in preference to searching for a traditional dbm library. 
-      INN also supports Berkeley DB 4.4, 4.5 and 4.6 thanks to Marco d'Itri.
-
-    * ovdb_init now properly closes stdin/out/err when it becomes a daemon. 
-      The issue was reported by Viktor Pilpenok and fixed by Marco d'Itri.
-
-    * Added support for Diablo quickhash and hashfeed algorithms.  It allows
-      to distribute the messages among several peers (new Q flag for
-      newsfeeds).  Thanks to Miquel van Smoorenburg for this implementation
-      in INN.
-
-    * innd now listen on separate sockets for IPv4 and IPv6 connections if
-      the IPV6_V6ONLY socket option is available.  There might also be
-      operating systems that still have separate IPv4 and IPv6 TCP
-      implementations, and advanced features like TCP SACK might not be
-      available on v6 sockets.  Thanks to Miquel van Smoorenburg for this
-      patch.
-
-    * The two configuration options *bindaddress* and *bindaddress6* can now
-      be set on a per-peer basis for innfeed.  Setting *bindaddress6* to
-      "none" tells innfeed to never attempt an IPv6 connection to that host.
-      Thanks to Miquel van Smoorenburg for this patch.
-
-    * Added a *nnrpdflags* parameter to inn.conf (modeled on the concept of
-      *innflags*) to permit passing of command line arguments to instances
-      of nnrpd spawned from innd.
-
-    * A new inn.conf parameter called *pathcluster* has been added: it
-      allows to append a common name to the Path: header on all incoming
-      articles.  *pathhost* and *pathalias* (if set) are still appended to
-      the path as usual, but *pathcluster* is always appended as the last
-      element (e.g. on the leftmost side of the Path: header).  Thanks to
-      Miquel van Smoorenburg for this feature.
-
-    * simpleftp has been rewritten to use "Net::FTP".  Indeed, ftp.pl is no
-      longer shipped with Perl 5 and the script did not work.
-
-    * perl-nocem will now check for a timeout and re-open the socket if
-      required.  Additionally, perl-nocem will switch to cancel_ctlinnd in
-      case cancel_nntp fails after sending the Message-ID.  Thanks to
-      Christoph Biedl for the patch.  A more detailed documentation has also
-      been written for perl-nocem(8).
-
-    * The RADIUS configuration is now wrapped in a "server {}" block in
-      radius.conf.
-
-    * Checkgroups when there is nothing to change no longer result in
-      sending a blank mail to administrators.  Besides, no mail is sent by
-      controlchan for the creation of a newsgroup when the action is "no
-      change".
-
-    * Checkgroups are now properly propagated even though the news server
-      does not carry the groups they are posted to.
-
-    * controlchan and docheckgroups now handle wire format messages so that
-      articles from the spool can be directly fed to them.
-
-    * Newgroup control messages for existing groups now change their
-      description.  If a mail is sent to administrators, it reminds them to
-      update their newsgroups file.  It also warns when there are missing or
-      obsolete descriptions.  Furthermore, the newsgroups file is now
-      written prettier (from one to three tabulations between the name of
-      the group and its short description) and to.* groups cannot be
-      created.
-
-    * The sample control.ctl file has been extensively updated.
-
-    * Fixed empty LISTGROUP replies which were not terminated.  Thanks to
-      David Canzi for the patch.
-
-    * In response to a LIST [file] command, if the file does not exist, we
-      assume it is not maintained and return 503 instead of 215 and an empty
-      file.  Moreover, capability to LIST ACTIVE.TIMES for a wildmat pattern
-      as its third argument has been added in order to select wanted
-      newsgroups.
-
-    * inews now tries to authenticate if it does not receive a 200 return
-      code after MODE READER.  Indeed, it might be able to post even with a
-      201 return code and also with another codes like 440 or 480.
-
-    * If creating a new history file, set the ownership and mode
-      appropriately.  inncheck also expects fewer things to be private to
-      the news user.  Most of the configuration files will never contain
-      private information like passwords.
-
-    * Other minor bug fixes and documentation improvements.
-
-Changes in 2.4.3
-
-    * Previous versions of INN had an optimization for handling XHDR
-      Newsgroups that used the Xref: header from overview.  While this does
-      make the command much faster, it doesn't produce accurate results and
-      breaks the NNTP protocol, so this optimization has been removed.
-
-    * Fixed a bug in innd that allowed it to accept articles with duplicated
-      headers if the header occurred an odd number of times.  Modified the
-      programs for rebuilding overview to use the last Xref: header if there
-      are multiple ones to avoid problems with spools that contain such
-      invalid articles.
-
-    * Fixed yet another problem with verifying that a user has permissions
-      to approve posts to a moderated group.  Thanks, Jens Schlegel.
-
-    * Increase the send and receive buffer on the Unix domain socket used by
-      ctlinnd.  This should allow longer replies (particularly for innstat)
-      on platforms with very low default Unix domain socket buffer sizes.
-
-    * rnews's handling of articles with nul characters, NNTP errors, header
-      problems, and deferrals has been significantly improved.
-
-    * Thomas Parmelan added support to send-uucp for specifying the funnel
-      or exploder site to flush for feeds managed through one and fixed a
-      problem with picking up old stranded work files.
-
-    * Many other more minor bug fixes, optimization improvements, and
-      documentation fixes.
-
-Changes in 2.4.2
-
-    * INN is now licensed under a less restrictive license (about as
-      minimally restrictive as possible shy of public domain), and the
-      clause similar to the old BSD advertising clause has been dropped.
-
-    * "make install" and "make update" now always install the newly built
-      binaries, rather than only installing them if the modification times
-      are newer.  This is the behavior that people expect.  "make install"
-      now also automatically builds a new (empty) history database if one
-      doesn't already exist.
-
-    * The embedded Tcl filter code has been disabled (and will be removed
-      entirely in the next major release of INN).  It hasn't worked for some
-      time and causes innd crashes if compiled in (even if not used).  If
-      someone wants to step forward and maintain it, I recommend starting
-      from scratch and emulating the Perl and Python filters.
-
-    * ctlinnd should now successfully handle messages from INN up to the
-      maximum allowable packet size in the protocol, fixing problems sites
-      with many active peers were having with innstat output.
-
-    * Overview generation has been fixed in both makehistory and innd to
-      follow the rules in the latest NNTP draft rather than just replacing
-      special characters with spaces.  This means that the unfolding of
-      folded header lines will not introduce additional, incorrect
-      whitespace in the overview data.
-
-    * nnrpd now uniformly responds with a 480 or 502 status code to attempts
-      to read a newsgroup to which the user does not have access, depending
-      on whether the user has authenticated.  Previously, it returned a 411
-      status code, claiming the group didn't exist, which confuses the
-      reactive authentication capability of news readers.
-
-    * If a user is not authorized to approve articles (using the "A"
-      *access* control in readers.conf), articles that include Approved:
-      headers will be rejected even if posted to unmoderated groups.  Some
-      other site may consider that group to be moderated.
-
-    * The configuration parser used for readers.conf and others now
-      correctly handles "#" inside quoted strings and is more robust against
-      unmatched double quotes.
-
-    * Messages mailed to moderators had two spaces after the colons in the
-      headers, rather than one.  This bug has been fixed.
-
-    * A bug that could cause heap corruption and random crashes in innd if
-      INN were compiled with Python support has been fixed.
-
-    * Some problems with innd's tracking of article size and enforcement of
-      the configured maximum article size have been fixed.
-
-    * pgpverify will now correctly verify signatures generated by GnuPG and
-      better supports GnuPG as the PGP implementation.
-
-    * INN's code should now be more 64-bit clean in its handling of size_t,
-      pointer differences, and casting of pointers, correcting problems that
-      showed up on 64-bit platforms like AMD64.
-
-    * Improved the error reporting in the history database code, in inews,
-      in controlchan, and in expire.
-
-    * Many other, more minor bugs have also been fixed.
-
-Changes in 2.4.1
-
-    * SECURITY:  Handle the special filing of control messages into per-type
-      newsgroups more robustly.  This closes a potentially exploitable
-      buffer overflow.  Thanks to Dan Riley for his excellent bug report.
-
-    * Fixed article handling in innd so that articles without a Path: header
-      (arising from peers sending malformatted articles or injecting
-      malformatted articles through rnews) would not cause innd to crash. 
-      (This was not exploitable.)
-
-    * Fixed a serious bug in XPAT handling, thanks to Tommy van Leeuwen.
-
-    * "configure" now looks for sendmail only in /usr/sbin and /usr/lib, not
-      on the user's path.  This should reduce the need for --with-sendmail
-      if your preferred sendmail is in a standard location.
-
-    * The robustness of the tradindexed overview method has been further
-      increased, handling more edge cases arising from corrupted databases
-      and oddly-named newsgroups.
-
-    * innd now never decreases the high water mark of a newsgroup when
-      renumbering, which should help ameliorate overview and active file
-      synchronization problems.
-
-    * Do not close and reopen the history file on ctlinnd reload when the
-      server is paused or throttled.  This was breaking ctlinnd reload all
-      during a server pause.
-
-    * Various minor portability and compilation issues fixed.  Substantial
-      numbers of compiler warnings have been cleaned up, thanks largely to
-      work by Ilya Kovalenko.
-
-    * Multiple other more minor bugs have been fixed.
-
-    * Documentation and man pages have been clarified and updated.
-
-Upgrading from 2.3 to 2.4
-
-    The inn.conf parser has changed between INN 2.3 and 2.4.  Due to that
-    change, options in inn.conf that contain whitespace or a few other
-    special characters must be quoted with double quotes, and empty
-    parameters (parameters with no value) are not allowed.  INN 2.4 comes
-    with a script, innupgrade, run automatically during "make update", that
-    will attempt to fix any problems that it finds with your inn.conf file,
-    saving the original as inn.conf.OLD.
-
-    This change is the beginning of standardization of parsing and syntax
-    across all of INN's configuration files.
-
-    The history subsystem now has a standard API that allows other backends
-    to be used.  Because of this, you now need to specify the history method
-    in inn.conf.  Adding:
-
-        hismethod: hisv6
-
-    will tell INN to use the same history backend as was used in previous
-    versions.  innupgrade should take care of this for you.
-
-    ovdb is known to have some locking and timing issues related to how
-    nnrpd shuts down (or fails to shut down) the overview databases.  If you
-    have stability problems with ovdb, try setting *readserver* to "true" in
-    ovdb.conf.  This will funnel all ovdb reads through a single process
-    with a cleaner interface to the underlying Berkeley DB database.
-
-    If you use Perl authentication for nnrpd (if *nnrpdperlauth* in inn.conf
-    is "true"), there have been major changes.  See "Changes to Perl
-    Authentication Support for nnrpd" in doc/hook-perl for details.
-
-    Similarly, if you use Python authentication for nnrpd (if
-    *nnrpdpythonauth* in inn.conf is "true"), there have been major changes.
-    See "Changes to Python Authentication and Access Control Support for
-    nnrpd" in doc/hook-python for details.
-
-    If you use send-uucp, it has been completely rewritten and now takes a
-    configuration file to specify its behavior.  See its man page for more
-    information.  If you use sendbatch, it is no longer included in INN
-    since the new send-uucp can handle all of the same functionality.
-
-    The wildmat API has been renamed (to uwildmat and friends; see
-    uwildmat(3) for the interfaces) to distinguish it from Rich $alz's
-    original version, since it now supports UTF-8.  This may require changes
-    in other software packages that link against INN's libraries.
-
-    If you are upgrading from a version prior to INN 2.3, see "Upgrading
-    from 2.2 to 2.3".
-
-Changes in 2.4.0
-
-    * IPv6 support has been added, disabled by default.  If you have IPv6
-      connectivity, build with --enable-ipv6 to try it.  There are no known
-      bugs, but please report any problems you find (or even successes, if
-      you use an unusual platform).  There are a few changes of interest;
-      further information is available in doc/IPv6-info.
-
-    * The tradindexed overview method has been completely rewritten and
-      should be considerably more robust in the face of system crashes.  A
-      new utility, tdx-util, is provided to examine the contents of the
-      overview database, repair inconsistencies, and rebuild the overview
-      for particular groups from a tradspool news spool.  See tdx-util(8)
-      for more details.
-
-    * The Perl and Python authentication hooks for readers have been
-      extensively overhauled and integrated better with readers.conf.  See
-      the Changes sections in doc/hook-perl and doc/hook-python for more
-      details.
-
-    * nnrpd now optionally supports article injection via IHAVE, see
-      readers.conf(5).  Any articles injected this way must have Date, From,
-      Message-ID, Newsgroups, Path, and Subject headers.  X-Trace and
-      X-Complaints-To headers will be added if the appropriate options are
-      set in readers.conf, but other headers will not be modified/inserted
-      (e.g.  NNTP-Posting-Host, NNTP-Posting-Date, Organization, Lines, Cc,
-      Bcc, and To headers).
-
-    * nnrpd now handles arbitrarily long lines in POST and IHAVE;
-      administrators who want to limit the length of lines in locally posted
-      articles will need to add this to their local filters instead.
-
-    * nnrpd no longer handles the poorly-specified RFC 977 optional fourth
-      argument to the NEWGROUPS command specifying the "distributions" that
-      the command was supposed to apply to.
-
-      Clients that use that argument will break.  There are not believed to
-      be any such clients, and it's easy enough to just filter the returned
-      list of newsgroups (which is generally fairly short) to achieve the
-      same results.
-
-    * nnrpd no longer accepts UTC as a synonym for GMT for NEWGROUPS or
-      NEWNEWS.  This usage was never portable, and was rejected by the NNTP
-      working group.  It is being removed now in the hope that it will be
-      caught before anyone starts to rely on it.
-
-    * innfeed supports a new peer parameter, *backlog-feed-first*, that if
-      set to "true" feeds any backlog to a peer before new articles, see
-      innfeed.conf(5).  When used in combination with *max-connections* set
-      to 1, this can be used to enforce in-order delivery of messages to a
-      peer that is doing Xref slaving, avoiding cases where a
-      higher-numbered message is received before a lower-numbered message in
-      the same group.
-
-    * Several other, more minor protocol issues have been fixed: 
-      connections rejected due to the connection rate limiting in innd
-      receive 400 replies instead of 504 or 505, and ARTICLE without an
-      argument will always either retrieve the current article or return a
-      423 error, never advance the current article number to the next valid
-      article.
-
-      See doc/compliance-nntp for all of the known issues with INN's
-      compliance with the current NNTP draft.
-
-    * All accesses to the history file for all parts of INN now go through a
-      generic API like the storage and overview subsystems do.  This will
-      eventually allow new history implementations to be dropped in without
-      affecting the rest of INN, and will significantly improve the
-      encapsulation of the history subsystem.  See the libinnhist(3) man
-      page for the details of the interface.
-
-    * INN now uses a new parser for the inn.conf file.  This means that
-      parameters containing whitespace or other special characters must now
-      be quoted; see inn.conf(5).  It fixes the long-standing bug that
-      certain values must be included in inn.conf even if using the defaults
-      for the use of shell or Perl scripts, and it will serve as the basis
-      for standardizing and cleaning up the configuration file parsing in
-      other parts of INN.  innupgrade is run during "make update" and should
-      convert an existing inn.conf file for you.
-
-    * send-uucp has been replaced by a completely rewritten version from
-      Marco d'Itri, Edvard Tuinder, and Miquel van Smoorenburg, which uses a
-      configuration file that specifies batch sizes, compression methods,
-      and hours during which batches should be generated.  The old sendbatch
-      script has been retired, since send-uucp can now handle everything
-      that it did.
-
-    * Two "configure" options have changed names:  --with-tmp-path is now
-      --with-tmp-dir, and --with-largefiles is now --enable-largefiles, to
-      improve consistency and better match the "autoconf" option guidelines.
-
-    * Variables can now be used in the newsfeeds file to make it easier to
-      specify many similar feeds or feed patterns.  See the newsfeeds(5) man
-      page for details.
-
-    * Local connections to INN support a new special mode, MODE CANCEL, that
-      allows efficient batch cancellation of messages.  This is intended to
-      be the preferred interface for external spam and abuse filters like
-      NoCeM.  See "CANCEL FEEDS" in innd(8) for details.
-
-    * Two new options, *nfsreader* and *nfswriter*, have been added to
-      inn.conf to aid in building NFS based shared reader/writer platforms. 
-      On the writer server configure *nfswriter* to "true" and on all of the
-      readers configure *nfsreader* to "true"; these options add calls to
-      force data out to the NFS server and force it to be read directly from
-      the NFS server at the appropriate moments.  Note that it has only been
-      tested on Solaris 8, using CNFS as the storage mechanism and
-      tradindexed as the overview method.
-
-    * A new option, *tradindexedmmap*, has been added to inn.conf.  If set
-      to "true" (the default), then the tradindexed overview method will use
-      mmap() to access its overview data (in 2.3 you couldn't control this;
-      it always used mmap).
-
-    * Thanks to code contributed by CMU, innfeed can now feed an IMAP server
-      as well as other NNTP servers.  See the man page for innfeed(8) for
-      more information.
-
-    * An authenticator, auth_smb, that checks a username and password
-      against a remote Samba server is now included.  See auth_smb(8) for
-      details.
-
-    * The wildmat functions in INN now support UTF-8, in a way that should
-      allow them to still work with most simple 8-bit character sets in
-      widespread use.  As part of this change, some additional wildmat
-      interfaces are now available and the names have changed (to uwildmat,
-      where "u" is for Unicode).  See uwildmat(3) for the details.
-
-    * The interface between external authenticators and nnrpd is now
-      properly documented, in doc/external-auth.  A library implementing
-      this interface in C is provided, which should make it easier to write
-      additional authenticators resolvers.  See libauth(3) for details, and
-      any of the existing programs in authprogs/ for examples.
-
-    * Most (if not all) of the temporary file creation in INN now uses
-      functions that create temporary files properly and safely.
-
-Changes in 2.3.5
-
-    * Clients using POST are no longer permitted to provide an
-      Injector-Info: header.
-
-    * Fixed a bug causing posts with Followup-To: set to a moderated group
-      to be rejected if the posting user didn't have permission to approve
-      postings.
-
-    * Fixed bugs in inncheck with setuid rnews or setgid inews, in
-      *innconfval* with inn.conf parameters containing shell metacharacters
-      but no spaces, and in parsedate.y with some versions of yacc.  Fixed a
-      variety of size-related printf format warnings (e.g., %d vs. %ld)
-      thanks to the work of Winfried Szukalski.
-
-Changes in 2.3.4
-
-    * LIST ACTIVE no longer returns data when given a single group argument
-      if the client is not authorized to read that group.
-
-    * XHDR and XPAT weren't correctly parsing article headers, resulting in
-      searches for the header "newsgroup" matching the header "newsgroups".
-
-    * Made CNFS more robust against crashes by actually syncing the cycbuff
-      headers to disk as was originally intended.  Fixed a memory leak in
-      the tradspool code.
-
-    * Two bugs in pgpverify when using GnuPG were fixed:  it now correctly
-      checks for gpgv (rather than pgp) when told to use GnuPG and expects
-      the keyring to be pubring.gpg (not pubring.pgp).
-
-    * Substantial updates to the sample provided control.ctl file.
-
-    * Compilation fixes with Perl 5.8.0, Berkeley DB 4.x, current versions
-      of Linux (including with large file support), and Tru64.  inndf fixes
-      for ReiserFS.
-
-    * Various bugs in the header handling in nnrpd have been fixed,
-      including hangs when using virtual domains and improper processing of
-      folded headers under certain circumstances.
-
-    * Other minor bug fixes and documentation improvements.
-
-Changes in 2.3.3
-
-    * pgpverify now supports using GnuPG to check signatures (rather than
-      PGP) without the pgpgpg wrapper.  GnuPG can check both old-style RSA
-      signatures and new OpenPGP signatures and is recommended over PGP 2.6.
-      If you have GnuPG installed, pgpverify will use it rather than PGP,
-      which means that you may have to create a new key ring for GnuPG to
-      use to verify signatures if you were previously using PGP.
-
-    * Users can no longer post articles containing Approved: headers to
-      moderated groups by default; they must be specifically given that
-      permission with the *access* parameter in readers.conf.  See the man
-      page for more details.
-
-    * Two bugs in repacking overview index files and a reliability bug with
-      writing overview data were all fixed in the tradindexed overview
-      method, hopefully making it somewhat more reliable, particularly for
-      makehistory.
-
-    * If rc.news.local exists in the INN binary directory, it will be run
-      with the start or stop argument whenever rc.news is run.  This is
-      available as a hook for local startup and shutdown code.
-
-    * The default history table hash sizes were increased because a
-      too-small value can cause serious performance problems (whereas a
-      too-large hash just wastes a bit of disk space).
-
-    * The sample control.ctl file has been extensively updated.
-
-    * Wildmat exclusions ("@" and "!") should now work properly in
-      storage.conf newsgroup patterns.
-
-    * The implementation of the -w flag for expireover was fixed;
-      previously, the value given to -w to change expireover's notion of the
-      current time was scaled by too much.
-
-    * Various other more minor bug fixes, standards compliance fixes, and
-      documentation improvements.
-
-Changes in 2.3.2
-
-    * innxmit can again handle regular filenames as input as well as storage
-      API tokens (allowing it to be used to import an old traditional
-      spool).
-
-    * Several problems with tagged-hash history files have been fixed thanks
-      to the debugging efforts of Andrew Gierth and Sang-yong Suh.
-
-    * A very long-standing (since INN 1.0!) NNTP protocol bug in nnrpd was
-      fixed.  The response to an ARTICLE command retrieving a message by
-      Message-ID should have the Message-ID as the third word of the
-      response, not the fourth.  Fixing this is reported to *possibly* cause
-      problems with some Netscape browsers, but other news servers correctly
-      follow the protocol.
-
-    * Some serious performance problems with expiration of tradspool should
-      now be at least somewhat alleviated.  tradspool and timehash now know
-      how to output file names for removal rather than tokens, and fastrm's
-      ability to remove regular files has been restored.  This should bring
-      expiration times for tradspool back to within a factor of two of
-      pre-storage-API expiration times.
-
-    * Added a sample subscriptions file and documentation for it and
-      innmail.
-
-Changes in 2.3.1
-
-    * inews no longer downloads the active file, no longer tries to send
-      postings to moderated groups to the moderator directly, and in general
-      duplicates less of the functionality of nnrpd, instead letting nnrpd
-      handle it.  This fixes the problem of inews not working properly for
-      users other than news without being setgid.
-
-    * Added a man page for ckpasswd.
-
-    * A serious bug in the embedded Perl authentication hooks was fixed,
-      thanks to Jan Rychter.
-
-    * The annoying compilation problem with embedded Perl filtering on Linux
-      systems without libgdbm installed should be fixed.
-
-    * INN now complains loudly at "configure" time if the configured path
-      for temporary files is world-writeable, since this configuration can
-      be a security hole.
-
-    * Many other varied bug fixes and documentation fixes of all sorts.
-
-Upgrading from 2.2 to 2.3
-
-    There may be additional things to watch out for not listed here; if you
-    run across any, please let <inn-bugs@isc.org> know about them.
-
-    Simply doing a "make update" is not sufficient to upgrade; the history
-    and overview information will also have to be regenerated, since the
-    formats of both files have changed between 2.2 and 2.3.  Regardless of
-    whether you were using the storage API or traditional spool under 2.2,
-    you'll need to rebuild your overview and history files.  You will also
-    need to add a storage.conf file, if you weren't using the storage API
-    under INN 2.2.  A good default storage.conf file for 2.2 users would be:
-
-        method tradspool {
-            newsgroups: *
-            class: 0
-        }
-
-    Create this storage.conf file before rebuilding history or overview.
-
-    If you want to allow readers, or if you want to expire based on
-    newsgroup name, you need to tell INN to generate overview data and pick
-    an overview method by setting *ovmethod* in inn.conf.  See INSTALL and
-    inn.conf(5) for more details.
-
-    The code that generates the dbz index files has been split into a
-    separate program, makedbz.  makehistory still generates the base history
-    file and the overview information, but some of its options have been
-    changed.  To rebuild the history and overview files, use something like:
-
-        makehistory -b -f history.n -O -T /usr/local/news/tmp -l 600000
-
-    (change the /usr/local/news/tmp path to some directory that has plenty
-    of temporary space, and leave off -O if you're running a transit-only
-    server and don't intend to expire based on group name, and therefore
-    don't need overview.)  Or if your overview is buffindexed, use:
-
-        makehistory -b -f history.n -O -F
-
-    Both will generate a new history file as history.n and rebuild overview
-    at the same time.  If you want to preseve a record of expired
-    Message-IDs in the history file, run:
-
-        awk 'NF==2 { print; }' < history >> history.n
-
-    to append them to the new history file you created above.  Look over the
-    new history file and make sure it looks right, then generate the new
-    index files and move them into place:
-
-        makedbz -s `wc -l < history.n` -f history.n
-        mv history.n history
-        mv history.n.dir history.dir
-        mv history.n.hash history.hash
-        mv history.n.index history.index
-
-    (Rather than .hash and .index files, you may have a .pag file if you're
-    using tagged hash.)
-
-    For reader machines, nnrp.access has been replaced by readers.conf. 
-    There currently isn't a program to convert between the old format and
-    the new format (if you'd like to contribute one, it would be welcomed
-    gratefully).  The new file is unfortunately considerably more complex as
-    a result of its new capabilities; please carefully read the example
-    readers.conf provided and the man page when setting up your initial
-    configuration.  The provided commented-out examples cover the most
-    common installation (IP-based authentication for all machines on the
-    local network).
-
-    INN makes extensive use of mmap(2) for the new overview mechanisms, so
-    at the present time NFS-mounting the spool and overview on multiple
-    reader machines from one central server probably isn't feasible in this
-    version.  mmap tends to interact poorly with NFS (at the least, NFS
-    clients won't see updates to the mapped files in situations where they
-    should).  (The preferred way to fix this would, rather than backing out
-    the use of mmap or making it optional, to add support for Diablo-style
-    header feeds and pull-on-demand of articles from a master server.)
-
-    The flags for overchan have changed, plus you probably don't want to run
-    overchan at all any more.  Letting innd write overview data itself
-    results in somewhat slower performance, but is more reliable and has a
-    better failure mode under high loads.  Writing overview data directly is
-    the default, so in a normal upgrade from 2.2 to 2.3 you'll want to
-    comment out or remove your overchan entry in newsfeeds and set
-    *useoverchan* to "false" in inn.conf.
-
-    crosspost is no longer installed, and no longer works (even with
-    traditional spool).  If you have an entry for crosspost in newsfeeds,
-    remove it.
-
-    If you're importing a traditional spool from a pre-storage API INN
-    server, it's strongly recommended that you use NNTP to feed the articles
-    to your new server rather than trying to build overview and history
-    directly from the old spool.  It's more reliable and ensures that
-    everything gets put into the right place.  The easiest way to do this is
-    to generate, on your old server, a list of all of your existing article
-    files and then feed that list to innxmit.  Further details can be found
-    in the FAQ at <http://www.eyrie.org/~eagle/faqs/inn.html>.
-
-    If you are using a version of Cleanfeed that still has a line in it
-    like:
-
-        $lines = $hdr{'__BODY__'} =~ tr/\n/\n/;
-
-    you will need to change this line to:
-
-        $lines = $hdr{'__LINES__'};
-
-    to work with INN 2.3 or later.  This is due to an internal optimization
-    of the interface to embedded filters that's new in INN 2.3.
-
-Changes in 2.3.0
-
-    * New readers.conf file (replaces nnrp.access) which allows more
-      flexible specification of access restrictions.  Included in the sample
-      implementations is a RADIUS-based authenticator.
-
-    * Unified overview has been replaced with an overview API, and there are
-      now three separate overview implementations to choose from.  One
-      (tradindexed) is very like traditional overview but uses an additional
-      index file.  The second (buffindexed) uses large buffers rather than
-      separate files for each group and can handle a higher incoming article
-      rate while still being fast for readers.  The third (ovdb) uses
-      Berkeley DB to store overview information (so you need to have
-      Berkeley DB installed to use it).  The *ovmethod* key in inn.conf
-      chooses the overview method to use.
-
-      Note that ovdb has not been as widely tested as the other overview
-      mechanisms and should be considered experimental.
-
-    * All article storage and retrieval is now done via the storage API. 
-      Traditional spool is now available as a storage type under the storage
-      API.  (Note that the current traditional spool implementation causes
-      nightly expire to be extremely slow for a large number of articles, so
-      it's not recommended that you use the tradspool storage method for the
-      majority of a large spool.)
-
-    * The timecaf storage method has been added, similar to timehash but
-      storing multiple articles in a single file.  See INSTALL for details
-      on it.
-
-    * INN now supports embedded Python filters as well as Perl and Tcl
-      filters, and supports Python authentication hooks.
-
-    * There is preliminary support for news reading over SSL, using OpenSSL.
-
-    * To simplify anti-abuse filtering, and to be more compliant with news
-      standards and proposed standards, INN now treats as control messages
-      only articles containing a Control: header.  A Subject: line beginning
-      with "cmsg " is no longer sufficient for a message to be considered a
-      control message, and the Also-Control: header is no longer supported.
-
-    * The INN build system no longer uses subst.  (This will be transparent
-      to most users; it's an improvement and modernization of how INN is
-      configured.)
-
-    * The build and installation system has been substantially overhauled. 
-      "make update" now updates scripts as well as binaries and
-      documentation, there is better support for parallel builds ("make
-      -j"), there is less "make" recursion, and far more of the
-      system-dependent configuration is handled directly by "autoconf". 
-      libtool build support (including shared library support) should be
-      better than previous releases.
-
-Changes in 2.2.3
-
-    * inews is not installed setgid news and rnews is not installed setuid
-      root by default any more.  If you need the old permissions, you have
-      to give a flag to configure.  See INSTALL for more details.
-
-    * Fixed a security hole when *verifycancels* was enabled in inn.conf
-      (not the default).
-
-    * Message-IDs are now limited to 250 octets to prevent interoperability
-      problems with other servers.
-
-    * Embedded Perl filters now work with Perl 5.6.0.
-
-    * Lots of bug fixes and changes for security paranoia.
-
-Changes in 2.2.2
-
-    * Various minor bug fixes and a Y2K bug fix.  The Y2K bug is in version
-      version 2.2.1 only and will show up after Jan 1st, 2000 when a news
-      reader issues a NEWNEWS command for a date prior to the year 2000.
-
-Changes in 2.2.1
-
-    * Various bug fixes, mostly notably fixes for potential buffer overflow
-      security vulnerabilities.
-
-Changes in 2.2.0
-
-    * New storage.conf file (replaces storage.ctl).
-
-    * New (optional) way of handling non-cancel control messages
-      (controlchan) that serializes them and prevents server overload from
-      control message storms.
-
-    * Support for actsyncd to fetch active file with ftp; configured by
-      default to use <ftp://ftp.isc.org/pub/usenet/CONFIG/active.Z> if you
-      run actsyncd.  Be sure to read the manual page for actsync to
-      configure an actsync.ign file for your site, and test simpleftp if you
-      do not "configure" with wget or ncftp.  Also see
-      <ftp://ftp.isc.org/pub/usenet/CONFIG/README>.
-
-    * Some options to "configure" are now moved to inn.conf
-      (*merge-to-groups* and *pgp-verify*, without the hyphen).
-
-    * inndf, a portable version of df(1), is supplied.
-
-    * New cnfsstat program to show stats of CNFS buffers.
-
-    * news2mail and mailpost programs for gatewaying news to mail and mail
-      to news are supplied.
-
-    * pullnews program for doing a sucking feed is provided (not meant for
-      large feeds).
-
-    * The innshellvars.csh.in script is obsolete (and lives in the obsolete
-      directory, for now).
-
diff --git a/README b/README
deleted file mode 100644 (file)
index 722abc5..0000000
--- a/README
+++ /dev/null
@@ -1,288 +0,0 @@
-Welcome to INN 2.4!
-
-    This work is sponsored by Internet Systems Consortium.
-
-    Please see INSTALL for installation instructions, NEWS for what's
-    changed from the previous release, and LICENSE for the copyright,
-    license, and distribution terms.
-
-What is INN?
-
-    INN (InterNetNews), originally written by Rich Salz, is an extremely
-    flexible and configurable Usenet / netnews news server.  For a complete
-    description of the protocols behind Usenet and netnews, see RFC 1036 and
-    RFC 977 (or their replacements).  In brief, netnews is a set of
-    protocols for exchanging messages between a decentralized network of
-    news servers.  News articles are organized into newsgroups, which are
-    themselves organized into hierarchies.  Each individual news server
-    stores locally all articles it has received for a given newsgroup,
-    making access to stored articles extremely fast.  Netnews does not
-    require any central server; instead, each news server passes along
-    articles it receives to all of the news servers it peers with, those
-    servers pass the articles along to their peers, and so on, resulting in
-    "flood fill" propagation of news articles.
-
-    A news server performs three basic functions:  it accepts articles from
-    other servers and stores them on disk, sends articles it has received
-    out to other servers, and offers stored news articles to readers on
-    demand.  It additionally has to perform some periodic maintenance tasks,
-    such as deleting older articles to make room for new ones.
-
-    Originally, a news server would just store all of the news articles it
-    had received in a file system.  Users could then read news by reading
-    the article files on disk (or more commonly using news reading software
-    that did this efficiently).  These days, news servers are almost always
-    stand-alone systems and news reading is supported via network
-    connections.  A user who wants to read a newsgroup opens that newsgroup
-    in their newsreader software, which opens a network connection to the
-    news server and sends requests for articles and related information. 
-    The protocol that a newsreader uses to talk to a news server and that a
-    news server uses to talk to another news server over TCP/IP is called
-    NNTP (Network News Transport Protocol).
-
-    INN supports accepting articles via either NNTP connections or via UUCP.
-    innd, the heart of INN, handles NNTP feeding connections directly; UUCP
-    newsfeeds use rnews (included in INN) to hand articles off to innd. 
-    Other parts of INN handle feeding articles out to other news servers,
-    most commonly innfeed (for real-time outgoing feeds) or nntpsend and
-    innxmit (used to send batches of news created by innd to a remote site
-    via TCP/IP).  INN can also handle outgoing UUCP feeds.
-
-    The part of INN that handles connections from newsreaders is nnrpd.
-
-    Also included in INN are a wide variety of supporting programs to handle
-    periodic maintenance and recovery from crashes, process special control
-    messages, maintain the list of active newsgroups, and generate and
-    record a staggering variety of statistics and summary information on the
-    usage and performance of the server.
-
-    INN also supports an extremely powerful filtering system that allows the
-    server administrator to reject unwanted articles (such as spam and other
-    abuses of Usenet).
-
-    INN is free software, supported by Internet Systems Consortium and
-    volunteers around the world.  See "Supporting the INN Effort" below.
-
-Prerequisites
-
-    Compiling INN requires an ANSI C compiler (gcc is recommended).  INN was
-    originally written in K&R C, but supporting pre-ANSI compilers has
-    become enough of a headache that a lot of the newer parts of INN will no
-    longer compile with a non-ANSI compiler.  gcc itself will compile with
-    most vendor non-ANSI compilers, however, so if you're stuck with one,
-    installing gcc is highly recommended.  Not only will it let you build
-    INN, it will make installing lots of other software much easier.  You
-    may also need GNU make (particularly if your system make is
-    BSD-derived), although most SysV make programs should work fine. 
-    Compiling INN also currently requires a yacc implementation (bison will
-    do fine).
-
-    INN uses GNU autoconf to probe the capabilities of your system, and
-    therefore should compile on nearly any Unix system.  It does, however,
-    make extensive use of mmap(), which can cause problems on some older
-    operating systems.  See INSTALL for a list of systems it is known to
-    work on.  If you encounter problems compiling or running INN, or if you
-    successfully run INN on a platform that isn't listed in INSTALL, please
-    let us know (see "Reporting Bugs" below).
-
-    Perl 5.003 or later is required to build INN.  Perl 5.004 is required if
-    you want the embedded Perl filter support (which is highly recommended;
-    some excellent spam filters have been written for INN).  Since all
-    versions of Perl previous to 5.004 are buggy (including security
-    problems) and have fewer features, installing Perl 5.004 or later is
-    recommended.
-
-    If you want to enable PGP verification of control messages (highly
-    recommended), you will need to have a PGP implementation installed.  See
-    INSTALL for more details.
-
-Getting Started
-
-    A news server can be a fairly complicated piece of software to set up
-    just because of the wide variety of pieces that have to be configured
-    (who is authorized to read from the server, what newsgroups it carries,
-    and how the articles are stored on disk at a bare minimum, and if the
-    server isn't completely stand-alone -- and very few servers are -- both
-    incoming and outgoing feeds have to be set up and tested).  Be prepared
-    to take some time to understand what's going on and how all the pieces
-    fit together.  If you have any specific suggestions for documentation,
-    or comments about things that are unclear, please send them to the INN
-    maintainers (see "Reporting Bugs" below).
-
-    See INSTALL for step-by-step instructions for setting up and configuring
-    a news server.
-
-    INN also comes with a very complete set of man pages; there is a man
-    page for every configuration file and program that comes with INN.  (If
-    you find one that doesn't have a man page, that's a bug.  Please do
-    report it.)  When trying to figure out some specific problem, reading
-    the man pages for all of the configuration files involved is a very good
-    start.
-
-Reporting Bugs
-
-    We're interested in all bug reports.  Not just on the programs, but on
-    the documentation too.  Please send *all* such reports to
-
-        inn-bugs@isc.org
-
-    (patches are certainly welcome, see below).  Even if you post to Usenet,
-    please CC the above address.  All other INN mail should go to
-
-        inn@isc.org
-
-    (please do *not* send bug reports to this address).
-
-    If you have general "how do I do this" questions or problems configuring
-    your server that you don't believe are due to a bug in INN, you should
-    post them to news.software.nntp.  A lot of experienced INN users,
-    including several of the INN maintainers, read that newsgroup regularly.
-    Please don't send general questions to the above addresses; those
-    addresses are specifically for INN, and the INN maintainers usually
-    won't have time to answer general questions.
-
-Contributing Code
-
-    If you have a patch or a utility that you'd like to be considered for
-    inclusion into INN, please mail it to
-
-        inn-patches@isc.org
-
-    in the body of the message (not as an attachment), or put it on a
-    webpage and send a link.  Patches included with a bug report as
-    described above should follow the same procedure, but need not be sent
-    to both addresses (either will do).
-
-    Have fun!
-
-Mailing Lists
-
-    There are various INN-related mailing lists you can join or send
-    messages to if you like.  Some of them you must be a member of before
-    you can send mail to them (thank the spammers for that policy), and one
-    of them is read-only (no postings allowed).
-
-    inn-announce@isc.org    Where announcements about INN are set (only
-                            maintainers may post).
-
-    inn-workers@isc.org     Discussion of INN development (postings by
-                            members only).
-
-    inn-patches@isc.org     Where to send patches for consideration for
-                            inclusion into INN (open posting).
-
-    inn-committers@isc.org  CVS commit messages for INN are sent to this
-                            list (only the automated messages are sent here,
-                            no regular posting).
-
-    inn-bugs@isc.org        Where to send bug reports (open posting).  If
-                            you're an INN expert and have the time to help
-                            out other users, we encourage you to join this
-                            mailing list to answer questions.  (You may also
-                            want to read the newsgroup news.software.nntp,
-                            which gets a lot of INN-related questions.)
-
-    To join these lists, send a subscription request to the "-request"
-    address.  The addresses for the above lists are:
-
-       inn-announce-request@isc.org
-       inn-workers-request@isc.org
-       inn-patches-request@isc.org
-       inn-committers-request@isc.org
-       inn-bugs-request@isc.org
-
-Who's Responsible / Who to Thank
-
-    See CONTRIBUTORS for a long list of past contributors as well as people
-    from the inn-workers mailing list who have dedicated a lot of time and
-    effort to getting this new version together.  They deserve a big round
-    of applause.  They've certainly got our thanks.
-
-    This product includes software developed by UUNET Technologies, Inc. and
-    by the University of California, Berkeley and its contributors.
-
-    Last, but certainly not least, Rich Salz, the original author of INN
-    deserves a lion's share of the credit for writing INN in the first place
-    and making it the most popular news server software on the planet (no
-    NNTP yet to the moon, but we plan to be there first).
-
-Related Packages
-
-    INN users may also be interested in the following software packages that
-    work with INN or are based on it.  Please note that none of this
-    software is developed or maintained by ISC; we don't support it and
-    generally can't answer questions about it.
-
-    CleanFeed
-        URL: <http://www.bofh.it/~md/cleanfeed/>
-
-        CleanFeed is an extremely powerful spam filter, probably the most
-        widely used spam filter on Usenet currently.  It catches excessive
-        multiposting and a host of other things, and is highly configurable.
-        Note that it requires that INN be built with Perl support (the
-        --with-perl option to configure).
-
-    GUP (Group Update Program)
-        URL: <ftp://ftp.debian.org/debian/pool/main/g/gup/>
-
-        GUP provides a way for your peers to update their newsfeeds entries
-        as they want without having to ask you to edit the configuration
-        file all the time.  It's useful when feeding peers who take limited
-        and very specific feeds that change periodically.
-
-    inflow
-        URL: <http://www.switch.ch/netnews/wg/netnews-wg.html>
-
-        inflow generates graphs of news flow statistics in real time from
-        INN's logs (things like articles accepted per peer, volume accepted
-        per peer, and the like).
-
-    News-Portal
-        URL: <http://floh.gartenhaus.net/newsportal/>
-
-        A PHP-based web news reader that works as a front-end to a regular
-        news server such as INN and lets people read and post without
-        learning a news reader.
-
-    PersonalINN
-        URL: <http://www.ritual.org/summer/pinn/>
-
-        PersonalINN is a version of INN modified for personal use and with a
-        friendly GUI built on top of it.  It is available for NeXTSTEP or
-        OPENSTEP only, unfortunately.
-
-    suck
-        URL: <http://home.comcast.net/~bobyetman/index.html>
-
-        suck is a separate package for downloading a news feed via a reading
-        connection (rather than via a direct NNTP or UUCP feed) and sending
-        outgoing local posts via POST.  It's intended primarily for personal
-        or small-organization news servers who get their news via an ISP and
-        are too small to warrant setting up a regular news feed.
-
-    newsx
-        URL: <http://www.kvaleberg.com/newsx.html>
-
-        Serving the same purpose as suck, newsx is a separate package for
-        downloading a news feed via a reading connectino and sending
-        outgoing local posts via POST.  Some people find suck easier to
-        configure and use, and some people find newsx easier.  If you have
-        problems with one, try the other.
-
-Supporting the INN Effort
-
-    Note that INN is supported by Internet Systems Consortium, and although
-    it is free for use and redistribution and incorporation into vendor
-    products and export and anything else you can think of, it costs money
-    to produce.  That money comes from ISPs, hardware and software vendors,
-    companies who make extensive use of the software, and generally
-    kind-hearted folk such as yourself.
-
-    Internet Systems Consortium has also commissioned a DHCP server
-    implementation and handles the official support/release of BIND.  You
-    can learn more about the ISC's goals and accomplishments from the web
-    page at <http://www.isc.org/>.
-
-                                            Russ Allbery
-                                            Katsuhiro Kondou
-                                            <inn@isc.org>
diff --git a/TODO b/TODO
deleted file mode 100644 (file)
index 28b655b..0000000
--- a/TODO
+++ /dev/null
@@ -1,847 +0,0 @@
-This is a rough and informal list of suggested improvements to INN, parts
-of INN that need work, and other tasks yet undone.  Some of these may be
-in progress, in which case the person working on them will be noted in
-square brackets and should be contacted if you want to help.  Otherwise,
-let inn-workers@isc.org know if you'd like to work on any item listed
-below.
-
-The list is divided into changes already tentatively scheduled for a
-particular release, higher priority changes that will hopefully be done in
-the near future, small or medium-scale projects for the future, and
-long-term, large-scale problems.  Note that just because a particular
-feature is scheduled for a later release doesn't mean it can't be
-completed earlier if someone decides to take it on.  The association of
-features with releases is intended to be a rough guide for prioritization
-and a set of milestones to use to judge when a new major release is
-justified.
-
-Also, one major thing that is *always* welcome is additions to the test
-suite, which is currently very minimal.  Any work done on the test suite
-to allow more portions of INN to be automatically tested will make all
-changes easier and will be *greatly* appreciated.
-
-Last modified $Id: TODO 7575 2006-09-11 22:59:38Z eagle $.
-
-
-Scheduled for INN 2.5
-
-* Rewrite configure, breaking all of the tests out into separate files
-  using the new capabilities in autoconf 2.5x.  Replace our local macros
-  with the more general features provided by autoconf.  At the same time,
-  configure.in and Makefile.global.in should be fixed to use the same
-  names as each other for various parameters.  [Russ plans to work on
-  this.]
-
-* Add support for groups, nesting, and vectors to the new configuration
-  parsing code.  [Russ plans on doing this.]
-
-* Convert readers.conf and storage.conf (and related configuration files)
-  to use the new parsing system and break out program-specific sections
-  of inn.conf into their own groups.
-
-* The current WIP cache and history cache should be integrated into the
-  history API, things like message ID hashing should become a selectable
-  property of the history file, and the history API should support
-  multiple backend storage formats and automatically select the right one
-  for an existing history file based on stored metainformation.
-
-* The interface to embedded filters needs to be reworked.  The information
-  about which filters are enabled should be isolated in the filtering API,
-  and there should be standard API calls for filtering message IDs, remote
-  posts, and local posts.  As part of this revision, all of the Perl
-  callbacks should be defined before any of the user code is loaded, and
-  the Perl loading code needs considerable cleanup.  At the same time as
-  this is done, the implementation should really be documented; we do some
-  interesting things with embedded filters and it would be nice to have a
-  general document describing how we do it.  [Russ is planning on working
-  on this at some point, but won't get upset if someone starts first.]
-
-* All of INN's documentation should be written in POD, with text and man
-  pages generated from the POD source.  Anyone is encouraged to work on
-  this by just taking any existing documentation in man format and convert
-  it to POD while checking that it's still accurate and adding any
-  additional useful information that was missed.
-
-* Replace the current innshellvars.pl file with a real INN Perl module for
-  Perl programs, and include the necessary glue so that other Perl modules
-  can be added to INN's build tree and installed with INN, allowing their
-  capabilities to be available to the portions of INN written in Perl.
-
-* Switch nnrpd over to using the new wildmat routines rather than breaking
-  apart strings on commas and matching each expression separately.  This
-  involves a lot of surgery, since PERMmatch is used all over the place,
-  and may change the interpretation of ! and @ in group permission
-  wildmats.
-
-* Rework and clean up the storage API.  The major change is that the
-  initialization function should return a pointer to an opaque struct
-  which stores all of the state of the storage subsystem, rather than all
-  of that being stored in static variables, and then all other functions
-  should take that pointer.  More of the structures should also be opaque,
-  all-caps structure names should be avoided in favor of named structures,
-  SMsetup and SMinit should be combined into one function that takes
-  flags, SMerrno and SMerrorstr should be replaced with functions that
-  return that information, and the wire format utilities should be moved
-  into libinn.
-
-* Rework and clean up the overview API.  The major change is that the
-  initialization function should return a pointer to an opaque struct
-  which stores all of the state of the overview subsystem, rather than all
-  of that being stored in static variables, and then all other functions
-  should take that pointer.  OVctl possibly should instead take and return
-  a struct rather than using an ioctl-style interface.  Currently, the
-  overview functions do a lot of breaking apart of Xref headers and
-  parsing them, which is very ugly; consider having the overview interface
-  always key off a newsgroup name and article number, even for storing.
-  OVadd should probably take a structure and OVsearch should probably
-  return a structure.
-
-
-Scheduled for INN 2.6
-
-* Add a generic, modular anti-spam and anti-abuse filter, off by default,
-  but coming with INN and prominently mentioned in the INSTALL
-  documentation.  [Andrew Gierth has work in progress that may be usable
-  for this.]
-
-* A unified configuration file combining the facilities of newsfeeds,
-  incoming.conf, and innfeed.conf, but hopefully more readable and easier
-  for new INN users to edit.  This should have all of the capabilities of
-  the existing configuration files, but specifying common things (such as
-  file feeds or innfeed feeds) should be very simple and straightforward.
-  This configuration file should use the new parsing infrastructure.
-
-* Convert all remaining INN configuration files to the new parsing
-  infrastructure.
-
-* INN really should be capable of both sending and receiving a
-  headers-only feed (or even an overview-only feed) similar to Diablo and
-  using it for the same things that Diablo does, namely clustering,
-  pull-on-demand for articles, and the like.  This should be implementable
-  as a new backend, although the API may need a few more hooks.  Both a
-  straight headers-only feed that only pulls articles down via NNTP from a
-  remote server and a caching feed where some articles are pre-fed, some
-  articles are pulled down at first read, and some articles are never
-  stored locally should be possible.  [Patches for a header-only feed have
-  already been written and submitted to inn-workers.]
-
-* The libinn, libstorage, and other library interfaces should be treated
-  as stable libraries and properly versioned using libtool's
-  recommendation for library versioning when changes are made so that they
-  can be installed as shared libraries and work properly through releases
-  of INN.  This is currently waiting on a systematic review of the
-  interface and removal of things that we don't want to support long-term.
-
-* The include files necessary to use libinn, libstorage, and other
-  libraries should be installed in a suitable directory so that other
-  programs can link against them.  All such include files should be under
-  include/inn and included with <inn/header.h>.  All such include files
-  should only depend on other inn/* header files and not on, e.g.,
-  config.h.  All such include files should be careful about namespace to
-  avoid conflicts with other include files used by applications.
-
-
-High Priority Projects
-
-* Modulo warnings from system headers and warnings where the compiler is
-  simply wrong and there's no equally readable way to rewrite the code,
-  INN should compile cleanly under "make warnings".  It should be possible
-  for maintainers to routinely compile INN with make warnings to catch
-  problems.  Note that -Wcast-qual warnings cannot be avoided entirely
-  because we don't want to write redundant functions for regular and const
-  strings and because of such things as struct iovec; -Wcast-qual will be
-  removed from make warnings when this task is reasonably complete.
-
-* INN shouldn't flush all feeds (particularly all program feeds) on
-  newgroup or rmgroup.  Currently it reloads newsfeeds to reparse all of
-  the wildmat patterns and rebuild the peer lists associated with the
-  active file on group changes, and this forces a flush of all feeds.
-  The best fix is probably to stash the wildmat pattern (and flags) for
-  each peer when newsfeeds is read and then just using the stashed copy on
-  newgroup or rmgroup, since otherwise the newsfeeds loading code would
-  need significant modification.  But in general, innd is too
-  reload-happy; it should be better at making incremental changes without
-  reloading everything.
-
-* Add authenticated Path support, based on the current USEFOR draft or the
-  behavior of some other servers (such as Diablo).  [Andrew Gierth wrote a
-  patch for part of this a while back, which Russ has.  Marco d'Itri
-  expressed some interest in working on this.]
-
-* Various parts of INN are using write or writev; they should all use
-  xwrite or xwritev instead.  Even for writes that are unlikely to ever be
-  partial, on some systems system calls aren't restartable and xwrite and
-  xwritev properly handle EINTR returns.
-
-* Apparently on Solaris open can also be interrupted by a signal; we may
-  need to have an xopen wrapper that checks for EINTR and retries.
-
-* tradspool has a few annoying problems.  Deleted newsgroups never have
-  their last articles expired, and there is no way of forcibly
-  resynchronizing the articles stored on disk with what overview knows
-  about unless tradindexed is used.  Some sort of utility program to take
-  care of these and to do things like analyze the tradspool.map file
-  should be provided.
-
-* Rewrite inndstart as a helper program that only binds the relevant
-  sockets and then returns them to innd.  Since file descriptors are
-  shared by child processes, this can be done with a program spawned by
-  innd.  This may have gotten more complicated with IPv6.  Drop
-  startinnfeed entirely in favor of recommending people use ulimit in the
-  news init script.
-
-* contrib/mkbuf and contrib/reset-cnfs.c should be combined into a utility
-  for creating and clearing cycbuffs, perhaps combined with cnfsheadconf,
-  and the whole thing moved into storage/cnfs rather than frontends (along
-  with cnfsstat).  pullart.c may also stand to be merged into the same
-  utility (cnfs-util might not be a bad name).
-
-
-Documentation Projects
-
-* Add man pages for all libinn interfaces.  There should be a subdirectory
-  of doc/pod for this since there will be a lot of them; installing them
-  as libinn_<section>.3 seems to make the most sense (so, for example,
-  error handling routines would be documented in libinn_error.3).
-
-* Better documentation of and support for UUCP feeds.  send-uucp is now
-  easier to use, but there's still a paucity of documentation covering the
-  whole theory and mechanisms of UUCP feeding.
-
-* Everything installed by INN should have a man page.  Currently, there
-  are several binaries and configuration files that don't have man pages.
-  (In some cases, the best thing to do with the configuration file may be
-  to merge it into another one or find a way to eliminate it.)
-
-* Document the internal formats of the various overview methods, CNFS,
-  timehash, and timecaf.  A lot of this documentation already exists in
-  various forms, but it needs to be cleaned up and collected in one place
-  for each format, preferrably as a man page.
-
-* Add documentation for slave servers.  [Russ has articles from
-  inn-workers that can be used as a beginning.]
-
-* Write complete documentation for all of our extensions to RFC 977 or RFC
-  1036, preferrably in a format that could be suitable for future
-  inclusion into new revisions of the RFCs.
-
-* Audit readers.conf.5 against perm.c for missing options ("include" at
-  least is missing from the documentation).
-
-* The distributions file is undocumented.
-
-
-Code Cleanup Projects
-
-* Eliminate everything in the LEGACY section of config.h.
-
-* Move all compile-time configuration in config.h either into a separate
-  header (such as inn/options.h) or turn it into a configuration file
-  directive or a command-line option.  In particular, the rnews
-  configuration should probably be an rnews-specific section of inn.conf.
-
-* Move include/paths.h to include/inn/paths.h and change _PATH as a prefix
-  to INN_PATH to move the identifiers out of the C reserved namespace.
-  Check to be sure we still need all of the #defines and look at adding
-  anything needed by innfeed (and eliminating the separate innfeed header
-  serving the same purpose).
-
-* Move include/nntp.h to include/inn/nntp.h and at the same time look at
-  standardizing the names of all of the #defines it provides, including
-  the message class.  [Russ has a start on this.]
-
-* Get rid of GetTimeInfo and TIMEINFO.  All the struct is is a struct
-  timeval plus time zone information.  All of the parts of INN that deal
-  with time zone information are isolated in lib/date.c.  The rest of INN
-  uses GetTimeInfo where a plain call to time would often work fine, or
-  at most gettimeofday, and there's no reason to compute the time zone
-  everywhere.  Plus, it makes the code more readable to use standard
-  functions and data types.
-
-* putman.sh should be merged into support/install-sh (which would mean
-  giving up any pretext of using the standard install-sh script, but that
-  should be fine).
-
-* Use vectors or cvectors everywhere that argify and friends are currently
-  used and eliminate the separate implementation in nnrpd/misc.c.
-
-* Break up the remainder of libinn.h into multiple inn/* include files for
-  specific functions (such as memory management, wildmat, date handling,
-  NNTP commands, etc.), with an inn/util.h header to collect the remaining
-  random utilities.  Consider adding some sort of prefix, like inn_, to all
-  functions that aren't part of some other logical set with its own prefix.
-
-* Break the CNFS and tradspool code into multiple source files to make it
-  easier to understand the logical divisions of the code and consider
-  doing the same with the other overview and storage methods.
-
-* Examine the (mostly socket) code that currently should probably be
-  compiled with -fno-strict-aliasing on gcc and move the relevant casts
-  to within function calls.  [Russ knows about this.]
-
-* Clean up the use of #ifdef for sockets and IPv6, perhaps involving
-  addition of more to include/portable/socket.h.
-
-
-Needed Bug Fixes
-
-* tradspool currently uses stdio to write out tradspool.map, which can
-  cause problems if more than 256 file descriptors are in use for other
-  things (such as incoming connections or tradindexed overview cache).
-  It should use write() instead.
-
-* LIST NEWSGROUPS should probably only list newsgroups that are marked in
-  the active file as valid groups.
-
-* INN's startup script should be sure to clean out old lock files and PID
-  files for innfeed.  Be careful, though, since innfeed may still be
-  running, spawned from a previous innd.
-
-* makedbz should be more robust in the presence of malformed history
-  lines, discarding with them or otherwise dealing with them.
-
-* CNFS, if the cycbuff is larger than 2GB and it doesn't have large file
-  support, reports a mysterious file not found error because it assumes
-  all errors from stat are the result of the cycbuff not being found.
-
-* Some servers reject some IHAVE, TAKETHIS, or CHECK commands with 500
-  syntax errors (particularly for long message IDs), and innfeed doesn't
-  handle this particularly well at the moment.  It really should have an
-  error handler for this case.  [Sven Paulus has a preliminary patch that
-  needs testing.]
-
-* Editing the active file by hand can currently munge it fairly badly even
-  if the server is throttled unless you reload active before restarting
-  the server.  This could be avoidable for at least that particular case
-  by checking the mtime of active before and after the server was
-  throttled.
-
-* innreport silently discards news.notice entries about most of the errors
-  innfeed generates.  It should ideally generate some summary, or at least
-  note that some error has occurred and the logs should be examined.
-
-* INN's message ID parser should be more forgiving about surrounding
-  whitespace.  Right now, it will reject messages with a trailing space in
-  the Message-ID header.
-
-* nnrpd doesn't check the message ID of a posted article for syntactic
-  validity before remailing it to the moderator, since normally it relies
-  on innd to check the message ID.  The message ID checking code from
-  innd/art.c should be moved into lib so that nnrpd can use it as well.
-
-* Currently, if the list of newsgroups on an Xref slave is out of sync
-  with the newsgroups on the master, receiving an article crossposted to
-  one of the groups that doesn't exist on the slave will cause the slave
-  to throttle.  This isn't the best behavior; the server should either
-  optionally create the missing newsgroup or just ignore that crossposted
-  group (and modify Xref accordingly?).
-
-* Handling of compressed batches needs to be thoroughly reviewed by
-  someone who understands how they're supposed to work.  It's not clear
-  that _PATH_GZIP is being used correctly at the moment and that
-  compressed batch handling will work right now on systems that don't have
-  gzip installed (but that do have uncompress).
-
-* innfeed's statistics don't add up properly all the time.  All of the
-  article dispositions don't add up to the offered count like they should.
-  Some article handling must not be recorded properly.
-
-* innd's counting of article size doesn't always work properly, and it can
-  accept articles that are larger than its configured limit.  It's not
-  clear exactly where this is happening.
-
-* If a channel feed exits immediately, innd respawns it immediately,
-  causing thrashing of the system and a huge spew of errors in syslog.  It
-  should mark the channel as dormant for some period of time before
-  respawning it, perhaps only if it's already died multiple times in a
-  short interval.
-
-* ctlinnd begin <site-name> was causing innd to core dump.
-
-* Handling of innfeed's dropped batches needs looking at.  There are three
-  places where articles can fall between the cracks:  an innfeed.togo file
-  written by innd when the feed can't be spawned, a batch file named after
-  the feed name which can be created under similar circumstances, and the
-  dropped files written by innfeed itself.  procbatch can clean these up,
-  but has to be run by hand.
-
-* When using tradspool, groups are not immediately added to tradspool.map
-  when created, making innfeed unable to find the articles until after
-  some period of time.  Part of the problem here is that tradspool only
-  updates tradspool.map on a lazy basis, when it sees an article in that
-  group, since there is no storage hook for creation of a new group.
-
-* nntpget doesn't handle long lines in messages.
-
-* WP feeds break if there are spaces in the Path header, and the inn.conf
-  parser doesn't check for this case and will allow people to configure
-  their server that way.  (It's not clear that the latter is actually a
-  bug, given the new USEFOR attempt to allow folding of Path headers, but
-  the space needs to be removed for WP feeds.)
-
-* Error handling in the history backend needs to be reviewed, since it
-  currently is always printing out errno regardless of whether it's
-  meaningful.  The error handling needs to record errno if it's useful and
-  the reporting function should only print it out if it's useful for that
-  error.
-
-* innd returns 437 for articles that were accepted but filed in the junk
-  group.  It should probably return the appropriate 2xx status code in
-  that case instead.
-
-* Someone should go through the BUGS sections of all of the manpages and
-  fix those for which the current behavior is unacceptable.
-
-
-Requested New Features
-
-* Consider implementing the HEADERS command as discussed rather
-  extensively in news.software.nntp.  [Greg Andruk has a preliminary
-  patch.]
-
-* There have been a few requests for the ability to programmatically set
-  the subject of the report generated by news.daily, with escapes that are
-  filled in by the various pieces of information that might be useful.
-
-* A bulk cancel command using the MODE CANCEL interface.  Possibly through
-  ctlinnd, although it may be a bit afield of what ctlinnd is currently
-  for.
-
-* Sven Paulus's patch for nnrpd volume reports should be integrated.  See
-  <ftp://ftp.tin.org/pub/news/servers/inn/unofficial-patches/
-  patch-inn-2.2.x-artstat+list+overstat>.
-
-* Lots of people encrypt X-Trace in various ways.  Should that be offered
-  as a standard option?  The first data element should probably remain
-  unencrypted so that the O flag in newsfeeds doesn't break.
-
-  Should there also be an option not to generate X-Trace?  And this whole
-  area may change if USEFOR ever standardizes poster trace information;
-  it's been proposed to put it in the path tail instead.  The current
-  USEFOR trend as of January, 2001 appears to be towards an Injector-Info
-  header with this information, allowing a token or an injecting hostname.
-  For a token, one really wants it to be hierarchically structured for
-  spam filtering even if it's encrypted (in other words, to get a "group"
-  of clients, one could just match the first n bytes of the token instead
-  of the whole thing).
-
-  Olaf Titz suggests:
-
-      This can be done by formatting the (rest of) the header in a way
-      that fields are always a multiple of 8 bytes and applying a 64 bit
-      block cipher in ECB mode on it.  But then we would be better off
-      using binary fields, as the timestamp is 9 bytes and an IP address
-      10-12 bytes.
-
-      Combining the timestamp and PID into one block, adding an
-      authenticated user field and omitting the redundant formatted time
-      would give the following format:
-
-      X-Trace: g212.hadiko.de [395109AA000016FF] [AC14302A00000000] [...]
-                               time    |    pid   ip      |reserved  user
-
-* ctlinnd flushlogs currently renames all of the log files.  It would be
-  nice to support the method of log rotation that most other daemons
-  support, namely to move the logs aside and then tell innd to reopen its
-  log files.  Ideally, that behavior would be triggered with a SIGHUP.
-  scanlogs would have to be modified to handle this.
-
-  The best way to support this seems to be to leave scanlogs as is by
-  default, but also add two additional modes.  One would flush all the
-  logs and prepare for the syslog logs to be rotated, and the other would
-  do all the work needed after the logs have been rotated.  That way, if
-  someone wanted to plug in a separate log rotation handler, they could do
-  so and just call scanlogs on either side of it.  The reporting portions
-  of scanlogs should be in a separate program.
-
-* Several people have Perl interfaces to pieces of INN that should ideally
-  be part of the INN source tree in some fashion.  Greg Andruk has a bunch
-  of stuff that Russ has copies of, for example.
-
-* Investigate using the new, stricter date parsing code in libinn for
-  nnrpd rather than the extremely lenient parsedate routine.
-
-* There are various available patches for Cancel-Lock and an Internet
-  draft; support should be added to INN for both generation and
-  verification (definitely optional and not on by default at this point).
-
-* It would be nice to be able to reload inn.conf (although difficult, due
-  to the amount of data that's generated from it and stashed in various
-  places).  This will need to wait for the new configuration parsing
-  library and an inn.conf parser that uses it.
-
-* remembertrash currently rejects and remembers articles with syntax
-  errors as well as things like unwanted newsgroups and unwanted
-  distributions, which means that if a peer sends you a bunch of mangled
-  articles, you'll then also reject the correct versions of the articles
-  from other peers.  This should probably be rethought.
-
-* Additional limits for readers.conf:  Limit on concurrent parallel reader
-  streams, limit on KB/second download (preliminary support for this is
-  already in), and a limit on maximum posted articles per day (tied in
-  with the backoff stuff?).  These should be per-IP or per-user, but
-  possibly also per-access group.  (Consider pulling the -H, -T, -X, and 
-  -i code out from innd and using it here.)
-
-* timecaf should have more configurable parameters (at the least, how
-  frequently to switch to a new CAF file should be an option).
-  storage.conf should really be extended to allow method-specific
-  configuration for things like this (and to allow the cycbuff.conf file
-  to be merged into storage.conf).
-
-* Allow generation of arbitrary additional information that could go in
-  overview by using embedded Perl or Python code.  This might be a cleaner
-  way to do the keywords code, which really wants Perl's regex engine
-  ideally.  It would also let one do something like doing MD5 hashes of
-  each article and putting that in the overview if you care a lot about
-  making sure that articles aren't corrupted.
-
-* Allow some way of accepting articles regardless of the Date header, even
-  if it's far into the future.  Some people are running into articles that
-  are dated years into the future for some reason that they still want to
-  store on the server.
-
-* There was a request to make --program-suffix and the other name
-  transformation options to autoconf work.  The standard GNU package does
-  this with really ugly sed commands in the Makefile rules; we could
-  probably do better, perhaps by substituting the autoconf results into
-  support/install-sh.
-
-* INN currently uses hash tables to store the active file internally.  It
-  would be worth trying ternary search trees to see if they're faster; the
-  data structure is simpler, performance may be comparable for hits and
-  significantly better for misses, sizing and resizing becomes a non-issue,
-  and the space penalty isn't too bad.  A generic implementation is already
-  available in libinn.  (An even better place to use ternary search trees
-  may be the configuration parser.)
-
-* Provide an innshellvars equivalent for Python.
-
-* inncheck should check the syntax of all the various files that are
-  returned by LIST commands, since having those files present with the
-  wrong syntax could result in non-compliant responses from the server.
-  Possibly the server should also refuse to send malformatted lines to
-  the client.
-
-* ctlinnd reload incoming.conf could return a count of the hosts that
-  failed, or even better a list of them.  This would make pruning old
-  stuff out of incoming.conf much easier.
-
-* nnrpd could use sendfile(2), if available, to send articles directly
-  to the socket (for those storage methods where to-wire conversion is
-  not needed).  This would need to be added to the storage API.
-
-* Somebody should look at keeping the "newsgroups" file more accurate
-  (e.g. newgroups for existing groups should change description, better
-  checkgroups handling, checking for duplicates)
-
-* The by-domain statistics innreport generates for nnrpd count all local
-  connections (those with no "." in the hostname) in with the errors as
-  just "?".  The host2dom function could be updated to group these as
-  something like "Local".
-
-* news.daily could detect if expire segfaults and unpause the server.
-
-* When using SSL, track the amount of data that's been transferred to the
-  client and periodically renegotiate the session key.
-
-* When using SSL, use SSL_get_peer to get a verified client certificate,
-  if available, and use it to create an additional header line when
-  posting articles (X-Auth-Poster?).  This header could use:
-
-      X509_NAME_oneline(X509_get_subject_name(peer),...)
-
-  for the full distinguished name, or
-
-      X509_name_get_text_by_NID(X509_get_subject_name(peer),
-                                NID_commonName, ...)
-   
-  for the client's "common name" alone.
-
-* When using SSL, use the server's key to generate an HMAC of the body of
-  the message (and most headers?), then include that digest in the
-  headers.  This allows a news administrator to determine if a complaint
-  about the content of a message is fradulent since the message was
-  changed after transmission.
-
-
-General Projects
-
-* All the old packages in unoff-contrib should be reviewed for integration
-  into INN.
-
-* It may be better for INN on SysV-derived systems to use poll rather than
-  select.  The semantics are better, and on some systems (such as Solaris)
-  select is limited to 1024 file descriptors whereas poll can handle any
-  number.  Unfortunately, the API is drastically different between the
-  two and poll isn't portable, so supporting both cleanly would require a
-  bit of thought.
-
-* Currently only innd and innfeed increase their file descriptor limits.
-  Other parts of INN, notably makehistory, may benefit from doing the same
-  thing if they can without root privileges.
-
-* The Tcl filtering support code has undergone serious bitrot and needs
-  some work to fix it and make it work with modern versions of Tcl and the
-  current version of INN.  It also lacks a lot of the functionality of the
-  Perl and Python filters, if anyone cares.
-
-* Revisit support for aliased groups and what nnrpd does with them.
-  Should posts to the alias automatically be redirected to the real group?
-  Regardless, the error return should provide useful information about
-  where to post instead.  Also, the new overview API, for at least some of
-  the overview methods, truncated the group status at one character and
-  lost the name of the group to which a group is aliased; that needs to be
-  fixed.
-
-* More details as to why a message ID is bad would be useful to return to
-  the user, particularly for rnews, inews, etc.  innd also rejects message
-  IDs with trailing spaces, which can be hard to check.
-
-* Support putting the active file and history file in different
-  directories without hand-editing a bunch of files.
-
-* nnrpd's NNTP command parsing interacts poorly with AUTHINFO and
-  passwords containing spaces.  The correct solution isn't clear; check
-  with the current NNTP RFC draft and how existing clients handle it?
-
-* frontends/pullnews and contrib/backupfeed solve the same problem; the
-  best ideas of both should be unified into one script.
-
-* actsyncd could stand a rewrite and cleaner handling of both
-  configuration and syncing against multiple sources which are canonical
-  for different sets of groups.
-
-* send-nntp and nntpsend basically do the same thing; send-nntp could
-  probably be removed (possibly with some extra support in nntpsend for
-  doing simpler things).
-
-
-Long-Term Projects
-
-* Look at turning header parsing into a library of some sort.  Lots of INN
-  does this, but different parts of INN need subtly different things, so
-  the best best API is unclear.
-
-* INN's header handling needs to be checked against the current USEFOR
-  draft.  This may want wait until after we have a header parsing library.
-
-* The innd filter should be able to specify additional or replacement
-  groups into which an article should be filed, or even spool the article
-  to a local disk file rather than storing it.  (See the stuff that the
-  nnrpd filter can already do.)
-
-* Add authentication via SASL to nnrpd.  This is a boatload of additional
-  issues, particularly if we want to add authentication methods like
-  Kerberos that require their own separate libraries (although we should
-  use Cyrus's SASL libraries, which will simplify a lot of that).
-  [Jeffrey Vinocur is working on a standard for this.]
-
-* When articles expire out of a storage method with self-expire
-  functionality, the overview and history entries for those articles
-  should also be expired immediately.  Otherwise, things like the GROUP
-  command don't give the correct results.  This will likely require a
-  callback that can be passed to CNFS that is called to do the overview
-  and history cleanup for each article overwritten.  It will also require
-  the new history API.
-
-* Feed control, namely allowing your peers to set policy on what articles
-  you feed them (not just newsgroups but max article size and perhaps even
-  filter properties like "non-binary").  Every site does this a bit
-  differently.  Some people have web interfaces, some people use GUP, some
-  people roll their own alternate things.  It would really be nice to have
-  some good way of doing this as part of INN.  It's worth considering an
-  NNTP extension for this purpose, although the first step is to build a
-  generic interface that an NNTP extension, a web page, etc. could all
-  use.  (An alternate way of doing this would be to extend IHAVE to pass
-  the list of newsgroups as part of the command, although this doesn't
-  seem as generally useful.)
-
-* Traffic classification as an extension of filtering.  The filter should
-  be able to label traffic as binary (e.g.) without rejecting it, and
-  newsfeeds should be extended to allow feeding only non-binary articles
-  (e.g.) to a peer.
-
-* External authenticators should also be able to do things like return a
-  list of groups that a person is allowed to read or post to.  Currently,
-  maintaining a set of users and a set of groups, each of which some
-  subset of the users is allowed to access, is far too difficult.  For a
-  good starting list of additional functionality that should be made
-  available, look at everything the Perl authentication hooks can do.
-  This should probably wait for the configuration file parsing rewrite.
-
-* Allow nnrpd to spawn long-running helper processes.  Not only would this
-  be useful for handling authentication (so that the auth hooks could work
-  without execing a program on every connection), but it may allow for
-  other architectures for handling requests (such as a pool of helpers
-  that deal only with overview requests).  More than that, nnrpd should
-  *be* a long-running helper process that innd can feed open file
-  descriptors to.  [Aidan Culley has ideas along these lines.]
-
-* The tradspool storage method requires assigning a number to every
-  newsgroup (for use in a token).  Currently this is maintained in a
-  separate tradspool.map file, but it would be much better to keep that
-  information in the active file where it can't drop out of sync.  A code
-  assigned to each newsgroup would be useful for other things as well,
-  such as hashing the directories for the tradindexed overview.  For use
-  for that purpose, though, the active file would have to be extended to
-  include removed groups, since they'd need to be kept in the active file
-  to reserve their numbers until the last articles expired.
-
-* The locking of the active file leaves something to be desired; in
-  general, the locking in INN (for the active file, the history file,
-  spool updates, overview updates, and the like) needs a thorough
-  inspection and some cleanup.  A good place to start would be tracing
-  through the pause and throttle code and write up a clear description of
-  what gets locked where and what is safely restarted and what isn't.
-  Long term, there needs to be a library locking routine used by
-  *everything* that needs to write to the history file, active file, etc.
-  and that keeps track of the PID of the process locking things and is
-  accessible via ctlinnd.
-
-* There is a fundamental problem with the current design of the
-  control.ctl file.  It combines two things:  A database of hierarchies,
-  their maintainers, and related information, and a list of which
-  hierarchies the local server should honor.  These should be separated
-  out into the database (which could mostly be updated from a remote
-  source like ftp.isc.org and then combined with local additions) and a
-  configured list of hierarchies (or sub-hierarchies within hierarchies)
-  that control messages should be honored for.  This should be reasonably
-  simple although correct handling of checkgroups could get a mite tricky.
-
-* Possible NNTP extension:  Compression of the protocol, using gzip,
-  bzip2, or some other technique.  Particularly useful for long lists like
-  the active file information or the overview information, but possibly
-  useful in general for other things.
-
-* Install wizards.  Configuring INN is currently very complex even for an
-  experienced news admin, and there are several fairly standard
-  configurations that shouldn't be nearly that complicated to get running
-  out of the box.  A little interactive Perl script asking some simple
-  questions could probably get a lot of cases easily right.
-
-* One ideally wants to be able to easily convert between different
-  overview formats or storage methods, refiling articles in place.  This
-  should be possible once we have a history API that allows changing the
-  storage location of an article in-place.
-
-* Set up the infrastructure required so that INN can use alloca.  This
-  would significantly decrease the number of calls to malloc needed and
-  would be a lot more convenient.
-
-* A serious investigation into whether INN could use a garbage collector
-  is probably a good idea.  The network buffers probably need to be
-  handled with decidated code, but there are a lot of other incidental
-  allocations and deallocations that may be much more efficient and safer
-  using a garbage collector.
-
-* Look at integrating asprintf and vasprintf.  Russ already tried this
-  once and couldn't see a good way of doing it (particularly vasprintf)
-  without hooking deep into an sprintf implementation, because the simple
-  hack of calling vsnprintf first, allocating that much memory, and then
-  calling it again on the new buffer doesn't work for vasprintf (you can't
-  reprocess the arguments).
-
-* Support building in a separate directory than the source tree.  It may
-  be best to just support this via lndir rather than try to do it in
-  configure, but it would be ideal to add support for this to the autoconf
-  system.  Unfortunately, the standard method requires letting configure
-  generate all of the makefiles, which would make running configure and
-  config.status take much longer than it does currently.
-
-* Look at adding some kind of support for MODE CANCEL via network sockets
-  and fixing up the protocol so that it could possibly be standardized
-  (the easiest thing to do would probably be to change it into a CANCEL
-  command).  If we want to get to the point where INN can accept and even
-  propagate such feeds from dedicated spam filters or the like, there must
-  also be some mechanism of negotiating policy in order to decide what
-  cancels the server wants to be fed.
-
-* The "possibly signed" char data type is one of the inherent flaws of C.
-  Some other projects have successfully gotten completely away from this
-  by declaring all of their strings to be unsigned char, defining a macro
-  like U that casts strings to unsigned char for use with literal strings,
-  and always using unsigned char everywhere.  Unfortunately, this also
-  requires wrappering all of the standard libc string functions, since
-  they're prototyped as taking char rather than unsigned char.  The
-  benefits include cleaner and consistent handling of characters over 127,
-  better warnings from the compiler, consistent behavior across platforms
-  with different notions about the signedness of char, and the elimination
-  of warnings from the <ctype.h> macros on platforms like Solaris where
-  those macros can't handle signed characters.  We should look at doing
-  this for INN.
-
-* It would clean up a lot of code considerably if we could just use mmap
-  semantics regardless of whether the system has mmap.  It may be possible
-  to emulate mmap on systems that don't have it by reading the entirety of
-  the file into memory and setting the flags that require things to call
-  mmap_flush and mmap_invalidate on a regular basis, but it's not clear
-  where to stash the file descriptor that corresponds to the mapped file.
-
-* Figure out some Samba library that we can link against for the Samba
-  authenticator so that we can get all the Samba code back out of INN's
-  source tree; we don't want to maintain it.
-
-* Consider replacing the awkward access: parameter in readers.conf with
-  separate commands (e.g. "allow_newnews: true") or otherwise cleaning up
-  the interaction between access: and read:/post:.  Note that at least
-  allownewnews: can be treated as a setting for overriding inn.conf and
-  should be very easy to add.
-
-* Add a localport: parameter (similar to localaddress:) to readers.conf
-  auth groups.  With those two parameters (and ssl_required:) we
-  essentially eliminate the need to run multiple instances of nnrpd just to
-  use different configurations.
-
-* Various things may break when trying to use data written while compiled
-  with large file support using a server that wasn't so compiled (and vice
-  versa).  The main one is the history file, but tradindexed is also
-  affected and buffindexed has been reported to have problems with this
-  as well.  Ideally, all of INN's data files should be as portable as
-  possible.
-
-
-Complete Code Reorganization
-
-At some point, we should probably abandon and archive the current CVS
-repository, reimport all of the current source files, and start with a
-fresh repository with a better revision control system such as Subversion.
-A better revision control system would let us rename and move things
-around arbitrarily, something CVS doesn't handle at all well.  Should this
-ever be done, we should consider doing all of the following at the same
-time:
-
-* Don't include any generated files in the CVS tree.  Maintainers should
-  have autoconf and friends, pod2text and pod2man, and bison around anyway.
-  This would save a bunch of extra check-ins, remove the danger of the
-  generated files getting out of sync, and drastically reduce the
-  repository size in the case of configure.
-
-* Don't include any of the generated man pages in the CVS tree, as an
-  additional case of the above.  All of the documentation should be in POD
-  and we can generate the man pages as part of the snapshot process.
-
-* storage should be reserved just for article storage; the overview
-  methods should be in a separate overview tree.
-
-* The split between frontends and backends is highly non-intuitive.  Some
-  better organization scheme should be arrived at.  Perhaps something
-  related to incoming and outgoing, with programs like cnfsstat moved into
-  the storage directory with the other storage-related code?
-
-* Add a separate utils directory for things like convdate, shlock,
-  shrinkfile, and the like.  Some of the scripts may possibly want to go
-  into that directory too.
-
-* The lib directory possibly should be split so that it contains only code
-  always compiled and part of INN, and the various replacements for
-  possibly missing system routines are in a separate directory (such as
-  replace).  These should possibly be separate libraries; there are things
-  that currently link against libinn that only need the portability
-  pieces.
-
-* The doc directory really should be broken down further by type of
-  documentation or section or something; it's getting a bit unwieldy.
-
-* Untabify and reformat all of the code according to a consistent coding
-  style which would then be enforced for all future check-ins.
diff --git a/authprogs/Makefile b/authprogs/Makefile
deleted file mode 100644 (file)
index efb2751..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top          = ..
-CFLAGS        = $(GCFLAGS)
-
-ALL           = auth_smb ckpasswd domain ident radius $(KRB5_AUTH)
-
-LIBSMB       = smbval/smbvalid.a
-
-LIBAUTH       = libauth.o
-
-SOURCES       = auth_krb5.c auth_smb.c ckpasswd.c domain.c ident.c libauth.c \
-               radius.c
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       if [ x"$(KRB5_AUTH)" != x ] ; then \
-           $(LI_XPUB) auth_krb5 $(D)$(PATHAUTHPASSWD)/auth_krb5 ; \
-       fi
-       for F in auth_smb ckpasswd radius ; do \
-           $(LI_XPUB) $$F $D$(PATHAUTHPASSWD)/$$F ; \
-       done
-       for F in domain ident ; do \
-           $(LI_XPUB) $$F $D$(PATHAUTHRESOLV)/$$F ; \
-       done
-
-clobber clean distclean:
-       rm -f *.o $(ALL)
-       rm -rf .libs
-       cd smbval && $(MAKE) clean
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES) ../lib/*.c ../include/*.h
-
-profiled:
-       $(MAKEPROFILING) all
-
-
-##  Compilation rules.
-
-LINK           = $(LIBLD) $(LDFLAGS) -o $@
-CKLIBS         = $(CRYPTLIB) $(SHADOWLIB) $(PAMLIB) $(DBMLIB)
-
-auth_krb5: auth_krb5.o $(LIBAUTH) $(LIBINN)
-       $(LINK) auth_krb5.o $(LIBAUTH) $(KRB5LIB) $(LIBINN) $(LIBS)
-
-auth_smb: auth_smb.o $(LIBSMB) $(LIBAUTH) $(LIBINN)
-       $(LINK) auth_smb.o $(LIBSMB) $(LIBAUTH) $(LIBINN) $(LIBS)
-
-ckpasswd: ckpasswd.o $(LIBAUTH) $(LIBINN)
-       $(LINK) ckpasswd.o $(LIBAUTH) $(CKLIBS) $(LIBINN) $(LIBS)
-
-domain: domain.o $(LIBAUTH) $(LIBINN)
-       $(LINK) domain.o $(LIBAUTH) $(LIBINN) $(LIBS)
-
-ident: ident.o $(LIBAUTH) $(LIBINN)
-       $(LINK) ident.o $(LIBAUTH) $(LIBINN) $(LIBS)
-
-radius: radius.o $(LIBAUTH) $(LIBINN)
-       $(LINK) radius.o $(LIBAUTH) $(LIBINN) $(LIBS)
-
-auth_krb5.o: auth_krb5.c
-       $(CC) $(CFLAGS) $(KRB5INC) -c auth_krb5.c
-
-ckpasswd.o: ckpasswd.c
-       $(CC) $(CFLAGS) $(DBMINC) -c ckpasswd.c
-
-$(LIBINN):     ; (cd ../lib ; $(MAKE))
-$(LIBSMB):     ; (cd smbval ; $(MAKE))
-$(LIBAUTH):    libauth.h libauth.c
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend: Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-auth_krb5.o: auth_krb5.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  libauth.h ../include/portable/socket.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h
-auth_smb.o: auth_smb.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h libauth.h \
-  ../include/portable/socket.h ../include/config.h smbval/valid.h
-ckpasswd.o: ckpasswd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/inn/qio.h \
-  ../include/inn/vector.h ../include/libinn.h libauth.h \
-  ../include/portable/socket.h ../include/config.h
-domain.o: domain.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h \
-  libauth.h ../include/portable/socket.h ../include/config.h
-ident.o: ident.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h \
-  libauth.h ../include/portable/socket.h ../include/config.h
-libauth.o: libauth.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h libauth.h ../include/portable/socket.h \
-  ../include/config.h ../include/inn/messages.h ../include/inn/defines.h
-radius.o: radius.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/md5.h ../include/inn/messages.h \
-  ../include/libinn.h ../include/nntp.h ../include/paths.h \
-  ../include/conffile.h libauth.h ../include/portable/socket.h
diff --git a/authprogs/auth_krb5.c b/authprogs/auth_krb5.c
deleted file mode 100644 (file)
index 1088b8b..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*  $Id: auth_krb5.c 7462 2005-12-12 01:06:54Z eagle $
-**
-**  Check an username and password against Kerberos v5.
-**
-**  Based on nnrpkrb5auth by Christopher P. Lindsey <lindsey@mallorn.com>
-**  See <http://www.mallorn.com/tools/nnrpkrb5auth>
-**
-**  This program takes a username and password pair from nnrpd and checks
-**  checks their validity against a Kerberos v5 KDC by attempting to obtain a
-**  TGT.  With the -i <instance> command line option, appends /<instance> to
-**  the username prior to authentication.
-**
-**  Special thanks to Von Welch <vwelch@vwelch.com> for giving me the initial
-**  code on which the Kerberos V authentication is based many years ago, and
-**  for introducing me to Kerberos back in '96.
-**
-**  Also, thanks to Graeme Mathieson <graeme@mathie.cx> for his inspiration
-**  through the pamckpasswd program.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libauth.h"
-#ifdef HAVE_ET_COM_ERR_H
-# include <et/com_err.h>
-#else
-# include <com_err.h>
-#endif
-
-/* krb5_get_in_tkt_with_password is deprecated. */
-#define KRB5_DEPRECATED 1
-#include <krb5.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-/*
- * Default life of the ticket we are getting. Since we are just checking
- * to see if the user can get one, it doesn't need a long lifetime.
- */
-#define KRB5_DEFAULT_LIFE    60 * 5 /* 5 minutes */
-
-
-/*
-**  Check the username and password by attempting to get a TGT.  Returns 1 on
-**  success and 0 on failure.  Errors are reported via com_err.
-*/
-static int
-krb5_check_password (char *principal_name, char *password)
-{
-   krb5_context      kcontext;
-   krb5_creds        creds;
-   krb5_principal    user_principal;
-   krb5_data         *user_realm;
-   krb5_principal    service_principal;
-   krb5_timestamp    now;
-   krb5_address      **addrs = (krb5_address **) NULL;   /* Use default */
-   long              lifetime = KRB5_DEFAULT_LIFE;
-   int               options = 0;
-
-   /* TGT service name for convenience */
-   krb5_data         tgtname = { 0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME };
-
-   krb5_preauthtype  *preauth = NULL;
-
-   krb5_error_code   code;
-
-   /* Our return code - 1 is success */
-   int                result = 0;
-   
-   /* Initialize our Kerberos state */
-   code = krb5_init_context (&kcontext);
-   if (code) {
-       com_err (message_program_name, code, "initializing krb5 context");
-       return 0;
-   }
-   
-#ifdef HAVE_KRB5_INIT_ETS
-   /* Initialize krb5 error tables */    
-   krb5_init_ets (kcontext);
-#endif
-
-   /* Get current time */
-   code = krb5_timeofday (kcontext, &now);
-   if (code) {
-       com_err (message_program_name, code, "getting time of day");
-       return 0;
-   }
-
-   /* Set up credentials to be filled in */
-   memset (&creds, 0, sizeof(creds));
-
-   /* From here on, goto cleanup to exit */
-
-   /* Parse the username into a krb5 principal */
-   if (!principal_name) {
-       com_err (message_program_name, 0, "passed NULL principal name");
-       goto cleanup;
-   }
-
-   code = krb5_parse_name (kcontext, principal_name, &user_principal);
-   if (code) {
-       com_err (message_program_name, code,
-                "parsing user principal name %.100s", principal_name);
-       goto cleanup;
-   }
-
-   creds.client = user_principal;
-
-   /* Get the user's realm for building service principal */
-   user_realm = krb5_princ_realm (kcontext, user_principal);
-   
-   /*
-    * Build the service name into a principal. Right now this is
-    * a TGT for the user's realm.
-    */
-   code = krb5_build_principal_ext (kcontext,
-               &service_principal,
-               user_realm->length,
-               user_realm->data,
-               tgtname.length,
-               tgtname.data,
-               user_realm->length,
-               user_realm->data,
-               0 /* terminator */);
-   if (code) {
-       com_err(message_program_name, code, "building service principal name");
-       goto cleanup;
-   }
-
-   creds.server = service_principal;
-
-   creds.times.starttime = 0;   /* Now */
-   creds.times.endtime = now + lifetime;
-   creds.times.renew_till = 0;   /* Unrenewable */
-
-   /* DO IT */
-   code = krb5_get_in_tkt_with_password (kcontext,
-               options,
-               addrs,
-               NULL,
-               preauth,
-               password,
-               0,
-               &creds,
-               0);
-   
-   /* We are done with password at this point... */
-
-   if (code) {   
-      /* FAILURE - Parse a few common errors here */
-      switch (code) {
-      case KRB5KRB_AP_ERR_BAD_INTEGRITY:
-         com_err (message_program_name, 0, "bad password for %.100s",
-                  principal_name);
-         break;
-      case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
-         com_err (message_program_name, 0, "unknown user \"%.100s\"",
-                  principal_name);
-         break;
-      default:
-         com_err (message_program_name, code,
-                  "checking Kerberos password for %.100s", principal_name);
-      }
-      result = 0;
-   } else {
-      /* SUCCESS */
-      result = 1;
-   }
-   
-   /* Cleanup */
- cleanup:
-   krb5_free_cred_contents (kcontext, &creds);
-
-   return result;
-}
-
-int
-main (int argc, char *argv[])
-{
-    struct auth_info *authinfo;
-    char *new_user;
-
-    message_program_name = "auth_krb5";
-
-    /* Retrieve the username and passwd from nnrpd. */
-    authinfo = get_auth_info(stdin);
-
-    /* Must have a username/password, and no '@' in the address.  @ checking
-      is there to prevent authentication against another Kerberos realm; there
-      should be a -r <realm> commandline option to make this check unnecessary
-      in the future. */
-    if (authinfo == NULL)
-        die("no authentication information from nnrpd");
-    if (authinfo->username[0] == '\0')
-        die("null username");
-    if (strchr(authinfo->username, '@') != NULL)
-        die("username contains @, not allowed");
-
-    /* May need to prepend instance name if -i option was given. */
-    if (argc > 1) {
-        if (argc == 3 && strcmp(argv[1], "-i") == 0) {
-            new_user = concat(authinfo->username, "/", argv[2], (char *) 0);
-            free(authinfo->username);
-            authinfo->username = new_user;
-        } else {
-            die("error parsing command-line options");
-        }
-    }
-
-    if (krb5_check_password(authinfo->username, authinfo->password)) {
-        printf("User:%s\r\n", authinfo->username);
-        exit(0);
-    } else {
-        die("failure validating password");
-    }
-}
diff --git a/authprogs/auth_smb.c b/authprogs/auth_smb.c
deleted file mode 100644 (file)
index 34fcc55..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Samba authenticator.
- * usage: auth_smb <server> [<backup_server>] <domain>
- *
- * Heavily based on:
- * pam_smb -- David Airlie 1998-2000 v1.1.6 <airlied@samba.org>
- * http://www.csn.ul.ie/~airlied
- *
- * Written 2000 October by Krischan Jodies <krischan@jodies.cx>
- * 
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "inn/messages.h"
-
-#include "libauth.h"
-#include "smbval/valid.h"
-
-int
-main(int argc, char *argv[])
-{
-    struct auth_info *authinfo;
-    int result;
-    char *server, *backup, *domain;
-
-    message_program_name = "auth_smb";
-
-    if ((argc > 4) || (argc < 3))
-        die("wrong number of arguments"
-            " (auth_smb <server> [<backup-server>] <domain>");
-
-    authinfo = get_auth_info(stdin);
-    if (authinfo == NULL)
-        die("no user information provided by nnrpd");
-
-    /* Got a username and password.  Now check to see if they're valid. */
-    server = argv[1];
-    backup = (argc > 3) ? argv[2] : argv[1];
-    domain = (argc > 3) ? argv[3] : argv[2];
-    result = Valid_User(authinfo->username, authinfo->password, server,
-                        backup, domain);
-
-    /* Analyze the result. */
-    switch (result) {
-    case NTV_NO_ERROR:
-        printf("User:%s\n", authinfo->username);
-        exit(0);
-        break;
-    case NTV_SERVER_ERROR:
-        die("server error");
-        break;
-    case NTV_PROTOCOL_ERROR:
-        die("protocol error");
-        break;
-    case NTV_LOGON_ERROR:
-        die("logon error");
-        break;
-    default:
-        die("unknown error");
-        break;
-    }
-
-    /* Never reached. */
-    return 1;
-}
diff --git a/authprogs/ckpasswd.c b/authprogs/ckpasswd.c
deleted file mode 100644 (file)
index e8f1db1..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*  $Id: ckpasswd.c 7565 2006-08-28 02:42:54Z eagle $
-**
-**  The default username/password authenticator.
-**
-**  This program is intended to be run by nnrpd and handle usernames and
-**  passwords.  It can authenticate against a regular flat file (the type
-**  managed by htpasswd), a DBM file, the system password file or shadow file,
-**  or PAM.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "inn/vector.h"
-#include "libinn.h"
-
-#include "libauth.h"
-
-#if HAVE_CRYPT_H
-# include <crypt.h>
-#endif
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-
-#if defined(HAVE_DBM) || defined(HAVE_BDB_DBM)
-# if HAVE_NDBM_H
-#  include <ndbm.h>
-# elif HAVE_BDB_DBM
-#  define DB_DBM_HSEARCH 1
-#  include <db.h>
-# elif HAVE_GDBM_NDBM_H
-#  include <gdbm-ndbm.h>
-# elif HAVE_DB1_NDBM_H
-#  include <db1/ndbm.h>
-# endif
-# define OPT_DBM "d:"
-#else
-# define OPT_DBM ""
-#endif
-
-#if HAVE_GETSPNAM
-# include <shadow.h>
-# define OPT_SHADOW "s"
-#else
-# define OPT_SHADOW ""
-#endif
-
-#if HAVE_PAM
-# if HAVE_PAM_PAM_APPL_H
-#  include <pam/pam_appl.h>
-# else
-#  include <security/pam_appl.h>
-# endif
-#endif
-
-
-/*
-**  The PAM conversation function.
-**
-**  Since we already have all the information and can't ask the user
-**  questions, we can't quite follow the real PAM protocol.  Instead, we just
-**  return the password in response to every question that PAM asks.  There
-**  appears to be no generic way to determine whether the message in question
-**  is indeed asking for the password....
-**
-**  This function allocates an array of struct pam_response to return to the
-**  PAM libraries that's never freed.  For this program, this isn't much of an
-**  issue, since it will likely only be called once and then the program will
-**  exit.  This function uses malloc and strdup instead of xmalloc and xstrdup
-**  intentionally so that the PAM conversation will be closed cleanly if we
-**  run out of memory rather than simply terminated.
-**
-**  appdata_ptr contains the password we were given.
-*/
-#if HAVE_PAM
-static int
-pass_conv(int num_msg, const struct pam_message **msgm UNUSED,
-          struct pam_response **response, void *appdata_ptr)
-{
-    int i;
-
-    *response = malloc(num_msg * sizeof(struct pam_response));
-    if (*response == NULL)
-        return PAM_CONV_ERR;
-    for (i = 0; i < num_msg; i++) {
-        (*response)[i].resp = strdup((char *)appdata_ptr);
-        (*response)[i].resp_retcode = 0;
-    }
-    return PAM_SUCCESS;
-}
-#endif /* HAVE_PAM */
-
-
-/*
-**  Authenticate a user via PAM.
-**
-**  Attempts to authenticate a user with PAM, returning true if the user
-**  successfully authenticates and false otherwise.  Note that this function
-**  doesn't attempt to handle any remapping of the authenticated user by the
-**  PAM stack, but just assumes that the authenticated user was the same as
-**  the username given.
-**
-**  Right now, all failures are handled via die.  This may be worth revisiting
-**  in case we want to try other authentication methods if this fails for a
-**  reason other than the system not having PAM support.
-*/
-#if !HAVE_PAM
-static bool
-auth_pam(char *username UNUSED, char *password UNUSED)
-{
-    return false;
-}
-#else
-static bool
-auth_pam(const char *username, char *password)
-{
-    pam_handle_t *pamh;
-    struct pam_conv conv;
-    int status;
-
-    conv.conv = pass_conv;
-    conv.appdata_ptr = password;
-    status = pam_start("nnrpd", username, &conv, &pamh);
-    if (status != PAM_SUCCESS)
-        die("pam_start failed: %s", pam_strerror(pamh, status));
-    status = pam_authenticate(pamh, PAM_SILENT);
-    if (status != PAM_SUCCESS)
-        die("pam_authenticate failed: %s", pam_strerror(pamh, status));
-    status = pam_acct_mgmt(pamh, PAM_SILENT);
-    if (status != PAM_SUCCESS)
-        die("pam_acct_mgmt failed: %s", pam_strerror(pamh, status));
-    status = pam_end(pamh, status);
-    if (status != PAM_SUCCESS)
-        die("pam_end failed: %s", pam_strerror(pamh, status));
-
-    /* If we get to here, the user successfully authenticated. */
-    return true;
-}
-#endif /* HAVE_PAM */
-
-
-/*
-**  Try to get a password out of a dbm file.  The dbm file should have the
-**  username for the key and the crypted password as the value.  The crypted
-**  password, if found, is returned as a newly allocated string; otherwise,
-**  NULL is returned.
-*/
-#if !(defined(HAVE_DBM) || defined(HAVE_BDB_DBM))
-static char *
-password_dbm(char *user UNUSED, const char *file UNUSED)
-{
-    return NULL;
-}
-#else
-static char *
-password_dbm(char *name, const char *file)
-{
-    datum key, value;
-    DBM *database;
-    char *password;
-
-    database = dbm_open(file, O_RDONLY, 0600);
-    if (database == NULL)
-        return NULL;
-    key.dptr = name;
-    key.dsize = strlen(name);
-    value = dbm_fetch(database, key);
-    if (value.dptr == NULL) {
-        dbm_close(database);
-        return NULL;
-    }
-    password = xmalloc(value.dsize + 1);
-    strlcpy(password, value.dptr, value.dsize + 1);
-    dbm_close(database);
-    return password;
-}
-#endif /* HAVE_DBM || HAVE_BDB_DBM */
-
-
-/*
-**  Try to get a password out of the system /etc/shadow file.  The crypted
-**  password, if found, is returned as a newly allocated string; otherwise,
-**  NULL is returned.
-*/
-#if !HAVE_GETSPNAM
-static char *
-password_shadow(const char *user UNUSED)
-{
-    return NULL;
-}
-#else
-static char *
-password_shadow(const char *user)
-{
-    struct spwd *spwd;
-
-    spwd = getspnam(user);
-    if (spwd != NULL)
-        return xstrdup(spwd->sp_pwdp);
-    return NULL;
-}
-#endif /* HAVE_GETSPNAM */
-
-
-/*
-**  Try to get a password out of a file.  The crypted password, if found, is
-**  returned as a newly allocated string; otherwise, NULL is returned.
-*/
-static char *
-password_file(const char *username, const char *file)
-{
-    QIOSTATE *qp;
-    char *line, *password;
-    struct cvector *info = NULL;
-
-    qp = QIOopen(file);
-    if (qp == NULL)
-        return NULL;
-    for (line = QIOread(qp); line != NULL; line = QIOread(qp)) {
-        if (*line == '#' || *line == '\n')
-            continue;
-        info = cvector_split(line, ':', info);
-        if (info->count < 2 || strcmp(info->strings[0], username) != 0)
-            continue;
-        password = xstrdup(info->strings[1]);
-        QIOclose(qp);
-        cvector_free(info);
-        return password;
-    }
-    if (QIOtoolong(qp))
-        die("line too long in %s", file);
-    if (QIOerror(qp))
-        sysdie("error reading %s", file);
-    QIOclose(qp);
-    cvector_free(info);
-    return NULL;
-}
-
-
-/*
-**  Try to get a password out of the system password file.  The crypted
-**  password, if found, is returned as a newly allocated string; otherwise,
-**  NULL is returned.
-*/
-static char *
-password_system(const char *username)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(username);
-    if (pwd != NULL)
-        return xstrdup(pwd->pw_passwd);
-    return NULL;
-}
-
-
-/*
-**  Try to get the name of a user's primary group out of the system group 
-**  file.  The group, if found, is returned as a newly allocated string;
-**  otherwise, NULL is returned.  If the username is not found, NULL is
-**  returned.
-*/
-static char *
-group_system(const char *username)
-{
-    struct passwd *pwd;
-    struct group *gr;
-
-    pwd = getpwnam(username);
-    if (pwd == NULL)
-        return NULL;
-    gr = getgrgid(pwd->pw_gid);
-    if (gr == NULL)
-        return NULL;
-    return xstrdup(gr->gr_name);
-}
-
-
-/*
-**  Output username (and group, if desired) in correct return format.
-*/
-static void
-output_user(const char *username, bool wantgroup)
-{
-    if (wantgroup) {
-        char *group = group_system(username);
-        if (group == NULL)
-            die("group info for user %s not available", username);
-        printf("User:%s@%s\n", username, group);
-    }
-    else
-        printf("User:%s\n", username);
-}
-
-
-/*
-**  Main routine.
-**
-**  We handle the variences between systems with #if blocks above, so that
-**  this code can look fairly clean.
-*/
-int
-main(int argc, char *argv[])
-{
-    enum authtype { AUTH_NONE, AUTH_SHADOW, AUTH_FILE, AUTH_DBM };
-
-    int opt;
-    enum authtype type = AUTH_NONE;
-    bool wantgroup = false;
-    const char *filename = NULL;
-    struct auth_info *authinfo = NULL;
-    char *password = NULL;
-
-    message_program_name = "ckpasswd";
-
-    while ((opt = getopt(argc, argv, "gf:u:p:" OPT_DBM OPT_SHADOW)) != -1) {
-        switch (opt) {
-        case 'g':
-            if (type == AUTH_DBM || type == AUTH_FILE)
-                die("-g option is incompatible with -d or -f");
-            wantgroup = true;
-            break;
-        case 'd':
-            if (type != AUTH_NONE)
-                die("only one of -s, -f, or -d allowed");
-            if (wantgroup)
-                die("-g option is incompatible with -d or -f");
-            type = AUTH_DBM;
-            filename = optarg;
-            break;
-        case 'f':
-            if (type != AUTH_NONE)
-                die("only one of -s, -f, or -d allowed");
-            if (wantgroup)
-                die("-g option is incompatible with -d or -f");
-            type = AUTH_FILE;
-            filename = optarg;
-            break;
-        case 's':
-            if (type != AUTH_NONE)
-                die("only one of -s, -f, or -d allowed");
-            type = AUTH_SHADOW;
-            break;
-        case 'u':
-            if (authinfo == NULL) {
-                authinfo = xmalloc(sizeof(struct auth_info));
-                authinfo->password = NULL;
-            }
-            authinfo->username = optarg;
-            break;
-        case 'p':
-            if (authinfo == NULL) {
-                authinfo = xmalloc(sizeof(struct auth_info));
-                authinfo->username = NULL;
-            }
-            authinfo->password = optarg;
-            break;
-        default:
-            exit(1);
-        }
-    }
-    if (argc != optind)
-       die("extra arguments given");
-    if (authinfo != NULL && authinfo->username == NULL)
-        die("-u option is required if -p option is given");
-    if (authinfo != NULL && authinfo->password == NULL)
-        die("-p option is required if -u option is given");
-
-    /* Unless a username or password was given on the command line, assume
-       we're being run by nnrpd. */
-    if (authinfo == NULL)
-        authinfo = get_auth_info(stdin);
-    if (authinfo == NULL)
-        die("no authentication information from nnrpd");
-    if (authinfo->username[0] == '\0')
-        die("null username");
-
-    /* Run the appropriate authentication routines. */
-    switch (type) {
-    case AUTH_SHADOW:
-        password = password_shadow(authinfo->username);
-        if (password == NULL)
-            password = password_system(authinfo->username);
-        break;
-    case AUTH_FILE:
-        password = password_file(authinfo->username, filename);
-        break;
-    case AUTH_DBM:
-        password = password_dbm(authinfo->username, filename);
-        break;
-    case AUTH_NONE:
-        if (auth_pam(authinfo->username, authinfo->password)) {
-            output_user(authinfo->username, wantgroup);
-            exit(0);
-        }
-        password = password_system(authinfo->username);
-        break;
-    }
-
-    if (password == NULL)
-        die("user %s unknown", authinfo->username);
-    if (strcmp(password, crypt(authinfo->password, password)) != 0)
-        die("invalid password for user %s", authinfo->username);
-
-    /* The password matched. */
-    output_user(authinfo->username, wantgroup);
-    exit(0);
-}
diff --git a/authprogs/domain.c b/authprogs/domain.c
deleted file mode 100644 (file)
index e4e0f4f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*  $Id: domain.c 7141 2005-03-17 11:42:46Z vinocur $
-**
-**  Domain authenticator.
-**
-**  Compares the domain of the client connection to the first argument given
-**  on the command line, and returns the host portion of the connecting host
-**  as the user if it matches.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "libauth.h"
-
-int
-main(int argc, char *argv[])
-{
-    char *p, *host;
-    struct res_info *res;
-
-    if (argc != 2)
-        die("Usage: domain <domain>");
-    message_program_name = "domain";
-
-    /* Read the connection information from stdin. */
-    res = get_res_info(stdin);
-    if (res == NULL)
-        die("did not get ClientHost data from nnrpd");
-    host = res->clienthostname;
-
-    /* Check the host against the provided domain.  Allow the domain to be
-       specified both with and without a leading period; if without, make sure
-       that there is a period right before where it matches in the host. */
-    p = strstr(host, argv[1]);
-    if (p == host)
-        die("host %s matches the domain exactly", host);
-    if (p == NULL || (argv[1][0] != '.' && p != host && *(p - 1) != '.'))
-        die("host %s didn't match domain %s", host, argv[1]);
-
-    /* Peel off the portion of the host before where the provided domain
-       matches and return it as the user. */
-    if (argv[1][0] != '.')
-        p--;
-    *p = '\0';
-    printf("User:%s\n", host);
-    return 0;
-}
diff --git a/authprogs/ident.c b/authprogs/ident.c
deleted file mode 100644 (file)
index ac728e1..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*  $Id: ident.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Ident authenticator.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <netdb.h>
-#include <signal.h>
-#include <syslog.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "libauth.h"
-
-#define IDENT_PORT 113
-
-static void out(int sig UNUSED) {
-    exit(1);
-}
-
-int main(int argc, char *argv[])
-{
-    struct servent *s;
-    char buf[2048];
-    struct res_info *res;
-    struct sockaddr_in *lsin, *csin;
-#ifdef HAVE_INET6
-    struct sockaddr_storage *lss;
-    struct sockaddr_in6 *lsin6, *csin6;
-#endif
-    int sock;
-    int opt;
-    int truncate_domain = 0;
-    char *iter;
-    char *p;
-    unsigned int got;
-    int lport, cport, identport;
-    char *endstr;
-
-    message_program_name = "ident";
-
-    xsignal_norestart(SIGALRM,out);
-    alarm(15);
-
-    s = getservbyname("ident", "tcp");
-    if (!s)
-       identport = IDENT_PORT;
-    else
-       identport = ntohs(s->s_port);
-
-    while ((opt = getopt(argc, argv, "p:t")) != -1) {
-       switch (opt) {
-         case 'p':
-           for (iter = optarg; *iter; iter++)
-               if (*iter < '0' || *iter > '9')
-                   break;
-           if (*iter) {
-               /* not entirely numeric */
-                s = getservbyname(optarg, "tcp");
-                if (s == NULL)
-                    die("cannot getsrvbyname(%s, tcp)", optarg);
-               identport = s->s_port;
-           } else
-               identport = atoi(optarg);
-           break;
-       case 't':
-           truncate_domain = 1;
-           break;
-       }
-    }
-
-    /* read the connection info from stdin */
-    res = get_res_info(stdin);
-    if (res == NULL)
-        die("did not get client information from nnrpd");
-
-#ifdef HAVE_INET6
-    lss = (struct sockaddr_storage *)(res->local);
-    lsin6 = (struct sockaddr_in6 *)(res->local);
-    csin6 = (struct sockaddr_in6 *)(res->client);
-    if( lss->ss_family == AF_INET6 )
-    {
-       lport = ntohs( lsin6->sin6_port );
-       lsin6->sin6_port = 0;
-       cport = ntohs( csin6->sin6_port );
-       csin6->sin6_port = htons( identport );
-       sock = socket(PF_INET6, SOCK_STREAM, 0);
-    } else
-#endif
-    {
-       lsin = (struct sockaddr_in *)(res->local);
-       lport = htons( lsin->sin_port );
-       lsin->sin_port = 0;
-       csin = (struct sockaddr_in *)(res->client);
-       cport = htons( csin->sin_port );
-       csin->sin_port = htons( identport );
-       sock = socket(PF_INET, SOCK_STREAM, 0);
-    }
-    if (sock < 0)
-        sysdie("cannot create socket");
-    if (bind(sock, res->local, SA_LEN(res->local)) < 0)
-        sysdie("cannot bind socket");
-    if (connect(sock, res->client, SA_LEN(res->local)) < 0) {
-        if (errno != ECONNREFUSED)
-            sysdie("cannot connect to ident server");
-        else
-            sysdie("client host does not accept ident connections");
-    }
-    free_res_info(res);
-
-    /* send the request out */
-    snprintf(buf, sizeof(buf), "%d , %d\r\n", cport, lport);
-    opt = xwrite(sock, buf, strlen(buf));
-    if (opt < 0)
-        sysdie("cannot write to ident server");
-
-    /* get the answer back */
-    got = 0;
-    do {
-       opt = read(sock, buf+got, sizeof(buf)-got);
-       if (opt < 0)
-            sysdie("cannot read from ident server");
-       else if (!opt)
-           die("end of file from ident server before response");
-       while (opt--)
-           if (buf[got] != '\n')
-               got++;
-    } while (buf[got] != '\n');
-    buf[got] = '\0';
-    if (buf[got-1] == '\r')
-       buf[got-1] = '\0';
-
-    /* buf now contains the entire ident response. */
-    if (!(iter = strchr(buf, ':')))
-       /* malformed response */
-        die("malformed response \"%s\" from ident server", buf);
-    iter++;
-
-    while (*iter && ISWHITE(*iter))
-       iter++;
-    endstr = iter;
-    while (*endstr && *endstr != ':' && !ISWHITE(*endstr))
-       endstr++;
-    if (!*endstr)
-       /* malformed response */
-        die("malformed response \"%s\" from ident server", buf);
-    if (*endstr != ':') {
-       *endstr++ = '\0';
-       while (*endstr != ':')
-           endstr++;
-    }
-
-    *endstr = '\0';
-
-    if (strcmp(iter, "ERROR") == 0)
-        die("ident server reported an error");
-    else if (strcmp(iter, "USERID") != 0)
-        die("ident server returned \"%s\", not USERID", iter);
-
-    /* skip the operating system */
-    if (!(iter = strchr(endstr+1, ':')))
-       exit(1);
-
-    /* everything else is username */
-    iter++;
-    while (*iter && ISWHITE(*iter))
-       iter++;
-    if (!*iter || *iter == '[')
-       /* null, or encrypted response */
-        die("ident response is null or encrypted");
-    if ((truncate_domain == 1) && ((p = strchr(iter, '@')) != NULL))
-       *p = '\0';
-    printf("User:%s\n", iter);
-
-    exit(0);
-}
diff --git a/authprogs/libauth.c b/authprogs/libauth.c
deleted file mode 100644 (file)
index c99dcd9..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*  $Id: libauth.c 7500 2006-03-20 01:52:44Z eagle $
-**
-**  Common code for authenticators and resolvers.
-**
-**  Collects common code to read information from nnrpd that should be done
-**  the same for all authenticators, and common code to get information about
-**  the incoming connection.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-
-#include "libauth.h"
-#include "inn/messages.h"
-
-#define NAMESTR "ClientAuthname: "
-#define PASSSTR "ClientPassword: "
-
-#define CLIHOST "ClientHost: "
-#define CLIIP "ClientIP: "
-#define CLIPORT "ClientPort: "
-#define LOCIP "LocalIP: "
-#define LOCPORT "LocalPort: "
-
-#ifdef HAVE_INET6
-# include <netdb.h>
-#endif
-
-/* Main loop.  If res != NULL, expects to get resolver info from nnrpd, and
-   writes it into the struct.  If auth != NULL, expects to get authentication
-   info from nnrpd, and writes it into the struct. */
-
-static bool
-get_connection_info(FILE *stream, struct res_info *res, struct auth_info *auth)
-{
-    char buff[SMBUF];
-    size_t length;
-    char *cip = NULL, *sip = NULL, *cport = NULL, *sport = NULL;
-#ifdef HAVE_INET6
-    struct addrinfo *r, hints;
-#else
-    struct sockaddr_in *loc_sin, *cli_sin;
-#endif
-
-    /* Zero fields first (anything remaining NULL after is missing data) */
-    if (res != NULL) {
-        res->clienthostname = NULL;
-        res->client = NULL;
-        res->local = NULL;
-    }
-    if (auth != NULL) {
-        auth->username = NULL;
-        auth->password = NULL;
-    }
-
-    /* Read input from nnrpd a line at a time, stripping \r\n. */
-    while (fgets(buff, sizeof(buff), stream) != NULL) {
-        length = strlen(buff);
-        if (length == 0 || buff[length - 1] != '\n')
-            goto error;
-        buff[length - 1] = '\0';
-        if (length > 1 && buff[length - 2] == '\r')
-            buff[length - 2] = '\0';
-
-        /* Parse */
-        if (strncmp(buff, ".", 2) == 0)
-            break;
-        else if (auth != NULL && strncmp(buff, NAMESTR, strlen(NAMESTR)) == 0)
-            auth->username = xstrdup(buff + strlen(NAMESTR));
-        else if (auth != NULL && strncmp(buff, PASSSTR, strlen(PASSSTR)) == 0)
-            auth->password = xstrdup(buff + strlen(PASSSTR));
-        else if (res != NULL && strncmp(buff, CLIHOST, strlen(CLIHOST)) == 0)
-            res->clienthostname = xstrdup(buff + strlen(CLIHOST));
-        else if (res != NULL && strncmp(buff, CLIIP, strlen(CLIIP)) == 0)
-            cip = xstrdup(buff + strlen(CLIIP));
-        else if (res != NULL && strncmp(buff, CLIPORT, strlen(CLIPORT)) == 0)
-            cport = xstrdup(buff + strlen(CLIPORT));
-        else if (res != NULL && strncmp(buff, LOCIP, strlen(LOCIP)) == 0)
-            sip = xstrdup(buff + strlen(LOCIP));
-        else if (res != NULL && strncmp(buff, LOCPORT, strlen(LOCPORT)) == 0)
-            sport = xstrdup(buff + strlen(LOCPORT));
-        else {
-            /**** We just ignore excess fields for now ****/
-
-            /* warn("libauth: unexpected data from nnrpd: \"%s\"", buff); */
-            /* goto error; */
-        }
-    }
-
-    /* If some field is missing, free the rest and error out. */
-    if (auth != NULL && (auth->username == NULL || auth->password == NULL)) {
-        warn("libauth: requested authenticator data not sent by nnrpd");
-        goto error;
-    }
-    if (res != NULL && (res->clienthostname == NULL || cip == NULL ||
-                cport == NULL || sip == NULL || sport == NULL)) {
-        warn("libauth: requested resolver data not sent by nnrpd");
-        goto error;
-    }
-
-    /* Generate sockaddrs from IP and port strings */
-    if (res != NULL) {
-#ifdef HAVE_INET6
-        /* sockaddr_in6 may be overkill for PF_INET case, but oh well */
-        res->client = xcalloc(1, sizeof(struct sockaddr_in6));
-        res->local = xcalloc(1, sizeof(struct sockaddr_in6));
-
-        memset( &hints, 0, sizeof( hints ) );
-        hints.ai_flags = AI_NUMERICHOST;
-        hints.ai_socktype = SOCK_STREAM;
-
-        hints.ai_family = strchr( cip, ':' ) != NULL ? PF_INET6 : PF_INET;
-        if( getaddrinfo( cip, cport, &hints, &r ) != 0)
-            goto error;
-        if( r->ai_addrlen > sizeof(struct sockaddr_in6) )
-            goto error;
-        memcpy( res->client, r->ai_addr, r->ai_addrlen );
-        freeaddrinfo( r );
-
-        hints.ai_family = strchr( sip, ':' ) != NULL ? PF_INET6 : PF_INET;
-        if( getaddrinfo( sip, sport, &hints, &r ) != 0)
-            goto error;
-        if( r->ai_addrlen > sizeof(struct sockaddr_in6) )
-            goto error;
-        memcpy( res->local, r->ai_addr, r->ai_addrlen );
-        freeaddrinfo( r );
-#else
-        res->client = xcalloc(1, sizeof(struct sockaddr_in));
-        res->local = xcalloc(1, sizeof(struct sockaddr_in));
-
-        cli_sin = (struct sockaddr_in *)(res->client);
-        loc_sin = (struct sockaddr_in *)(res->local);
-        cli_sin->sin_family = AF_INET;
-        if (!inet_aton(cip, &cli_sin->sin_addr))
-            goto error;
-        cli_sin->sin_port = htons( atoi(cport) );
-
-        loc_sin->sin_family = AF_INET;
-        if (!inet_aton(sip, &loc_sin->sin_addr))
-            goto error;
-        loc_sin->sin_port = htons( atoi(sport) );
-
-# ifdef HAVE_SOCKADDR_LEN
-        cli_sin->sin_len = sizeof(struct sockaddr_in);
-        loc_sin->sin_len = sizeof(struct sockaddr_in);
-# endif
-#endif
-
-        free(sip);
-        free(sport);
-        free(cip);
-        free(cport);
-    }
-
-    return true;
-
-error:
-    if (auth != NULL && auth->username != NULL)     free(auth->username);
-    if (auth != NULL && auth->password != NULL)     free(auth->password);
-    if (res != NULL && res->clienthostname != NULL) free(res->clienthostname);
-    if (res != NULL && res->client != NULL)         free(res->client);
-    if (res != NULL && res->local != NULL)          free(res->local);
-    if (sip != NULL)                                free(sip);
-    if (sport != NULL)                              free(sport);
-    if (cip != NULL)                                free(cip);
-    if (cport != NULL)                              free(cport);
-    return false;
-}
-
-
-/* Wrappers to read information from nnrpd, returning an allocated struct on
-   success. */
-
-struct res_info *
-get_res_info(FILE *stream) {
-    struct res_info *res = xmalloc(sizeof(struct res_info));
-
-    if(get_connection_info(stream, res, NULL))
-        return res;
-
-    free(res);
-    return NULL;
-}
-
-
-struct auth_info *
-get_auth_info(FILE *stream) {
-    struct auth_info *auth = xmalloc(sizeof(struct auth_info));
-
-    if(get_connection_info(stream, NULL, auth))
-        return auth;
-
-    free(auth);
-    return NULL;
-}
-
-void
-free_res_info(struct res_info *res) {
-    if(res == NULL)
-        return;
-    if(res->client != NULL)             free(res->client);
-    if(res->local != NULL)              free(res->local);
-    if(res->clienthostname != NULL)     free(res->clienthostname);
-    free(res);
-}
-
-void
-free_auth_info(struct auth_info *auth) {
-    if(auth == NULL)
-        return;
-    if(auth->username != NULL)          free(auth->username);
-    if(auth->password != NULL)          free(auth->password);
-    free(auth);
-}
-
diff --git a/authprogs/libauth.h b/authprogs/libauth.h
deleted file mode 100644 (file)
index faa6520..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-**
-**  Common headers for authenticators and resolvers.
-**
-*/
-
-#include "config.h"
-#include "portable/socket.h"
-
-/* Holds the resolver information from nnrpd. */
-struct res_info {
-    struct sockaddr *client;
-    struct sockaddr *local;
-    char *clienthostname;
-};
-
-/* Holds the authentication information from nnrpd. */
-struct auth_info {
-    char *username;
-    char *password;
-};
-
-/*
- * Reads connection information from a file descriptor (normally stdin, when
- * talking to nnrpd) and returns a new res_info or auth_info struct, or
- * returns NULL on failure.  Note that the fields will never be NULL; if the
- * corresponding information is missing, it is an error (which will be
- * logged and NULL will be returned).  The client is responsible for freeing
- * the struct and its fields; this can be done by calling the appropriate
- * destruction function below.
- */
-
-extern struct auth_info *get_auth_info(FILE *);
-extern struct res_info  *get_res_info (FILE *);
-
-extern void free_auth_info(struct auth_info*);
-extern void free_res_info (struct res_info*);
-
-
diff --git a/authprogs/radius.c b/authprogs/radius.c
deleted file mode 100644 (file)
index e6da348..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
-/*  $Id: radius.c 7745 2008-04-06 10:18:54Z iulius $
-**
-**  Authenticate a user against a remote radius server.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <signal.h>
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#if HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/md5.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-#include "conffile.h"
-
-#include "libauth.h"
-
-#define RADIUS_LOCAL_PORT       NNTP_PORT
-
-#define AUTH_VECTOR_LEN 16
-
-typedef struct _auth_req {
-    unsigned char      code;
-    unsigned char      id;
-    unsigned short     length;
-    unsigned char      vector[AUTH_VECTOR_LEN];
-    unsigned char      data[NNTP_STRLEN*2];
-    int                        datalen;
-} auth_req;
-
-typedef struct _rad_config_t {
-    char *secret;      /* pseudo encryption thingy secret that radius uses */
-
-    char *radhost;     /* parameters for talking to the remote radius sever */
-    int radport;
-    char *lochost;
-    int locport;
-
-    char *prefix, *suffix;     /* futz with the username, if necessary */
-    int ignore_source;
-
-    struct _rad_config_t *next;  /* point to any additional servers */
-} rad_config_t;
-  
-typedef struct _sending_t {
-    auth_req req;
-    int reqlen;
-    struct sockaddr_in sinr;
-    struct _sending_t *next;
-} sending_t;
-
-#define RADlbrace  1
-#define RADrbrace  2
-#define RADserver  10
-#define RADhost    11
-#define RADsecret  12
-#define RADport    13
-#define RADlochost 14
-#define RADlocport 15
-#define RADprefix  16
-#define RADsuffix  17
-#define RADsource  18
-
-static CONFTOKEN radtoks[] = {
-  { RADlbrace,   "{" },
-  { RADrbrace,   "}" },
-  { RADserver,   "server" },
-  { RADhost,     "radhost:" },
-  { RADsecret,   "secret:" },
-  { RADport,     "radport:" },
-  { RADlochost,  "lochost:" },
-  { RADlocport,  "locport:" },
-  { RADprefix,   "prefix:" },
-  { RADsuffix,   "suffix:" },
-  { RADsource,   "ignore-source:" },
-  { 0, 0 }
-};
-
-static rad_config_t *get_radconf(void)
-{
-  rad_config_t *new;
-
-  new = xcalloc(1, sizeof(rad_config_t));
-  new->next = NULL;
-
-  return new;
-}
-
-static int read_config(char *authfile, rad_config_t *radconf)
-{
-    int inbrace;
-    rad_config_t *radconfig=NULL;
-    CONFFILE *file;
-    CONFTOKEN *token;
-    char *server;
-    int type;
-    char *iter;
-
-    if ((file = CONFfopen(authfile)) == NULL)
-      sysdie("cannot open config file %s", authfile);
-
-    inbrace = 0;
-    while ((token = CONFgettoken(radtoks, file)) != NULL) {
-      if (!inbrace) {
-       if (token->type != RADserver)
-          die("expected server keyword on line %d", file->lineno);
-       if ((token = CONFgettoken(0, file)) == NULL)
-          die("expected server name on line %d", file->lineno);
-       server = xstrdup(token->name);
-       if ((token = CONFgettoken(radtoks, file)) == NULL 
-           || token->type != RADlbrace)
-          die("expected { on line %d", file->lineno);
-       inbrace = 1;
-
-       if (radconfig == NULL)
-         radconfig = radconf;
-       else {
-         radconfig->next = get_radconf();
-         radconfig = radconfig->next;
-       }
-      }
-      else {
-       type = token->type;
-       if (type == RADrbrace)
-         inbrace = 0;
-       else {
-         if ((token = CONFgettoken(0, file)) == NULL)
-            die("keyword with no value on line %d", file->lineno);
-         iter = token->name;
-
-         /* what are we setting? */
-         switch(type) {
-         case RADsecret:
-           if (radconfig->secret) continue;
-           radconfig->secret = xstrdup(iter);
-           break;
-         case RADhost:
-           if (radconfig->radhost) continue;
-           radconfig->radhost = xstrdup(iter);
-           break;
-         case RADport:
-           if (radconfig->radport) continue;
-           radconfig->radport = atoi(iter);
-           break;
-         case RADlochost:
-           if (radconfig->lochost) continue;
-           radconfig->lochost = xstrdup(iter);
-           break;
-         case RADlocport:
-           if (radconfig->locport) continue;
-           radconfig->locport = atoi(iter);
-           break;
-         case RADprefix:
-           if (radconfig->prefix) continue;
-           radconfig->prefix = xstrdup(iter);
-           break;
-         case RADsuffix:
-           if (radconfig->suffix) continue;
-           radconfig->suffix = xstrdup(iter);
-           break;
-         case RADsource:
-           if (!strcasecmp(iter, "true"))
-               radconfig->ignore_source = 1;
-           else if (!strcasecmp(iter, "false"))
-               radconfig->ignore_source = 0;
-           else
-                die("expected true or false after ignore-source on line %d",
-                    file->lineno);
-           break;
-         default:
-            die("unknown keyword on line %d", file->lineno);
-         }
-       }
-      }
-    }
-
-    CONFfclose(file);
-
-    if (!radconf->radhost)
-        die("no radius host specified");
-    else if (!radconf->secret)
-        die("no shared secret with radius host specified");
-
-    return(0);
-}
-
-#define PW_AUTH_UDP_PORT 1645
-
-#define PW_AUTHENTICATION_REQUEST 1
-#define PW_AUTHENTICATION_ACK     2
-#define PW_AUTHENTICATION_REJECT  3
-
-#define PW_USER_NAME            1
-#define PW_PASSWORD             2
-
-#define PW_SERVICE_TYPE         6
-#define PW_SERVICE_AUTH_ONLY    8
-
-#define RAD_NAS_IP_ADDRESS      4       /* IP address */
-#define RAD_NAS_PORT            5       /* Integer */
-
-static void req_copyto (auth_req to, sending_t *from)
-{
-    to = from->req;
-}
-
-static void req_copyfrom (sending_t *to, auth_req from)
-{
-    to->req = from;
-}
-
-static int rad_auth(rad_config_t *radconfig, char *uname, char *pass)
-{
-    auth_req req;
-    int i, j, jlen, passstart;
-    unsigned char secbuf[128];
-    char hostname[SMBUF];
-    unsigned char digest[MD5_DIGESTSIZE];
-    struct timeval seed;
-    struct sockaddr_in sinl;
-    int sock;
-    struct hostent *hent;
-    int passlen;
-    time_t now, end;
-    struct timeval tmout;
-    int got;
-    fd_set rdfds;
-    uint32_t nvalue;
-    socklen_t slen;
-    int authtries= 3; /* number of times to try reaching the radius server */
-    rad_config_t *config;
-    sending_t *reqtop, *sreq, *new;
-    int done;
-
-    /* set up the linked list */
-    config = radconfig;
-
-    if (config == NULL) {
-      warn("no configuration file");
-      return(-2);
-    } else {
-      /* setting sreq to NULL guarantees reqtop will be properly set later */
-      sreq = NULL;
-      reqtop = NULL;
-    }
-
-    while (config != NULL){
-      new = xmalloc(sizeof(sending_t));
-      new->next = NULL;
-
-      if (sreq == NULL){
-       reqtop = new;
-       sreq = new;
-      } else {
-       sreq->next = new;
-       sreq = sreq->next;
-      }
-      req_copyto(req, sreq);
-  
-      /* first, build the sockaddrs */
-      memset(&sinl, '\0', sizeof(sinl));
-      memset(&sreq->sinr, '\0', sizeof(sreq->sinr));
-      sinl.sin_family = AF_INET;
-      sreq->sinr.sin_family = AF_INET;
-      if (config->lochost == NULL) {
-        if (gethostname(hostname, sizeof(hostname)) != 0) {
-          syswarn("cannot get local hostname");
-          return(-2);
-        }
-       config->lochost = xstrdup(hostname);
-      }
-      if (config->lochost) {
-       if (inet_aton(config->lochost, &sinl.sin_addr) != 1) {
-          if ((hent = gethostbyname(config->lochost)) == NULL) {
-            warn("cannot gethostbyname lochost %s", config->lochost);
-            return(-2);
-          }
-          memcpy(&sinl.sin_addr.s_addr, hent->h_addr,
-                 sizeof(struct in_addr));
-       }
-      }
-      if (inet_aton(config->radhost, &sreq->sinr.sin_addr) != 1) {
-        if ((hent = gethostbyname(config->radhost)) == NULL) {
-          warn("cannot gethostbyname radhost %s", config->radhost);
-          return(-2);
-        }
-       memcpy(&sreq->sinr.sin_addr.s_addr, hent->h_addr_list[0],
-               sizeof(struct in_addr));
-      }
-
-      if (config->radport)
-        sreq->sinr.sin_port = htons(config->radport);
-      else
-       sreq->sinr.sin_port = htons(PW_AUTH_UDP_PORT);
-
-      /* seed the random number generator for the auth vector */
-      gettimeofday(&seed, 0);
-      srandom((unsigned) seed.tv_sec+seed.tv_usec);
-      /* build the visible part of the auth vector randomly */
-      for (i = 0; i < AUTH_VECTOR_LEN; i++)
-       req.vector[i] = random() % 256;
-      strlcpy((char *) secbuf, config->secret, sizeof(secbuf));
-      memcpy(secbuf+strlen(config->secret), req.vector, AUTH_VECTOR_LEN);
-      md5_hash(secbuf, strlen(config->secret)+AUTH_VECTOR_LEN, digest);
-      /* fill in the auth_req data */
-      req.code = PW_AUTHENTICATION_REQUEST;
-      req.id = 0;
-
-      /* bracket the username in the configured prefix/suffix */
-      req.data[0] = PW_USER_NAME;
-      req.data[1] = 2;
-      req.data[2] = '\0';
-      if (config->prefix) {
-       req.data[1] += strlen(config->prefix);
-       strlcat((char *) &req.data[2], config->prefix, sizeof(req.data) - 2);
-      }
-      req.data[1] += strlen(uname);
-      strlcat((char *)&req.data[2], uname, sizeof(req.data) - 2);
-      if (!strchr(uname, '@') && config->suffix) {
-       req.data[1] += strlen(config->suffix);
-       strlcat((char *)&req.data[2], config->suffix, sizeof(req.data) - 2);
-      }
-      req.datalen = req.data[1];
-
-      /* set the password */
-      passstart = req.datalen;
-      req.data[req.datalen] = PW_PASSWORD;
-      /* Null pad the password */
-      passlen = (strlen(pass) + 15) / 16;
-      passlen *= 16;
-      req.data[req.datalen+1] = passlen+2;
-      strlcpy((char *)&req.data[req.datalen+2], pass,
-              sizeof(req.data) - req.datalen - 2);
-      passlen -= strlen(pass);
-      while (passlen--)
-       req.data[req.datalen+passlen+2+strlen(pass)] = '\0';
-      req.datalen += req.data[req.datalen+1];
-
-      /* Add NAS_PORT and NAS_IP_ADDRESS into request */
-      if ((nvalue = config->locport) == 0)
-        nvalue = RADIUS_LOCAL_PORT;
-      req.data[req.datalen++] = RAD_NAS_PORT;
-      req.data[req.datalen++] = sizeof(nvalue) + 2;
-      nvalue = htonl(nvalue);
-      memcpy(req.data + req.datalen, &nvalue, sizeof(nvalue));
-      req.datalen += sizeof(nvalue);
-      req.data[req.datalen++] = RAD_NAS_IP_ADDRESS;
-      req.data[req.datalen++] = sizeof(struct in_addr) + 2;
-      memcpy(req.data + req.datalen, &sinl.sin_addr.s_addr,
-           sizeof(struct in_addr));
-      req.datalen += sizeof(struct in_addr);
-
-      /* we're only doing authentication */
-      req.data[req.datalen] = PW_SERVICE_TYPE;
-      req.data[req.datalen+1] = 6;
-      req.data[req.datalen+2] = (PW_SERVICE_AUTH_ONLY >> 24) & 0x000000ff;
-      req.data[req.datalen+3] = (PW_SERVICE_AUTH_ONLY >> 16) & 0x000000ff;
-      req.data[req.datalen+4] = (PW_SERVICE_AUTH_ONLY >> 8) & 0x000000ff;
-      req.data[req.datalen+5] = PW_SERVICE_AUTH_ONLY & 0x000000ff;
-      req.datalen += req.data[req.datalen+1];
-
-      /* filled in the data, now we know what the actual length is. */
-      req.length = 4+AUTH_VECTOR_LEN+req.datalen;
-
-      /* "encrypt" the password */
-      for (i = 0; i < req.data[passstart+1]-2; i += sizeof(HASH)) {
-       jlen = sizeof(HASH);
-       if (req.data[passstart+1]-(unsigned)i-2 < sizeof(HASH))
-           jlen = req.data[passstart+1]-i-2;
-       for (j = 0; j < jlen; j++)
-           req.data[passstart+2+i+j] ^= digest[j];
-       if (jlen == sizeof(HASH)) {
-           /* Recalculate the digest from the HASHed previous */
-           strlcpy((char *) secbuf, config->secret, sizeof(secbuf));
-           memcpy(secbuf+strlen(config->secret), &req.data[passstart+2+i],
-                   sizeof(HASH));
-            md5_hash(secbuf, strlen(config->secret)+sizeof(HASH), digest);
-       }
-      }
-      sreq->reqlen = req.length;
-      req.length = htons(req.length);
-
-      req_copyfrom(sreq, req);
-
-      /* Go to the next record in the list */
-      config = config->next;
-    }
-
-    /* YAYY! The auth_req is ready to go! Build the reply socket and send out
-     * the message. */
-
-    /* now, build the sockets */
-    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-      syswarn("cannot build reply socket");
-      return(-1);
-    }
-    if (bind(sock, (struct sockaddr*) &sinl, sizeof(sinl)) < 0) {
-      syswarn("cannot bind reply socket");
-      close(sock);
-      return(-1);
-    }
-
-    for(done = 0; authtries > 0 && !done; authtries--) {
-      for (config = radconfig, sreq = reqtop; sreq != NULL && !done;
-          config = config->next, sreq = sreq->next){
-       req_copyto(req, sreq);
-
-       /* send out the packet and wait for reply. */
-       if (sendto(sock, (char *)&req, sreq->reqlen, 0, 
-                  (struct sockaddr*) &sreq->sinr, 
-                  sizeof (struct sockaddr_in)) < 0) {
-          syswarn("cannot send auth_reg");
-         close(sock);
-         return(-1);
-       }
-
-       /* wait 5 seconds maximum for a radius reply. */
-       now = time(0);
-       end = now+5;
-       tmout.tv_sec = 6;
-       tmout.tv_usec = 0;
-       FD_ZERO(&rdfds);
-       /* store the old vector to verify next checksum */
-       memcpy(secbuf+sizeof(req.vector), req.vector, sizeof(req.vector));
-       FD_SET(sock, &rdfds);
-       got = select(sock+1, &rdfds, 0, 0, &tmout);
-       if (got < 0) {
-            syswarn("cannot not select");
-           break;
-       } else if (got == 0) {
-           /* timer ran out */
-           now = time(0);
-           tmout.tv_sec = end - now + 1;
-           tmout.tv_usec = 0;
-           continue;
-       }
-       slen = sizeof(sinl);
-       if ((jlen = recvfrom(sock, (char *)&req, sizeof(req)-sizeof(int), 0, 
-                            (struct sockaddr*) &sinl, &slen)) < 0) {
-            syswarn("cannot recvfrom");
-           break;
-       }
-       if (!config->ignore_source) {
-           if (sinl.sin_addr.s_addr != sreq->sinr.sin_addr.s_addr ||
-             (sinl.sin_port != sreq->sinr.sin_port)) {
-                warn("received unexpected UDP packet from %s:%d",
-                     inet_ntoa(sinl.sin_addr), ntohs(sinl.sin_port));
-               continue;
-           }
-       }
-       sreq->reqlen = ntohs(req.length);
-       if (jlen < 4+AUTH_VECTOR_LEN || jlen != sreq->reqlen) {
-            warn("received badly-sized packet");
-           continue;
-       }
-       /* verify the checksum */
-       memcpy(((char*)&req)+sreq->reqlen, config->secret, strlen(config->secret));
-       memcpy(secbuf, req.vector, sizeof(req.vector));
-       memcpy(req.vector, secbuf+sizeof(req.vector), sizeof(req.vector));
-        md5_hash((unsigned char *)&req, strlen(config->secret)+sreq->reqlen,
-           digest);
-       if (memcmp(digest, secbuf, sizeof(HASH)) != 0) {
-            warn("checksum didn't match");
-           continue;
-       }
-       /* FINALLY!  Got back a known-good packet.  See if we're in. */
-       close(sock);
-       return (req.code == PW_AUTHENTICATION_ACK) ? 0 : -1;
-       done = 1;
-       req_copyfrom(sreq, req);
-       break;
-      }
-    }
-    if (authtries == 0)
-        warn("cannot talk to remote radius server %s:%d",
-             inet_ntoa(sreq->sinr.sin_addr), ntohs(sreq->sinr.sin_port));
-    return(-2);
-}
-
-#define RAD_HAVE_HOST 1
-#define RAD_HAVE_PORT 2
-#define RAD_HAVE_PREFIX 4
-#define RAD_HAVE_SUFFIX 8
-#define RAD_HAVE_LOCHOST 16
-#define RAD_HAVE_LOCPORT 32
-
-int main(int argc, char *argv[])
-{
-    int opt;
-    int havefile, haveother;
-    struct auth_info *authinfo;
-    rad_config_t radconfig;
-    int retval;
-    char *radius_config;
-
-    message_program_name = "radius";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    memset(&radconfig, '\0', sizeof(rad_config_t));
-    haveother = havefile = 0;
-
-    while ((opt = getopt(argc, argv, "f:h")) != -1) {
-       switch (opt) {
-         case 'f':
-           if (haveother)
-                die("-f flag after another flag");
-           if (!havefile) {
-              /* override the standard config completely if the user
-               * specifies an alternate config file */
-              memset(&radconfig, '\0', sizeof(rad_config_t));
-              havefile = 1;
-           }
-           read_config(optarg, &radconfig);
-           break;
-       case 'h':
-         printf("Usage: radius [-f config]\n");
-          exit(0);
-       }
-    }
-    if (argc != optind)
-      exit(2);
-    if (!havefile) {
-      radius_config = concatpath(innconf->pathetc, _PATH_RADIUS_CONFIG);
-      read_config(radius_config, &radconfig);
-  
-      free(radius_config);
-    }
-
-    authinfo = get_auth_info(stdin);
-    if (authinfo == NULL)
-        die("failed getting auth info");
-    if (authinfo->username[0] == '\0')
-        die("empty username");
-
-    /* got username and password, check that they're valid */
-
-    retval = rad_auth(&radconfig, authinfo->username, authinfo->password);
-    if (retval == -1)
-        die("user %s password doesn't match", authinfo->username);
-    else if (retval == -2)
-       /* couldn't talk to the radius server..  output logged above. */
-       exit(1);
-    else if (retval != 0)
-        die("unexpected return code from authentication function: %d",
-            retval);
-
-    /* radius password matches! */
-    printf("User:%s\n", authinfo->username);
-    exit(0);
-}
diff --git a/authprogs/smbval/Makefile b/authprogs/smbval/Makefile
deleted file mode 100644 (file)
index 6bb6ef1..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-##  $Id: Makefile 5789 2002-09-29 23:34:26Z rra $
-
-include ../../Makefile.global
-
-top          = ../..
-CFLAGS       = $(GCFLAGS)
-
-ALL          = smbvalid.a
-
-SOURCES              = rfcnb-io.c rfcnb-util.c session.c smbdes.c \
-               smbencrypt.c smblib-util.c smblib.c valid.c
-
-OBJECTS              = $(SOURCES:.c=.o)
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-smbvalid.a: $(OBJECTS)
-       ar rc $@ $(OBJECTS)
-       $(RANLIB) $@
-
-clobber clean distclean:
-       rm -f *.o smbvalid.a
-
-depend: Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-rfcnb-io.o: rfcnb-io.c ../../include/config.h \
- ../../include/inn/defines.h ../../include/clibrary.h rfcnb-priv.h \
- rfcnb-error.h rfcnb-common.h byteorder.h rfcnb-util.h rfcnb-io.h
-rfcnb-util.o: rfcnb-util.c ../../include/config.h \
- ../../include/inn/defines.h ../../include/clibrary.h rfcnb-priv.h \
- rfcnb-error.h rfcnb-common.h byteorder.h rfcnb-util.h rfcnb-io.h
-session.o: session.c ../../include/config.h \
- ../../include/inn/defines.h ../../include/clibrary.h rfcnb-priv.h \
- rfcnb-error.h rfcnb-common.h byteorder.h rfcnb-util.h
-smbdes.o: smbdes.c
-smbencrypt.o: smbencrypt.c ../../include/config.h \
- ../../include/inn/defines.h ../../include/clibrary.h smblib-priv.h \
- smblib-common.h byteorder.h
-smblib-util.o: smblib-util.c ../../include/config.h \
- ../../include/inn/defines.h ../../include/clibrary.h smblib-priv.h \
- smblib-common.h byteorder.h rfcnb.h rfcnb-error.h rfcnb-common.h
-smblib.o: smblib.c ../../include/config.h ../../include/inn/defines.h \
- ../../include/clibrary.h smblib-priv.h smblib-common.h byteorder.h \
- rfcnb.h rfcnb-error.h rfcnb-common.h
-valid.o: valid.c ../../include/config.h ../../include/inn/defines.h \
- smblib-priv.h smblib-common.h byteorder.h valid.h
diff --git a/authprogs/smbval/byteorder.h b/authprogs/smbval/byteorder.h
deleted file mode 100644 (file)
index 9bea2b2..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
-   SMB Byte handling
-   Copyright (C) Andrew Tridgell 1992-1995
-   
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
-   This file implements macros for machine independent short and 
-   int manipulation
-*/
-
-#undef CAREFUL_ALIGNMENT
-
-/* we know that the 386 can handle misalignment and has the "right" 
-   byteorder */
-#ifdef __i386__
-#define CAREFUL_ALIGNMENT 0
-#endif
-
-#ifndef CAREFUL_ALIGNMENT
-#define CAREFUL_ALIGNMENT 1
-#endif
-
-#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
-#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
-#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
-
-
-#if CAREFUL_ALIGNMENT
-#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
-#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
-#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
-#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
-#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
-#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
-#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
-#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
-#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
-#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
-#else
-/* this handles things for architectures like the 386 that can handle
-   alignment errors */
-/*
-   WARNING: This section is dependent on the length of int16 and int32
-   being correct 
-*/
-#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
-#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
-#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
-#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
-#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
-#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
-#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
-#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
-#endif
diff --git a/authprogs/smbval/rfcnb-common.h b/authprogs/smbval/rfcnb-common.h
deleted file mode 100644 (file)
index ba09d7c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Common Structures etc Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* A data structure we need */
-
-typedef struct RFCNB_Pkt {
-
-  char * data;                 /* The data in this portion */
-  int len;
-  struct RFCNB_Pkt *next;
-
-} RFCNB_Pkt;
-
-void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt);
diff --git a/authprogs/smbval/rfcnb-error.h b/authprogs/smbval/rfcnb-error.h
deleted file mode 100644 (file)
index afa1328..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Error Response Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Error responses */
-
-#define RFCNBE_Bad -1          /* Bad response */
-#define RFCNBE_OK 0
-
-/* these should follow the spec ... is there one ?*/
-
-#define RFCNBE_NoSpace 1       /* Could not allocate space for a struct */
-#define RFCNBE_BadName 2       /* Could not translate a name            */
-#define RFCNBE_BadRead 3       /* Read sys call failed                  */
-#define RFCNBE_BadWrite 4      /* Write Sys call failed                 */
-#define RFCNBE_ProtErr 5       /* Protocol Error                        */
-#define RFCNBE_ConGone 6       /* Connection dropped                    */
-#define RFCNBE_BadHandle 7     /* Handle passed was bad                 */
-#define RFCNBE_BadSocket 8     /* Problems creating socket              */
-#define RFCNBE_ConnectFailed 9 /* Connect failed                        */
-#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN    */
-#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN   */
-#define RFCNBE_CallRejCNNP  12 /* Call rejected, called name not present */
-#define RFCNBE_CallRejInfRes 13/* Call rejetced, name ok, no resources   */
-#define RFCNBE_CallRejUnSpec 14/* Call rejected, unspecified error      */
-#define RFCNBE_BadParam      15/* Bad parameters passed ...             */
-#define RFCNBE_Timeout       16/* IO Timed out                          */
diff --git a/authprogs/smbval/rfcnb-io.c b/authprogs/smbval/rfcnb-io.c
deleted file mode 100644 (file)
index 3f030fa..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation
-
-   Version 1.0
-   RFCNB IO Routines ...
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/uio.h>
-
-#include "rfcnb-priv.h"
-#include "rfcnb-util.h"
-#include "rfcnb-io.h"
-
-int RFCNB_Timeout = 0;    /* Timeout in seconds ... */
-
-/* Discard the rest of an incoming packet as we do not have space for it
-   in the buffer we allocated or were passed ...                         */
-
-int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
-
-{ char temp[100];   /* Read into here */
-  int rest, this_read, bytes_read;
-
-  /* len is the amount we should read */
-
-  rest = len;
-
-  while (rest > 0) {
-
-    this_read = (rest > sizeof(temp)?sizeof(temp):rest);
-
-    bytes_read = read(con -> fd, temp, this_read);
-
-    if (bytes_read <= 0) { /* Error so return */
-
-      if (bytes_read < 0) 
-       RFCNB_errno = RFCNBE_BadRead;
-      else
-       RFCNB_errno = RFCNBE_ConGone;
-
-      RFCNB_saved_errno = errno;
-      return(RFCNBE_Bad);
-
-    }
-    
-    rest = rest - bytes_read;
-
-  }
-
-  return(0);
-
-}
-
-
-/* Send an RFCNB packet to the connection.
-
-   We just send each of the blocks linked together ... 
-
-   If we can, try to send it as one iovec ... 
-
-*/
-
-int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
-
-{ int len_sent, tot_sent, this_len;
-  struct RFCNB_Pkt *pkt_ptr;
-  char *this_data;
-  int i;
-  struct iovec io_list[10];          /* We should never have more      */
-                                     /* If we do, this will blow up ...*/
-
-  /* Try to send the data ... We only send as many bytes as len claims */
-  /* We should try to stuff it into an IOVEC and send as one write     */
-
-
-  pkt_ptr = pkt;
-  len_sent =  tot_sent = 0;             /* Nothing sent so far */
-  i = 0;
-
-  while ((pkt_ptr != NULL) & (i < 10)) {  /* Watch that magic number! */
-
-    this_len = pkt_ptr -> len;
-    this_data = pkt_ptr -> data;
-    if ((tot_sent + this_len) > len) 
-      this_len = len - tot_sent;        /* Adjust so we don't send too much */
-
-    /* Now plug into the iovec ... */
-
-    io_list[i].iov_len = this_len;
-    io_list[i].iov_base = this_data;
-    i++;
-
-    tot_sent += this_len;
-
-    if (tot_sent == len) break;   /* Let's not send too much */
-
-    pkt_ptr = pkt_ptr -> next;
-
-  }
-
-  /* Set up an alarm if timeouts are set ... */
-
-  if (RFCNB_Timeout > 0) 
-    alarm(RFCNB_Timeout);
-
-  if ((len_sent = writev(con -> fd, io_list, i)) < 0) { /* An error */
-
-    con -> rfc_errno = errno;
-    if (errno == EINTR)  /* We were interrupted ... */
-      RFCNB_errno = RFCNBE_Timeout;
-    else
-      RFCNB_errno = RFCNBE_BadWrite;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-
-  }
-
-  if (len_sent < tot_sent) { /* Less than we wanted */
-    if (errno == EINTR)      /* We were interrupted */
-      RFCNB_errno = RFCNBE_Timeout;
-    else
-      RFCNB_errno = RFCNBE_BadWrite;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-  }
-
-  if (RFCNB_Timeout > 0)
-    alarm(0);                /* Reset that sucker */
-
-  return(len_sent);
-
-}
-
-/* Read an RFCNB packet off the connection. 
-
-   We read the first 4 bytes, that tells us the length, then read the
-   rest. We should implement a timeout, but we don't just yet 
-
-*/
-
-
-int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
-
-{ int read_len, pkt_len;
-  char hdr[RFCNB_Pkt_Hdr_Len];      /* Local space for the header */
-  struct RFCNB_Pkt *pkt_frag;
-  int more, this_time, offset, frag_len, this_len;
-  bool seen_keep_alive = true;
-
-  /* Read that header straight into the buffer */
-
-  if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */
-
-    RFCNB_errno = RFCNBE_BadParam;
-    return(RFCNBE_Bad);
-
-  }
-
-  /* We discard keep alives here ... */
-
-  if (RFCNB_Timeout > 0) 
-    alarm(RFCNB_Timeout);
-
-  while (seen_keep_alive) {
-
-    if ((read_len = read(con -> fd, hdr, sizeof(hdr))) < 0) { /* Problems */
-      if (errno == EINTR)
-       RFCNB_errno = RFCNBE_Timeout;
-      else
-       RFCNB_errno = RFCNBE_BadRead;
-      RFCNB_saved_errno = errno;
-      return(RFCNBE_Bad);
-
-    }
-
-    /* Now we check out what we got */
-
-    if (read_len == 0) { /* Connection closed, send back eof?  */
-
-      if (errno == EINTR) 
-       RFCNB_errno = RFCNBE_Timeout;
-      else
-       RFCNB_errno = RFCNBE_ConGone;
-      RFCNB_saved_errno = errno;
-      return(RFCNBE_Bad);
-
-    }
-
-    if (RFCNB_Pkt_Type(hdr) != RFCNB_SESSION_KEEP_ALIVE) {
-      seen_keep_alive = false;
-    }
-
-  }
-  /* What if we got less than or equal to a hdr size in bytes? */
-
-  if (read_len < sizeof(hdr)) { /* We got a small packet */
-
-    /* Now we need to copy the hdr portion we got into the supplied packet */
-
-    memcpy(pkt -> data, hdr, read_len);  /*Copy data */
-
-    return(read_len);
-
-  }
-
-  /* Now, if we got at least a hdr size, alloc space for rest, if we need it */
-
-  pkt_len = RFCNB_Pkt_Len(hdr);
-
-  /* Now copy in the hdr */
-
-  memcpy(pkt -> data, hdr, sizeof(hdr));
-
-  /* Get the rest of the packet ... first figure out how big our buf is? */
-  /* And make sure that we handle the fragments properly ... Sure should */
-  /* use an iovec ...                                                    */
-
-  if (len < pkt_len)            /* Only get as much as we have space for */
-    more = len - RFCNB_Pkt_Hdr_Len;
-  else
-    more = pkt_len;
-
-  this_time = 0;
-
-  /* We read for each fragment ... */
-
-  if (pkt -> len == read_len){     /* If this frag was exact size */
-    pkt_frag = pkt -> next;        /* Stick next lot in next frag */
-    offset = 0;                    /* then we start at 0 in next  */
-  }
-  else {
-    pkt_frag = pkt;                /* Otherwise use rest of this frag */
-    offset = RFCNB_Pkt_Hdr_Len;    /* Otherwise skip the header       */
-  }
-
-  frag_len = pkt_frag -> len;
-
-  if (more <= frag_len)     /* If len left to get less than frag space */
-    this_len = more;        /* Get the rest ...                        */
-  else
-    this_len = frag_len - offset;
-
-  while (more > 0) {
-
-    if ((this_time = read(con -> fd, (pkt_frag -> data) + offset, this_len)) <= 0) { /* Problems */
-
-      if (errno == EINTR) {
-
-       RFCNB_errno = RFCNB_Timeout;
-
-      }
-      else {
-       if (this_time < 0)
-         RFCNB_errno = RFCNBE_BadRead;
-       else
-         RFCNB_errno = RFCNBE_ConGone;
-      }
-
-      RFCNB_saved_errno = errno;
-      return(RFCNBE_Bad);
-
-    }
-
-    read_len = read_len + this_time;  /* How much have we read ... */
-
-    /* Now set up the next part */
-
-    if (pkt_frag -> next == NULL) break;       /* That's it here */
-
-    pkt_frag = pkt_frag -> next;
-    this_len = pkt_frag -> len;
-    offset = 0;
-
-    more = more - this_time;
-
-  }
-
-  if (read_len < (pkt_len + sizeof(hdr))) {  /* Discard the rest */
-
-    return(RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len));
-
-  }
-
-  if (RFCNB_Timeout > 0)
-    alarm(0);                /* Reset that sucker */
-
-  return(read_len + sizeof(RFCNB_Hdr));
-}
diff --git a/authprogs/smbval/rfcnb-io.h b/authprogs/smbval/rfcnb-io.h
deleted file mode 100644 (file)
index 753c7ae..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB IO Routines Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
-
-int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
diff --git a/authprogs/smbval/rfcnb-priv.h b/authprogs/smbval/rfcnb-priv.h
deleted file mode 100644 (file)
index a6b9da8..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Defines we need */
-
-typedef unsigned short uint16;
-
-#define GLOBAL extern
-
-#include <netinet/in.h>
-
-#include "rfcnb-error.h"
-#include "rfcnb-common.h"
-#include "byteorder.h"
-
-#define RFCNB_Default_Port 139
-
-#define RFCNB_MAX_STATS 1
-
-/* Protocol defines we need */
-
-#define RFCNB_SESSION_MESSAGE 0
-#define RFCNB_SESSION_REQUEST 0x81
-#define RFCNB_SESSION_ACK 0x82
-#define RFCNB_SESSION_REJ 0x83
-#define RFCNB_SESSION_RETARGET 0x84
-#define RFCNB_SESSION_KEEP_ALIVE 0x85
-
-/* Structures      */
-
-typedef struct redirect_addr * redirect_ptr;
-
-struct redirect_addr {
-
-  struct in_addr ip_addr;
-  int port;
-  redirect_ptr next;
-
-};
-
-typedef struct RFCNB_Con {
-
-  int fd;                     /* File descripter for TCP/IP connection */
-  int rfc_errno;                  /* last error                            */
-  int timeout;               /* How many milli-secs before IO times out */
-  int redirects;             /* How many times we were redirected     */
-  struct redirect_addr *redirect_list;  /* First is first address */
-  struct redirect_addr *last_addr;
-
-} RFCNB_Con;
-
-typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with  */
-                                    /* char[0] as the type, char[1] the */
-                                   /* flags, and char[2..3] the length */
-
-/* Macros to extract things from the header. These are for portability
-   between architecture types where we are worried about byte order     */
-
-#define RFCNB_Pkt_Hdr_Len        4
-#define RFCNB_Pkt_Sess_Len       72
-#define RFCNB_Pkt_Retarg_Len     10
-#define RFCNB_Pkt_Nack_Len       5
-#define RFCNB_Pkt_Type_Offset    0
-#define RFCNB_Pkt_Flags_Offset   1
-#define RFCNB_Pkt_Len_Offset     2   /* Length is 2 bytes plus a flag bit */
-#define RFCNB_Pkt_N1Len_Offset   4
-#define RFCNB_Pkt_Called_Offset  5
-#define RFCNB_Pkt_N2Len_Offset   38
-#define RFCNB_Pkt_Calling_Offset 39
-#define RFCNB_Pkt_Error_Offset   4
-#define RFCNB_Pkt_IP_Offset      4
-#define RFCNB_Pkt_Port_Offset    8
-
-/* The next macro isolates the length of a packet, including the bit in the
-   flags                                                                   */
-
-#define RFCNB_Pkt_Len(p)  (PVAL(p, 3) | (PVAL(p, 2) << 8) |     \
-                          ((PVAL(p, RFCNB_Pkt_Flags_Offset) & 0x01) << 16))
-
-#define RFCNB_Put_Pkt_Len(p, v) ((p)[1] = (((v) >> 16) & 1)); \
-                               ((p)[2] = (((v) >> 8) & 0xFF)); \
-                               ((p)[3] = ((v) & 0xFF));
-
-#define RFCNB_Pkt_Type(p) (CVAL(p, RFCNB_Pkt_Type_Offset))
-
-/* Static variables */
-
-/* Only declare this if not defined */
-
-#ifndef RFCNB_ERRNO
-extern int RFCNB_errno;
-extern int RFCNB_saved_errno;    /* Save this from point of error */
-#endif
diff --git a/authprogs/smbval/rfcnb-util.c b/authprogs/smbval/rfcnb-util.c
deleted file mode 100644 (file)
index 9e57e4e..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Utility Routines ...
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <errno.h>
-#include <netdb.h>
-
-#include "rfcnb-priv.h"
-#include "rfcnb-util.h"
-#include "rfcnb-io.h"
-
-#ifndef INADDR_NONE
-# define INADDR_NONE -1
-#endif
-
-extern void (*Prot_Print_Routine)(); /* Pointer to protocol print routine */
-
-/* Convert name and pad to 16 chars as needed */
-/* Name 1 is a C string with null termination, name 2 may not be */
-/* If SysName is true, then put a <00> on end, else space>       */
-
-void RFCNB_CvtPad_Name(char *name1, char *name2)
-
-{ char c, c1, c2;
-  int i, len;
-
-  len = strlen(name1);
-
-  for (i = 0; i < 16; i++) {
-
-    if (i >= len) {
-
-     c1 = 'C'; c2 = 'A'; /* CA is a space */
-    } else {
-
-      c = name1[i];
-      c1 = (char)((int)c/16 + (int)'A');
-      c2 = (char)((int)c%16 + (int)'A');
-    }
-
-    name2[i*2] = c1;
-    name2[i*2+1] = c2;
-
-  }
-
-  name2[32] = 0;   /* Put in the nll ...*/
-
-}
-
-/* Get a packet of size n */
-
-struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n)
-
-{ RFCNB_Pkt *pkt;
-
-  if ((pkt = (struct RFCNB_Pkt *)malloc(sizeof(struct RFCNB_Pkt))) == NULL) {
-
-    RFCNB_errno = RFCNBE_NoSpace;
-    RFCNB_saved_errno = errno;
-    return(NULL);
-
-  }
-
-  pkt -> next = NULL;
-  pkt -> len = n;
-
-  if (n == 0) return(pkt);
-
-  if ((pkt -> data = (char *)malloc(n)) == NULL) {
-
-    RFCNB_errno = RFCNBE_NoSpace;
-    RFCNB_saved_errno = errno;
-    free(pkt);
-    return(NULL);
-
-  }
-
-  return(pkt);
-
-}
-
-/* Free up a packet */
-
-void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
-
-{ struct RFCNB_Pkt *pkt_next; char *data_ptr;
-
-  while (pkt != NULL) {
-
-    pkt_next = pkt -> next;
-
-    data_ptr = pkt -> data;
-
-    if (data_ptr != NULL)
-      free(data_ptr);
-
-    free(pkt);
-
-    pkt = pkt_next;
-
-  }
-
-}
-
-/* Resolve a name into an address */
-
-int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
-
-{ int addr;         /* Assumes IP4, 32 bit network addresses */
-  struct hostent *hp;
-
-        /* Use inet_addr to try to convert the address */
-
-  if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */
-
-        /* Now try a name look up with gethostbyname */
-
-    if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */
-
-        /* Try NetBIOS name lookup, how the hell do we do that? */
-
-      RFCNB_errno = RFCNBE_BadName;   /* Is this right? */
-      RFCNB_saved_errno = errno;
-      return(RFCNBE_Bad);
-
-    }
-    else {  /* We got a name */
-
-       memcpy((void *)Dest_IP, (void *)hp -> h_addr_list[0], sizeof(struct in_addr));
-
-    }
-  }
-  else { /* It was an IP address */
-
-    memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr));
-
-  }
-
-  return 0;
-
-}
-
-/* Disconnect the TCP connection to the server */
-
-int RFCNB_Close(int socket)
-
-{
-
-  close(socket);
-
-  /* If we want to do error recovery, here is where we put it */
-
-  return 0;
-
-}
-
-/* Connect to the server specified in the IP address.
-   Not sure how to handle socket options etc.         */
-
-int RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
-
-{ struct sockaddr_in Socket;
-  int fd;
-
-  /* Create a socket */
-
-  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */
-
-    RFCNB_errno = RFCNBE_BadSocket;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-    } 
-
-  memset(&Socket, 0, sizeof(Socket));
-  memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP));
-
-  Socket.sin_port = htons(port);
-  Socket.sin_family = PF_INET;
-
-  /* Now connect to the destination */
-
-  if (connect(fd, (struct sockaddr *)&Socket, sizeof(Socket)) < 0) { /* Error */
-
-    close(fd);
-    RFCNB_errno = RFCNBE_ConnectFailed;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-    }
-
-  return(fd);
-
-}
-
-/* handle the details of establishing the RFCNB session with remote 
-   end 
-
-*/
-
-int RFCNB_Session_Req(struct RFCNB_Con *con, 
-                     char *Called_Name, 
-                     char *Calling_Name,
-                     bool *redirect,
-                     struct in_addr *Dest_IP,
-                     int * port)
-
-{ char *sess_pkt;
-
-  /* Response packet should be no more than 9 bytes, make 16 jic */
-
-  char resp[16];
-  int len;
-  struct RFCNB_Pkt *pkt, res_pkt;
-
-  /* We build and send the session request, then read the response */
-
-  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
-
-  if (pkt == NULL) {
-
-    return(RFCNBE_Bad);  /* Leave the error that RFCNB_Alloc_Pkt gives) */
-
-  }
-
-  sess_pkt = pkt -> data;    /* Get pointer to packet proper */
-
-  sess_pkt[RFCNB_Pkt_Type_Offset]  = RFCNB_SESSION_REQUEST;
-  RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len-RFCNB_Pkt_Hdr_Len);
-  sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
-  sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;
-
-  RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset));
-  RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset));
-
-  /* Now send the packet */
-
-  if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
-
-    return(RFCNBE_Bad);       /* Should be able to write that lot ... */
-
-    }
-
-  res_pkt.data = resp;
-  res_pkt.len  = sizeof(resp);
-  res_pkt.next = NULL;
-
-  if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) {
-
-    return(RFCNBE_Bad);
-
-  }
-
-  /* Now analyze the packet ... */
-
-  switch (RFCNB_Pkt_Type(resp)) {
-
-    case RFCNB_SESSION_REJ:         /* Didnt like us ... too bad */
-
-      /* Why did we get rejected ? */
-    
-      switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) {
-
-      case 0x80: 
-       RFCNB_errno = RFCNBE_CallRejNLOCN;
-       break;
-      case 0x81:
-       RFCNB_errno = RFCNBE_CallRejNLFCN;
-       break;
-      case 0x82:
-       RFCNB_errno = RFCNBE_CallRejCNNP;
-       break;
-      case 0x83:
-       RFCNB_errno = RFCNBE_CallRejInfRes;
-       break;
-      case 0x8F:
-       RFCNB_errno = RFCNBE_CallRejUnSpec;
-       break;
-      default:
-       RFCNB_errno = RFCNBE_ProtErr;
-       break;
-      }
-
-      return(RFCNBE_Bad);
-      break;
-
-    case RFCNB_SESSION_ACK:        /* Got what we wanted ...      */
-
-      return(0);
-      break;
-
-    case RFCNB_SESSION_RETARGET:   /* Go elsewhere                */
-
-      *redirect = true;       /* Copy port and ip addr       */
-
-      memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr));
-      *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
-
-      return(0);
-      break;
-
-    default:  /* A protocol error */
-
-      RFCNB_errno = RFCNBE_ProtErr;
-      return(RFCNBE_Bad);
-      break;
-    }
-}
diff --git a/authprogs/smbval/rfcnb-util.h b/authprogs/smbval/rfcnb-util.h
deleted file mode 100644 (file)
index 1af7e5e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Utility Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-void RFCNB_CvtPad_Name(char *name1, char *name2);
-
-struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n);
-
-int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP);
-
-int RFCNB_Close(int socket);
-
-int RFCNB_IP_Connect(struct in_addr Dest_IP, int port);
-
-int RFCNB_Session_Req(struct RFCNB_Con *con, 
-                     char *Called_Name, 
-                     char *Calling_Name,
-                     bool *redirect,
-                     struct in_addr *Dest_IP,
-                     int * port);
-
diff --git a/authprogs/smbval/rfcnb.h b/authprogs/smbval/rfcnb.h
deleted file mode 100644 (file)
index 8c2ea1c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   RFCNB Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Error responses */
-
-#include "rfcnb-error.h"
-#include "rfcnb-common.h"
-
-/* Defines we need */
-
-#define RFCNB_Default_Port 139
-
-/* Definition of routines we define */
-
-void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
-                int port);
-
-int RFCNB_Send(void *Con_Handle, struct RFCNB_Pkt *Data, int Length);
-
-int RFCNB_Recv(void *Con_Handle, struct RFCNB_Pkt *Data, int Length);
-
-int RFCNB_Hangup(void *con_Handle);
-
-void *RFCNB_Listen();
-
-struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n);
diff --git a/authprogs/smbval/session.c b/authprogs/smbval/session.c
deleted file mode 100644 (file)
index ec35bcd..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
-   Version 1.0
-   Session Routines ...
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/socket.h>
-
-int RFCNB_errno = 0;
-int RFCNB_saved_errno = 0;
-#define RFCNB_ERRNO
-
-#include "rfcnb-priv.h"
-#include "rfcnb-io.h"
-#include "rfcnb-util.h"
-
-int RFCNB_Stats[RFCNB_MAX_STATS];
-
-void (*Prot_Print_Routine)() = NULL;      /* Pointer to print routine */
-
-/* Set up a session with a remote name. We are passed Called_Name as a
-   string which we convert to a NetBIOS name, ie space terminated, up to
-   16 characters only if we need to. If Called_Address is not empty, then
-   we use it to connect to the remote end, but put in Called_Name ... Called 
-   Address can be a DNS based name, or a TCP/IP address ...
-*/
-
-void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
-                int port)
-
-{ struct RFCNB_Con *con;
-  struct in_addr Dest_IP;
-  int Client;
-  bool redirect; struct redirect_addr *redir_addr;
-  char *Service_Address;
-
-  /* Now, we really should look up the port in /etc/services ... */
-
-  if (port == 0) port = RFCNB_Default_Port;
-
-  /* Create a connection structure first */
-
-  if ((con = (struct RFCNB_Con *)malloc(sizeof(struct RFCNB_Con))) == NULL) { /* Error in size */
-
-    RFCNB_errno = RFCNBE_NoSpace;
-    RFCNB_saved_errno = errno;
-    return(NULL);
-
-    }
-  con -> fd = -0;             /* no descriptor yet */
-  con -> rfc_errno = 0;           /* no error yet */
-  con -> timeout = 0;         /* no timeout   */
-  con -> redirects = 0;
-  con -> redirect_list = NULL; /* Fix bug still in version 0.50 */
-
-  /* Resolve that name into an IP address */
-
-  Service_Address = Called_Name;
-  if (strcmp(Called_Address, "") != 0) { /* If the Called Address = "" */
-    Service_Address = Called_Address;
-  }
-
-  if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) { /* Error */
-
-    /* No need to modify RFCNB_errno as it was done by RFCNB_Name_To_IP */
-
-    return(NULL);
-
-    }
-
-  /* Now connect to the remote end */
-
-  redirect = true;     /* Fudge this one so we go once through */
-
-  while (redirect) {   /* Connect and get session info etc */
-
-    redirect = false;  /* Assume all OK */
-
-    /* Build the redirect info. First one is first addr called */
-    /* And tack it onto the list of addresses we called        */
-
-    if ((redir_addr = (struct redirect_addr *)malloc(sizeof(struct redirect_addr))) == NULL) { /* Could not get space */
-      
-      RFCNB_errno = RFCNBE_NoSpace;
-      RFCNB_saved_errno = errno;
-      return(NULL);
-
-    }
-
-    memcpy((char *)&(redir_addr -> ip_addr), (char *)&Dest_IP, sizeof(Dest_IP));
-    redir_addr -> port = port;
-    redir_addr -> next = NULL;
-
-    if (con -> redirect_list == NULL) { /* Stick on head */
-
-      con -> redirect_list = con -> last_addr = redir_addr;
-
-    } else {
-
-      con -> last_addr -> next = redir_addr;
-      con -> last_addr = redir_addr;
-
-    }
-
-    /* Now, make that connection */
-
-    if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) { /* Error */
-
-      /* No need to modify RFCNB_errno as it was done by RFCNB_IP_Connect */
-
-      return(NULL);
-
-      }
-
-    con -> fd = Client;
-
-    /* Now send and handle the RFCNB session request              */
-    /* If we get a redirect, we will comeback with redirect true 
-       and a new IP address in DEST_IP                            */
-
-    if ((errno = RFCNB_Session_Req(con, 
-                                  Called_Name,
-                                  Calling_Name,
-                                  &redirect, &Dest_IP, &port)) < 0) {
-
-      /* No need to modify RFCNB_errno as it was done by RFCNB_Session.. */
-
-      return(NULL);
-
-      }
-
-    if (redirect) {
-
-      /* We have to close the connection, and then try again */
-
-      (con -> redirects)++;
-
-      RFCNB_Close(con -> fd);  /* Close it */
-
-      }
-    }
-
-  return(con);
-
-}
-
-/* We send a packet to the other end ... for the moment, we treat the 
-   data as a series of pointers to blocks of data ... we should check the
-   length ... */
-
-int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
-
-{ struct RFCNB_Pkt *pkt; char *hdr;
-  int len;
-
-  /* Plug in the header and send the data */
-
-  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
-
-  if (pkt == NULL) {
-
-    RFCNB_errno = RFCNBE_NoSpace;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-
-  }
-
-  pkt -> next = udata;   /* The user data we want to send */
-
-  hdr = pkt -> data;
-
-  /* Following crap is for portability across multiple UNIX machines */
-
-  *(hdr + RFCNB_Pkt_Type_Offset)  = RFCNB_SESSION_MESSAGE;
-  RFCNB_Put_Pkt_Len(hdr, Length);
-
-#ifdef RFCNB_DEBUG
-
-  fprintf(stderr, "Sending packet: ");
-  
-#endif
-
-  if ((len = RFCNB_Put_Pkt(Con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
-
-    /* No need to change RFCNB_errno as it was done by put_pkt ...     */
-
-    return(RFCNBE_Bad);   /* Should be able to write that lot ... */
-    
-  }
-
-  /* Now we have sent that lot, let's get rid of the RFCNB Header and return */
-
-  pkt -> next = NULL;
-
-  RFCNB_Free_Pkt(pkt);
-
-  return(len);
-
-}
-
-/* We pick up a message from the internet ... We have to worry about 
-   non-message packets ...                                           */
-
-int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
-
-{ struct RFCNB_Pkt *pkt;
-  int ret_len;
-
-  if (con_Handle == NULL){
-
-    RFCNB_errno = RFCNBE_BadHandle;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-
-  }
-
-  /* Now get a packet from below. We allocate a header first */
-
-  /* Plug in the header and send the data */
-
-  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
-
-  if (pkt == NULL) {
-
-    RFCNB_errno = RFCNBE_NoSpace;
-    RFCNB_saved_errno = errno;
-    return(RFCNBE_Bad);
-
-  }
-
-  pkt -> next = Data;  /* Plug in the data portion */
-
-  if ((ret_len = RFCNB_Get_Pkt(con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
-
-#ifdef RFCNB_DEBUG
-    fprintf(stderr, "Bad packet return in RFCNB_Recv... \n");
-#endif
-
-    return(RFCNBE_Bad);
-
-  }
-
-  /* We should check that we go a message and not a keep alive */
-
-  pkt -> next = NULL;
-
-  RFCNB_Free_Pkt(pkt);
-
-  return(ret_len);
-
-}
-
-/* We just disconnect from the other end, as there is nothing in the RFCNB */
-/* protocol that specifies any exchange as far as I can see                */
-
-int RFCNB_Hangup(struct RFCNB_Con *con_Handle)
-
-{
-
-  if (con_Handle != NULL) {
-    RFCNB_Close(con_Handle -> fd);  /* Could this fail? */
-    free(con_Handle);
-  }
-
-  return 0;
-
-
-}
-
-/* Set TCP_NODELAY on the socket                                          */
-
-int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, bool yn)
-
-{
-
-  return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY, 
-                   (char *)&yn, sizeof(yn)));
-
-}
diff --git a/authprogs/smbval/smbdes.c b/authprogs/smbval/smbdes.c
deleted file mode 100644 (file)
index e4f8280..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
-
-   a partial implementation of DES designed for use in the 
-   SMB authentication protocol
-
-   Copyright (C) Andrew Tridgell 1997
-   
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/* NOTES: 
-
-   This code makes no attempt to be fast! In fact, it is a very
-   slow implementation 
-
-   This code is NOT a complete DES implementation. It implements only
-   the minimum necessary for SMB authentication, as used by all SMB
-   products (including every copy of Microsoft Windows95 ever sold)
-
-   In particular, it can only do a unchained forward DES pass. This
-   means it is not possible to use this code for encryption/decryption
-   of data, instead it is only useful as a "hash" algorithm.
-
-   There is no entry point into this code that allows normal DES operation.
-
-   I believe this means that this code does not come under ITAR
-   regulations but this is NOT a legal opinion. If you are concerned
-   about the applicability of ITAR regulations to this code then you
-   should confirm it for yourself (and maybe let me know if you come
-   up with a different answer to the one above)
-*/
-
-
-
-static int perm1[56] = {57, 49, 41, 33, 25, 17,  9,
-                        1, 58, 50, 42, 34, 26, 18,
-                       10,  2, 59, 51, 43, 35, 27,
-                       19, 11,  3, 60, 52, 44, 36,
-                       63, 55, 47, 39, 31, 23, 15,
-                        7, 62, 54, 46, 38, 30, 22,
-                       14,  6, 61, 53, 45, 37, 29,
-                       21, 13,  5, 28, 20, 12,  4};
-
-static int perm2[48] = {14, 17, 11, 24,  1,  5,
-                         3, 28, 15,  6, 21, 10,
-                        23, 19, 12,  4, 26,  8,
-                        16,  7, 27, 20, 13,  2,
-                        41, 52, 31, 37, 47, 55,
-                        30, 40, 51, 45, 33, 48,
-                        44, 49, 39, 56, 34, 53,
-                        46, 42, 50, 36, 29, 32};
-
-static int perm3[64] = {58, 50, 42, 34, 26, 18, 10,  2,
-                       60, 52, 44, 36, 28, 20, 12,  4,
-                       62, 54, 46, 38, 30, 22, 14,  6,
-                       64, 56, 48, 40, 32, 24, 16,  8,
-                       57, 49, 41, 33, 25, 17,  9,  1,
-                       59, 51, 43, 35, 27, 19, 11,  3,
-                       61, 53, 45, 37, 29, 21, 13,  5,
-                       63, 55, 47, 39, 31, 23, 15,  7};
-
-static int perm4[48] = {   32,  1,  2,  3,  4,  5,
-                            4,  5,  6,  7,  8,  9,
-                            8,  9, 10, 11, 12, 13,
-                           12, 13, 14, 15, 16, 17,
-                           16, 17, 18, 19, 20, 21,
-                           20, 21, 22, 23, 24, 25,
-                           24, 25, 26, 27, 28, 29,
-                           28, 29, 30, 31, 32,  1};
-
-static int perm5[32] = {      16,  7, 20, 21,
-                              29, 12, 28, 17,
-                               1, 15, 23, 26,
-                               5, 18, 31, 10,
-                               2,  8, 24, 14,
-                              32, 27,  3,  9,
-                              19, 13, 30,  6,
-                              22, 11,  4, 25};
-
-
-static int perm6[64] ={ 40,  8, 48, 16, 56, 24, 64, 32,
-                        39,  7, 47, 15, 55, 23, 63, 31,
-                        38,  6, 46, 14, 54, 22, 62, 30,
-                        37,  5, 45, 13, 53, 21, 61, 29,
-                        36,  4, 44, 12, 52, 20, 60, 28,
-                        35,  3, 43, 11, 51, 19, 59, 27,
-                        34,  2, 42, 10, 50, 18, 58, 26,
-                        33,  1, 41,  9, 49, 17, 57, 25};
-
-
-static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
-
-static int sbox[8][4][16] = {
-       {{14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
-        {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
-        {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
-        {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
-
-       {{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
-        {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
-        {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
-        {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
-
-       {{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
-        {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
-        {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
-        {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
-
-       {{7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
-        {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
-        {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
-        {3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14}},
-
-       {{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
-        {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
-        {4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
-        {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
-
-       {{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
-        {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
-        {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
-        {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
-
-       {{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
-        {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
-        {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
-        {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
-
-       {{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
-        {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
-        {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
-        {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
-
-static void permute(char *out, char *in, int *p, int n)
-{
-       int i;
-       for (i=0;i<n;i++)
-               out[i] = in[p[i]-1];
-}
-
-static void lshift(char *d, int count, int n)
-{
-       char out[64];
-       int i;
-       for (i=0;i<n;i++)
-               out[i] = d[(i+count)%n];
-       for (i=0;i<n;i++)
-               d[i] = out[i];
-}
-
-static void concat(char *out, char *in1, char *in2, int l1, int l2)
-{
-       while (l1--)
-               *out++ = *in1++;
-       while (l2--)
-               *out++ = *in2++;
-}
-
-static void xor(char *out, char *in1, char *in2, int n)
-{
-       int i;
-       for (i=0;i<n;i++)
-               out[i] = in1[i] ^ in2[i];
-}
-
-static void dohash(char *out, char *in, char *key)
-{
-       int i, j, k;
-       char pk1[56];
-       char c[28];
-       char d[28];
-       char cd[56];
-       char ki[16][48];
-       char pd1[64];
-       char l[32], r[32];
-       char rl[64];
-
-       permute(pk1, key, perm1, 56);
-
-       for (i=0;i<28;i++)
-               c[i] = pk1[i];
-       for (i=0;i<28;i++)
-               d[i] = pk1[i+28];
-
-       for (i=0;i<16;i++) {
-               lshift(c, sc[i], 28);
-               lshift(d, sc[i], 28);
-
-               concat(cd, c, d, 28, 28); 
-               permute(ki[i], cd, perm2, 48); 
-       }
-
-       permute(pd1, in, perm3, 64);
-
-       for (j=0;j<32;j++) {
-               l[j] = pd1[j];
-               r[j] = pd1[j+32];
-       }
-
-       for (i=0;i<16;i++) {
-               char er[48];
-               char erk[48];
-               char b[8][6];
-               char cb[32];
-               char pcb[32];
-               char r2[32];
-
-               permute(er, r, perm4, 48);
-
-               xor(erk, er, ki[i], 48);
-
-               for (j=0;j<8;j++)
-                       for (k=0;k<6;k++)
-                               b[j][k] = erk[j*6 + k];
-
-               for (j=0;j<8;j++) {
-                       int m, n;
-                       m = (b[j][0]<<1) | b[j][5];
-
-                       n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; 
-
-                       for (k=0;k<4;k++) 
-                               b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; 
-               }
-
-               for (j=0;j<8;j++)
-                       for (k=0;k<4;k++)
-                               cb[j*4+k] = b[j][k];
-               permute(pcb, cb, perm5, 32);
-
-               xor(r2, l, pcb, 32);
-
-               for (j=0;j<32;j++)
-                       l[j] = r[j];
-
-               for (j=0;j<32;j++)
-                       r[j] = r2[j];
-       }
-
-       concat(rl, r, l, 32, 32);
-
-       permute(out, rl, perm6, 64);
-}
-
-static void str_to_key(unsigned char *str,unsigned char *key)
-{
-       int i;
-
-       key[0] = str[0]>>1;
-       key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
-       key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
-       key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
-       key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
-       key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
-       key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
-       key[7] = str[6]&0x7F;
-       for (i=0;i<8;i++) {
-               key[i] = (key[i]<<1);
-       }
-}
-
-
-static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key)
-{
-       int i;
-       char outb[64];
-       char inb[64];
-       char keyb[64];
-       unsigned char key2[8];
-
-       str_to_key(key, key2);
-
-       for (i=0;i<64;i++) {
-               inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
-               keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
-               outb[i] = 0;
-       }
-
-       dohash(outb, inb, keyb);
-
-       for (i=0;i<8;i++) {
-               out[i] = 0;
-       }
-
-       for (i=0;i<64;i++) {
-               if (outb[i])
-                       out[i/8] |= (1<<(7-(i%8)));
-       }
-}
-
-void E_P16(unsigned char *p14,unsigned char *p16)
-{
-       unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
-       smbhash(p16, sp8, p14);
-       smbhash(p16+8, sp8, p14+7);
-}
-
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
-{
-       smbhash(p24, c8, p21);
-       smbhash(p24+8, c8, p21+7);
-       smbhash(p24+16, c8, p21+14);
-}
-
-void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
-{
-       unsigned char buf[8];
-
-       smbhash(buf, in, key);
-       smbhash(out, buf, key+9);
-}
-
-void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
-{
-       unsigned char buf[8];
-       static unsigned char key2[8];
-
-       smbhash(buf, in, key);
-       key2[0] = key[7];
-       smbhash(out, buf, key2);
-}
-
diff --git a/authprogs/smbval/smbencrypt.c b/authprogs/smbval/smbencrypt.c
deleted file mode 100644 (file)
index 4cae973..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
-   SMB parameters and setup
-   Copyright (C) Andrew Tridgell 1992-1997
-   Modified by Jeremy Allison 1995.
-   
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#include "smblib-priv.h"
-
-typedef unsigned char uchar;
-
-void strupper(char *s);
-
-/*
-   This implements the X/Open SMB password encryption
-   It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
-   encrypted password into p24 */
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
-{
-  uchar p14[15], p21[21];
-
-  memset(p21,'\0',21);
-  memset(p14,'\0',14);
-  strlcpy((char *) p14, (char *) passwd, sizeof(p14));
-
-  strupper((char *)p14);
-  E_P16(p14, p21); 
-  E_P24(p21, c8, p24);
-}
-
-void strupper(char *s)
-{
-  while (*s)
-  {
-    {
-      if (CTYPE(islower, *s))
-        *s = toupper(*s);
-      s++;
-    }
-  }
-}                      
diff --git a/authprogs/smbval/smblib-common.h b/authprogs/smbval/smblib-common.h
deleted file mode 100644 (file)
index b8441e0..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* UNIX SMBlib NetBIOS implementation
-
-   Version 1.0
-   SMBlib Common Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Error CLASS codes and etc ... */
-
-#define SMBC_SUCCESS        0
-#define SMBC_ERRDOS         0x01
-#define SMBC_ERRSRV         0x02
-#define SMBC_ERRHRD         0x03
-#define SMBC_ERRCMD         0xFF
-
-/* Define the protocol types ... */
-
-#define SMB_P_Unknown      -1        /* Hmmm, is this smart? */
-#define SMB_P_Core         0
-#define SMB_P_CorePlus     1
-#define SMB_P_DOSLanMan1   2
-#define SMB_P_LanMan1      3
-#define SMB_P_DOSLanMan2   4 
-#define SMB_P_LanMan2      5
-#define SMB_P_DOSLanMan2_1 6
-#define SMB_P_LanMan2_1    7
-#define SMB_P_NT1          8
-
-/* SMBlib return codes */
-/* We want something that indicates whether or not the return code was a   */
-/* remote error, a local error in SMBlib or returned from lower layer ...  */
-/* Wonder if this will work ...                                            */
-/* SMBlibE_Remote = 1 indicates remote error                               */
-/* SMBlibE_ values < 0 indicate local error with more info available       */
-/* SMBlibE_ values >1 indicate local from SMBlib code errors?              */
-
-#define SMBlibE_Success 0
-#define SMBlibE_Remote  1    /* Remote error, get more info from con        */
-#define SMBlibE_BAD     -1
-#define SMBlibE_LowerLayer 2 /* Lower layer error                           */
-#define SMBlibE_NotImpl 3    /* Function not yet implemented                */
-#define SMBlibE_ProtLow 4    /* Protocol negotiated does not support req    */
-#define SMBlibE_NoSpace 5    /* No space to allocate a structure            */
-#define SMBlibE_BadParam 6   /* Bad parameters                              */
-#define SMBlibE_NegNoProt 7  /* None of our protocols was liked             */
-#define SMBlibE_SendFailed 8 /* Sending an SMB failed                       */
-#define SMBlibE_RecvFailed 9 /* Receiving an SMB failed                     */
-#define SMBlibE_GuestOnly 10 /* Logged in as guest                          */
-#define SMBlibE_CallFailed 11 /* Call remote end failed                     */
-#define SMBlibE_ProtUnknown 12 /* Protocol unknown                          */
-#define SMBlibE_NoSuchMsg  13 /* Keep this up to date                       */
diff --git a/authprogs/smbval/smblib-priv.h b/authprogs/smbval/smblib-priv.h
deleted file mode 100644 (file)
index 155b66b..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* UNIX SMBlib NetBIOS implementation
-
-   Version 1.0
-   SMBlib private Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "smblib-common.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-typedef unsigned short uint16;
-typedef unsigned int   uint32;
-
-#include "byteorder.h"     /* Hmmm ... hot good */
-
-#define SMB_DEF_IDF 0x424D53FF        /* "\377SMB" */
-/* The protocol commands and constants we need */
-#define SMBnegprot    0x72   /* negotiate protocol */
-#define SMBsesssetupX 0x73   /* Session Set Up & X (including User Logon) */
-#define SMBdialectID  0x02   /* a dialect id */
-
-typedef unsigned short WORD;
-typedef unsigned short UWORD;
-typedef unsigned int ULONG;
-typedef unsigned char BYTE;
-typedef unsigned char UCHAR;
-
-/* Some macros to allow access to actual packet data so that we */
-/* can change the underlying representation of packets.         */
-/*                                                              */
-/* The current formats vying for attention are a fragment       */
-/* approach where the SMB header is a fragment linked to the    */
-/* data portion with the transport protocol (rfcnb or whatever) */
-/* being linked on the front.                                   */
-/*                                                              */
-/* The other approach is where the whole packet is one array    */
-/* of bytes with space allowed on the front for the packet      */
-/* headers.                                                     */
-
-#define SMB_Hdr(p) (char *)(p -> data)
-
-/* SMB Hdr def for File Sharing Protocol? From MS and Intel,    */
-/* Intel PN 138446 Doc Version 2.0, Nov 7, 1988. This def also  */
-/* applies to LANMAN1.0 as well as the Core Protocol            */
-/* The spec states that wct and bcc must be present, even if 0  */
-
-/* We define these as offsets into a char SMB[] array for the   */
-/* sake of portability                                          */
-
-/* NOTE!. Some of the lenght defines, SMB_<protreq>_len do not include */
-/* the data that follows in the SMB packet, so the code will have to   */
-/* take that into account.                                             */
-
-#define SMB_hdr_idf_offset    0          /* 0xFF,'SMB' 0-3 */
-#define SMB_hdr_com_offset    4          /* BYTE       4   */
-#define SMB_hdr_rcls_offset   5          /* BYTE       5   */
-#define SMB_hdr_reh_offset    6          /* BYTE       6   */
-#define SMB_hdr_err_offset    7          /* WORD       7   */
-#define SMB_hdr_reb_offset    9          /* BYTE       9   */
-#define SMB_hdr_flg_offset    9          /* same as reb ...*/
-#define SMB_hdr_res_offset    10         /* 7 WORDs    10  */
-#define SMB_hdr_res0_offset   10         /* WORD       10  */
-#define SMB_hdr_flg2_offset   10         /* WORD           */
-#define SMB_hdr_res1_offset   12         /* WORD       12  */
-#define SMB_hdr_res2_offset   14
-#define SMB_hdr_res3_offset   16
-#define SMB_hdr_res4_offset   18
-#define SMB_hdr_res5_offset   20
-#define SMB_hdr_res6_offset   22
-#define SMB_hdr_tid_offset    24
-#define SMB_hdr_pid_offset    26
-#define SMB_hdr_uid_offset    28
-#define SMB_hdr_mid_offset    30
-#define SMB_hdr_wct_offset    32
-
-#define SMB_hdr_len           33        /* 33 byte header?      */
-
-#define SMB_hdr_axc_offset    33        /* AndX Command         */
-#define SMB_hdr_axr_offset    34        /* AndX Reserved        */
-#define SMB_hdr_axo_offset    35     /* Offset from start to WCT of AndX cmd */
-
-/* Format of the Negotiate Protocol SMB */
-
-#define SMB_negp_bcc_offset   33
-#define SMB_negp_buf_offset   35        /* Where the buffer starts   */
-#define SMB_negp_len          35        /* plus the data             */
-
-/* Format of the Negotiate Response SMB, for CoreProtocol, LM1.2 and */
-/* NT LM 0.12. wct will be 1 for CoreProtocol, 13 for LM 1.2, and 17 */
-/* for NT LM 0.12                                                    */
-
-#define SMB_negrCP_idx_offset   33        /* Response to the neg req */
-#define SMB_negrCP_bcc_offset   35
-#define SMB_negrLM_idx_offset   33        /* dialect index           */
-#define SMB_negrLM_sec_offset   35        /* Security mode           */
-#define SMB_sec_user_mask       0x01      /* 0 = share, 1 = user     */
-#define SMB_sec_encrypt_mask    0x02      /* pick out encrypt        */
-#define SMB_negrLM_mbs_offset   37        /* max buffer size         */
-#define SMB_negrLM_mmc_offset   39        /* max mpx count           */
-#define SMB_negrLM_mnv_offset   41        /* max number of VCs       */
-#define SMB_negrLM_rm_offset    43        /* raw mode support bit vec*/
-#define SMB_negrLM_sk_offset    45        /* session key, 32 bits    */
-#define SMB_negrLM_st_offset    49        /* Current server time     */
-#define SMB_negrLM_sd_offset    51        /* Current server date     */
-#define SMB_negrLM_stz_offset   53        /* Server Time Zone        */
-#define SMB_negrLM_ekl_offset   55        /* encryption key length   */
-#define SMB_negrLM_res_offset   57        /* reserved                */
-#define SMB_negrLM_bcc_offset   59        /* bcc                     */
-#define SMB_negrLM_len          61        /* 61 bytes ?              */
-#define SMB_negrLM_buf_offset   61        /* Where the fun begins    */
-
-#define SMB_negrNTLM_idx_offset 33        /* Selected protocol       */
-#define SMB_negrNTLM_sec_offset 35        /* Security more           */
-#define SMB_negrNTLM_mmc_offset 36        /* Different format above  */
-#define SMB_negrNTLM_mnv_offset 38        /* Max VCs                 */
-#define SMB_negrNTLM_mbs_offset 40        /* MBS now a long          */
-#define SMB_negrNTLM_mrs_offset 44        /* Max raw size            */
-#define SMB_negrNTLM_sk_offset  48        /* Session Key             */
-#define SMB_negrNTLM_cap_offset 52        /* Capabilities            */
-#define SMB_negrNTLM_stl_offset 56        /* Server time low         */
-#define SMB_negrNTLM_sth_offset 60        /* Server time high        */
-#define SMB_negrNTLM_stz_offset 64        /* Server time zone        */
-#define SMB_negrNTLM_ekl_offset 66        /* Encrypt key len         */
-#define SMB_negrNTLM_bcc_offset 67        /* Bcc                     */
-#define SMB_negrNTLM_len        69
-#define SMB_negrNTLM_buf_offset 69
-
-/* Offsets for Delete file                                           */
-
-#define SMB_delet_sat_offset    33        /* search attribites          */
-#define SMB_delet_bcc_offset    35        /* bcc                        */
-#define SMB_delet_buf_offset    37
-#define SMB_delet_len           37
-
-/* Offsets for SESSION_SETUP_ANDX for both LM and NT LM protocols    */
-
-#define SMB_ssetpLM_mbs_offset  37        /* Max buffer Size, allow for AndX */
-#define SMB_ssetpLM_mmc_offset  39        /* max multiplex count             */
-#define SMB_ssetpLM_vcn_offset  41        /* VC number if new VC             */
-#define SMB_ssetpLM_snk_offset  43        /* Session Key                     */
-#define SMB_ssetpLM_pwl_offset  47        /* password length                 */
-#define SMB_ssetpLM_res_offset  49        /* reserved                        */
-#define SMB_ssetpLM_bcc_offset  53        /* bcc                             */
-#define SMB_ssetpLM_len         55        /* before data ...                 */
-#define SMB_ssetpLM_buf_offset  55
-
-#define SMB_ssetpNTLM_mbs_offset 37       /* Max Buffer Size for NT LM 0.12  */
-                                          /* and above                       */
-#define SMB_ssetpNTLM_mmc_offset 39       /* Max Multiplex count             */
-#define SMB_ssetpNTLM_vcn_offset 41       /* VC Number                       */
-#define SMB_ssetpNTLM_snk_offset 43       /* Session key                     */
-#define SMB_ssetpNTLM_cipl_offset 47      /* Case Insensitive PW Len         */
-#define SMB_ssetpNTLM_cspl_offset 49      /* Unicode pw len                  */
-#define SMB_ssetpNTLM_res_offset 51       /* reserved                        */
-#define SMB_ssetpNTLM_cap_offset 55       /* server capabilities             */
-#define SMB_ssetpNTLM_bcc_offset 59       /* bcc                             */
-#define SMB_ssetpNTLM_len        61       /* before data                     */
-#define SMB_ssetpNTLM_buf_offset 61
-
-#define SMB_ssetpr_axo_offset  35         /* Offset of next response ...    */
-#define SMB_ssetpr_act_offset  37         /* action, bit 0 = 1 => guest     */
-#define SMB_ssetpr_bcc_offset  39         /* bcc                            */
-#define SMB_ssetpr_buf_offset  41         /* Native OS etc                  */
-
-/* The following two arrays need to be in step!              */
-/* We must make it possible for callers to specify these ... */
-
-extern const char *SMB_Prots[];
-extern int SMB_Types[];
-
-typedef struct SMB_Connect_Def * SMB_Handle_Type;
-
-struct SMB_Connect_Def {
-
-  SMB_Handle_Type Next_Con, Prev_Con;          /* Next and previous conn */
-  int protocol;                                /* What is the protocol   */
-  int prot_IDX;                                /* And what is the index  */
-  void *Trans_Connect;                         /* The connection         */
-
-  /* All these strings should be malloc'd */
-
-  char service[80], username[80], password[80], desthost[80], sock_options[80];
-  char address[80], myname[80];
-
-  int gid;         /* Group ID, do we need it?                      */
-  int mid;         /* Multiplex ID? We might need one per con       */
-  int pid;         /* Process ID                                    */
-
-  int uid;         /* Authenticated user id.                        */
-
-                   /* It is pretty clear that we need to bust some of */
-                   /* these out into a per TCon record, as there may  */
-                   /* be multiple TCon's per server, etc ... later    */
-
-  int port;        /* port to use in case not default, this is a TCPism! */
-
-  int max_xmit;    /* Max xmit permitted by server                  */
-  int Security;    /* 0 = share, 1 = user                           */
-  int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */
-  bool encrypt_passwords; /* false = don't                          */ 
-  int MaxMPX, MaxVC, MaxRaw;
-  unsigned int SessionKey, Capabilities;
-  int SvrTZ;                                 /* Server Time Zone */
-  int Encrypt_Key_Len;
-  char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40];
-  char Svr_OS[80], Svr_LMType[80], Svr_PDom[80];
-
-};
-
-#define SMBLIB_DEFAULT_OSNAME "UNIX of some type"
-#define SMBLIB_DEFAULT_LMTYPE "SMBlib LM2.1 minus a bit"
-#define SMBLIB_MAX_XMIT 65535
-
-/* global Variables for the library */
-
-#ifndef SMBLIB_ERRNO
-extern int SMBlib_errno;
-extern int SMBlib_SMB_Error;          /* last Error             */
-#endif
-
-/* From smbdes.c. */
-void E_P16(unsigned char *, unsigned char *);
-void E_P24(unsigned char *, unsigned char *, unsigned char *);
-
-/* From smblib-util.c. */
-void SMB_Get_My_Name(char *name, int len);
-
-/* From smbencrypt.c. */
-void SMBencrypt(unsigned char *passwd, unsigned char *, unsigned char *);
diff --git a/authprogs/smbval/smblib-util.c b/authprogs/smbval/smblib-util.c
deleted file mode 100644 (file)
index 27f5619..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/* UNIX SMBlib NetBIOS implementation
-
-   Version 1.0
-   SMBlib Utility Routines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "smblib-priv.h"
-#include "rfcnb.h"
-
-/* The following two arrays need to be in step!              */
-/* We must make it possible for callers to specify these ... */
-
-const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", 
-                           "MICROSOFT NETWORKS 1.03",
-                           "MICROSOFT NETWORKS 3.0",
-                           "DOS LANMAN1.0",
-                           "LANMAN1.0",
-                           "DOS LM1.2X002",
-                           "LM1.2X002",
-                           "DOS LANMAN2.1",
-                           "LANMAN2.1",
-                           "Samba",
-                           "NT LM 0.12",
-                           "NT LANMAN 1.0",
-                           NULL};
-
-int SMB_Types[] = {SMB_P_Core,
-                   SMB_P_CorePlus,
-                   SMB_P_DOSLanMan1,
-                   SMB_P_DOSLanMan1,
-                   SMB_P_LanMan1,
-                   SMB_P_DOSLanMan2,
-                   SMB_P_LanMan2,
-                   SMB_P_LanMan2_1,
-                   SMB_P_LanMan2_1,
-                   SMB_P_NT1,
-                   SMB_P_NT1,
-                   SMB_P_NT1,
-                   -1};
-
-/* Figure out what protocol was accepted, given the list of dialect strings */
-/* We offered, and the index back from the server. We allow for a user      */
-/* supplied list, and assume that it is a subset of our list                */
-
-int SMB_Figure_Protocol(const char *dialects[], int prot_index)
-
-{ int i;
-
-  if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */
-
-    return(SMB_Types[prot_index]);
-  }
-  else { /* Search through SMB_Prots looking for a match */
-
-    for (i = 0; SMB_Prots[i] != NULL; i++) {
-
-      if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */
-
-       return(SMB_Types[i]);
-
-      }
-
-    }
-
-    /* If we got here, then we are in trouble, because the protocol was not */
-    /* One we understand ...                                                */
-
-    return(SMB_P_Unknown);
-
-  }
-
-}
-
-
-/* Negotiate the protocol we will use from the list passed in Prots       */
-/* we return the index of the accepted protocol in NegProt, -1 indicates  */
-/* none acceptible, and our return value is 0 if ok, <0 if problems       */
-
-int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
-{
-  struct RFCNB_Pkt *pkt;
-  int prots_len, i, pkt_len, prot, alloc_len;
-  char *p;
-
-  /* Figure out how long the prot list will be and allocate space for it */
-
-  prots_len = 0;
-
-  for (i = 0; Prots[i] != NULL; i++) {
-
-    prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */
-
-  }
-
-  /* The -1 accounts for the one byte smb_buf we have because some systems */
-  /* don't like char msg_buf[]                                             */
-
-  pkt_len = SMB_negp_len + prots_len;
-
-  /* Make sure that the pkt len is long enough for the max response ...   */
-  /* Which is a problem, because the encryption key len eec may be long   */
-
-  if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40)) {
-
-    alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40;
-
-  }
-  else {
-
-    alloc_len = pkt_len;
-
-  }
-
-  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(alloc_len);
-
-  if (pkt == NULL) {
-
-    SMBlib_errno = SMBlibE_NoSpace;
-    return(SMBlibE_BAD);
-
-  }
-
-  /* Now plug in the bits we need */
-
-  memset(SMB_Hdr(pkt), 0, SMB_negp_len);
-  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
-  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot;
-  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
-  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
-  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
-  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
-  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
-
-  SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len);
-
-  /* Now copy the prot strings in with the right stuff */
-
-  p = (char *)(SMB_Hdr(pkt) + SMB_negp_buf_offset);
-
-  for (i = 0; Prots[i] != NULL; i++) {
-
-    *p = SMBdialectID;
-    strcpy(p + 1, Prots[i]);
-    p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */
-
-  }
-
-  /* Now send the packet and sit back ... */
-
-  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){
-
-
-#ifdef DEBUG
-    fprintf(stderr, "Error sending negotiate protocol\n");
-#endif
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */
-    return(SMBlibE_BAD);
-
-  }
-
-  /* Now get the response ... */
-
-  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, alloc_len) < 0) {
-
-#ifdef DEBUG
-    fprintf(stderr, "Error receiving response to negotiate\n");
-#endif
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */
-    return(SMBlibE_BAD);
-
-  }
-
-  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
-
-#ifdef DEBUG
-    fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n",
-           CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
-           SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
-#endif
-
-    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_Remote;
-    return(SMBlibE_BAD);
-
-  }
-  
-  if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
-
-#ifdef DEBUG
-    fprintf(stderr, "None of our protocols was accepted ... ");
-#endif
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_NegNoProt;
-    return(SMBlibE_BAD);
-
-  }
-
-  /* Now, unpack the info from the response, if any and evaluate the proto */
-  /* selected. We must make sure it is one we like ...                     */
-
-  Con_Handle -> prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset);
-  Con_Handle -> protocol = SMB_Figure_Protocol(Prots, prot);
-
-  if (Con_Handle -> protocol == SMB_P_Unknown) { /* No good ... */
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_ProtUnknown;
-    return(SMBlibE_BAD);
-
-  }
-  
-  switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
-
-  case 0x01:      /* No more info ... */
-
-    break;
-
-  case 13:        /* Up to and including LanMan 2.1 */
-
-    Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset);
-    Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
-    Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
-
-    Con_Handle -> max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset);
-    Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset);
-    Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset);
-    Con_Handle -> Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset);
-    Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
-    Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
-    Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
-    
-    p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
-    fprintf(stderr, "%p", (char *)(SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
-    memcpy(Con_Handle->Encrypt_Key, p, 8);
-
-    p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
-
-    strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
-
-    break;
-
-  case 17:        /* NT LM 0.12 and LN LM 1.0 */
-
-    Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset);
-    Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
-    Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
-
-    Con_Handle -> max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset);
-    Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset);
-    Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset);
-    Con_Handle -> MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset);
-    Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset);
-    Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset);
-    Con_Handle -> Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset);
-
-    p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset );
-    memcpy(Con_Handle -> Encrypt_Key, p, 8);
-    p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
-
-    strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
-
-    break;
-
-  default:
-
-#ifdef DEBUG
-    fprintf(stderr, "Unknown NegProt response format ... Ignored\n");
-    fprintf(stderr, "  wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset));
-#endif
-
-    break;
-  }
-
-#ifdef DEBUG
-  fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]);
-#endif
-
-  RFCNB_Free_Pkt(pkt);
-  return(0);
-
-}
-
-/* Get our hostname */
-
-void SMB_Get_My_Name(char *name, int len)
-
-{
-  if (gethostname(name, len) < 0) { /* Error getting name */
-
-    strncpy(name, "unknown", len);
-
-    /* Should check the error */
-
-#ifdef DEBUG
-    fprintf(stderr, "gethostname in SMB_Get_My_Name returned error:");
-    perror("");
-#endif
-
-  }
-
-  /* only keep the portion up to the first "." */
-
-
-}
diff --git a/authprogs/smbval/smblib.c b/authprogs/smbval/smblib.c
deleted file mode 100644 (file)
index 06c8509..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/* UNIX SMBlib NetBIOS implementation
-
-   Version 1.0
-   SMBlib Routines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <signal.h>
-
-int SMBlib_errno;
-int SMBlib_SMB_Error;
-#define SMBLIB_ERRNO
-typedef unsigned char uchar;
-#include "smblib-priv.h"
-
-#include "rfcnb.h"
-
-/* Initialize the SMBlib package     */
-
-int SMB_Init()
-
-{
-  signal(SIGPIPE, SIG_IGN);   /* Ignore these ... */
-
-  return 0;
-
-}
-
-int SMB_Term()
-
-{
-
-  return 0;
-
-}
-
-/* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */
-/* or anything else ...                                                  */
-
-SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle,
-                                  char *server, char *NTdomain)
-
-{ SMB_Handle_Type con;
-  char called[80], calling[80], *address;
-  int i;
-
-  /* Get a connection structure if one does not exist */
-
-  con = Con_Handle;
-
-  if (Con_Handle == NULL) {
-
-    if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) {
-
-
-      SMBlib_errno = SMBlibE_NoSpace;
-      return NULL;
-    }
-
-  }
-
-  /* Init some things ... */
-
-  strlcpy(con->service, "", sizeof(con->service));
-  strlcpy(con->username, "", sizeof(con->username));
-  strlcpy(con->password, "", sizeof(con->password));
-  strlcpy(con->sock_options, "", sizeof(con->sock_options));
-  strlcpy(con->address, "", sizeof(con->address));
-  strlcpy(con->desthost, server, sizeof(con->desthost));
-  strlcpy(con->PDomain, NTdomain, sizeof(con->PDomain));
-  strlcpy(con->OSName, SMBLIB_DEFAULT_OSNAME, sizeof(con->OSName));
-  strlcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE, sizeof(con->LMType));
-
-  SMB_Get_My_Name(con -> myname, sizeof(con -> myname));
-
-  con -> port = 0;                    /* No port selected */
-
-  /* Get some things we need for the SMB Header */
-
-  con -> pid = getpid();
-  con -> mid = con -> pid;      /* This will do for now ... */
-  con -> uid = 0;               /* Until we have done a logon, no uid ... */ 
-  con -> gid = getgid();
-
-  /* Now connect to the remote end, but first upper case the name of the
-     service we are going to call, sine some servers want it in uppercase */
-
-  for (i=0; i < strlen(server); i++)
-    called[i] = toupper(server[i]);
-                      
-  called[strlen(server)] = 0;    /* Make it a string */
-
-  for (i=0; i < strlen(con -> myname); i++)
-    calling[i] = toupper(con -> myname[i]);
-                      
-  calling[strlen(con -> myname)] = 0;    /* Make it a string */
-
-  if (strcmp(con -> address, "") == 0)
-    address = con -> desthost;
-  else
-    address = con -> address;
-
-  con -> Trans_Connect = RFCNB_Call(called,
-                                   calling,
-                                   address, /* Protocol specific */
-                                   con -> port);
-
-  /* Did we get one? */
-
-  if (con -> Trans_Connect == NULL) {
-
-    if (Con_Handle == NULL) {
-      Con_Handle = NULL;
-      free(con);
-    }
-    SMBlib_errno = -SMBlibE_CallFailed;
-    return NULL;
-
-  }
-
-  return(con);
-
-}
-
-/* Logon to the server. That is, do a session setup if we can. We do not do */
-/* Unicode yet!                                                             */
-
-int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, 
-                    char *PassWord)
-
-{ struct RFCNB_Pkt *pkt;
-  int param_len, pkt_len, pass_len;
-  char *p, pword[128];
-
-  /* First we need a packet etc ... but we need to know what protocol has  */
-  /* been negotiated to figure out if we can do it and what SMB format to  */
-  /* use ...                                                               */
-
-  if (Con_Handle -> protocol < SMB_P_LanMan1) {
-
-    SMBlib_errno = SMBlibE_ProtLow;
-    return(SMBlibE_BAD);
-
-  }
-
-  strlcpy(pword, PassWord, sizeof(pword));
-  if (Con_Handle -> encrypt_passwords)
-  {
-    pass_len=24;
-    SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword); 
-  } 
-  else 
-       pass_len=strlen(pword);
-
-
-  /* Now build the correct structure */
-
-  if (Con_Handle -> protocol < SMB_P_NT1) {
-
-    param_len = strlen(UserName) + 1 + pass_len + 1 + 
-                strlen(Con_Handle -> PDomain) + 1 + 
-               strlen(Con_Handle -> OSName) + 1;
-
-    pkt_len = SMB_ssetpLM_len + param_len;
-
-    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
-
-    if (pkt == NULL) {
-
-      SMBlib_errno = SMBlibE_NoSpace;
-      return(SMBlibE_BAD); /* Should handle the error */
-
-    }
-
-    memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len);
-    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
-    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
-    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
-    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
-
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
-    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1);
-    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
-
-    /* Now copy the param strings in with the right stuff */
-
-    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
-
-    /* Copy  in password, then the rest. Password has a null at end */
-
-    memcpy(p, pword, pass_len);
-
-    p = p + pass_len + 1;
-
-    strcpy(p, UserName);
-    p = p + strlen(UserName);
-    *p = 0;
-
-    p = p + 1;
-
-    strcpy(p, Con_Handle -> PDomain);
-    p = p + strlen(Con_Handle -> PDomain);
-    *p = 0;
-    p = p + 1;
-
-    strcpy(p, Con_Handle -> OSName);
-    p = p + strlen(Con_Handle -> OSName);
-    *p = 0;
-
-  }
-  else {
-
-    /* We don't admit to UNICODE support ... */
-
-    param_len = strlen(UserName) + 1 + pass_len + 
-                strlen(Con_Handle -> PDomain) + 1 + 
-               strlen(Con_Handle -> OSName) + 1 +
-               strlen(Con_Handle -> LMType) + 1;
-
-    pkt_len = SMB_ssetpNTLM_len + param_len;
-
-    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
-
-    if (pkt == NULL) {
-
-      SMBlib_errno = SMBlibE_NoSpace;
-      return(-1); /* Should handle the error */
-
-    }
-
-    memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len);
-    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
-    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
-    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
-    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
-    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
-
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
-    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
-    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
-    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
-    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
-
-    /* Now copy the param strings in with the right stuff */
-
-    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
-
-    /* Copy  in password, then the rest. Password has no null at end */
-
-    memcpy(p, pword, pass_len);
-
-    p = p + pass_len;
-
-    strcpy(p, UserName);
-    p = p + strlen(UserName);
-    *p = 0;
-
-    p = p + 1;
-
-    strcpy(p, Con_Handle -> PDomain);
-    p = p + strlen(Con_Handle -> PDomain);
-  *p = 0;
-    p = p + 1;
-
-    strcpy(p, Con_Handle -> OSName);
-    p = p + strlen(Con_Handle -> OSName);
-    *p = 0;
-    p = p + 1;
-
-    strcpy(p, Con_Handle -> LMType);
-    p = p + strlen(Con_Handle -> LMType);
-    *p = 0;
-
-  }
-
-  /* Now send it and get a response */
-
-  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_SendFailed;
-    return(SMBlibE_BAD);
-
-  }
-
-  /* Now get the response ... */
-
-  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
-
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_RecvFailed;
-    return(SMBlibE_BAD);
-
-  }
-
-  /* Check out the response type ... */
-
-  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
-
-    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
-    RFCNB_Free_Pkt(pkt);
-    SMBlib_errno = SMBlibE_Remote;
-    return(SMBlibE_BAD);
-
-  }
-/** @@@ mdz: check for guest login { **/
-       if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1)
-       {
-               /* do we allow guest login? NO! */
-               return(SMBlibE_BAD);
-       }
- /** @@@ mdz: } **/
-
-
-  /* Now pick up the UID for future reference ... */
-
-  Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
-  RFCNB_Free_Pkt(pkt);
-
-  return(0);
-
-}
-
-
-/* Disconnect from the server, and disconnect all tree connects */
-
-int SMB_Discon(SMB_Handle_Type Con_Handle, bool KeepHandle)
-
-{
-
-  /* We just disconnect the connection for now ... */
-
-  RFCNB_Hangup(Con_Handle -> Trans_Connect);
-
-  if (!KeepHandle)
-    free(Con_Handle);
-
-  return(0);
-
-}
diff --git a/authprogs/smbval/smblib.h b/authprogs/smbval/smblib.h
deleted file mode 100644 (file)
index a93255f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* UNIX SMBlib NetBIOS implementation
-
-   Version 1.0
-   SMBlib Defines
-
-   Copyright (C) Richard Sharpe 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "smblib-common.h"
-
-/* Just define all the entry points */
-
-/* Initialize the library. */
-
-int SMB_Init(void);
-
-/* Connect to a server, but do not do a tree con etc ... */
-
-void *SMB_Connect_Server(void *Con, char *server, char *NTdomain);
-
-/* Negotiate a protocol                                                  */
-
-int SMB_Negotiate(void *Con_Handle, char *Prots[]);
-
-/* Disconnect from server. Has flag to specify whether or not we keep the */
-/* handle.                                                                */
-
-int SMB_Discon(void *Con, bool KeepHandle);
-
-/* Log on to a server. */
-
-int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
-                     char *PassWord);
diff --git a/authprogs/smbval/valid.c b/authprogs/smbval/valid.c
deleted file mode 100644 (file)
index 425b14f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/types.h>
-#include <unistd.h>
-#include <syslog.h>
-#include "config.h"
-#include "smblib-priv.h"
-#include "smblib.h"
-#include "valid.h"
-
-int Valid_User(char *USERNAME,char *PASSWORD,char *SERVER,char *BACKUP, char *DOMAIN)
-{
-  char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0",
-                           "MICROSOFT NETWORKS 1.03",
-                           "MICROSOFT NETWORKS 3.0",
-                           "LANMAN1.0",
-                           "LM1.2X002",
-                           "Samba",
-                           "NT LM 0.12",
-                           "NT LANMAN 1.0",
-                           NULL};
-  SMB_Handle_Type con;
-
-  SMB_Init();
-  con = SMB_Connect_Server(NULL, SERVER, DOMAIN);
-  if (con == NULL) { /* Error ... */
-   con = SMB_Connect_Server(NULL, BACKUP, DOMAIN);
-   if (con == NULL) {
-       return(NTV_SERVER_ERROR);   
-   }
-  }
-  if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */
-    SMB_Discon(con,0);
-    return(NTV_PROTOCOL_ERROR);
-  }
-  /* Test for a server in share level mode do not authenticate against it */
-  if (con -> Security == 0)
-    {
-      SMB_Discon(con,0);
-      return(NTV_PROTOCOL_ERROR);
-    }
-
-  if (SMB_Logon_Server(con, USERNAME, PASSWORD) < 0) {
-    SMB_Discon(con,0);
-    return(NTV_LOGON_ERROR);
-  }
-  
-  SMB_Discon(con,0);
-  return(NTV_NO_ERROR);
-}
diff --git a/authprogs/smbval/valid.h b/authprogs/smbval/valid.h
deleted file mode 100644 (file)
index 00d068b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _VALID_H_
-#define _VALID_H_
-/* SMB User verification function */
-
-#define NTV_NO_ERROR 0
-#define NTV_SERVER_ERROR 1
-#define NTV_PROTOCOL_ERROR 2
-#define NTV_LOGON_ERROR 3
-
-int Valid_User(char *USERNAME,char *PASSWORD,char *SERVER, char *BACKUP, char *DOMAIN);
-
-#endif
diff --git a/backends/actmerge.in b/backends/actmerge.in
deleted file mode 100644 (file)
index 237a332..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-# @(#) $Id: actmerge.in 2674 1999-11-15 06:28:29Z rra $
-# @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actmerge.sh,v
-#
-# actmerge - merge two active files
-#
-# usage:
-#      actmerge [-s] ign1 ign2 host1 host2 
-#
-#      -s      - write status on stderr even if no fatal error
-#      ign1    - ignore file for host1
-#      ign2    - ignore file for host2
-#      host1   - 1st active file or host
-#      host2   - 2nd active file or host
-#
-# The merge of two active files are sent to stdout.  The status is
-# written to stderr.
-
-# By: Landon Curt Noll         chongo@toad.com         (chongo was here /\../\)
-#
-# Copyright (c) Landon Curt Noll, 1996.
-# All rights reserved.
-#
-# Permission to use and modify is hereby granted so long as this 
-# notice remains.  Use at your own risk.  No warranty is implied.
-
-# preset vars
-#
-
-# Our lock file
-LOCK=${LOCKS}/LOCK.actmerge
-# where actsync is located
-ACTSYNC=${PATHBIN}/actsync
-# exit value of actsync if unable to get an active file
-NOSYNC=127
-# args used by actsync a fetch of an active file
-FETCH="-b 0 -d 0 -g 0 -o aK -p 0 -q 12 -s 0 -t 0 -v 2"
-# args used to merge two active files
-MERGE="-b 0 -d 0 -g 0 -m -o aK -p 0 -q 12 -s 0 -t 0 -v 3"
-# unless -q
-QUIET=true
-
-# parse args
-#
-if [ $# -gt 1 ]; then
-    if [ X"-s" = X"$1" ]; then
-       QUIET=
-       shift
-    fi
-fi
-if [ $# -ne 4 ]; then
-    echo "usage: $0 ign1 ign2 host1 host2" 1>&2
-    exit 1
-fi
-ign1="$1"
-if [ ! -s "$ign1" ]; then
-    echo "$0: host1 ignore file not found or empty: $ign1" 1>&2
-    exit 2
-fi
-ign2="$2"
-if [ ! -s "$ign2" ]; then
-    echo "$0: host2 ignore file not found or empty: $ign2" 1>&2
-    exit 3
-fi
-host1="$3"
-host2="$4"
-
-
-# Lock out others
-#
-trap 'rm -f ${LOCK}; exit 1' 0 1 2 3 15
-shlock -p $$ -f ${LOCK} || {
-    echo "$0: Locked by `cat ${LOCK}`" 1>&2
-    exit 4
-}
-
-# setup
-#
-tmp="$TMPDIR/.merge$$"
-act1="$TMPDIR/.act1$$"
-act2="$TMPDIR/.act2$$"
-trap "rm -f $tmp ${LOCK} $act1 $act2; exit" 0 1 2 3 15
-rm -f "$tmp"
-touch "$tmp"
-chmod 0600 "$tmp"
-rm -f "$act1"
-touch "$act1"
-chmod 0600 "$act1"
-rm -f "$act2"
-touch "$act2"
-chmod 0600 "$act2"
-
-# try to fetch the first active file
-#
-echo "=-= fetching $host1" >>$tmp
-eval "$ACTSYNC -i $ign1 $FETCH /dev/null $host1 > $act1 2>>$tmp"
-status=$?
-if [ "$status" -ne 0 ]; then
-
-    # We failed on our first try, so we will trice knock 3 times after
-    # waiting 5 minutes.
-    #
-    for loop in 1 2 3; do
-
-       # wait 5 minutes
-       sleep 300
-
-       # try #1
-       eval "$ACTSYNC -i $ign1 $FETCH /dev/null $host1 > $act1 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-
-       # try #2
-       eval "$ACTSYNC -i $ign1 $FETCH /dev/null $host1 > $act1 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-
-       # try #3
-       eval "$ACTSYNC -i $ign1 $FETCH /dev/null $host1 > $act1 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-    done
-
-    # give up
-    #
-    if [ "$status" -ne 0 ]; then
-       echo "=-= `date` merge $host1 $host2 exit $status" 1>&2
-       sed -e 's/^/    /' < "$tmp" 1>&2
-       exit "$status"
-    fi
-fi
-if [ ! -s "$act1" ]; then
-    echo "$0: host1 active file not found or empty: $act1" 1>&2
-    exit 5
-fi
-
-# try to fetch the second active file
-#
-echo "=-= fetching $host2" >>$tmp
-eval "$ACTSYNC -i $ign2 $FETCH /dev/null $host2 > $act2 2>>$tmp"
-status=$?
-if [ "$status" -ne 0 ]; then
-
-    # We failed on our first try, so we will trice knock 3 times after
-    # waiting 5 minutes.
-    #
-    for loop in 1 2 3; do
-
-       # wait 5 minutes
-       sleep 300
-
-       # try #1
-       eval "$ACTSYNC -i $ign2 $FETCH /dev/null $host2 > $act2 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-
-       # try #2
-       eval "$ACTSYNC -i $ign2 $FETCH /dev/null $host2 > $act2 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-
-       # try #3
-       eval "$ACTSYNC -i $ign2 $FETCH /dev/null $host2 > $act2 2>>$tmp"
-       status=$?
-       if [ "$status" -eq "$NOSYNC" ]; then
-           break;
-       fi
-    done
-
-    # give up
-    #
-    if [ "$status" -ne 0 ]; then
-       echo "=-= `date` merge $host1 $host2 exit $status" 1>&2
-       sed -e 's/^/    /' < "$tmp" 1>&2
-       exit "$status"
-    fi
-fi
-if [ ! -s "$act2" ]; then
-    echo "$0: host2 active file not found or empty: $act2" 1>&2
-    exit 6
-fi
-
-# merge the 2 active files to stdout
-#
-echo "=-= merging $host1 and $host2" >>$tmp
-eval "$ACTSYNC $MERGE $act1 $act2" 2>>$tmp
-status=$?
-if [ "$status" -ne 0 ]; then
-    echo "=-= `date` merge $host1 $host2 exit $status" 1>&2
-    sed -e 's/^/    /' < "$tmp" 1>&2
-    exit "$status"
-fi
-
-# if not -q, send status to stderr
-#
-if [ -z "$QUIET" ]; then
-    echo "=-= `date` merge $host1 $host2 successful" 1>&2
-    sed -e 's/^/    /' < "$tmp" 1>&2
-fi
-
-# all done
-#
-rm -f "${LOCK}"
-exit 0
diff --git a/backends/actsync.c b/backends/actsync.c
deleted file mode 100644 (file)
index 41c35e0..0000000
+++ /dev/null
@@ -1,2766 +0,0 @@
-/* @(#) $Id: actsync.c 6372 2003-05-31 19:48:28Z rra $ */
-/* @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actsync.c,v */
-/*
- * actsync - sync or merge two active files
- *
- * usage:
- *    actsync [-b hostid][-d hostid][-g max][-i ignore_file][-I][-k][-l hostid]
- *           [-m][-n name][-o fmt][-p %][-q hostid][-s size]
- *           [-t hostid][-T][-v verbose_lvl][-z sec]
- *           [host1] host2
- *
- *      -A              use authentication to server
- *     -b hostid       ignore *.bork.bork.bork groups from:      (def: -b 0)
- *                         0   from neither host
- *                         1   from host1
- *                         2   from host2
- *                         12  from host1 and host2
- *                         21  from host1 and host2
- *     -d hostid       ignore groups with all numeric components (def: -d 0)
- *     -g max          ignore group >max levels (0=dont ignore)  (def: -g 0)
- *     -i ignore_file  file with list/types of groups to ignore  (def: no file)
- *     -I hostid       ignore_file applies only to hostid        (def: -I 12)
- *     -k              keep host1 groups with errors             (def: remove)
- *     -l hostid       flag =group problems as errors            (def: -l 12)
- *     -m              merge, keep group not on host2            (def: sync)
- *     -n name         name given to ctlinnd newgroup commands   (def: actsync)
- *     -o fmt          type of output:                           (def: -o c)
- *                         a   output groups in active format
- *                         a1  like 'a', but output ignored non-err host1 grps
- *                         ak  like 'a', keep host2 hi/low values on new groups
- *                         aK  like 'a', use host2 hi/low values always
- *                         c   output in ctlinnd change commands
- *                         x   no output, safely exec ctlinnd commands
- *                         xi  no output, safely exec commands interactively
- *     -p %            min % host1 lines unchanged allowed       (def: -p 96)
- *     -q hostid       silence errors from a host (see -b)       (def: -q 0)
- *     -s size         ignore names longer than size (0=no lim)  (def: -s 0)
- *     -t hostid       ignore bad top level groups from:(see -b) (def: -t 2)
- *     -T              no new hierarchies                        (def: allow)
- *     -v verbose_lvl  verbosity level                           (def: -v 0)
- *                         0   no debug or status reports
- *                         1   summary if work done
- *                         2   summary & actions (if exec output) only if done
- *                         3   summary & actions (if exec output)
- *                         4   debug output plus all -v 3 messages
- *     -z sec          sleep sec seconds per exec if -o x        (def: -z 4)
- *     host1           host to be changed                  (def: local server)
- *     host2           reference host used in merge
- */
-/* 
- * By: Landon Curt Noll        chongo@toad.com         (chongo was here /\../\)
- *
- * Copyright (c) Landon Curt Noll, 1996.
- * All rights reserved.
- *
- * Permission to use and modify is hereby granted so long as this 
- * notice remains.  Use at your own risk.  No warranty is implied.
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/stat.h>
-#include <signal.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-
-static const char usage[] = "\
-Usage: actsync [-A][-b hostid][-d hostid][-i ignore_file][-I hostid][-k]\n\
-        [-l hostid][-m][-n name][-o fmt][-p min_%_unchg][-q hostid]\n\
-        [-s size][-t hostid][-T][-v verbose_lvl][-z sec]\n\
-        [host1] host2\n\
-\n\
-    -A          use authentication to server\n\
-    -b hostid   ignore *.bork.bork.bork groups from:    (def: -b 0)\n\
-                0       from neither host\n\
-                1       from host1\n\
-                2       from host2\n\
-                12      from host1 and host2\n\
-                21      from host1 and host2\n\
-    -d hostid   ignore grps with all numeric components (def: -d 0)\n\
-    -g max      ignore group >max levels (0=don't)      (def: -g 0)\n\
-    -i file     file with groups to ignore              (def: no file)\n\
-    -I hostid   ignore_file applies only to hostid      (def: -I 12)\n\
-    -k          keep host1 groups with errors           (def: remove)\n\
-    -l hostid   flag =group problems as errors          (def: -l 12)\n\
-    -m          merge, keep group not on host2          (def: sync)\n\
-    -n name     name given to ctlinnd newgroup cmds     (def: actsync)\n\
-    -o fmt      type of output:                         (def: -o c)\n\
-                a       output groups in active format\n\
-                a1      like 'a', but output ignored non-err host1 grps\n\
-                ak      like 'a', keep host2 hi/low values on new groups\n\
-                aK      like 'a', use host2 hi/low values always\n\
-                c       output in ctlinnd change commands\n\
-                x       no output, safely exec ctlinnd commands\n\
-                xi      no output, safely exec commands interactively\n\
-    -p %        min % host1 lines unchanged allowed     (def: -p 96)\n\
-    -q hostid   silence errors from a host (see -b)     (def: -q 0)\n\
-    -s size     ignore names > than size (0=no lim)     (def: -s 0)\n\
-    -t hostid   ignore bad top level grps from: (see -b)(def: -t 2)\n\
-    -T          no new hierarchies                      (def: allow)\n\
-    -v level    verbosity level                         (def: -v 0)\n\
-                0       no debug or status reports\n\
-                1       summary if work done\n\
-                2       summary & actions (if exec output) only if done\n\
-                3       summary & actions (if exec output)\n\
-                4       debug output plus all -v 3 messages\n\
-    -z sec      sleep sec seconds per exec if -o x      (def: -z 4)\n\
-\n\
-    host1       host to be changed                      (def: local server)\n\
-    host2       reference host used in merge\n";
-
-
-/*
- * pat - internal ignore/check pattern
- *
- * A pattern, derived from an ignore file, will determine if a group
- * is will be checked if it is on both hosts or ignored altogether.
- *
- * The type related to the 4th field of an active file.  Types may
- * currently be one of [ymjnx=].  If '=' is one of the types, an
- * optional equivalence pattern may be given in the 'epat' element.
- *
- * For example, to ignore "foo.bar.*", if it is junked or equated to
- * a group of the form "alt.*.foo.bar.*":
- *
- *     x.pat = "foo.bar.*";
- *     x.type = "j=";
- *     x.epat = "alt.*.foo.bar.*";
- *     x.ignore = 1;
- *
- * To further check "foo.bar.mod" if it is moderated:
- *
- *     x.pat = "foo.bar.mod";
- *     x.type = "m";
- *     x.epat = NULL;
- *     x.ignore = 0;
- *
- * The 'i' value means ignore, 'c' value means 'compare'.   The last pattern
- * that matches a group determines the fate of the group.  By default all
- * groups are included.
- */
-struct pat {
-    char *pat;         /* newsgroup pattern */
-    int type_match;    /* 1 => match only if group type matches */
-    int y_type;                /* 1 => match if a 'y' type group */
-    int m_type;                /* 1 => match if a 'm' type group */
-    int n_type;                /* 1 => match if a 'n' type group */
-    int j_type;                /* 1 => match if a 'j' type group */
-    int x_type;                /* 1 => match if a 'x' type group */
-    int eq_type;       /* 1 => match if a 'eq' type group */
-    char *epat;                /* =pattern to match, if non-NULL and = is in type */
-    int ignore;                /* 0 => check matching group, 1 => ignore it */
-};
-
-/* internal representation of an active line */
-struct grp {
-    int ignore;                /* ignore reason, 0 => not ignore (see below) */
-    int hostid;                /* HOSTID this group is from */
-    int linenum;       /* >0 => active line number, <=0 => not a line */
-    int output;                /* 1 => output to produce the merged active file */
-    int remove;                /* 1 => remove this group */
-    char *name;                /* newsgroup name */
-    char *hi;          /* high article string */
-    char *low;         /* low article string */
-    char *type;                /* newsgroup type string */
-    char *outhi;       /* output high article string */
-    char *outlow;      /* output low article string */
-    char *outtype;     /* output newsgroup type string */
-};
-
-/* structure used in the process of looking for =group type problems */
-struct eqgrp {
-    int skip;          /* 1 => skip this entry */
-    struct grp *g;     /* =group that is being examined */
-    char *eq;          /* current equivalence name */
-};
-
-/*
- * These ignore reasons are listed in order severity; from mild to severe.
- */
-#define NOT_IGNORED    0x0000  /* newsgroup has not been ignored */
-#define CHECK_IGNORE   0x0001  /* ignore file ignores this entry */
-#define CHECK_TYPE     0x0002  /* group type is ignored */
-#define CHECK_BORK     0x0004  /* group is a *.bork.bork.bork group */
-#define CHECK_HIER     0x0008  /* -T && new group's hierarchy does not exist */
-#define ERROR_LONGLOOP 0x0010  /* =name refers to long =grp chain or cycle */
-#define ERROR_EQLOOP   0x0020  /* =name refers to itself in some way */
-#define ERROR_NONEQ    0x0040  /* =name does not refer to a valid group */
-#define ERROR_DUP      0x0080  /* newsgroup is a duplicate of another */
-#define ERROR_EQNAME   0x0100  /* =name is a bad group name */
-#define ERROR_BADTYPE  0x0200  /* newsgroup type is invalid */
-#define ERROR_BADNAME  0x0400  /* newsgroup name is invalid */
-#define ERROR_FORMAT   0x0800  /* entry line is malformed */
-
-#define IS_IGNORE(ign) ((ign) & (CHECK_IGNORE|CHECK_TYPE|CHECK_BORK|CHECK_HIER))
-#define IS_ERROR(ign) ((ign) & ~(CHECK_IGNORE|CHECK_TYPE|CHECK_BORK|CHECK_HIER))
-
-#define NOHOST 0               /* neither host1 nor host2 */
-#define HOSTID1 1              /* entry from the first host */
-#define HOSTID2 2              /* entry from the second host */
-
-#define CHUNK 5000             /* number of elements to alloc at a time */
-
-#define TYPES "ymjnx="         /* group types (1st char of 4th active fld) */
-#define TYPECNT (sizeof(TYPES)-1)
-
-#define DEF_HI   "0000000000"  /* default hi string value for new groups */
-#define DEF_LOW  "0000000001"  /* default low string value for new groups */
-#define WATER_LEN 10           /* string length of hi/low water mark */
-
-#define DEF_NAME "actsync"     /* default name to use for ctlinnd newgroup */
-
-#define MIN_UNCHG (double)96.0 /* min % of host1 lines unchanged allowed */
-
-#define DEV_NULL "/dev/null"   /* path to the bit bucket */
-#define CTLINND_NAME "ctlinnd" /* basename of ctlinnd command */
-#define CTLINND_TIME_OUT "-t30"        /* seconds to wait before timeout */
-
-#define READ_SIDE 0            /* read side of a pipe */
-#define WRITE_SIDE 1           /* write side of a pipe */
-
-#define EQ_LOOP 16             /* give up if =eq loop/chain is this long */
-#define NOT_REACHED 127                /* exit value if unable to get active files */
-
-#define NEWGRP_EMPTY 0         /* no new group dir was found */
-#define NEWGRP_NOCHG 1         /* new group dir found but no hi/low change */
-#define NEWGRP_CHG 2           /* new group dir found but no hi/low change */
-
-/* -b macros */
-#define BORK_CHECK(hostid)  \
-    ((hostid == HOSTID1 && bork_host1_flag) || \
-     (hostid == HOSTID2 && bork_host2_flag))
-
-/* -d macros */
-#define NUM_CHECK(hostid)  \
-    ((hostid == HOSTID1 && num_host1_flag) || \
-     (hostid == HOSTID2 && num_host2_flag))
-
-/* -t macros */
-#define TOP_CHECK(hostid)  \
-    ((hostid == HOSTID1 && t_host1_flag) || \
-     (hostid == HOSTID2 && t_host2_flag))
-
-/* -o output types */
-#define OUTPUT_ACTIVE 1                /* output in active file format */
-#define OUTPUT_CTLINND 2       /* output in ctlinnd change commands */
-#define OUTPUT_EXEC 3          /* no output, safely exec commands */
-#define OUTPUT_IEXEC 4         /* no output, exec commands interactively */
-
-/* -q macros */
-#define QUIET(hostid)  \
-    ((hostid == HOSTID1 && quiet_host1) || (hostid == HOSTID2 && quiet_host2))
-
-/* -v verbosity level */
-#define VER_MIN 0              /* minimum -v level */
-#define VER_NONE 0             /* no -v output */
-#define VER_SUMM_IF_WORK 1     /* output summary if actions were performed */
-#define VER_REPT_IF_WORK 2     /* output summary & actions only if performed */
-#define VER_REPORT 3           /* output summary & actions performed */
-#define VER_FULL 4             /* output all summary, actins and debug */
-#define VER_MAX 4              /* maximum -v level */
-#define D_IF_SUMM (v_flag >= VER_SUMM_IF_WORK) /* true => give summary always */
-#define D_REPORT (v_flag >= VER_REPT_IF_WORK)  /* true => give reports */
-#define D_BUG (v_flag == VER_FULL)            /* true => debug processing */
-#define D_SUMMARY (v_flag >= VER_REPORT)       /* true => give summary always */
-
-/* flag and arg related defaults */
-int bork_host1_flag = 0;       /* 1 => -b 1 or -b 12 or -b 21 given */
-int bork_host2_flag = 0;       /* 1 => -b 2 or -b 12 or -b 21 given */
-int num_host1_flag = 0;        /* 1 => -d 1 or -d 12 or -d 21 given */
-int num_host2_flag = 0;        /* 1 => -d 2 or -d 12 or -d 21 given */
-char *ign_file = NULL;         /* default ignore file */
-int ign_host1_flag = 1;                /* 1 => -i ign_file applies to host1 */
-int ign_host2_flag = 1;                /* 1 => -i ign_file applies to host2 */
-int g_flag = 0;                        /* ignore grps deeper than > g_flag, 0=>dont */
-int k_flag = 0;                        /* 1 => -k given */
-int l_host1_flag = HOSTID1;    /* HOSTID1 => host1 =group error detection */
-int l_host2_flag = HOSTID2;    /* HOSTID2 => host2 =group error detection */
-int m_flag = 0;                        /* 1 => merge active files, don't sync */
-const char *new_name = DEF_NAME;       /* ctlinnd newgroup name */
-int o_flag = OUTPUT_CTLINND;   /* default output type */
-double p_flag = MIN_UNCHG;     /* min % host1 lines allowed to be unchanged */
-int host1_errs = 0;            /* errors found in host1 active file */
-int host2_errs = 0;            /* errors found in host2 active file */
-int quiet_host1 = 0;           /* 1 => -q 1 or -q 12 or -q 21 given */
-int quiet_host2 = 0;           /* 1 => -q 2 or -q 12 or -q 21 given */
-int s_flag = 0;                        /* max group size (length), 0 => do not check */
-int t_host1_flag = 0;          /* 1 => -t 1 or -t 12 or -t 21 given */
-int t_host2_flag = 1;          /* 1 => -t 2 or -d 12 or -t 21 given */
-int no_new_hier = 0;           /* 1 => -T; no new hierarchies */
-int host2_hilow_newgrp = 0;    /* 1 => use host2 hi/low on new groups */
-int host2_hilow_all = 0;       /* 1 => use host2 hi/low on all groups */
-int host1_ign_print = 0;       /* 1 => print host1 ignored groups too */
-int v_flag = 0;                        /* default verbosity level */
-int z_flag = 4;                        /* sleep z_flag sec per exec if -o x */
-int A_flag = 0;
-
-/* forward declarations */
-static struct grp *get_active();    /* get an active file from a remote host */
-static int bad_grpname();          /* test if string is a valid group name */
-static struct pat *get_ignore();    /* read in an ignore file */
-static void ignore();              /* ignore newsgroups given an ignore list */
-static int merge_cmp();                    /* qsort compare for active file merge */
-static void merge_grps();          /* merge groups from active files */
-static int active_cmp();           /* qsort compare for active file output */
-static void output_grps();         /* output the merged groups */
-static void process_args();        /* process command line arguments */
-static void error_mark();          /* mark for removal, error grps from host */
-static int eq_merge_cmp();         /* qsort compare for =type grp processing */
-static int mark_eq_probs();        /* mark =type problems from a host */
-static int exec_cmd();             /* exec a ctlinnd command */
-static int new_top_hier();         /* see if we have a new top level */
-
-int
-main(argc, argv)
-    int         argc;                  /* arg count */
-    char *argv[];              /* the args */
-{
-    struct grp *grp;           /* struct grp array for host1 & host2 */
-    struct pat *ignor;         /* ignore list from ignore file */
-    int grplen;                        /* length of host1/host2 group array */
-    int iglen;                 /* length of ignore list */
-    char *host1;               /* host to change */
-    char *host2;               /* comparison host */
-
-    /* First thing, set up our identity. */
-    message_program_name = "actsync";
-
-    /* Read in default info from inn.conf. */
-    if (!innconf_read(NULL))
-        exit(1);
-    process_args(argc, argv, &host1, &host2);
-
-    /* obtain the active files */
-    grp = get_active(host1, HOSTID1, &grplen, NULL, &host1_errs);
-    grp = get_active(host2, HOSTID2, &grplen, grp, &host2_errs);
-
-    /* ignore groups from both active files, if -i */
-    if (ign_file != NULL) {
-
-       /* read in the ignore file */
-       ignor = get_ignore(ign_file, &iglen);
-
-       /* ignore groups */
-       ignore(grp, grplen, ignor, iglen);
-    }
-
-    /* compare groups from both hosts */
-    merge_grps(grp, grplen, host1, host2);
-
-    /* mark for removal, error groups from host1 if -e */
-    if (! k_flag) {
-
-       /* mark error groups for removal */
-       error_mark(grp, grplen, HOSTID1);
-    }
-
-    /* output result of merge */
-    output_grps(grp, grplen);
-
-    /* all done */
-    exit(0);
-}
-
-/*
- * process_args - process the command line arguments
- *
- * given:
- *     argc    arg count
- *     argv    the args
- *     host1   name of first host (may be 2nd if -R)
- *     host2   name of second host2 *may be 1st if -R)
- */
-static void
-process_args(argc, argv, host1, host2)
-    int argc;          /* arg count */
-    char *argv[];      /* the arg array */
-    char **host1;      /* where to place name of host1 */
-    char **host2;      /* where to place name of host2 */
-{
-    char *def_serv = NULL;     /* name of default server */
-    int i;
-
-    /* parse args */
-    while ((i = getopt(argc,argv,"Ab:d:g:i:I:kl:mn:o:p:q:s:t:Tv:z:")) != EOF) {
-       switch (i) {
-       case 'A':
-           A_flag = 1;
-           break;
-       case 'b':               /* -b {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               bork_host1_flag = 0;
-               bork_host2_flag = 0;
-               break;
-           case 1:
-               bork_host1_flag = 1;
-               break;
-           case 2:
-               bork_host2_flag = 1;
-               break;
-           case 12:
-           case 21:
-               bork_host1_flag = 1;
-               bork_host2_flag = 1;
-               break;
-           default:
-                warn("-b option must be 0, 1, 2, 12, or 21");
-                die("%s", usage);
-           }
-           break;
-       case 'd':               /* -d {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               num_host1_flag = 0;
-               num_host2_flag = 0;
-               break;
-           case 1:
-               num_host1_flag = 1;
-               break;
-           case 2:
-               num_host2_flag = 1;
-               break;
-           case 12:
-           case 21:
-               num_host1_flag = 1;
-               num_host2_flag = 1;
-               break;
-           default:
-                warn("-d option must be 0, 1, 2, 12, or 21");
-               die("%s", usage);
-           }
-           break;
-       case 'g':               /* -g max */
-           g_flag = atoi(optarg);
-           break;
-       case 'i':               /* -i ignore_file */
-           ign_file = optarg;
-           break;
-       case 'I':               /* -I {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               ign_host1_flag = 0;
-               ign_host2_flag = 0;
-               break;
-           case 1:
-               ign_host1_flag = 1;
-               ign_host2_flag = 0;
-               break;
-           case 2:
-               ign_host1_flag = 0;
-               ign_host2_flag = 1;
-               break;
-           case 12:
-           case 21:
-               ign_host1_flag = 1;
-               ign_host2_flag = 1;
-               break;
-           default:
-                warn("-I option must be 0, 1, 2, 12, or 21");
-               die("%s", usage);
-           }
-           break;
-       case 'k':               /* -k */
-           k_flag = 1;
-           break;
-       case 'l':               /* -l {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               l_host1_flag = NOHOST;
-               l_host2_flag = NOHOST;
-               break;
-           case 1:
-               l_host1_flag = HOSTID1;
-               l_host2_flag = NOHOST;
-               break;
-           case 2:
-               l_host1_flag = NOHOST;
-               l_host2_flag = HOSTID2;
-               break;
-           case 12:
-           case 21:
-               l_host1_flag = HOSTID1;
-               l_host2_flag = HOSTID2;
-               break;
-           default:
-                warn("-l option must be 0, 1, 2, 12, or 21");
-               die("%s", usage);
-           }
-           break;
-       case 'm':               /* -m */
-           m_flag = 1;
-           break;
-       case 'n':               /* -n name */
-           new_name = optarg;
-           break;
-       case 'o':               /* -o out_type */
-           switch (optarg[0]) {
-           case 'a':
-               o_flag = OUTPUT_ACTIVE;
-               switch (optarg[1]) {
-               case '1':
-                   switch(optarg[2]) {
-                   case 'K':   /* -o a1K */
-                       host1_ign_print = 1;
-                       host2_hilow_all = 1;
-                       host2_hilow_newgrp = 1;
-                       break;
-                   case 'k':   /* -o a1k */
-                       host1_ign_print = 1;
-                       host2_hilow_newgrp = 1;
-                       break;
-                   default:    /* -o a1 */
-                       host1_ign_print = 1;
-                       break;
-                   }
-                   break;
-               case 'K':
-                   switch(optarg[2]) {
-                   case '1':   /* -o aK1 */
-                       host1_ign_print = 1;
-                       host2_hilow_all = 1;
-                       host2_hilow_newgrp = 1;
-                       break;
-                   default:    /* -o aK */
-                       host2_hilow_all = 1;
-                       host2_hilow_newgrp = 1;
-                       break;
-                   };
-                   break;
-               case 'k':
-                   switch(optarg[2]) {
-                   case '1':   /* -o ak1 */
-                       host1_ign_print = 1;
-                       host2_hilow_newgrp = 1;
-                       break;
-                   default:    /* -o ak */
-                       host2_hilow_newgrp = 1;
-                       break;
-                   };
-                   break;
-               case '\0':      /* -o a */
-                   break;
-               default:
-                    warn("-o type must be a, a1, ak, aK, ak1, or aK1");
-                   die("%s", usage);
-               }
-               break;
-           case 'c':
-               o_flag = OUTPUT_CTLINND;
-               break;
-           case 'x':
-               if (optarg[1] == 'i') {
-                   o_flag = OUTPUT_IEXEC;
-               } else {
-                   o_flag = OUTPUT_EXEC;
-               }
-               break;
-           default:
-                warn("-o type must be a, a1, ak, aK, ak1, aK1, c, x, or xi");
-               die("%s", usage);
-           }
-           break;
-       case 'p':               /* -p %_min_host1_change */
-           /* parse % into [0,100] */
-           p_flag = atof(optarg);
-           if (p_flag > (double)100.0) {
-               p_flag = (double)100.0;
-           } else if (p_flag < (double)0.0) {
-               p_flag = (double)0.0;
-           }
-           break;
-       case 'q':               /* -q {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               quiet_host1 = 0;
-               quiet_host2 = 0;
-               break;
-           case 1:
-               quiet_host1 = 1;
-               break;
-           case 2:
-               quiet_host2 = 1;
-               break;
-           case 12:
-           case 21:
-               quiet_host1 = 1;
-               quiet_host2 = 1;
-               break;
-           default:
-                warn("-q option must be 0, 1, 2, 12, or 21");
-               die("%s", usage);
-           }
-           break;
-       case 's':               /* -s size */
-           s_flag = atoi(optarg);
-           break;
-       case 't':               /* -t {0|1|2|12|21} */
-           switch (atoi(optarg)) {
-           case 0:
-               t_host1_flag = NOHOST;
-               t_host2_flag = NOHOST;
-               break;
-           case 1:
-               t_host1_flag = HOSTID1;
-               t_host2_flag = NOHOST;
-               break;
-           case 2:
-               t_host1_flag = NOHOST;
-               t_host2_flag = HOSTID2;
-               break;
-           case 12:
-           case 21:
-               t_host1_flag = HOSTID1;
-               t_host2_flag = HOSTID2;
-               break;
-           default:
-                warn("-t option must be 0, 1, 2, 12, or 21");
-               die("%s", usage);
-           }
-           break;
-       case 'T':               /* -T */
-           no_new_hier = 1;
-           break;
-       case 'v':               /* -v verbose_lvl */
-           v_flag = atoi(optarg);
-           if (v_flag < VER_MIN || v_flag > VER_MAX) {
-                warn("-v level must be >= %d and <= %d", VER_MIN, VER_MAX);
-               die("%s", usage);
-           }
-           break;
-       case 'z':               /* -z sec */
-           z_flag = atoi(optarg);
-           break;
-       default:
-            warn("unknown flag");
-           die("%s", usage);
-       }
-    }
-
-    /* process the remaining args */
-    argc -= optind;
-    argv += optind;
-    *host1 = NULL;
-    switch (argc) {
-    case 1:
-       /* assume host1 is the local server */
-       *host2 = argv[0];
-       break;
-    case 2:
-       *host1 = argv[0];
-       *host2 = argv[1];
-       break;
-    default:
-        warn("expected 1 or 2 host args, found %d", argc);
-       die("%s", usage);
-    }
-
-    /* determine default host name if needed */
-    if (*host1 == NULL || strcmp(*host1, "-") == 0) {
-       def_serv = innconf->server;
-       *host1 = def_serv;
-    }
-    if (*host2 == NULL || strcmp(*host2, "-") == 0) {
-       def_serv = innconf->server;
-       *host2 = def_serv;
-    }
-    if (*host1 == NULL || *host2 == NULL)
-        die("unable to determine default server name");
-    if (D_BUG && def_serv != NULL)
-        warn("STATUS: using default server: %s", def_serv);
-
-    /* processing done */
-    return;
-}
-
-/*
- * get_active - get an active file from a host
- *
- * given:
- *     host    host to contact or file to read, NULL => local server
- *     hostid  HOST_ID of host
- *     len     pointer to length of grp return array
- *     grp     existing host array to add, or NULL
- *     errs    count of lines that were found to have some error
- *
- * returns;
- *     Pointer to an array of grp structures describing each active entry.
- *     Does not return on fatal error.
- *
- * If host starts with a '/' or '.', then it is assumed to be a local file.
- * In that case, the local file is opened and read.
- */
-static struct grp *
-get_active(host, hostid, len, grp, errs)
-    char *host;                        /* the host to contact */
-    int hostid;                        /* HOST_ID of host */
-    int *len;                  /* length of returned grp array in elements */
-    struct grp* grp;           /* existing group array or NULL */
-    int *errs;                 /* line error count */
-{
-    FILE *active;              /* stream for fetched active data */
-    FILE *FromServer;          /* stream from server */
-    FILE *ToServer;            /* stream to server */
-    QIOSTATE *qp;              /* QIO active state */
-    char buff[8192+1];         /* QIO buffer */
-    char *line;                        /* the line just read */
-    struct grp *ret;           /* array of groups to return */
-    struct grp *cur;           /* current grp entry being formed */
-    int max;                   /* max length of ret */
-    int cnt;                   /* number of entries read */
-    int ucnt;                  /* number of entries to be used */
-    int namelen;               /* length of newsgroup name */
-    int is_file;               /* 1 => host is actually a filename */
-    int num_check;             /* true => check for all numeric components */
-    char *rhost;
-    int rport;
-    char *p;
-    int i;
-
-    /* firewall */
-    if (len == NULL)
-        die("internal error #1: len is NULL");
-    if (errs == NULL)
-        die("internal error #2: errs in NULL");
-    if (D_BUG)
-        warn("STATUS: obtaining active file from %s", host);
-
-    /* setup return array if needed */
-    if (grp == NULL) {
-        ret = xmalloc(CHUNK * sizeof(struct grp));
-       max = CHUNK;
-       *len = 0;
-
-    /* or prep to use the existing array */
-    } else {
-       ret = grp;
-       max = ((*len + CHUNK-1)/CHUNK)*CHUNK;
-    }
-
-    /* check for host being a filename */
-    if (host != NULL && (host[0] == '/' || host[0] == '.')) {
-
-       /* note that host is actually a file */
-       is_file = 1;
-
-       /* setup to read the local file quickly */
-       if ((qp = QIOopen(host)) == NULL)
-            sysdie("cannot open active file");
-
-    /* case: host is a hostname or NULL (default server) */
-    } else {
-
-       /* note that host is actually a hostname or NULL */
-       is_file = 0;
-
-        /* prepare remote host variables */
-       if ((p = strchr(host, ':')) != NULL) {
-               rport = atoi(p + 1);
-               *p = '\0';
-               rhost = xstrdup(host);
-               *p = ':';
-       } else {
-               rhost = xstrdup(host);
-               rport = NNTP_PORT;
-       }
-
-       /* open a connection to the server */
-       buff[0] = '\0';
-       if (NNTPconnect(rhost, rport, &FromServer, &ToServer, buff) < 0)
-            die("cannot connect to server: %s",
-                buff[0] ? buff : strerror(errno));
-
-        if (A_flag && NNTPsendpassword(rhost, FromServer, ToServer) < 0)
-            die("cannot authenticate to server");
-
-       free(rhost);
-
-       /* get the active data from the server */
-       active = CAlistopen(FromServer, ToServer, NULL);
-       if (active == NULL)
-            sysdie("cannot retrieve data");
-
-       /* setup to read the retrieved data quickly */
-       if ((qp = QIOfdopen((int)fileno(active))) == NULL)
-            sysdie("cannot read temp file");
-    }
-
-    /* scan server's output, processing appropriate lines */
-    num_check = NUM_CHECK(hostid);
-    for (cnt=0, ucnt=0; (line = QIOread(qp)) != NULL; ++(*len), ++cnt) {
-
-       /* expand return array if needed */
-       if (*len >= max) {
-           max += CHUNK;
-            ret = xrealloc(ret, sizeof(struct grp) * max);
-       }
-
-       /* setup the next return element */
-       cur = &ret[*len];
-       cur->ignore = NOT_IGNORED;
-       cur->hostid = hostid;
-       cur->linenum = cnt+1;
-       cur->output = 0;
-       cur->remove = 0;
-       cur->name = NULL;
-       cur->hi = NULL;
-       cur->low = NULL;
-       cur->type = NULL;
-       cur->outhi = NULL;
-       cur->outlow = NULL;
-       cur->outtype = NULL;
-
-       /* obtain a copy of the current line */
-        cur->name = xstrdup(line);
-
-       /* get the group name */
-       if ((p = strchr(cur->name, ' ')) == NULL) {
-           if (!QUIET(hostid))
-                warn("line %d from %s is malformed, skipping line", cnt + 1,
-                     host);
-
-           /* don't form an entry for this group */
-           --(*len);
-           continue;
-       }
-       *p = '\0';
-       namelen = p - cur->name;
-
-       /* find the other 3 fields, ignore if not found */
-       cur->hi = p+1;
-       if ((p = strchr(p + 1, ' ')) == NULL) {
-           if (!QUIET(hostid))
-                warn("skipping malformed line %d (field 2) from %s", cnt + 1,
-                     host);
-
-           /* don't form an entry for this group */
-           --(*len);
-           continue;
-       }
-       *p = '\0';
-       cur->low = p+1;
-       if ((p = strchr(p + 1, ' ')) == NULL) {
-           if (!QUIET(hostid))
-                warn("skipping malformed line %d (field 3) from %s", cnt + 1,
-                     host);
-
-           /* don't form an entry for this group */
-           --(*len);
-           continue;
-       }
-       *p = '\0';
-       cur->type = p+1;
-       if ((p = strchr(p + 1, ' ')) != NULL) {
-           if (!QUIET(hostid))
-                warn("skipping line %d from %s, it has more than 4 fields",
-                     cnt + 1, host);
-
-           /* don't form an entry for this group */
-           --(*len);
-           continue;
-       }
-
-       /* check for bad group name */
-       if (bad_grpname(cur->name, num_check)) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s has a bad newsgroup name",
-                     cnt + 1, cur->name, host);
-           cur->ignore |= ERROR_BADNAME;
-           continue;
-       }
-
-       /* check for long name if requested */
-       if (s_flag > 0 && strlen(cur->name) > (size_t)s_flag) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s has a name that is too long",
-                     cnt + 1, cur->name, host);
-           cur->ignore |= ERROR_BADNAME;
-           continue;
-       }
-
-       /* look for only a bad top level element if the proper -t was given */
-       if (TOP_CHECK(hostid)) {
-
-           /* look for a '.' in the name */
-           if (strcmp(cur->name, "junk") != 0 && 
-               strcmp(cur->name, "control") != 0 && 
-               strcmp(cur->name, "to") != 0 && 
-               strcmp(cur->name, "test") != 0 && 
-               strcmp(cur->name, "general") != 0 && 
-               strchr(cur->name, '.') == NULL) {
-               if (!QUIET(hostid))
-                    warn("line %d <%s> from %s is an invalid top level name",
-                         cnt + 1, cur->name, host);
-               cur->ignore |= ERROR_BADNAME;
-               continue;
-           }
-       }
-
-       /* look for *.bork.bork.bork groups if the proper -b was given */
-       if (BORK_CHECK(cur->hostid)) {
-           int elmlen;         /* length of element */
-           char *q;            /* beyond end of element */
-
-           /* scan the name backwards */
-           q = &(cur->name[namelen]);
-           for (p = &(cur->name[namelen-1]); p >= cur->name; --p) {
-               /* if '.', see if this is a bork element */
-               if (*p == '.') {
-                   /* see if the bork element is short enough */
-                   elmlen = q-p;
-                   if (3*elmlen <= q-cur->name) {
-                       /* look for a triple match */
-                       if (strncmp(p,p-elmlen,elmlen) == 0 &&
-                           strncmp(p,p-(elmlen*2),elmlen) == 0) {
-                           /* found a *.bork.bork.bork group */
-                           cur->ignore |= CHECK_BORK;
-                           break;
-                       }
-                   }
-                   /* note the end of a new element */
-                   q = p;
-               }
-           }
-       }
-
-       /* 
-        * check for bad chars in the hi water mark 
-        */
-       for (p=cur->hi, i=0; *p && isascii(*p) && isdigit((int)*p); ++p, ++i) {
-       }
-       if (*p) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s has non-digits in hi water",
-                     cnt + 1, cur->name, cur->hi);
-           cur->ignore |= ERROR_FORMAT;
-           continue;
-       }
-
-       /*
-        * check for excessive hi water length
-        */
-       if (i > WATER_LEN) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s hi water len: %d < %d",
-                     cnt + 1, cur->name, cur->hi, i, WATER_LEN);
-           cur->ignore |= ERROR_FORMAT;
-           continue;
-       }
-
-       /*
-        * if the hi water length is too small, malloc and resize
-        */
-       if (i != WATER_LEN) {
-            p = xmalloc(WATER_LEN + 1);
-           memcpy(p, cur->hi, ((i > WATER_LEN) ? WATER_LEN : i)+1);
-       }
-
-       /* 
-        * check for bad chars in the low water mark 
-        */
-       for (p=cur->low, i=0; *p && isascii(*p) && isdigit((int)*p); ++p, ++i) {
-       }
-       if (*p) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s has non-digits in low water",
-                    cnt + 1, cur->name, cur->low);
-           cur->ignore |= ERROR_FORMAT;
-           continue;
-       }
-
-       /*
-        * check for excessive low water length
-        */
-       if (i > WATER_LEN) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s low water len: %d < %d",
-                    cnt + 1, cur->name, cur->hi, i, WATER_LEN);
-           cur->ignore |= ERROR_FORMAT;
-           continue;
-       }
-
-       /*
-        * if the low water length is too small, malloc and resize
-        */
-       if (i != WATER_LEN) {
-            p = xmalloc(WATER_LEN + 1);
-           memcpy(p, cur->low, ((i > WATER_LEN) ? WATER_LEN : i)+1);
-       }
-
-       /* check for a bad group type */
-       switch (cur->type[0]) {
-       case 'y':
-               /* of COURSE: collabra has incompatible flags. but it   */
-               /* looks like they can be fixed easily enough.          */
-               if (cur->type[1] == 'g') {
-                       cur->type[1] = '\0';
-               }
-       case 'm':
-       case 'j':
-       case 'n':
-       case 'x':
-           if (cur->type[1] != '\0') {
-               if (!QUIET(hostid))
-                    warn("line %d <%s> from %s has a bad newsgroup type",
-                         cnt + 1, cur->name, host);
-               cur->ignore |= ERROR_BADTYPE;
-           }
-           break;
-       case '=':
-           if (cur->type[1] == '\0') {
-               if (!QUIET(hostid))
-                    warn("line %d <%s> from %s has an empty =group name",
-                         cnt + 1, cur->name, host);
-               cur->ignore |= ERROR_BADTYPE;
-           }
-           break;
-       default:
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s has an unknown newsgroup type",
-                     cnt + 1, cur->name, host);
-           cur->ignore |= ERROR_BADTYPE;
-           break;
-       }
-       if (cur->ignore & ERROR_BADTYPE) {
-           continue;
-       }
-
-       /* if an = type, check for bad = name */
-       if (cur->type[0] == '=' && bad_grpname(&(cur->type[1]), num_check)) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s is equivalenced to a bad name:"
-                     " <%s>", cnt+1, cur->name, host,
-                    (cur->type) ? cur->type : "NULL");
-           cur->ignore |= ERROR_EQNAME;
-           continue;
-       }
-
-       /* if an = type, check for long = name if requested */
-       if (cur->type[0] == '=' && s_flag > 0 &&
-           strlen(&(cur->type[1])) > (size_t)s_flag) {
-           if (!QUIET(hostid))
-                warn("line %d <%s> from %s is equivalenced to a long name:"
-                     " <%s>", cnt+1, cur->name, host,
-                    (cur->type) ? cur->type : "NULL");
-           cur->ignore |= ERROR_EQNAME;
-           continue;
-       }
-
-       /* count this entry which will be used */
-       ++ucnt;
-    }
-    if (D_BUG)
-        warn("STATUS: read %d groups, will merge %d groups from %s",
-             cnt, ucnt, host);
-
-    /* count the errors */
-    *errs = cnt - ucnt;
-    if (D_BUG)
-        warn("STATUS: found %d line errors from %s", *errs, host);
-
-    /* determine why we stopped */
-    if (QIOerror(qp))
-        sysdie("cannot read temp file for %s at line %d", host, cnt);
-    else if (QIOtoolong(qp))
-        sysdie("line %d from host %s is too long", cnt, host);
-
-    /* all done */
-    if (is_file) {
-       QIOclose(qp);
-    } else {
-       CAclose();
-       fprintf(ToServer, "quit\r\n");
-       fclose(ToServer);
-       fgets(buff, sizeof buff, FromServer);
-       fclose(FromServer);
-    }
-    return ret;
-}
-
-/*
- * bad_grpname - test if the string is a valid group name
- *
- * Newsgroup names must consist of only alphanumeric chars and
- * characters from the following regular expression:
- *
- *     [.+-_]
- *
- * One cannot have two '.'s in a row.  The first character must be
- * alphanumeric.  The character following a '.' must be alphanumeric.
- * The name cannot end in a '.' character.
- *
- * If we are checking for all numeric compnents, (see num_chk) then
- * a component cannot be all numeric.  I.e,. there must be a non-numeric
- * character in the name, there must be a non-numeric character between
- * the start and the first '.', there must be a non-numeric character
- * between two '.'s anmd there must be a non-numeric character between
- * the last '.' and the end.
- *
- * given:
- *     name    newsgroup name to check
- *     num_chk true => all numeric newsgroups components are invalid
- *             false => do not check for numeric newsgroups
- *
- * returns:
- *     0       group is ok
- *     1       group is bad
- */
-static int
-bad_grpname(name, num_chk)
-    char *name;                        /* newsgroup name to check */
-    int num_chk;               /* true => check for numeric newsgroup */
-{
-    char *p;
-    int non_num;       /* true => found a non-numeric, non-. character */
-    int level;         /* group levels (.'s) */
-
-    /* firewall */
-    if (name == NULL) {
-       return 1;
-    }
-
-    /* must start with a alpha numeric ascii character */
-    if (!isascii(name[0])) {
-       return 1;
-    }
-    /* set non_num as needed */
-    if (isalpha((int)name[0])) {
-       non_num = true;
-    } else if ((int)isdigit((int)name[0])) {
-       non_num = false;
-    } else {
-       return 1;
-    }
-
-    /* scan each char */
-    level = 0;
-    for (p=name+1; *p; ++p) {
-
-       /* name must contain ASCII chars */
-       if (!isascii(*p)) {
-           return 1;
-       }
-
-       /* alpha chars are ok */
-       if (isalpha((int)*p)) {
-           non_num = true;
-           continue;
-       }
-
-       /* numeric chars are ok */
-       if (isdigit((int)*p)) {
-           continue;
-       }
-
-       /* +, - and _ are ok */
-       if (*p == '+' || *p == '-' || *p == '_') {
-           non_num = true;
-           continue;
-       }
-
-       /* check for the '.' case */
-       if (*p == '.') {
-           /*
-            * look for groups that are too deep, if requested by -g
-            */
-           if (g_flag > 0 && ++level > g_flag) {
-               /* we are too deep */
-               return 1;
-           }
-
-           /*
-            * A '.' is ok as long as the next character is alphanumeric.
-            * This imples that '.' cannot before a previous '.' and
-            * that it cannot be at the end.
-            *
-            * If we are checking for all numeric compnents, then
-            * '.' is ok if we saw a non-numeric char before the
-            * last '.', or before the beginning if no previous '.'
-            * has been seen.
-            */
-           if ((!num_chk || non_num) && isascii(*(p+1)) && isalnum((int)*(p+1))) {
-               ++p;            /* '.' is ok, and so is the next char */
-               if (isdigit((int)*p)) { /* reset non_num as needed */
-                   non_num = false;
-               } else {
-                   non_num = true;
-               }
-               continue;
-           }
-       }
-
-       /* this character must be invalid */
-       return 1;
-    }
-    if (num_chk && !non_num) {
-       /* last component is all numeric */
-       return 1;
-    }
-
-    /* the name must be ok */
-    return 0;
-}
-
-/*
- * get_ignore - get the ignore list from an ignore file
- *
- * given:
- *     filename        name of the ignore file to read
- *     *len            pointer to length of ignore return array
- *
- * returns:
- *     returns a malloced ignore pattern array, changes len
- *
- * An ignore file is of the form:
- *
- *     # this is a comment which is ignored
- *     # comments begin at the first # character
- *     # comments may follow text on the same line
- *
- *     # blank lines are ignored too
- *
- *     # lines are [ic] <spaces-tabs> pattern [<spaces-tabs> type] ...
- *     i    foo.*              # ignore foo.* groups,
- *     c    foo.bar m          # but check foo.bar if moderated
- *     c    foo.keep.*         # and check foo.keep.*
- *     i    foo.keep.* j =alt.*      # except when foo.keep.* is junked
- *                                   #     or equivalenced to an alt.* group
- *
- * The 'i' value means ignore, 'c' value means 'compare'.   The last pattern
- * that matches a group determines the fate of the group.  By default all
- * groups are included.
- *
- * NOTE: Only one '=name' is allowed per line.
- *       "=" is considered to be equivalent to "=*".
- */
-static struct pat *
-get_ignore(filename, len)
-    char *filename;            /* name of the ignore file to read */
-    int *len;                  /* length of return array */
-{
-    QIOSTATE *qp;              /* QIO ignore file state */
-    char *line;                        /* the line just read */
-    struct pat *ret;           /* array of ignore patterns to return */
-    struct pat *cur;           /* current pattern entry being formed */
-    int max;                   /* max length (in elements) of ret */
-    int linenum;               /* current line number */
-    char *p;
-    int i;
-
-    /* firewall */
-    if (filename == NULL)
-        die("internal error #3: filename is NULL");
-    if (len == NULL)
-        die("internal error #4: len is NULL");
-    if (D_BUG)
-        warn("STATUS: reading ignore file %s", filename);
-
-    /* setup return array */
-    ret = xmalloc(CHUNK * sizeof(struct grp));
-    max = CHUNK;
-
-    /* setup to read the ignore file data quickly */
-    if ((qp = QIOopen(filename)) == NULL)
-        sysdie("cannot read ignore file %s", filename);
-
-    /* scan server's output, displaying appropriate lines */
-    *len = 0;
-    for (linenum = 1; (line = QIOread(qp)) != NULL; ++linenum) {
-
-       /* expand return array if needed */
-       if (*len >= max) {
-           max += CHUNK;
-            ret = xrealloc(ret, sizeof(struct pat) * max);
-       }
-
-       /* remove any trailing comments */
-       p = strchr(line, '#');
-       if (p != NULL) {
-           *p = '\0';
-       }
-
-       /* remove any trailing spaces and tabs */
-       for (p = &line[strlen(line)-1];
-            p >= line && (*p == ' ' || *p == '\t');
-            --p) {
-           *p = '\0';
-       }
-
-       /* ignore line if the remainder of the line is empty */
-       if (line[0] == '\0') {
-           continue;
-       }
-
-       /* ensure that the line starts with an i or c token */
-       if ((line[0] != 'i' && line[0] != 'c') ||
-           (line[1] != ' ' && line[1] != '\t'))
-            die("first token is not i or c in line %d of %s", linenum,
-                filename);
-
-       /* ensure that the second newsgroup pattern token follows */
-       p = strtok(line+2, " \t");
-       if (p == NULL)
-            die("did not find 2nd field in line %d of %s", linenum,
-                filename);
-
-       /* setup the next return element */
-       cur = &ret[*len];
-       cur->pat = NULL;
-       cur->type_match = 0;
-       cur->y_type = 0;
-       cur->m_type = 0;
-       cur->n_type = 0;
-       cur->j_type = 0;
-       cur->x_type = 0;
-       cur->eq_type = 0;
-       cur->epat = NULL;
-       cur->ignore = (line[0] == 'i');
-
-       /* obtain a copy of the newsgroup pattern token */
-        cur->pat = xstrdup(p);
-
-       /* process any other type tokens */
-       for (p=strtok(NULL, " \t"), i=3;
-            p != NULL;
-            p=strtok(NULL, " \t"), ++i) {
-
-           /* ensure that this next token is a valid type */
-           switch (p[0]) {
-           case 'y':
-           case 'm':
-           case 'j':
-           case 'n':
-           case 'x':
-               if (p[1] != '\0') {
-                    warn("field %d on line %d of %s not a valid type",
-                         i, linenum, filename);
-                    die("valid types are a char from [ymnjx=] or =name");
-               }
-               break;
-           case '=':
-               break;
-           default:
-                warn("field %d on line %d of %s is not a valid type",
-                     i, linenum, filename);
-                die("valid types are a char from [ymnjx=] or =name");
-            }
-
-           /* note that we have a type specific pattern */
-           cur->type_match = 1;
-
-           /* ensure that type is not a duplicate */
-           if ((p[0] == 'y' && cur->y_type) ||
-               (p[0] == 'm' && cur->m_type) ||
-               (p[0] == 'n' && cur->n_type) ||
-               (p[0] == 'j' && cur->j_type) ||
-               (p[0] == 'x' && cur->x_type) ||
-               (p[0] == '=' && cur->eq_type)) {
-                warn("only one %c type allowed per line", p[0]);
-                die("field %d on line %d of %s is a duplicate type",
-                    i, linenum, filename);
-           }
-
-           /* note what we have seen */
-           switch (p[0]) {
-           case 'y':
-               cur->y_type = 1;
-               break;
-           case 'm':
-               cur->m_type = 1;
-               break;
-           case 'j':
-               cur->j_type = 1;
-               break;
-           case 'n':
-               cur->n_type = 1;
-               break;
-           case 'x':
-               cur->x_type = 1;
-               break;
-           case '=':
-               cur->eq_type = 1;
-               if (p[0] == '=' && p[1] != '\0')
-                    cur->epat = xstrdup(p + 1);
-               break;
-           }
-
-           /* object if too many fields */
-           if (i-3 > TYPECNT)
-                die("too many fields on line %d of %s", linenum, filename);
-       }
-
-       /* count another pat element */
-       ++(*len);
-    }
-
-    /* return the pattern array */
-    return ret;
-}
-
-/*
- * ignore - ignore newsgroups given an ignore list
- *
- * given:
- *     grp     array of groups
- *     grplen  length of grp array in elements
- *     igcl    array of ignore
- *     iglen   length of igcl array in elements
- */
-static void
-ignore(grp, grplen, igcl, iglen)
-    struct grp *grp;           /* array of groups */
-    int grplen;                        /* length of grp array in elements */
-    struct pat *igcl;          /* array of ignore patterns */
-    int iglen;                 /* length of igcl array in elements */
-{
-    struct grp *gp;            /* current group element being examined */
-    struct pat *pp;            /* current pattern element being examined */
-    int g;                     /* current group index number */
-    int p;                     /* current pattern index number */
-    int ign;                   /* 1 => ignore this group, 0 => check it */
-    int icnt;                  /* groups ignored */
-    int ccnt;                  /* groups to be checked */
-
-    /* firewall */
-    if (grp == NULL)
-        die("internal error #5: grp is NULL");
-    if (igcl == NULL)
-        die("internal error $6: igcl is NULL");
-    if (D_BUG)
-        warn("STATUS: determining which groups to ignore");
-
-    /* if nothing to do, return quickly */
-    if (grplen <= 0 || iglen <= 0) {
-       return;
-    }
-
-    /* examine each group */
-    icnt = 0;
-    ccnt = 0;
-    for (g=0; g < grplen; ++g) {
-
-       /* check the group to examine */
-       gp = &grp[g];
-       if (gp->ignore) {
-           /* already ignored no need to examine */
-           continue;
-       }
-
-       /* check group against all patterns */
-       ign = 0;
-       for (p=0, pp=igcl; p < iglen; ++p, ++pp) {
-
-           /* if pattern has a specific type, check it first */
-           if (pp->type_match) {
-
-               /* specific type required, check for match */
-               switch (gp->type[0]) {
-               case 'y':
-                   if (! pp->y_type) continue;  /* pattern does not apply */
-                   break;
-               case 'm':
-                   if (! pp->m_type) continue;  /* pattern does not apply */
-                   break;
-               case 'n':
-                   if (! pp->n_type) continue;  /* pattern does not apply */
-                   break;
-               case 'j':
-                   if (! pp->j_type) continue;  /* pattern does not apply */
-                   break;
-               case 'x':
-                   if (! pp->x_type) continue;  /* pattern does not apply */
-                   break;
-               case '=':
-                   if (! pp->eq_type) continue;  /* pattern does not apply */
-                   if (pp->epat != NULL && !uwildmat(&gp->type[1], pp->epat)) {
-                       /* equiv pattern doesn't match, patt does not apply */
-                       continue;
-                   }
-                   break;
-               }
-           }
-
-           /* perform a match on group name */
-           if (uwildmat(gp->name, pp->pat)) {
-               /* this pattern fully matches, use the ignore value */
-               ign = pp->ignore;
-           }
-       }
-
-       /* if this group is to be ignored, note it */
-       if (ign) {
-           switch (gp->hostid) {
-           case HOSTID1:
-               if (ign_host1_flag) {
-                   gp->ignore |= CHECK_IGNORE;
-                   ++icnt;
-               }
-               break;
-           case HOSTID2:
-               if (ign_host2_flag) {
-                   gp->ignore |= CHECK_IGNORE;
-                   ++icnt;
-               }
-               break;
-           default:
-                die("newsgroup %s bad hostid: %d", gp->name, gp->hostid);
-           }
-       } else {
-           ++ccnt;
-       }
-    }
-    if (D_BUG)
-        warn("STATUS: examined %d groups: %d ignored, %d to be checked",
-             grplen, icnt, ccnt);
-}
-
-/*
- * merge_cmp - qsort compare function for later group merge
- *
- * given:
- *     a       group a to compare
- *     b       group b to compare
- *
- * returns:
- *     >0      a > b
- *     0       a == b elements match (fatal error if a and b are different)
- *     <0      a < b
- *
- * To speed up group comparison, we compare by the following items listed
- * in order of sorting:
- *
- *     group name
- *     hostid                  (host1 ahead of host2)
- *     linenum                 (active file line number)
- */
-static int
-merge_cmp(arg_a, arg_b)
-    const void *arg_a;         /* first qsort compare arg */
-    const void *arg_b;         /* first qsort compare arg */
-{
-    const struct grp *a = arg_a;       /* group a to compare */
-    const struct grp *b = arg_b;       /* group b to compare */
-    int i;
-
-    /* firewall */
-    if (a == b) {
-       /* we guess this could happen */
-       return(0);
-    }
-
-    /* compare group names */
-    i = strcmp(a->name, b->name);
-    if (i != 0) {
-       return i;
-    }
-
-    /* compare hostid's */
-    if (a->hostid != b->hostid) {
-       if (a->hostid > b->hostid) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* compare active line numbers */
-    if (a->linenum != b->linenum) {
-       if (a->linenum > b->linenum) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* two different elements match, this should not happen! */
-    die("two internal grp elements match!");
-    /*NOTREACHED*/
-}
-
-/*
- * merge_grps - compare groups from both hosts
- *
- * given:
- *     grp     array of groups
- *     grplen  length of grp array in elements
- *     host1   name of host with HOSTID1
- *     host2   name of host with HOSTID2
- *
- * This routine will select which groups to output form a merged active file.
- */
-static void
-merge_grps(grp, grplen, host1, host2)
-    struct grp *grp;           /* array of groups */
-    int grplen;                        /* length of grp array in elements */
-    char *host1;               /* name of host with HOSTID1 */
-    char *host2;               /* name of host with HOSTID2 */
-{
-    int cur;           /* current group index being examined */
-    int nxt;           /* next group index being examined */
-    int outcnt;                /* groups to output */
-    int rmcnt;         /* groups to remove */
-    int h1_probs;      /* =type problem groups from host1 */
-    int h2_probs;      /* =type problem groups from host2 */
-
-    /* firewall */
-    if (grp == NULL)
-        die("internal error #7: grp is NULL");
-
-    /* sort groups for the merge */
-    if (D_BUG)
-        warn("STATUS: sorting groups");
-    qsort((char *)grp, grplen, sizeof(grp[0]), merge_cmp);
-
-    /* mark =type problem groups from host2, if needed */
-    h2_probs = mark_eq_probs(grp, grplen, l_host2_flag, host1, host2);
-
-    /*
-     * We will walk thru the sorted group array, looking for pairs
-     * among the groups that we have not already ignored.
-     *
-     * If a host has duplicate groups, then the duplicates will
-     * be next to each other.
-     *
-     * If both hosts have the name group, they will be next to each other.
-     */
-    if (D_BUG)
-        warn("STATUS: merging groups");
-    outcnt = 0;
-    rmcnt = 0;
-    for (cur=0; cur < grplen; cur=nxt) {
-
-       /* determine the next group index */
-       nxt = cur+1;
-
-       /* skip if this group is ignored */
-       if (grp[cur].ignore) {
-           continue;
-       }
-       /* assert: cur is not ignored */
-
-       /* check for duplicate groups from the same host */
-       while (nxt < grplen) {
-
-           /* mark the later as a duplicate */
-           if (grp[cur].hostid == grp[nxt].hostid &&
-               strcmp(grp[cur].name, grp[nxt].name) == 0) {
-               grp[nxt].ignore |= ERROR_DUP;
-               if (!QUIET(grp[cur].hostid))
-                    warn("lines %d and %d from %s refer to the same group",
-                         grp[cur].linenum, grp[nxt].linenum,
-                         ((grp[cur].hostid == HOSTID1) ? host1 : host2));
-               ++nxt;
-           } else {
-               break;
-           }
-       }
-       /* assert: cur is not ignored */
-       /* assert: cur & nxt are not the same group from the same host */
-
-       /* if nxt is ignored, look for the next non-ignored group */
-       while (nxt < grplen && grp[nxt].ignore) {
-           ++nxt;
-       }
-       /* assert: cur is not ignored */
-       /* assert: nxt is not ignored or is beyond end */
-       /* assert: cur & nxt are not the same group from the same host */
-
-       /* case: cur and nxt are the same group */
-       if (nxt < grplen && strcmp(grp[cur].name, grp[nxt].name) == 0) {
-
-           /* assert: cur is HOSTID1 */
-           if (grp[cur].hostid != HOSTID1)
-                die("internal error #8: grp[%d].hostid: %d != %d",
-                   cur, grp[cur].hostid, HOSTID1);
-
-           /*
-            * Both hosts have the same group.  Make host1 group type
-            * match host2.  (it may already)
-            */
-           grp[cur].output = 1;
-           grp[cur].outhi = (host2_hilow_all ? grp[nxt].hi : grp[cur].hi);
-           grp[cur].outlow = (host2_hilow_all ? grp[nxt].low : grp[cur].low);
-           grp[cur].outtype = grp[nxt].type;
-           ++outcnt;
-
-           /* do not process nxt, skip to the one beyond */
-           ++nxt;
-
-       /* case: cur and nxt are different groups */
-       } else {
-
-           /*
-            * if cur is host2, then host1 doesn't have it, so output it
-            */
-           if (grp[cur].hostid == HOSTID2) {
-               grp[cur].output = 1;
-               grp[cur].outhi = (host2_hilow_newgrp ? grp[cur].hi : DEF_HI);
-               grp[cur].outlow = (host2_hilow_newgrp ? grp[cur].low : DEF_LOW);
-               grp[cur].outtype = grp[cur].type;
-               ++outcnt;
-
-           /*
-            * If cur is host1, then host2 doesn't have it.
-            * Mark for removal if -m was not given.
-            */
-           } else {
-               grp[cur].output = 1;
-               grp[cur].outhi = grp[cur].hi;
-               grp[cur].outlow = grp[cur].low;
-               grp[cur].outtype = grp[cur].type;
-               if (! m_flag) {
-                   grp[cur].remove = 1;
-                   ++rmcnt;
-               }
-           }
-
-           /* if no more groups to examine, we are done */
-           if (nxt >= grplen) {
-               break;
-           }
-       }
-    }
-
-    /* mark =type problem groups from host1, if needed */
-    h1_probs = mark_eq_probs(grp, grplen, l_host1_flag, host1, host2);
-
-    /* all done */
-    if (D_BUG) {
-        warn("STATUS: sort-merge passed thru %d groups", outcnt);
-        warn("STATUS: sort-merge marked %d groups for removal", rmcnt);
-       warn("STATUS: marked %d =type error groups from host1", h1_probs);
-        warn("STATUS: marked %d =type error groups from host2", h2_probs);
-    }
-    return;
-}
-
-/*
- * active_cmp - qsort compare function for active file style output
- *
- * given:
- *     a       group a to compare
- *     b       group b to compare
- *
- * returns:
- *     >0      a > b
- *     0       a == b elements match (fatal error if a and b are different)
- *     <0      a < b
- *
- * This sort will sort groups so that the lines that will we output
- * host1 lines followed by host2 lines.  Thus, we will sort by
- * the following keys:
- *
- *     hostid                  (host1 ahead of host2)
- *     linenum                 (active file line number)
- */
-static int
-active_cmp(arg_a, arg_b)
-    const void *arg_a;         /* first qsort compare arg */
-    const void *arg_b;         /* first qsort compare arg */
-{
-    const struct grp *a = arg_a;       /* group a to compare */
-    const struct grp *b = arg_b;       /* group b to compare */
-
-    /* firewall */
-    if (a == b) {
-       /* we guess this could happen */
-       return(0);
-    }
-
-    /* compare hostid's */
-    if (a->hostid != b->hostid) {
-       if (a->hostid > b->hostid) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* compare active line numbers */
-    if (a->linenum != b->linenum) {
-       if (a->linenum > b->linenum) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* two different elements match, this should not happen! */
-    die("two internal grp elements match!");
-    /*NOTREACHED*/
-}
-
-/*
- * output_grps - output the result of the merge
- *
- * given:
- *     grp     array of groups
- *     grplen  length of grp array in elements
- */
-static void
-output_grps(grp, grplen)
-    struct grp *grp;           /* array of groups */
-    int grplen;                        /* length of grp array in elements */
-{
-    int add;           /* number of groups added */
-    int change;                /* number of groups changed */
-    int remove;                /* number of groups removed */
-    int no_new_dir;    /* number of new groups with missing/empty dirs */
-    int new_dir;       /* number of new groupsm, non-empty dir no water chg */
-    int water_change;  /* number of new groups where hi&low water changed */
-    int work;          /* adds + changes + removals */
-    int same;          /* the number of groups the same */
-    int ignore;                /* host1 newsgroups to ignore */
-    int not_done;      /* exec errors and execs not performed */
-    int rm_cycle;      /* 1 => removals only, 0 => adds & changes only */
-    int sleep_msg;     /* 1 => -o x sleep message was given */
-    int top_ignore;    /* number of groups ignored because of no top level */
-    int restore;       /* host1 groups restored due to -o a1 */
-    double host1_same; /* % of host1 that is the same */
-    int i;
-
-    /* firewall */
-    if (grp == NULL)
-        die("internal error #9: grp is NULL");
-
-    /*
-     * If -a1 was given, mark for output any host1 newsgroup that was
-     * simply ignored due to the -i ign_file.
-     */
-    if (host1_ign_print) {
-       restore = 0;
-       for (i=0; i < grplen; ++i) {
-           if (grp[i].hostid == HOSTID1 && 
-               (grp[i].ignore == CHECK_IGNORE ||
-                grp[i].ignore == CHECK_TYPE ||
-                grp[i].ignore == (CHECK_IGNORE|CHECK_TYPE))) {
-               /* force group to output and not be ignored */
-               grp[i].ignore = 0;
-               grp[i].output = 1;
-               grp[i].remove = 0;
-               grp[i].outhi = grp[i].hi;
-               grp[i].outlow = grp[i].low;
-               grp[i].outtype = grp[i].type;
-               ++restore;
-           }
-       }
-       if (D_BUG)
-            warn("STATUS: restored %d host1 groups", restore);
-    }
-
-    /*
-     * If -T, ignore new top level groups from host2
-     */
-    if (no_new_hier) {
-       top_ignore = 0;
-       for (i=0; i < grplen; ++i) {
-           /* look at new newsgroups */
-           if (grp[i].hostid == HOSTID2 &&
-               grp[i].output != 0 &&
-               new_top_hier(grp[i].name)) {
-                /* no top level ignore this new group */
-                grp[i].ignore |= CHECK_HIER;
-                grp[i].output = 0;
-                if (D_BUG)
-                     warn("ignore new newsgroup: %s, new hierarchy",
-                          grp[i].name);
-                ++top_ignore;
-           }
-       }
-       if (D_SUMMARY)
-            warn("STATUS: ignored %d new newsgroups due to new hierarchy",
-                 top_ignore);
-    }
-
-    /* sort by active file order if active style output (-a) */
-    if (o_flag == OUTPUT_ACTIVE) {
-       if (D_BUG)
-            warn("STATUS: sorting groups in output order");
-       qsort((char *)grp, grplen, sizeof(grp[0]), active_cmp);
-    }
-
-    /*
-     * Determine the % of lines from host1 active file that remain unchanged
-     * ignoring any low/high water mark changes.
-     *
-     * Determine the number of old groups that will remain the same
-     * the number of new groups that will be added.
-     */
-    add = 0;
-    change = 0;
-    remove = 0;
-    same = 0;
-    ignore = 0;
-    no_new_dir = 0;
-    new_dir = 0;
-    water_change = 0;
-    for (i=0; i < grplen; ++i) {
-       /* skip non-output ...  */
-       if (grp[i].output == 0) {
-           if (grp[i].hostid == HOSTID1) {
-               ++ignore;
-           }
-           continue;
-
-       /* case: group needs removal */
-       } else if (grp[i].remove) {
-           ++remove;
-
-       /* case: group is from host2, so we need a newgroup */
-       } else if (grp[i].hostid == HOSTID2) {
-           ++add;
-
-       /* case: group is from host1, but the type changed */
-       } else if (grp[i].type != grp[i].outtype &&
-                  strcmp(grp[i].type,grp[i].outtype) != 0) {
-           ++change;
-
-       /* case: group did not change */
-       } else {
-           ++same;
-       }
-    }
-    work = add+change+remove;
-    if (same+work+host1_errs <= 0) {
-       /* no lines, no work, no errors == nothing changed == 100% the same */
-       host1_same = (double)100.0;
-    } else {
-       /* calculate % unchanged */
-       host1_same = (double)100.0 *
-                    ((double)same / (double)(same+work+host1_errs));
-    }
-    if (D_BUG) {
-        warn("STATUS: same=%d add=%d, change=%d, remove=%d",
-             same, add, change, remove);
-        warn("STATUS: ignore=%d, work=%d, err=%d",
-             ignore, work, host1_errs);
-        warn("STATUS: same+work+err=%d, host1_same=%.2f%%",
-             same+work+host1_errs, host1_same);
-    }
-
-    /* 
-     * Bail out if we too few lines in host1 active file (ignoring
-     * low/high water mark changes) remaining unchanged.
-     *
-     * We define change as:
-     *
-     * line errors from host1 active file
-     * newsgroups to be added to host1
-     * newsgroups to be removed from host1
-     * newsgroups to be change in host1
-     */
-    if (host1_same < p_flag) {
-        warn("HALT: lines unchanged: %.2f%% < min change limit: %.2f%%",
-             host1_same, p_flag);
-        warn("    No output or commands executed.  Determine if the degree");
-        warn("    of changes is okay and re-execute with a lower -p value");
-        die("    or with the problem fixed.");
-    }
-
-    /*
-     * look at all groups
-     *
-     * If we are not producing active file output, we must do removals
-     * before we do any adds and changes.
-     *
-     * We recalculate the work stats in finer detail as well as noting how
-     * many actions were successful.
-     */
-    add = 0;
-    change = 0;
-    remove = 0;
-    same = 0;
-    ignore = 0;
-    work = 0;
-    not_done = 0;
-    sleep_msg = 0;
-    rm_cycle = ((o_flag == OUTPUT_ACTIVE) ? 0 : 1);
-    do {
-       for (i=0; i < grplen; ++i) {
-
-           /* if -o Ax, output ignored non-error groups too */
-
-           /*
-            * skip non-output ...
-            *
-            * but if '-a' and active output mode, then don't skip ignored,
-            * non-error, non-removed groups from host1
-            */
-           if (grp[i].output == 0) {
-               if (grp[i].hostid == HOSTID1) {
-                   ++ignore;
-               }
-               continue;
-           }
-
-           /* case: output active lines */
-           if (o_flag == OUTPUT_ACTIVE) {
-
-               /* case: group needs removal */
-               if (grp[i].remove) {
-                   ++remove;
-                   ++work;
-
-               /* case: group will be kept */
-               } else {
-
-                   /* output in active file format */
-                   printf("%s %s %s %s\n",
-                       grp[i].name,  grp[i].outhi, grp[i].outlow,
-                       grp[i].outtype);
-
-                   /* if -v level is high enough, do group accounting */
-                   if (D_IF_SUMM) {
-
-                       /* case: group is from host2, so we need a newgroup */
-                       if (grp[i].hostid == HOSTID2) {
-                           ++add;
-                           ++work;
-
-                       /* case: group is from host1, but the type changed */
-                       } else if (grp[i].type != grp[i].outtype &&
-                                  strcmp(grp[i].type,grp[i].outtype) != 0) {
-                           ++change;
-                           ++work;
-
-                       /* case: group did not change */
-                       } else {
-                           ++same;
-                       }
-                   }
-               }
-
-           /* case: output ctlinnd commands */
-           } else if (o_flag == OUTPUT_CTLINND) {
-
-               /* case: group needs removal */
-               if (grp[i].remove) {
-
-                   /* output rmgroup */
-                   if (rm_cycle) {
-                       printf("ctlinnd rmgroup %s\n", grp[i].name);
-                       ++remove;
-                       ++work;
-                   }
-
-               /* case: group is from host2, so we need a newgroup */
-               } else if (grp[i].hostid == HOSTID2) {
-
-                   /* output newgroup */
-                   if (! rm_cycle) {
-                       printf("ctlinnd newgroup %s %s %s\n",
-                           grp[i].name, grp[i].outtype, new_name);
-                       ++add;
-                       ++work;
-                   }
-
-               /* case: group is from host1, but the type changed */
-               } else if (grp[i].type != grp[i].outtype &&
-                          strcmp(grp[i].type,grp[i].outtype) != 0) {
-
-                   /* output changegroup */
-                   if (! rm_cycle) {
-                       printf("ctlinnd changegroup %s %s\n",
-                           grp[i].name, grp[i].outtype);
-                       ++change;
-                       ++work;
-                   }
-
-               /* case: group did not change */
-               } else {
-                   if (! rm_cycle) {
-                       ++same;
-                   }
-               }
-
-           /* case: exec ctlinnd commands */
-           } else if (o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC) {
-
-               /* warn about sleeping if needed and first time */
-               if (o_flag == OUTPUT_EXEC && z_flag > 0 && sleep_msg == 0) {
-                   if (D_SUMMARY)
-                        warn("will sleep %d seconds before each fork/exec",
-                             z_flag);
-                   sleep_msg = 1;
-               }
-
-               /* case: group needs removal */
-               if (grp[i].remove) {
-
-                   /* exec rmgroup */
-                   if (rm_cycle) {
-                       if (D_REPORT && o_flag == OUTPUT_EXEC)
-                            warn("rmgroup %s", grp[i].name);
-                       if (! exec_cmd(o_flag, "rmgroup",
-                           grp[i].name, NULL, NULL)) {
-                           ++not_done;
-                       } else {
-                           ++remove;
-                           ++work;
-                       }
-                   }
-
-               /* case: group is from host2, so we need a newgroup */
-               } else if (grp[i].hostid == HOSTID2) {
-
-                   /* exec newgroup */
-                   if (!rm_cycle) {
-                       if (D_REPORT && o_flag == OUTPUT_EXEC)
-                            warn("newgroup %s %s %s",
-                                 grp[i].name, grp[i].outtype, new_name);
-                       if (! exec_cmd(o_flag, "newgroup", grp[i].name,
-                                grp[i].outtype, new_name)) {
-                           ++not_done;
-                       } else {
-                           ++add;
-                           ++work;
-                       }
-                   }
-
-               /* case: group is from host1, but the type changed */
-               } else if (grp[i].type != grp[i].outtype &&
-                          strcmp(grp[i].type,grp[i].outtype) != 0) {
-
-                   /* exec changegroup */
-                   if (!rm_cycle) {
-                       if (D_REPORT && o_flag == OUTPUT_EXEC)
-                            warn("changegroup %s %s",
-                                 grp[i].name, grp[i].outtype);
-                       if (! exec_cmd(o_flag, "changegroup", grp[i].name,
-                                grp[i].outtype, NULL)) {
-                           ++not_done;
-                       } else {
-                           ++change;
-                           ++work;
-                       }
-                   }
-
-               /* case: group did not change */
-               } else {
-                   if (! rm_cycle) {
-                       ++same;
-                   }
-               }
-           }
-       }
-    } while (--rm_cycle >= 0);
-
-    /* final accounting, if -v */
-    if (D_SUMMARY || (D_IF_SUMM && (work > 0 || not_done > 0))) {
-        warn("STATUS: %d group(s)", add+remove+change+same);
-        warn("STATUS: %d group(s)%s added", add,
-             ((o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC) ?
-              "" : " to be"));
-        warn("STATUS: %d group(s)%s removed",  remove,
-             ((o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC) ?
-              "" : " to be"));
-        warn("STATUS: %d group(s)%s changed", change,
-             ((o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC) ?
-              "" : " to be"));
-        warn("STATUS: %d group(s) %s the same", same,
-             ((o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC) ?
-              "remain" : "are"));
-        warn("STATUS: %.2f%% of lines unchanged", host1_same);
-        warn("STATUS: %d group(s) ignored", ignore);
-       if (o_flag == OUTPUT_EXEC || o_flag == OUTPUT_IEXEC)
-            warn("STATUS: %d exec(s) not performed", not_done);
-    }
-}
-
-/*
- * error_mark - mark for removal, error groups from a given host
- *
- * given:
- *     grp     array of groups
- *     grplen  length of grp array in elements
- *     hostid  host to mark error groups for removal
- */
-static void
-error_mark(grp, grplen, hostid)
-    struct grp *grp;           /* array of groups */
-    int grplen;                        /* length of grp array in elements */
-    int hostid;                        /* host to mark error groups for removal */
-{
-    int i;
-    int errcnt;
-
-    /* firewall */
-    if (grp == NULL)
-        die("internal error #11: grp is NULL");
-
-    /* loop thru groups, looking for error groups from a given host */
-    errcnt = 0;
-    for (i=0; i < grplen; ++i) {
-
-       /* skip if not from hostid */
-       if (grp[i].hostid != hostid) {
-           continue;
-       }
-
-       /* mark for removal if an error group not already removed */
-       if (IS_ERROR(grp[i].ignore)) {
-
-           /* mark for removal */
-           if (grp[i].output != 1 || grp[i].remove != 1) {
-               grp[i].output = 1;
-               grp[i].remove = 1;
-           }
-           ++errcnt;
-       }
-    }
-
-    /* all done */
-    if (D_SUMMARY || (D_IF_SUMM && errcnt > 0))
-        warn("STATUS: marked %d error groups for removal", errcnt);
-    return;
-}
-
-/*
- * eq_merge_cmp - qsort compare function for =type group processing
- *
- * given:
- *     a       =group a to compare
- *     b       =group b to compare
- *
- * returns:
- *     >0      a > b
- *     0       a == b elements match (fatal error if a and b are different)
- *     <0      a < b
- *
- * To speed up group comparison, we compare by the following items listed
- * in order of sorting:
- *
- *     skip                    (non-skipped groups after skipped ones)
- *     group equiv name
- *     group name
- *     hostid                  (host1 ahead of host2)
- *     linenum                 (active file line number)
- */
-static int
-eq_merge_cmp(arg_a, arg_b)
-    const void *arg_a;         /* first qsort compare arg */
-    const void *arg_b;         /* first qsort compare arg */
-{
-    const struct eqgrp *a = arg_a;     /* group a to compare */
-    const struct eqgrp *b = arg_b;     /* group b to compare */
-    int i;
-
-    /* firewall */
-    if (a == b) {
-       /* we guess this could happen */
-       return(0);
-    }
-
-    /* compare skip values */
-    if (a->skip != b->skip) {
-       if (a->skip > b->skip) {
-           /* a is skipped, b is not */
-           return 1;
-       } else {
-           /* b is skipped, a is not */
-           return -1;
-       }
-    }
-
-    /* compare the names the groups are equivalenced to */
-    i = strcmp(a->eq, b->eq);
-    if (i != 0) {
-       return i;
-    }
-
-    /* compare the group names themselves */
-    i = strcmp(a->g->name, b->g->name);
-    if (i != 0) {
-       return i;
-    }
-
-    /* compare hostid's */
-    if (a->g->hostid != b->g->hostid) {
-       if (a->g->hostid > b->g->hostid) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* compare active line numbers */
-    if (a->g->linenum != b->g->linenum) {
-       if (a->g->linenum > b->g->linenum) {
-           return 1;
-       } else {
-           return -1;
-       }
-    }
-
-    /* two different elements match, this should not happen! */
-    die("two internal eqgrp elements match!");
-}
-
-/*
- * mark_eq_probs - mark =type groups from a given host that have problems
- *
- * given:
- *     grp      sorted array of groups
- *     grplen   length of grp array in elements
- *     hostid   host to mark error groups for removal, or NOHOST
- *     host1   name of host with HOSTID1
- *     host2   name of host with HOSTID2
- *
- * This function assumes that the grp array has been sorted by name.
- */
-static int
-mark_eq_probs(grp, grplen, hostid, host1, host2)
-    struct grp *grp;           /* array of groups */
-    int grplen;                        /* length of grp array in elements */
-    int hostid;                        /* host to mark error groups for removal */
-    char *host1;               /* name of host with HOSTID1 */
-    char *host2;               /* name of host with HOSTID2 */
-{
-    struct eqgrp *eqgrp;       /* =type pointer array */
-    int eq_cnt;                        /* number of =type groups from host */
-    int new_eq_cnt;            /* number of =type groups remaining */
-    int missing;               /* =type groups equiv to missing groups */
-    int cycled;                        /* =type groups equiv to themselves */
-    int chained;               /* =type groups in long chain or loop */
-    int cmp;                   /* strcmp of two names */
-    int step;                  /* equiv loop step */
-    int i;
-    int j;
-
-    /* firewall */
-    if (grp == NULL)
-        die("internal error #12: grp is NULL");
-    if (hostid == NOHOST) {
-       /* nothing to detect, nothing else to do */
-       return 0;
-    }
-
-    /* count the =type groups from hostid that are not in error */
-    eq_cnt = 0;
-    for (i=0; i < grplen; ++i) {
-       if (grp[i].hostid == hostid &&
-           ! IS_ERROR(grp[i].ignore) &&
-           grp[i].type != NULL &&
-           grp[i].type[0] == '=') {
-           ++eq_cnt;
-       }
-    }
-    if (D_BUG && hostid != NOHOST)
-        warn("STATUS: host%d has %d =type groups", hostid, eq_cnt);
-
-    /* if no groups, then there is nothing to do */
-    if (eq_cnt == 0) {
-       return 0;
-    }
-
-    /* setup the =group record array */
-    eqgrp = xmalloc(eq_cnt * sizeof(eqgrp[0]));
-    for (i=0, j=0; i < grplen && j < eq_cnt; ++i) {
-       if (grp[i].hostid == hostid &&
-           ! IS_ERROR(grp[i].ignore) &&
-           grp[i].type != NULL &&
-           grp[i].type[0] == '=') {
-
-           /* initialize record */
-           eqgrp[j].skip = 0;
-           eqgrp[j].g = &grp[i];
-           eqgrp[j].eq = &(grp[i].type[1]);
-           ++j;
-       }
-    }
-
-    /*
-     * try to resolve =type groups in at least EQ_LOOP equiv links
-     */
-    new_eq_cnt = eq_cnt;
-    missing = 0;
-    cycled = 0;
-    for (step=0; step < EQ_LOOP && new_eq_cnt >= 0; ++step) {
-
-       /* sort the =group record array */
-       qsort((char *)eqgrp, eq_cnt, sizeof(eqgrp[0]), eq_merge_cmp);
-
-       /* look for the groups to which =type group point at */
-       eq_cnt = new_eq_cnt;
-       for (i=0, j=0; i < grplen && j < eq_cnt; ++i) {
-
-           /* we will skip any group in error or from the wrong host */
-           if (grp[i].hostid != hostid || IS_ERROR(grp[i].ignore)) {
-               continue;
-           }
-
-           /* we will skip any skipped eqgrp's */
-           if (eqgrp[j].skip) {
-               /* try the same group against the next eqgrp */
-               --i;
-               ++j;
-               continue;
-           }
-
-           /* compare the =name of the eqgrp with the name of the grp */
-           cmp = strcmp(grp[i].name, eqgrp[j].eq);
-
-           /* case: this group is pointed at by an eqgrp */
-           if (cmp == 0) {
-
-                /* see if we have looped around to the original group name */
-                if (strcmp(grp[i].name, eqgrp[j].g->name) == 0) {
-
-                   /* note the detected loop */
-                   if (! QUIET(hostid))
-                        warn("%s from %s line %d =loops around to itself",
-                             eqgrp[j].g->name,
-                             ((eqgrp[j].g->hostid == HOSTID1) ? host1 : host2),
-                             eqgrp[j].g->linenum);
-                    eqgrp[j].g->ignore |= ERROR_EQLOOP;
-
-                   /* the =group is bad, so we don't need to bother with it */
-                   eqgrp[j].skip = 1;
-                   --new_eq_cnt;
-                   ++cycled;
-                   --i;
-                   ++j;
-                   continue;
-               }
-
-               /* if =group refers to a valid group, we are done with it */
-               if (grp[i].type != NULL && grp[i].type[0] != '=') {
-                   eqgrp[j].skip = 1;
-                   --new_eq_cnt;
-               /* otherwise note the equiv name */
-               } else {
-                   eqgrp[j].eq = &(grp[i].type[1]);
-               }
-               --i;
-               ++j;
-
-           /* case: we missed the =name */
-           } else if (cmp > 0) {
-
-               /* mark the eqgrp in error */
-               eqgrp[j].g->ignore |= ERROR_NONEQ;
-               if (! QUIET(hostid))
-                    warn("%s from %s line %d not equiv to a valid group",
-                         eqgrp[j].g->name,
-                         ((eqgrp[j].g->hostid == HOSTID1) ? host1 : host2),
-                         eqgrp[j].g->linenum);
-
-               /* =group is bad, so we don't need to bother with it anymore */
-               eqgrp[j].skip = 1;
-               --new_eq_cnt;
-               ++missing;
-               ++j;
-           }
-       }
-
-       /* any remaining non-skipped eqgrps are bad */
-       while (j < eq_cnt) {
-
-           /* mark the eqgrp in error */
-           eqgrp[j].g->ignore |= ERROR_NONEQ;
-           if (! QUIET(hostid))
-                warn("%s from %s line %d isn't equiv to a valid group",
-                     eqgrp[j].g->name,
-                     ((hostid == HOSTID1) ? host1 : host2),
-                     eqgrp[j].g->linenum);
-
-           /* the =group is bad, so we don't need to bother with it anymore */
-           eqgrp[j].skip = 1;
-           --new_eq_cnt;
-           ++missing;
-           ++j;
-       }
-    }
-
-    /* note groups that are in a long chain or loop */
-    chained = new_eq_cnt;
-    qsort((char *)eqgrp, eq_cnt, sizeof(eqgrp[0]), eq_merge_cmp);
-    for (j=0; j < new_eq_cnt; ++j) {
-
-       /* skip if already skipped */
-       if (eqgrp[j].skip == 1) {
-           continue;
-       }
-
-       /* mark as a long loop group */
-       eqgrp[j].g->ignore |= ERROR_LONGLOOP;
-       if (! QUIET(hostid))
-            warn("%s from %s line %d in a long equiv chain or loop > %d",
-                 eqgrp[j].g->name,
-                 ((hostid == HOSTID1) ? host1 : host2),
-                 eqgrp[j].g->linenum, EQ_LOOP);
-    }
-
-    /* all done */
-    if (D_BUG) {
-        warn("%d =type groups from %s are not equiv to a valid group",
-             missing, ((hostid == HOSTID1) ? host1 : host2));
-        warn("%d =type groups from %s are equiv to themselves",
-             cycled, ((hostid == HOSTID1) ? host1 : host2));
-        warn("%d =type groups from %s are in a long chain or loop > %d",
-             chained, ((hostid == HOSTID1) ? host1 : host2), EQ_LOOP);
-    }
-    free(eqgrp);
-    return missing+cycled+chained;
-}
-
-/*
- * exec_cmd - exec a ctlinnd command in forked process
- *
- * given:
- *     mode    OUTPUT_EXEC or OUTPUT_IEXEC (interactive mode)
- *     cmd     "changegroup", "newgroup", "rmgroup"
- *     grp     name of group
- *     type    type of group or NULL
- *     who     newgroup creator or NULL
- *
- * returns:
- *     1       exec was performed
- *     0       exec was not performed
- */
-static int
-exec_cmd(mode, cmd, grp, type, who)
-    int mode;          /* OUTPUT_EXEC or OUTPUT_IEXEC (interactive mode) */
-    char *cmd;         /* changegroup, newgroup or rmgroup */
-    char *grp;         /* name of group to change, add, remove */
-    char *type;                /* type of group or NULL */
-    char *who;         /* newgroup creator or NULL */
-{
-    FILE *ch_stream = NULL;    /* stream from a child process */
-    char buf[BUFSIZ+1];                /* interactive buffer */
-    int pid;                   /* pid of child process */
-    int io[2];                 /* pair of pipe descriptors */
-    int status;                        /* wait status */
-    int exitval;               /* exit status of the child */
-    char *p;
-
-    /* firewall */
-    if (cmd == NULL || grp == NULL)
-        die("internal error #13, cmd or grp is NULL");
-
-    /* if interactive, ask the question */
-    if (mode == OUTPUT_IEXEC) {
-
-       /* ask the question */
-       fflush(stdin);
-       fflush(stdout);
-       fflush(stderr);
-       if (type == NULL) {
-           printf("%s %s  [yn]? ", cmd, grp);
-       } else if (who == NULL) {
-           printf("%s %s %s  [yn]? ", cmd, grp, type);
-       } else {
-           printf("%s %s %s %s  [yn]? ", cmd, grp, type, who);
-       }
-       fflush(stdout);
-       buf[0] = '\0';
-       buf[BUFSIZ] = '\0';
-       p = fgets(buf, BUFSIZ, stdin);
-       if (p == NULL) {
-           /* EOF/ERROR on interactive input, silently stop processing */
-           exit(43);
-       }
-
-       /* if non-empty line doesn't start with 'y' or 'Y', skip command */
-       if (buf[0] != 'y' && buf[0] != 'Y' && buf[0] != '\n') {
-           /* indicate nothing was done */
-           return 0;
-       }
-    }
-
-    /* build a pipe for output from child interactive mode */
-    if (mode == OUTPUT_IEXEC) {
-       if (pipe(io) < 0)
-            sysdie("pipe create failed");
-
-    /* setup a fake pipe to /dev/null for non-interactive mode */
-    } else {
-       io[READ_SIDE] = open(DEV_NULL, 0);
-       if (io[READ_SIDE] < 0)
-            sysdie("unable to open %s for reading", DEV_NULL);
-       io[WRITE_SIDE] = open(DEV_NULL, 1);
-       if (io[WRITE_SIDE] < 0)
-            sysdie("unable to open %s for writing", DEV_NULL);
-    }
-
-    /* pause if in non-interactive mode so as to not busy-out the server */
-    if (mode == OUTPUT_EXEC && z_flag > 0) {
-       if (D_BUG)
-            warn("sleeping %d seconds before fork/exec", z_flag);
-           /* be sure they know what we are stalling */
-           fflush(stderr);
-       sleep(z_flag);
-    }
-
-    /* fork the child process */
-    fflush(stdout);
-    fflush(stderr);
-    pid = fork();
-    if (pid == -1)
-        sysdie("fork failed");
-
-    /* case: child process */
-    if (pid == 0) {
-
-       /*
-        * prep file descriptors
-        */
-       fclose(stdin);
-       close(io[READ_SIDE]);
-       if (dup2(io[WRITE_SIDE], 1) < 0)
-            sysdie("child: dup of write I/O pipe to stdout failed");
-       if (dup2(io[WRITE_SIDE], 2) < 0)
-            sysdie("child: dup of write I/O pipe to stderr failed");
-
-       /* exec the ctlinnd command */
-       p = concatpath(innconf->pathbin, _PATH_CTLINND);
-       if (type == NULL) {
-           execl(p,
-                 CTLINND_NAME, CTLINND_TIME_OUT, cmd, grp, (char *) 0);
-       } else if (who == NULL) {
-           execl(p,
-                 CTLINND_NAME, CTLINND_TIME_OUT, cmd, grp, type, (char *) 0);
-       } else {
-           execl(p,
-                 CTLINND_NAME, CTLINND_TIME_OUT, cmd, grp, type, who, (char *) 0);
-       }
-
-       /* child exec failed */
-        sysdie("child process exec failed");
-
-    /* case: parent process */
-    } else {
-
-       /* prep file descriptors */
-       if (mode != OUTPUT_IEXEC) {
-           close(io[READ_SIDE]);
-       }
-       close(io[WRITE_SIDE]);
-
-       /* print a line from the child, if interactive */
-       if (mode == OUTPUT_IEXEC) {
-
-           /* read what the child says */
-           buf[0] = '\0';
-           buf[BUFSIZ] = '\0';
-           ch_stream = fdopen(io[READ_SIDE], "r");
-           if (ch_stream == NULL)
-                sysdie("fdopen of pipe failed");
-           p = fgets(buf, BUFSIZ, ch_stream);
-
-           /* print what the child said, if anything */
-           if (p != NULL) {
-               if (buf[strlen(buf)-1] == '\n')
-                    buf[strlen(buf)-1] = '\0';
-                warn("    %s", buf);
-           }
-       }
-
-       /* look for abnormal child termination/status */
-       errno = 0;
-       while (wait(&status) < 0) {
-           if (errno == EINTR) {
-               /* just an interrupt, try to wait again */
-               errno = 0;
-           } else {
-                sysdie("wait returned -1");
-           }
-       }
-       if (mode == OUTPUT_IEXEC) {
-           /* close the pipe now that we are done with reading it */
-           fclose(ch_stream);
-       }
-       if (WIFSTOPPED(status)) {
-            warn("    %s %s %s%s%s%s%s stopped",
-                 CTLINND_NAME, cmd, grp,
-                 (type ? "" : " "), (type ? type : ""),
-                 (who ? "" : " "), (who ? who : ""));
-           /* assume no work was done */
-           return 0;
-       }
-       if (WIFSIGNALED(status)) {
-            warn("    %s %s %s%s%s%s%s killed by signal %d",
-                 CTLINND_NAME, cmd, grp,
-                 (type ? "" : " "), (type ? type : ""),
-                 (who ? "" : " "), (who ? who : ""), WTERMSIG(status));
-           /* assume no work was done */
-           return 0;
-       }
-       if (!WIFEXITED(status)) {
-            warn("    %s %s %s%s%s%s%s returned unknown wait status: 0x%x",
-                 CTLINND_NAME, cmd, grp,
-                 (type ? "" : " "), (type ? type : ""),
-                 (who ? "" : " "), (who ? who : ""), status);
-           /* assume no work was done */
-           return 0;
-       }
-       exitval = WEXITSTATUS(status);
-       if (exitval != 0) {
-            warn("    %s %s %s%s%s%s%s exited with status: %d",
-                 CTLINND_NAME, cmd, grp,
-                 (type ? "" : " "), (type ? type : ""),
-                 (who ? "" : " "), (who ? who : ""), exitval);
-           /* assume no work was done */
-           return 0;
-       }
-    }
-
-    /* all done */
-    return 1;
-}
-
-/*
- * new_top_hier - determine if the newsgroup represents a new hierarchy
- *
- * Determine of the newsgroup name is a new hierarchy.
- *
- * given:
- *     name    name of newsgroup to check
- *
- * returns:
- *     false   hierarchy already exists
- *     true    hierarchy does not exist, name represents a new hierarchy
- *
- * NOTE: This function assumes that we are at the top of the news spool.
- */
-static int
-new_top_hier(name)
-    char *name;
-{
-    struct stat        statbuf;        /* stat of the hierarchy */
-    int result;                        /* return result */
-    char *dot;
-
-    /*
-     * temp change name to just the top level
-     */
-    dot = strchr(name, '.');
-    if (dot != NULL) {
-       *dot = '\0';
-    }
-
-    /*
-     * determine if we can find this top level hierarchy directory
-     */
-    result = !(stat(name, &statbuf) >= 0 && S_ISDIR(statbuf.st_mode));
-    /* restore name */
-    if (dot != NULL) {
-       *dot = '.';
-    }
-
-    /*
-     * return the result
-     */
-    return result;
-}
diff --git a/backends/actsyncd.in b/backends/actsyncd.in
deleted file mode 100644 (file)
index a88f25d..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-# @(#) $Id: actsyncd.in 6490 2003-10-18 05:49:04Z rra $
-# @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actsyncd.sh,v
-#
-# actsyncd - actsync daemon
-#
-# usage:
-#      actsyncd [-x] config_file [debug_level [debug_outfmt]]
-#
-#      -x              xexec instead of reload
-#      config_file     name of file used to determine how to run actsync
-#      debug_level     force no action and use -v debug_level
-#      debug_outfmt    change -o a1 output to -o debug_outfmt for debug
-
-# By: Landon Curt Noll         chongo@toad.com         (chongo was here /\../\)
-#
-# Copyright (c) Landon Curt Noll, 1993.
-# All rights reserved.
-#
-# Permission to use and modify is hereby granted so long as this 
-# notice remains.  Use at your own risk.  No warranty is implied.
-
-# preset vars
-#
-
-# Our lock file
-LOCK="${LOCKS}/LOCK.actsyncd"
-# where actsync is located
-ACTSYNC="${PATHBIN}/actsync"
-# exit value of actsync if unable to get an active file
-NOSYNC=127
-
-# parse args
-#
-if [ $# -gt 1 ]; then
-    case $1 in
-    -x|-r) shift ;;     # no longer relevant
-    esac
-fi
-case $# in
-    1) cfg="$1"; DEBUG=; DEBUG_FMT=; ;;
-    2) cfg="$1"; DEBUG="$2"; DEBUG_FMT=; ;;
-    3) cfg="$1"; DEBUG="$2"; DEBUG_FMT="$3"; ;;
-    *) echo "usage: $0 [-x] config_file [debug_level [debug_outfmt]]" 1>&2;
-       exit 1 ;;
-esac
-if [ ! -s "$cfg" ]; then
-    echo "$0: config_file not found or empty: $ign" 1>&2
-    exit 2
-fi
-
-# parse config_file
-#
-host="`sed -n -e 's/^host=[    ]*//p' $cfg | tail -1`"
-if [ -z "$host" ]; then
-    echo "$0: no host specified in $cfg" 1>&2
-    exit 3
-fi
-flags="`sed -n -e 's/^flags=[  ]*//p' $cfg | tail -1`"
-if [ -z "$flags" ]; then
-    echo "$0: no flags specified in $cfg" 1>&2
-    exit 4
-fi
-ign="`sed -n -e 's/^ignore_file=[      ]*//p' $cfg | tail -1`"
-if [ -z "$ign" ]; then
-    echo "$0: no ignore file specified in $cfg" 1>&2
-    exit 5
-fi
-ftp="`sed   -n -e 's/^ftppath=[        ]*//p' $cfg | tail -1`"
-spool="`sed -n -e 's/^spool=[  ]*//p' $cfg | tail -1`"
-if [ -z "$spool" ]; then
-    spool=$SPOOL
-    #echo "$0: no spool directory specified in $cfg" 1>&2
-    #exit 6
-fi
-if [ ! -f "$ign" ]; then
-    ign="${PATHETC}/$ign"
-fi
-if [ ! -s "$ign" ]; then
-    echo "$0: ignore_file not found or empty: $ign" 1>&2
-    exit 7
-fi
-
-# force -o c mode (overrides any -o argument in the command line)
-#
-if [ -z "$DEBUG" ]; then
-
-    # standard actsyncd output mode
-    flags="$flags -o c"
-
-# DEBUG processing, if debug_level was given
-#
-else
-
-    if [ ! -z "$ftp" ]; then
-        echo "$0: cannot use DEBUG mode with ftp (yet)" >&2
-        exit 88;
-    fi
-
-    # force -v level as needed
-    flags="$flags -v $DEBUG"
-
-    # force -o level but reject -o x modes
-    if [ ! -z "$DEBUG_FMT" ]; then
-       case "$DEBUG_FMT" in
-       x*) echo "$0: do not use any of the -o x debug_outfmt modes!" 1>&2;
-           exit 8 ;;
-       *) flags="$flags -o $DEBUG_FMT" ;;
-       esac
-    fi
-
-    # execute actsync directly
-    echo "DEBUG: will execute $ACTSYNC -i $ign $flags $host" 1>&2
-    eval "$ACTSYNC -i $ign $flags $host"
-    status="$?"
-    echo "DEBUG: exit status $status" 1>&2
-    exit "$status"
-fi
-
-# Lock out others
-#
-shlock -p $$ -f "${LOCK}" || {
-    echo "$0: Locked by `cat '${LOCK}'`" 1>&2
-    exit 9
-}
-
-# setup
-#
-origdir=`pwd`
-workdir="${TMPDIR}/actsyncd"
-ctlinndcmds="cc_commands"
-out="sync.msg"
-cleanup="$SED -e 's/^/    /' < $out; cd ${origdir}; rm -rf '$workdir' '$LOCK'"
-trap "eval $cleanup; exit 123" 1 2 3 15
-
-set -e
-rm -rf "$workdir"
-mkdir "$workdir"
-cd "$workdir"
-set +e
-
-rm -f "$out"
-touch "$out"
-chmod 0644 "$out"
-
-# try to sync 
-# 
-# Try to sync off of the host.  If unable to connect/sync then retry
-# up to 9 more times waiting 6 minutes between each try.
-#
-echo "=-= `date` for $host" >>$out 2>&1
-for loop in 1 2 3 4 5 6 7 8 9 10; do
-
-    # get the active file to compare against
-    status=0
-    case $host in
-    /*) cp $host          active; status=$? ;;
-    .*) cp $origdir/$host active; status=$? ;;
-     *)
-        if [ -z "$ftp" ]; then
-           port=`expr "$host" : '.*:\(.*\)'`
-           if [ -n "$port" ]; then
-             port="-p $port"
-             host=`expr "$host" : '\(.*\):.*'`
-           fi
-           echo "getlist -h $host $port" >>$out
-           if getlist -h $host $port > active 2>>$out; then
-             :
-           else
-             status=$NOSYNC
-           fi
-        else
-           echo "$GETFTP ftp://$host/$ftp" >>$out
-           $GETFTP ftp://$host/$ftp >>$out 2>&1
-           status=$?
-           if [ "$status" -ne 0 ]; then
-             status=$NOSYNC
-           else
-             case "$ftp" in
-             *.gz)
-                   echo "$GZIP -d active" >>$out
-                   if $GZIP -d active >>$out 2>&1; then
-                     :
-                   else
-                     status=1
-                   fi
-                   ;;
-             *.Z)
-                   echo "$UNCOMPRESS active" >>$out
-                   if $UNCOMPRESS active >>$out 2>&1; then
-                     :
-                   else
-                     status=1
-                   fi
-                   ;;
-             esac
-           fi
-        fi
-        ;;
-    esac
-
-    if [ "$status" -ne "$NOSYNC" ]; then
-
-       # detect bad status
-       #
-       if [ "$status" -ne 0 ]; then
-           echo "FATAL: `date` for $host exit $status" >>$out
-            eval $cleanup
-           exit "$status"
-       fi
-
-        echo "$ACTSYNC -i $ign $flags ./active" >>$out
-        eval "$ACTSYNC -i $ign $flags ./active >$ctlinndcmds 2>>$out"
-
-        if [ $? -ne 0 ]; then
-            echo "FATAL: `date` for $host actsync balked" >>$out
-            eval $cleanup
-            exit $?
-        fi
-
-        if [ ! -s $ctlinndcmds ]; then
-            echo "No changes need to be made" >>$out
-        else
-            echo "=-= `date` for $host, updating active" >>$out
-            echo "mod-active $ctlinndcmds" >>$out
-            mod-active $ctlinndcmds >>$out 2>&1
-
-            if [ $? -ne 0 ]; then
-                echo "FATAL: `date` for $host mod-active FAILED" >>$out
-                eval $cleanup
-               exit 1
-            fi
-        fi
-
-       # normal exit - all done
-       #
-       echo "=-= `date` for $host, end" >>$out
-        eval $cleanup
-       exit 0
-    fi
-
-    # failed to get the remote active file
-    echo "=-= `date` for $host failed to connect/sync, retrying" >>$out
-
-    # wait 6 minutes
-    #
-    sleep 360
-done
-
-# give up
-#
-echo "FATAL: `date` for $host failed to connect/sync 10 times" >>$out 2>&1
-eval $cleanup
-exit 1
diff --git a/backends/archive.c b/backends/archive.c
deleted file mode 100644 (file)
index 73a7970..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/*  $Id: archive.c 6138 2003-01-19 04:13:51Z rra $
-**
-**  Read batchfiles on standard input and archive them.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#ifdef TM_IN_SYS_TIME
-# include <sys/time.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-
-static char    *Archive = NULL;
-static char    *ERRLOG = NULL;
-
-/*
-**  Return a YYYYMM string that represents the current year/month
-*/
-static char *
-DateString(void)
-{
-    static char                ds[10];
-    time_t             now;
-    struct tm          *x;
-
-    time(&now);
-    x = localtime(&now);
-    snprintf(ds, sizeof(ds), "%d%d", x->tm_year + 1900, x->tm_mon + 1);
-
-    return ds;
-}
-
-
-/*
-**  Try to make one directory.  Return false on error.
-*/
-static bool
-MakeDir(char *Name)
-{
-    struct stat                Sb;
-
-    if (mkdir(Name, GROUPDIR_MODE) >= 0)
-       return true;
-
-    /* See if it failed because it already exists. */
-    return stat(Name, &Sb) >= 0 && S_ISDIR(Sb.st_mode);
-}
-
-
-/*
-**  Given an entry, comp/foo/bar/1123, create the directory and all
-**  parent directories needed.  Return false on error.
-*/
-static bool
-MakeArchiveDirectory(char *Name)
-{
-    char       *p;
-    char       *save;
-    bool               made;
-
-    if ((save = strrchr(Name, '/')) != NULL)
-       *save = '\0';
-
-    /* Optimize common case -- parent almost always exists. */
-    if (MakeDir(Name)) {
-       if (save)
-           *save = '/';
-       return true;
-    }
-
-    /* Try to make each of comp and comp/foo in turn. */
-    for (p = Name; *p; p++)
-       if (*p == '/' && p != Name) {
-           *p = '\0';
-           made = MakeDir(Name);
-           *p = '/';
-           if (!made) {
-               if (save)
-                   *save = '/';
-               return false;
-           }
-       }
-
-    made = MakeDir(Name);
-    if (save)
-       *save = '/';
-    return made;
-}
-
-
-/*
-**  Copy a file.  Return false if error.
-*/
-static bool
-Copy(char *src, char *dest)
-{
-    FILE       *in;
-    FILE       *out;
-    size_t     i;
-    char       *p;
-    char       buff[BUFSIZ];
-
-    /* Open the output file. */
-    if ((out = fopen(dest, "w")) == NULL) {
-       /* Failed; make any missing directories and try again. */
-       if ((p = strrchr(dest, '/')) != NULL) {
-           if (!MakeArchiveDirectory(dest)) {
-                syswarn("cannot mkdir for %s", dest);
-               return false;
-           }
-           out = fopen(dest, "w");
-       }
-       if (p == NULL || out == NULL) {
-            syswarn("cannot open %s for writing", dest);
-           return false;
-       }
-    }
-
-    /* Opening the input file is easier. */
-    if ((in = fopen(src, "r")) == NULL) {
-        syswarn("cannot open %s for reading", src);
-       fclose(out);
-       unlink(dest);
-       return false;
-    }
-
-    /* Write the data. */
-    while ((i = fread(buff, 1, sizeof buff, in)) != 0)
-       if (fwrite(buff, 1, i, out) != i) {
-            syswarn("cannot write to %s", dest);
-           fclose(in);
-           fclose(out);
-           unlink(dest);
-           return false;
-       }
-    fclose(in);
-
-    /* Flush and close the output. */
-    if (ferror(out) || fflush(out) == EOF) {
-        syswarn("cannot flush %s", dest);
-       unlink(dest);
-       fclose(out);
-       return false;
-    }
-    if (fclose(out) == EOF) {
-        syswarn("cannot close %s", dest);
-       unlink(dest);
-       return false;
-    }
-
-    return true;
-}
-
-
-/*
-**  Copy an article from memory into a file.
-*/
-static bool
-CopyArt(ARTHANDLE *art, char *dest, bool Concat)
-{
-    FILE       *out;
-    const char         *p;
-    char               *q, *article;
-    size_t             i;
-    const char         *mode = "w";
-
-    if (Concat) mode = "a";
-
-    /* Open the output file. */
-    if ((out = fopen(dest, mode)) == NULL) {
-       /* Failed; make any missing directories and try again. */
-       if ((p = strrchr(dest, '/')) != NULL) {
-           if (!MakeArchiveDirectory(dest)) {
-                syswarn("cannot mkdir for %s", dest);
-               return false;
-           }
-           out = fopen(dest, mode);
-       }
-       if (p == NULL || out == NULL) {
-            syswarn("cannot open %s for writing", dest);
-           return false;
-       }
-    }
-
-    /* Copy the data. */
-    article = xmalloc(art->len);
-    for (i=0, q=article, p=art->data; p<art->data+art->len;) {
-       if (&p[1] < art->data + art->len && p[0] == '\r' && p[1] == '\n') {
-           p += 2;
-           *q++ = '\n';
-           i++;
-           if (&p[1] < art->data + art->len && p[0] == '.' && p[1] == '.') {
-               p += 2;
-               *q++ = '.';
-               i++;
-           }
-           if (&p[2] < art->data + art->len && p[0] == '.' && p[1] == '\r' && p[2] == '\n') {
-               break;
-           }
-       } else {
-           *q++ = *p++;
-           i++;
-       }
-    }
-    *q++ = '\0';
-
-    /* Write the data. */
-    if (Concat) {
-       /* Write a separator... */
-       fprintf(out, "-----------\n");
-    }
-    if (fwrite(article, i, 1, out) != 1) {
-        syswarn("cannot write to %s", dest);
-       fclose(out);
-       if (!Concat) unlink(dest);
-       free(article);
-       return false;
-    }
-    free(article);
-
-    /* Flush and close the output. */
-    if (ferror(out) || fflush(out) == EOF) {
-        syswarn("cannot flush %s", dest);
-       if (!Concat) unlink(dest);
-       fclose(out);
-       return false;
-    }
-    if (fclose(out) == EOF) {
-        syswarn("cannot close %s", dest);
-       if (!Concat) unlink(dest);
-       return false;
-    }
-
-    return true;
-}
-
-
-/*
-**  Write an index entry.  Ignore I/O errors; our caller checks for them.
-*/
-static void
-WriteArtIndex(ARTHANDLE *art, char *ShortName)
-{
-    const char *p;
-    int        i;
-    char               Subject[BUFSIZ];
-    char               MessageID[BUFSIZ];
-
-    Subject[0] = '\0';         /* default to null string */
-    p = wire_findheader(art->data, art->len, "Subject");
-    if (p != NULL) {
-       for (i=0; *p != '\r' && *p != '\n' && *p != '\0'; i++) {
-           Subject[i] = *p++;
-       }
-       Subject[i] = '\0';
-    }
-
-    MessageID[0] = '\0';       /* default to null string */
-    p = wire_findheader(art->data, art->len, "Message-ID");
-    if (p != NULL) {
-       for (i=0; *p != '\r' && *p != '\n' && *p != '\0'; i++) {
-           MessageID[i] = *p++;
-       }
-       MessageID[i] = '\0';
-    }
-
-    printf("%s %s %s\n",
-           ShortName,
-           MessageID[0] ? MessageID : "<none>",
-           Subject[0] ? Subject : "<none>");
-}
-
-
-/*
-** Crack an Xref line apart into separate strings, each of the form "ng:artnum".
-** Return in "lenp" the number of newsgroups found.
-** 
-** This routine blatantly stolen from tradspool.c
-*/
-static char **
-CrackXref(const char *xref, unsigned int *lenp) {
-    char *p;
-    char **xrefs;
-    char *q;
-    unsigned int len, xrefsize;
-
-    len = 0;
-    xrefsize = 5;
-    xrefs = xmalloc(xrefsize * sizeof(char *));
-
-    /* skip pathhost */
-    if ((p = strchr(xref, ' ')) == NULL) {
-        warn("cannot find pathhost in Xref header");
-       return NULL;
-    }
-    /* skip next spaces */
-    for (p++; *p == ' ' ; p++) ;
-    while (true) {
-       /* check for EOL */
-       /* shouldn't ever hit null w/o hitting a \r\n first, but best to be paranoid */
-       if (*p == '\n' || *p == '\r' || *p == 0) {
-           /* hit EOL, return. */
-           *lenp = len;
-           return xrefs;
-       }
-       /* skip to next space or EOL */
-       for (q=p; *q && *q != ' ' && *q != '\n' && *q != '\r' ; ++q) ;
-
-        xrefs[len] = xstrndup(p, q - p);
-
-       if (++len == xrefsize) {
-           /* grow xrefs if needed. */
-           xrefsize *= 2;
-            xrefs = xrealloc(xrefs, xrefsize * sizeof(char *));
-       }
-
-       p = q;
-       /* skip spaces */
-       for ( ; *p == ' ' ; p++) ;
-    }
-}
-
-
-/*
-** Crack an groups pattern parameter apart into separate strings
-** Return in "lenp" the number of patterns found.
-*/
-static char **
-CrackGroups(char *group, unsigned int *lenp) {
-    char *p;
-    char **groups;
-    char *q;
-    unsigned int len, grpsize;
-
-    len = 0;
-    grpsize = 5;
-    groups = xmalloc(grpsize * sizeof(char *));
-
-    /* skip leading spaces */
-    for (p=group; *p == ' ' ; p++) ;
-    while (true) {
-       /* check for EOL */
-       /* shouldn't ever hit null w/o hitting a \r\n first, but best to be paranoid */
-       if (*p == '\n' || *p == '\r' || *p == 0) {
-           /* hit EOL, return. */
-           *lenp = len;
-           return groups;
-       }
-       /* skip to next comma, space, or EOL */
-       for (q=p; *q && *q != ',' && *q != ' ' && *q != '\n' && *q != '\r' ; ++q) ;
-
-        groups[len] = xstrndup(p, q - p);
-
-       if (++len == grpsize) {
-           /* grow groups if needed. */
-           grpsize *= 2;
-            groups = xrealloc(groups, grpsize * sizeof(char *));
-       }
-
-       p = q;
-       /* skip commas and spaces */
-       for ( ; *p == ' ' || *p == ',' ; p++) ;
-    }
-}
-
-
-int
-main(int ac, char *av[])
-{
-    char       *Name;
-    char       *p;
-    FILE       *F;
-    int        i;
-    bool               Flat;
-    bool               Redirect;
-    bool               Concat;
-    char               *Index;
-    char               buff[BUFSIZ];
-    char               *spool;
-    char               dest[BUFSIZ];
-    char               **groups, *q, *ng;
-    char               **xrefs;
-    const char         *xrefhdr;
-    ARTHANDLE          *art;
-    TOKEN              token;
-    unsigned int       numgroups, numxrefs;
-    int                        j;
-    char               *base = NULL;
-    bool               doit;
-
-    /* First thing, set up our identity. */
-    message_program_name = "archive";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    Concat = false;
-    Flat = false;
-    Index = NULL;
-    Redirect = true;
-    umask(NEWSUMASK);
-    ERRLOG = concatpath(innconf->pathlog, _PATH_ERRLOG);
-    Archive = innconf->patharchive;
-    groups = NULL;
-    numgroups = 0;
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "a:cfi:p:r")) != EOF)
-       switch (i) {
-       default:
-            die("usage error");
-            break;
-       case 'a':
-           Archive = optarg;
-           break;
-       case 'c':
-           Flat = true;
-           Concat = true;
-           break;
-       case 'f':
-           Flat = true;
-           break;
-       case 'i':
-           Index = optarg;
-           break;
-       case 'p':
-           groups = CrackGroups(optarg, &numgroups);
-           break;
-       case 'r':
-           Redirect = false;
-           break;
-       }
-
-    /* Parse arguments -- at most one, the batchfile. */
-    ac -= optind;
-    av += optind;
-    if (ac > 2)
-        die("usage error");
-
-    /* Do file redirections. */
-    if (Redirect)
-       freopen(ERRLOG, "a", stderr);
-    if (ac == 1 && freopen(av[0], "r", stdin) == NULL)
-        sysdie("cannot open %s for input", av[0]);
-    if (Index && freopen(Index, "a", stdout) == NULL)
-        sysdie("cannot open %s for output", Index);
-
-    /* Go to where the action is. */
-    if (chdir(innconf->patharticles) < 0)
-        sysdie("cannot chdir to %s", innconf->patharticles);
-
-    /* Set up the destination. */
-    strcpy(dest, Archive);
-    Name = dest + strlen(dest);
-    *Name++ = '/';
-
-    if (!SMinit())
-        die("cannot initialize storage manager: %s", SMerrorstr);
-
-    /* Read input. */
-    while (fgets(buff, sizeof buff, stdin) != NULL) {
-       if ((p = strchr(buff, '\n')) == NULL) {
-            warn("skipping %.40s: too long", buff);
-           continue;
-       }
-       *p = '\0';
-       if (buff[0] == '\0' || buff[0] == '#')
-           continue;
-
-       /* Check to see if this is a token... */
-       if (IsToken(buff)) {
-           /* Get a copy of the article. */
-           token = TextToToken(buff);
-           if ((art = SMretrieve(token, RETR_ALL)) == NULL) {
-                warn("cannot retrieve %s", buff);
-               continue;
-           }
-
-           /* Determine groups from the Xref header */
-           xrefhdr = wire_findheader(art->data, art->len, "Xref");
-           if (xrefhdr == NULL) {
-                warn("cannot find Xref header");
-               SMfreearticle(art);
-               continue;
-           }
-
-           if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
-                warn("bogus Xref header");
-               SMfreearticle(art);
-               continue;
-           }
-
-           /* Process each newsgroup... */
-           if (base) {
-               free(base);
-               base = NULL;
-           }
-           for (i=0; (unsigned)i<numxrefs; i++) {
-               /* Check for group limits... -p flag */
-               if ((p=strchr(xrefs[i], ':')) == NULL) {
-                    warn("bogus Xref entry %s", xrefs[i]);
-                   continue;   /* Skip to next xref */
-               }
-               if (numgroups > 0) {
-                   *p = '\0';
-                   ng = xrefs[i];
-                   doit = false;
-                   for (j=0; (unsigned)j<numgroups && !doit; j++) {
-                       if (uwildmat(ng, groups[j]) != 0) doit=true;
-                   }
-               }
-               else {
-                   doit = true;
-               }
-               *p = '/';
-               if (doit) {
-                   p = Name;
-                   q = xrefs[i];
-                   while(*q) {
-                       *p++ = *q++;
-                   }
-                   *p='\0';
-
-                   if (!Flat) {
-                       for (p=Name; *p; p++) {
-                           if (*p == '.') {
-                               *p = '/';
-                           }
-                       }
-                   }
-
-                   if (Concat) {
-                       p = strrchr(Name, '/');
-                       q = DateString();
-                       p++;
-                       while (*q) {
-                           *p++ = *q++;
-                       }
-                       *p = '\0';
-                   }
-                       
-                   if (base && !Concat) {
-                       /* Try to link the file into the archive. */
-                       if (link(base, dest) < 0) {
-
-                           /* Make the archive directory. */
-                           if (!MakeArchiveDirectory(dest)) {
-                                syswarn("cannot mkdir for %s", dest);
-                               continue;
-                           }
-
-                           /* Try to link again; if that fails, make a copy. */
-                           if (link(base, dest) < 0) {
-#if    defined(HAVE_SYMLINK)
-                               if (symlink(base, dest) < 0)
-                                    syswarn("cannot symlink %s to %s",
-                                            dest, base);
-                               else
-#endif /* defined(HAVE_SYMLINK) */
-                               if (!Copy(base, dest))
-                                   continue;
-                               continue;
-                           }
-                       }
-                   } else {
-                       if (!CopyArt(art, dest, Concat))
-                            syswarn("copying %s to %s failed", buff, dest);
-                       base = xstrdup(dest);
-                   }
-
-                   /* Write index. */
-                   if (Index) {
-                       WriteArtIndex(art, Name);
-                       if (ferror(stdout) || fflush(stdout) == EOF)
-                            syswarn("cannot write index for %s", Name);
-                   }
-               }
-           }
-
-           /* Free up the article storage space */
-           SMfreearticle(art);
-           art = NULL;
-           /* Free up the xrefs storage space */
-           for ( i=0; (unsigned)i<numxrefs; i++) free(xrefs[i]);
-           free(xrefs);
-           numxrefs = 0;
-           xrefs = NULL;
-       } else {
-            warn("%s is not a token", buff);
-           continue;
-       }
-    }
-
-    /* close down the storage manager api */
-    SMshutdown();
-
-    /* If we read all our input, try to remove the file, and we're done. */
-    if (feof(stdin)) {
-       fclose(stdin);
-       if (av[0])
-           unlink(av[0]);
-       exit(0);
-    }
-
-    /* Make an appropriate spool file. */
-    p = av[0];
-    if (p == NULL)
-        spool = concatpath(innconf->pathoutgoing, "archive");
-    else if (*p == '/')
-        spool = concat(p, ".bch", (char *) 0);
-    else
-        spool = concat(innconf->pathoutgoing, "/", p, ".bch", (char *) 0);
-    if ((F = xfopena(spool)) == NULL)
-        sysdie("cannot spool to %s", spool);
-
-    /* Write the rest of stdin to the spool file. */
-    i = 0;
-    if (fprintf(F, "%s\n", buff) == EOF) {
-        syswarn("cannot start spool");
-       i = 1;
-    }
-    while (fgets(buff, sizeof buff, stdin) != NULL) 
-       if (fputs(buff, F) == EOF) {
-            syswarn("cannot write to spool");
-           i = 1;
-           break;
-       }
-    if (fclose(F) == EOF) {
-        syswarn("cannot close spool");
-       i = 1;
-    }
-
-    /* If we had a named input file, try to rename the spool. */
-    if (p != NULL && rename(spool, av[0]) < 0) {
-        syswarn("cannot rename spool");
-       i = 1;
-    }
-
-    exit(i);
-    /* NOTREACHED */
-}
diff --git a/backends/batcher.c b/backends/batcher.c
deleted file mode 100644 (file)
index 0595778..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-/*  $Id: batcher.c 6762 2004-05-17 04:24:53Z rra $
-**
-**  Read batchfiles on standard input and spew out batches.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <syslog.h> 
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/timer.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-
-/*
-**  Global variables.
-*/
-static bool    BATCHopen;
-static bool    STATprint;
-static double  STATbegin;
-static double  STATend;
-static char    *Host;
-static char    *InitialString;
-static char    *Input;
-static char    *Processor;
-static int     ArtsInBatch;
-static int     ArtsWritten;
-static int     BATCHcount;
-static int     MaxBatches;
-static int     BATCHstatus;
-static long    BytesInBatch = 60 * 1024;
-static long    BytesWritten;
-static long    MaxArts;
-static long    MaxBytes;
-static sig_atomic_t    GotInterrupt;
-static const char *Separator = "#! rnews %ld";
-static char    *ERRLOG;
-
-/*
-**  Start a batch process.
-*/
-static FILE *
-BATCHstart(void)
-{
-    FILE       *F;
-    char       buff[SMBUF];
-
-    if (Processor && *Processor) {
-       snprintf(buff, sizeof(buff), Processor, Host);
-       F = popen(buff, "w");
-       if (F == NULL)
-           return NULL;
-    }
-    else
-       F = stdout;
-    BATCHopen = true;
-    BATCHcount++;
-    return F;
-}
-
-
-/*
-**  Close a batch, return exit status.
-*/
-static int
-BATCHclose(FILE *F)
-{
-    BATCHopen = false;
-    if (F == stdout)
-       return fflush(stdout) == EOF ? 1 : 0;
-    return pclose(F);
-}
-
-
-/*
-**  Update the batch file and exit.
-*/
-static void
-RequeueAndExit(off_t Cookie, char *line, long BytesInArt)
-{
-    static char        LINE1[] = "batcher %s times user %.3f system %.3f elapsed %.3f";
-    static char        LINE2[] ="batcher %s stats batches %d articles %d bytes %ld";
-    char       *spool;
-    char       buff[BIG_BUFFER];
-    int                i;
-    FILE       *F;
-    double     usertime;
-    double     systime;
-
-    /* Do statistics. */
-    STATend = TMRnow_double();
-    if (GetResourceUsage(&usertime, &systime) < 0) {
-       usertime = 0;
-       systime = 0;
-    }
-
-    if (STATprint) {
-       printf(LINE1, Host, usertime, systime, STATend - STATbegin);
-       printf("\n");
-       printf(LINE2, Host, BATCHcount, ArtsWritten, BytesWritten);
-       printf("\n");
-    }
-
-    syslog(L_NOTICE, LINE1, Host, usertime, systime, STATend - STATbegin);
-    syslog(L_NOTICE, LINE2, Host, BATCHcount, ArtsWritten, BytesWritten);
-
-    /* Last batch exit okay? */
-    if (BATCHstatus == 0) {
-       if (feof(stdin) && Cookie != -1) {
-           /* Yes, and we're all done -- remove input and exit. */
-           fclose(stdin);
-           if (Input)
-               unlink(Input);
-           exit(0);
-       }
-    }
-
-    /* Make an appropriate spool file. */
-    if (Input == NULL)
-        spool = concatpath(innconf->pathoutgoing, Host);
-    else
-        spool = concat(Input, ".bch", (char *) 0);
-    if ((F = xfopena(spool)) == NULL)
-        sysdie("%s cannot open %s", Host, spool);
-
-    /* If we can back up to where the batch started, do so. */
-    i = 0;
-    if (Cookie != -1 && fseeko(stdin, Cookie, SEEK_SET) == -1) {
-        syswarn("%s cannot seek", Host);
-       i = 1;
-    }
-
-    /* Write the line we had; if the fseeko worked, this will be an
-     * extra line, but that's okay. */
-    if (line && fprintf(F, "%s %ld\n", line, BytesInArt) == EOF) {
-        syswarn("%s cannot write spool", Host);
-       i = 1;
-    }
-
-    /* Write rest of stdin to spool. */
-    while (fgets(buff, sizeof buff, stdin) != NULL) 
-       if (fputs(buff, F) == EOF) {
-            syswarn("%s cannot write spool", Host);
-           i = 1;
-           break;
-       }
-    if (fclose(F) == EOF) {
-        syswarn("%s cannot close spool", Host);
-       i = 1;
-    }
-
-    /* If we had a named input file, try to rename the spool. */
-    if (Input != NULL && rename(spool, Input) < 0) {
-        syswarn("%s cannot rename spool", Host);
-       i = 1;
-    }
-
-    exit(i);
-    /* NOTREACHED */
-}
-
-
-/*
-**  Mark that we got interrupted.
-*/
-static RETSIGTYPE
-CATCHinterrupt(int s)
-{
-    GotInterrupt = true;
-
-    /* Let two interrupts kill us. */
-    xsignal(s, SIG_DFL);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    bool       Redirect;
-    FILE       *F;
-    const char *AltSpool;
-    char       *p;
-    char       *data;
-    char       line[BIG_BUFFER];
-    char       buff[BIG_BUFFER];
-    int                BytesInArt;
-    long       BytesInCB;
-    off_t      Cookie;
-    size_t     datasize;
-    int                i;
-    int                ArtsInCB;
-    int                length;
-    TOKEN      token;
-    ARTHANDLE  *art;
-    char       *artdata;
-
-    /* Set defaults. */
-    openlog("batcher", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "batcher";
-    if (!innconf_read(NULL))
-        exit(1);
-    AltSpool = NULL;
-    Redirect = true;
-    umask(NEWSUMASK);
-    ERRLOG = concatpath(innconf->pathlog, _PATH_ERRLOG);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "a:A:b:B:i:N:p:rs:S:v")) != EOF)
-       switch (i) {
-       default:
-            die("usage error");
-            break;
-       case 'a':
-           ArtsInBatch = atoi(optarg);
-           break;
-       case 'A':
-           MaxArts = atol(optarg);
-           break;
-       case 'b':
-           BytesInBatch = atol(optarg);
-           break;
-       case 'B':
-           MaxBytes = atol(optarg);
-           break;
-       case 'i':
-           InitialString = optarg;
-           break;
-       case 'N':
-           MaxBatches = atoi(optarg);
-           break;
-       case 'p':
-           Processor = optarg;
-           break;
-       case 'r':
-           Redirect = false;
-           break;
-       case 's':
-           Separator = optarg;
-           break;
-       case 'S':
-           AltSpool = optarg;
-           break;
-       case 'v':
-           STATprint = true;
-           break;
-       }
-    if (MaxArts && ArtsInBatch == 0)
-       ArtsInBatch = MaxArts;
-    if (MaxBytes && BytesInBatch == 0)
-       BytesInBatch = MaxBytes;
-
-    /* Parse arguments. */
-    ac -= optind;
-    av += optind;
-    if (ac != 1 && ac != 2)
-        die("usage error");
-    Host = av[0];
-    if ((Input = av[1]) != NULL) {
-       if (Input[0] != '/')
-            Input = concatpath(innconf->pathoutgoing, av[1]);
-       if (freopen(Input, "r", stdin) == NULL)
-            sysdie("%s cannot open %s", Host, Input);
-    }
-
-    if (Redirect)
-       freopen(ERRLOG, "a", stderr);
-
-    /* Go to where the articles are. */
-    if (chdir(innconf->patharticles) < 0)
-        sysdie("%s cannot chdir to %s", Host, innconf->patharticles);
-
-    /* Set initial counters, etc. */
-    datasize = 8 * 1024;
-    data = xmalloc(datasize);
-    BytesInCB = 0;
-    ArtsInCB = 0;
-    Cookie = -1;
-    GotInterrupt = false;
-    xsignal(SIGHUP, CATCHinterrupt);
-    xsignal(SIGINT, CATCHinterrupt);
-    xsignal(SIGTERM, CATCHinterrupt);
-    /* xsignal(SIGPIPE, CATCHinterrupt); */
-    STATbegin = TMRnow_double();
-
-    SMinit();
-    F = NULL;
-    while (fgets(line, sizeof line, stdin) != NULL) {
-       /* Record line length in case we do an ftello. Not portable to
-        * systems with non-Unix file formats. */
-       length = strlen(line);
-       Cookie = ftello(stdin) - length;
-
-       /* Get lines like "name size" */
-       if ((p = strchr(line, '\n')) == NULL) {
-            warn("%s skipping %.40s: too long", Host, line);
-           continue;
-       }
-       *p = '\0';
-       if (line[0] == '\0' || line[0] == '#')
-           continue;
-       if ((p = strchr(line, ' ')) != NULL) {
-           *p++ = '\0';
-           /* Try to be forgiving of bad input. */
-           BytesInArt = CTYPE(isdigit, (int)*p) ? atol(p) : -1;
-       }
-       else
-           BytesInArt = -1;
-
-       /* Strip of leading spool pathname. */
-       if (line[0] == '/'
-        && line[strlen(innconf->patharticles)] == '/'
-        && strncmp(line, innconf->patharticles, strlen(innconf->patharticles)) == 0)
-           p = line + strlen(innconf->patharticles) + 1;
-       else
-           p = line;
-
-       /* Open the file. */
-       if (IsToken(p)) {
-           token = TextToToken(p);
-           if ((art = SMretrieve(token, RETR_ALL)) == NULL) {
-               if ((SMerrno != SMERR_NOENT) && (SMerrno != SMERR_UNINIT))
-                    warn("%s skipping %.40s: %s", Host, p, SMerrorstr);
-               continue;
-           }
-           BytesInArt = -1;
-           artdata = FromWireFmt(art->data, art->len, (size_t *)&BytesInArt);
-           SMfreearticle(art);
-       } else {
-            warn("%s skipping %.40s: not token", Host, p);
-           continue;
-       }
-
-       /* Have an open article, do we need to open a batch?  This code
-        * is here (rather then up before the while loop) so that we
-        * can avoid sending an empty batch.  The goto makes the code
-        * a bit more clear. */
-       if (F == NULL) {
-           if (GotInterrupt) {
-               RequeueAndExit(Cookie, (char *)NULL, 0L);
-           }
-           if ((F = BATCHstart()) == NULL) {
-                syswarn("%s cannot start batch %d", Host, BATCHcount);
-               break;
-           }
-           if (InitialString && *InitialString) {
-               fprintf(F, "%s\n", InitialString);
-               BytesInCB += strlen(InitialString) + 1;
-               BytesWritten += strlen(InitialString) + 1;
-           }
-           goto SendIt;
-       }
-
-       /* We're writing a batch, see if adding the current article
-        * would exceed the limits. */
-       if ((ArtsInBatch > 0 && ArtsInCB + 1 >= ArtsInBatch)
-        || (BytesInBatch > 0 && BytesInCB + BytesInArt >= BytesInBatch)) {
-           if ((BATCHstatus = BATCHclose(F)) != 0) {
-               if (BATCHstatus == -1)
-                    syswarn("%s cannot close batch %d", Host, BATCHcount);
-               else
-                    syswarn("%s batch %d exit status %d", Host, BATCHcount,
-                            BATCHstatus);
-               break;
-           }
-           ArtsInCB = 0;
-           BytesInCB = 0;
-
-           /* See if we can start a new batch. */
-           if ((MaxBatches > 0 && BATCHcount >= MaxBatches)
-            || (MaxBytes > 0 && BytesWritten + BytesInArt >= MaxBytes)
-            || (MaxArts > 0 && ArtsWritten + 1 >= MaxArts)) {
-               break;
-           }
-
-           if (GotInterrupt) {
-               RequeueAndExit(Cookie, (char *)NULL, 0L);
-           }
-
-           if ((F = BATCHstart()) == NULL) {
-                syswarn("%s cannot start batch %d", Host, BATCHcount);
-               break;
-           }
-       }
-
-    SendIt:
-       /* Now we can start to send the article! */
-       if (Separator && *Separator) {
-           snprintf(buff, sizeof(buff), Separator, BytesInArt);
-           BytesInCB += strlen(buff) + 1;
-           BytesWritten += strlen(buff) + 1;
-           if (fprintf(F, "%s\n", buff) == EOF || ferror(F)) {
-                syswarn("%s cannot write separator", Host);
-               break;
-           }
-       }
-
-        /* Write the article.  In case of interrupts, retry the read but not
-           the fwrite because we can't check that reliably and portably. */
-       if ((fwrite(artdata, 1, BytesInArt, F) != BytesInArt) || ferror(F))
-           break;
-
-       /* Update the counts. */
-       BytesInCB += BytesInArt;
-       BytesWritten += BytesInArt;
-       ArtsInCB++;
-       ArtsWritten++;
-
-       if (GotInterrupt) {
-           Cookie = -1;
-           BATCHstatus = BATCHclose(F);
-           RequeueAndExit(Cookie, line, BytesInArt);
-       }
-    }
-
-    if (BATCHopen)
-       BATCHstatus = BATCHclose(F);
-    RequeueAndExit(Cookie, NULL, 0);
-
-    return 0;
-}
diff --git a/backends/buffchan.c b/backends/buffchan.c
deleted file mode 100644 (file)
index 34c9e5b..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/*  $Id: buffchan.c 6163 2003-01-19 22:56:34Z rra $
-**
-**  Buffered file exploder for innd.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-#include "map.h"
-
-/*
-**  Hash functions for hashing sitenames.
-*/
-#define SITE_HASH(Name, p, j)    \
-       for (p = Name, j = 0; *p; ) j = (j << 5) + j + *p++
-#define SITE_SIZE      128
-#define SITE_BUCKET(j) &SITEtable[j & (SITE_SIZE - 1)]
-
-
-/*
-**  Entry for a single active site.
-*/
-typedef struct _SITE {
-    bool       Dropped;
-    const char *Name;
-    int                CloseLines;
-    int                FlushLines;
-    time_t     LastFlushed;
-    time_t     LastClosed;
-    int        CloseSeconds;
-    int                FlushSeconds;
-    FILE       *F;
-    const char *Filename;
-    char       *Buffer;
-} SITE;
-
-
-/*
-**  Site hashtable bucket.
-*/
-typedef struct _SITEHASH {
-    int                Size;
-    int                Used;
-    SITE       *Sites;
-} SITEHASH;
-
-
-/* Global variables. */
-static char    *Format;
-static const char *Map;
-static int     BufferMode;
-static int     CloseEvery;
-static int     FlushEvery;
-static int     CloseSeconds;
-static int     FlushSeconds;
-static sig_atomic_t    GotInterrupt;
-static SITEHASH        SITEtable[SITE_SIZE];
-static TIMEINFO        Now;
-
-
-/*
-**  Set up the site information.  Basically creating empty buckets.
-*/
-static void
-SITEsetup(void)
-{
-    SITEHASH   *shp;
-
-    for (shp = SITEtable; shp < ARRAY_END(SITEtable); shp++) {
-       shp->Size = 3;
-       shp->Sites = xmalloc(shp->Size * sizeof(SITE));
-       shp->Used = 0;
-    }
-}
-
-
-/*
-**  Close a site
-*/
-static void
-SITEclose(SITE *sp)
-{
-    FILE       *F;
-
-    if ((F = sp->F) != NULL) {
-       if (fflush(F) == EOF || ferror(F)
-        || fchmod((int)fileno(F), 0664) < 0
-        || fclose(F) == EOF)
-            syswarn("%s cannot close %s", sp->Name, sp->Filename);
-       sp->F = NULL;
-    }
-}
-
-/*
-**  Close all open sites.
-*/
-static void
-SITEcloseall(void)
-{
-    SITEHASH   *shp;
-    SITE       *sp;
-    int        i;
-
-    for (shp = SITEtable; shp < ARRAY_END(SITEtable); shp++)
-       for (sp = shp->Sites, i = shp->Used; --i >= 0; sp++)
-           SITEclose(sp);
-}
-
-
-/*
-**  Open the file for a site.
-*/
-static void SITEopen(SITE *sp)
-{
-    int                        e;
-
-    if ((sp->F = xfopena(sp->Filename)) == NULL
-     && ((e = errno) != EACCES || chmod(sp->Filename, 0644) < 0
-      || (sp->F = xfopena(sp->Filename)) == NULL)) {
-        syswarn("%s cannot fopen %s", sp->Name, sp->Filename);
-       if ((sp->F = fopen("/dev/null", "w")) == NULL)
-           /* This really should not happen. */
-            sysdie("%s cannot fopen /dev/null", sp->Name);
-    }
-    else if (fchmod((int)fileno(sp->F), 0444) < 0)
-        syswarn("%s cannot fchmod %s", sp->Name, sp->Filename);
-       
-    if (BufferMode != '\0')
-       setbuf(sp->F, sp->Buffer);
-
-    /* Reset all counters. */
-    sp->FlushLines = 0;
-    sp->CloseLines = 0;
-    sp->LastFlushed = Now.time;
-    sp->LastClosed = Now.time;
-    sp->Dropped = false;
-}
-
-
-/*
-**  Find a site, possibly create if not found.
-*/
-static SITE *
-SITEfind(char *Name, bool CanCreate)
-{
-    char       *p;
-    int        i;
-    unsigned int       j;
-    SITE       *sp;
-    SITEHASH           *shp;
-    char               c;
-    char               buff[BUFSIZ];
-
-    /* Look for site in the hash table. */
-    SITE_HASH(Name, p, j);
-    shp = SITE_BUCKET(j);
-    for (c = *Name, sp = shp->Sites, i = shp->Used; --i >= 0; sp++)
-       if (c == sp->Name[0] && strcasecmp(Name, sp->Name) == 0)
-           return sp;
-    if (!CanCreate)
-       return NULL;
-
-    /* Adding a new site -- grow hash bucket if we need to. */
-    if (shp->Used == shp->Size - 1) {
-       shp->Size *= 2;
-        shp->Sites = xrealloc(shp->Sites, shp->Size * sizeof(SITE));
-    }
-    sp = &shp->Sites[shp->Used++];
-
-    /* Fill in the structure for the new site. */
-    sp->Name = xstrdup(Name);
-    snprintf(buff, sizeof(buff), Format, Map ? MAPname(Name) : sp->Name);
-    sp->Filename = xstrdup(buff);
-    if (BufferMode == 'u')
-       sp->Buffer = NULL;
-    else if (BufferMode == 'b')
-       sp->Buffer = xmalloc(BUFSIZ);
-    SITEopen(sp);
-
-    return sp;
-}
-
-
-/*
-**  Flush a site -- close and re-open the file.
-*/
-static void
-SITEflush(SITE *sp)
-{
-    FILE       *F;
-
-    if ((F = sp->F) != NULL) {
-       if (fflush(F) == EOF || ferror(F)
-        || fchmod((int)fileno(F), 0664) < 0
-        || fclose(F) == EOF)
-            syswarn("%s cannot close %s", sp->Name, sp->Filename);
-       sp->F = NULL;
-    }
-    if (!sp->Dropped)
-       SITEopen(sp);
-}
-
-
-/*
-**  Flush all open sites.
-*/
-static void
-SITEflushall(void)
-{
-    SITEHASH   *shp;
-    SITE       *sp;
-    int        i;
-
-    for (shp = SITEtable; shp < ARRAY_END(SITEtable); shp++)
-       for (sp = shp->Sites, i = shp->Used; --i >= 0; sp++)
-           SITEflush(sp);
-}
-
-
-/*
-**  Write data to a site.
-*/
-static void
-SITEwrite(char *name, char *text, size_t len)
-{
-    SITE       *sp;
-
-    sp = SITEfind(name, true);
-    if (sp->F == NULL)
-       SITEopen(sp);
-
-    if (fwrite(text, 1, len, sp->F) != len)
-        syswarn("%s cannot write", sp->Name);
-
-    /* Bump line count; see if time to close or flush. */
-    if (CloseEvery && ++(sp->CloseLines) >= CloseEvery) {
-       SITEflush(sp);
-       return;
-    }
-    if (CloseSeconds && sp->LastClosed + CloseSeconds < Now.time) {
-       SITEflush(sp);
-       return;
-    }
-    if (FlushEvery && ++(sp->FlushLines) >= FlushEvery) {
-       if (fflush(sp->F) == EOF || ferror(sp->F))
-            syswarn("%s cannot flush %s", sp->Name, sp->Filename);
-       sp->LastFlushed = Now.time;
-       sp->FlushLines = 0;
-    }
-    else if (FlushSeconds && sp->LastFlushed + FlushSeconds < Now.time) {
-       if (fflush(sp->F) == EOF || ferror(sp->F))
-            syswarn("%s cannot flush %s", sp->Name, sp->Filename);
-       sp->LastFlushed = Now.time;
-       sp->FlushLines = 0;
-    }
-}
-
-
-/*
-**  Handle a command message.
-*/
-static void
-Process(char *p)
-{
-    SITE       *sp;
-
-    if (*p == 'b' && strncmp(p, "begin", 5) == 0)
-       /* No-op. */
-       return;
-
-    if (*p == 'f' && strncmp(p, "flush", 5) == 0) {
-       for (p += 5; ISWHITE(*p); p++)
-           continue;
-       if (*p == '\0')
-           SITEflushall();
-       else if ((sp = SITEfind(p, false)) != NULL)
-           SITEflush(sp);
-       /*else
-           fprintf(stderr, "buffchan flush %s unknown site\n", p);*/
-       return;
-    }
-
-    if (*p == 'd' && strncmp(p, "drop", 4) == 0) {
-       for (p += 4; ISWHITE(*p); p++)
-           continue;
-       if (*p == '\0')
-           SITEcloseall();
-       else if ((sp = SITEfind(p, false)) == NULL)
-            warn("drop %s unknown site", p);
-       else {
-           SITEclose(sp);
-           sp->Dropped = true;
-       }
-       return;
-    }
-
-    if (*p == 'r' && strncmp(p, "readmap", 7) == 0) {
-       MAPread(Map);
-       return;
-    }
-
-    /* Other command messages -- ignored. */
-    warn("unknown message %s", p);
-}
-
-
-/*
-**  Mark that we got a signal; let two signals kill us.
-*/
-static RETSIGTYPE
-CATCHinterrupt(int s)
-{
-    GotInterrupt = true;
-    xsignal(s, SIG_DFL);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    QIOSTATE   *qp;
-    int        i;
-    int        Fields;
-    char       *p;
-    char       *next;
-    char       *line;
-    char               *Directory;
-    bool               Redirect;
-    FILE               *F;
-    char               *ERRLOG;
-
-    /* First thing, set up our identity. */
-    message_program_name = "buffchan";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    ERRLOG = concatpath(innconf->pathlog, _PATH_ERRLOG);
-    Directory = NULL;
-    Fields = 1;
-    Format = NULL;
-    Redirect = true;
-    GotInterrupt = false;
-    umask(NEWSUMASK);
-
-    xsignal(SIGHUP, CATCHinterrupt);
-    xsignal(SIGINT, CATCHinterrupt);
-    xsignal(SIGQUIT, CATCHinterrupt);
-    xsignal(SIGPIPE, CATCHinterrupt);
-    xsignal(SIGTERM, CATCHinterrupt);
-    xsignal(SIGALRM, CATCHinterrupt);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "bc:C:d:f:l:L:m:p:rs:u")) != EOF)
-       switch (i) {
-       default:
-            die("usage error");
-            break;
-       case 'b':
-       case 'u':
-           BufferMode = i;
-           break;
-       case 'c':
-           CloseEvery = atoi(optarg);
-           break;
-       case 'C':
-           CloseSeconds = atoi(optarg);
-           break;
-       case 'd':
-           Directory = optarg;
-           if (Format == NULL)
-               Format =xstrdup("%s");
-           break;
-       case 'f':
-           Fields = atoi(optarg);
-           break;
-       case 'l':
-           FlushEvery = atoi(optarg);
-           break;
-       case 'L':
-           FlushSeconds = atoi(optarg);
-           break;
-       case 'm':
-           Map = optarg;
-           MAPread(Map);
-           break;
-       case 'p':
-           if ((F = fopen(optarg, "w")) == NULL)
-                sysdie("cannot fopen %s", optarg);
-           fprintf(F, "%ld\n", (long)getpid());
-           if (ferror(F) || fclose(F) == EOF)
-                sysdie("cannot fclose %s", optarg);
-           break;
-       case 'r':
-           Redirect = false;
-           break;
-       case 's':
-           Format = optarg;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if (ac)
-       die("usage error");
-
-    /* Do some basic set-ups. */
-    if (Redirect)
-       freopen(ERRLOG, "a", stderr);
-    if (Format == NULL) {
-        Format = concatpath(innconf->pathoutgoing, "%s");
-    }
-    if (Directory && chdir(Directory) < 0)
-        sysdie("cannot chdir to %s", Directory);
-    SITEsetup();
-
-    /* Read input. */
-    for (qp = QIOfdopen((int)fileno(stdin)); !GotInterrupt ; ) {
-       if ((line = QIOread(qp)) == NULL) {
-           if (QIOerror(qp)) {
-                syswarn("cannot read");
-               break;
-           }
-           if (QIOtoolong(qp)) {
-                warn("long line");
-               QIOread(qp);
-               continue;
-           }
-
-           /* Normal EOF. */
-           break;
-       }
-
-       /* Command? */
-       if (*line == EXP_CONTROL && *++line != EXP_CONTROL) {
-           Process(line);
-           continue;
-       }
-
-       /* Skip the right number of leading fields. */
-       for (i = Fields, p = line; *p; p++)
-           if (*p == ' ' && --i <= 0)
-               break;
-       if (*p == '\0')
-           /* Nothing to write.  Probably shouldn't happen. */
-           continue;
-
-       /* Add a newline, get the length of all leading fields. */
-       *p++ = '\n';
-       i = p - line;
-
-       if (GetTimeInfo(&Now) < 0) {
-            syswarn("cannot get time");
-           break;
-       }
-
-       /* Rest of the line is space-separated list of filenames. */
-       for (; *p; p = next) {
-           /* Skip whitespace, get next word. */
-           while (*p == ' ')
-               p++;
-           for (next = p; *next && *next != ' '; next++)
-               continue;
-           if (*next)
-               *next++ = '\0';
-
-           SITEwrite(p, line, i);
-       }
-
-    }
-
-    SITEcloseall();
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/crosspost.c b/backends/crosspost.c
deleted file mode 100644 (file)
index bef4fb2..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/*  $Id: crosspost.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Parse input to add links for cross posted articles.  Input format is one
-**  line per article.  Dots '.' are changed to '/'.  Commas ',' or blanks
-**  ' ' separate entries.  Typically this is via a channel feed from innd
-**  though an edit of the history file can also be used for recovery
-**  purposes.  Sample newsfeeds entry:
-**
-**     # Create the links for cross posted articles
-**     crosspost:*:Tc,Ap,WR:/usr/local/newsbin/crosspost
-**
-**  WARNING: This no longer works with the current INN; don't use it
-**  currently.  It still exists in the source tree in case someone will
-**  want to clean it up and make it useable again.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-
-
-static char    *Dir;
-
-static int     debug = false;
-static int     syncfiles = true;
-
-static unsigned long STATTime    = 0;
-static unsigned long STATMissing = 0; /* Source file missing */
-static unsigned long STATTooLong = 0; /* Name Too Long (src or dest) */
-static unsigned long STATLink    = 0; /* Link done */
-static unsigned long STATLError  = 0; /* Link problem */
-static unsigned long STATSymlink = 0; /* Symlink done */
-static unsigned long STATSLError = 0; /* Symlink problem */
-static unsigned long STATMkdir   = 0; /* Mkdir done */
-static unsigned long STATMdError = 0; /* Mkdir problem */
-static unsigned long STATOError  = 0; /* Other errors */
-
-#define MAXXPOST 256
-#define STATREFRESH 10800   /* 3 hours */
-
-/*
-**  Write some statistics and reset all counters.
-*/
-void
-ProcessStats()
-{
-  time_t Time;
-
-  Time = time (NULL);
-  syslog(L_NOTICE,
-       "seconds %lu links %lu %lu symlinks %lu %lu mkdirs %lu %lu missing %lu toolong %lu other %lu",
-       Time - STATTime, STATLink, STATLError, STATSymlink, STATSLError,
-       STATMkdir, STATMdError, STATMissing, STATTooLong, STATOError);
-
-  STATMissing = STATTooLong = STATLink = STATLError = 0;
-  STATSymlink = STATSLError = STATMkdir = STATMdError = STATOError = 0;
-  STATTime = Time;
-}
-
-/*
-**  Try to make one directory.  Return false on error.
-*/
-static bool
-MakeDir(Name)
-    char               *Name;
-{
-    struct stat                Sb;
-
-    if (mkdir(Name, GROUPDIR_MODE) >= 0) {
-        STATMkdir++;
-       return true;
-    }
-
-    /* See if it failed because it already exists. */
-    return stat(Name, &Sb) >= 0 && S_ISDIR(Sb.st_mode);
-}
-
-
-/*
-**  Make spool directory.  Return false on error.
-*/
-static bool
-MakeSpoolDir(Name)
-    char       *Name;
-{
-    char       *p;
-    bool               made;
-
-    /* Optimize common case -- parent almost always exists. */
-    if (MakeDir(Name))
-       return true;
-
-    /* Try to make each of comp and comp/foo in turn. */
-    for (p = Name; *p; p++)
-       if (*p == '/') {
-           *p = '\0';
-           made = MakeDir(Name);
-           *p = '/';
-           if (!made) {
-               STATMdError++;
-               return false;
-           }
-       }
-
-    return MakeDir(Name);
-}
-
-
-/*
-**  Process the input.  Data can come from innd:
-**     news/group/name/<number> [space news/group/<number>]...
-**  or
-**     news.group.name/<number>,[news.group.name/<number>]...
-*/
-static void
-ProcessIncoming(qp)
-    QIOSTATE           *qp;
-{
-    char       *p;
-    int        i;
-    int                        nxp;
-    int                        fd;
-    int                        lnval ;
-    char       *names[MAXXPOST];
-
-
-    for ( ; ; ) {
-
-        if (time(NULL) - STATTime > STATREFRESH)
-         ProcessStats();
-
-       /* Read the first line of data. */
-       if ((p = QIOread(qp)) == NULL) {
-           if (QIOtoolong(qp)) {
-               fprintf(stderr, "crosspost line too long\n");
-               STATTooLong++;
-               continue;
-           }
-           break;
-       }
-
-       for (i = 0; *p && (i < MAXXPOST); i++) { /* parse input into array */
-           names[i] = p;
-           for ( ; *p; p++) {
-               if (*p == '.') *p++ = '/'; /* dot to slash translation */
-               else if ((*p == ',')       /* name separators */
-                 ||     (*p == ' ')
-                 ||     (*p == '\t')
-                 ||     (*p == '\n')) {
-                   *p++ = '\0';
-                   break;
-               }
-           }
-       }
-       nxp = i;
-       if (debug) {
-           for (i = 0; i < nxp; i++)
-               fprintf(stderr, "crosspost: debug %d %s\n",
-                   i, names[i]);
-       }
-
-       if(syncfiles) fd = open(names[0], O_RDWR);
-
-       for (i = 1; i < nxp; i++) {
-            lnval = link(names[0], names[i]) ;
-           if (lnval == 0) STATLink++;
-           if (lnval < 0 && errno != EXDEV) { /* first try to link */
-               int j;
-               char path[SPOOLNAMEBUFF+2];
-
-               for (j = 0; (path[j] = names[i][j]) != '\0' ; j++) ;
-               for (j--; (j > 0) && (path[j] != '/'); j--) ;
-               if (path[j] == '/') {
-                   path[j] = '\0';
-                   /* try making parent dir */
-                   if (MakeSpoolDir(path) == false) {
-                       fprintf(stderr, "crosspost cant mkdir %s\n",
-                               path);
-                   }
-                   else {
-                       /* 2nd try to link */
-                       lnval = link(names[0], names[i]) ;
-                       if (lnval == 0) STATLink++;
-                       if (lnval < 0 && errno == EXDEV) {
-#if !defined(HAVE_SYMLINK)
-                           fprintf(stderr, "crosspost cant link %s %s",
-                               names[0], names[i]);
-                           perror(" ");
-#else
-                           /* Try to make a symbolic link
-                           ** to the full pathname.
-                           */
-                           for (j = 0, p = Dir; (j < SPOOLNAMEBUFF) && *p; )
-                               path[j++] = *p++; /* copy spool dir */
-                           if (j < SPOOLNAMEBUFF) path[j++] = '/';
-                           for (p = names[0]; (j < SPOOLNAMEBUFF) && *p; )
-                               path[j++] = *p++;       /* append path */
-                           path[j++] = '\0';
-                           if (symlink(path, names[i]) < 0) {
-                               fprintf(stderr,
-                                   "crosspost cant symlink %s %s",
-                                   path, names[i]);
-                               perror(" ");
-                               STATSLError++;
-                           }
-                           else
-                             STATSymlink++;
-#endif /* !defined(HAVE_SYMLINK) */
-                       } else if (lnval < 0) {
-                           if (lnval == ENOENT)
-                             STATMissing++;
-                           else {
-                             fprintf(stderr, "crosspost cant link %s %s",
-                                           names[0], names[i]);
-                             perror(" ");
-                             STATLError++;
-                           }
-                        }
-                   }
-               } else {
-                   fprintf(stderr, "crosspost bad path %s\n",
-                           names[i]);
-                   STATOError++;
-               }
-           } else if (lnval < 0) {
-               int j;
-               char path[SPOOLNAMEBUFF+2];
-
-#if !defined(HAVE_SYMLINK)
-                fprintf(stderr, "crosspost cant link %s %s",
-                              names[0], names[i]);
-                perror(" ");
-#else
-                /* Try to make a symbolic link
-                ** to the full pathname.
-                */
-                for (j = 0, p = Dir; (j < SPOOLNAMEBUFF) && *p; )
-                    path[j++] = *p++; /* copy spool dir */
-                if (j < SPOOLNAMEBUFF) path[j++] = '/';
-                for (p = names[0]; (j < SPOOLNAMEBUFF) && *p; )
-                    path[j++] = *p++;  /* append path */
-                path[j++] = '\0';
-                if (symlink(path, names[i]) < 0) {
-                    fprintf(stderr,
-                                  "crosspost cant symlink %s %s",
-                                  path, names[i]);
-                    perror(" ");
-                   STATSLError++;
-                }
-               else
-                 STATSymlink++;
-#endif /* !defined(HAVE_SYMLINK) */
-            }
-       }
-
-       if (syncfiles && (fd >= 0)) {
-           fsync(fd);
-           close(fd);
-       }
-    }
-
-    if (QIOerror(qp))
-       fprintf(stderr, "crosspost cant read %s\n", strerror(errno));
-    QIOclose(qp);
-}
-
-
-static void
-Usage(void)
-{
-    fprintf(stderr, "usage:  crosspost [-D dir] [files...]\n");
-    exit(1);
-}
-
-
-int
-main(ac, av)
-    int                        ac;
-    char               *av[];
-{
-    int        i;
-    QIOSTATE           *qp;
-
-    /* Set defaults. */
-    if (ReadInnConf() < 0) exit(1);
-    Dir = innconf->patharticles;
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "D:ds")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'D':
-           Dir = optarg;       /* specify spool path */
-           break;
-       case 'd':
-           debug = true;
-           break;
-       case 's':
-           syncfiles = false;  /* do not fsync articles */
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    if (chdir(Dir) < 0) {
-       fprintf(stderr, "crosspost cant chdir %s %s\n",
-               Dir, strerror(errno));
-       exit(1);
-    }
-    openlog("crosspost", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    STATTime = time (NULL);
-    if (ac == 0)
-       ProcessIncoming(QIOfdopen(STDIN_FILENO));
-    else {
-       for ( ; *av; av++)
-           if (strcmp(*av, "-") == 0)
-               ProcessIncoming(QIOfdopen(STDIN_FILENO));
-           else if ((qp = QIOopen(*av)) == NULL)
-               fprintf(stderr, "crosspost cant open %s %s\n",
-                       *av, strerror(errno));
-           else
-               ProcessIncoming(qp);
-    }
-
-    ProcessStats();
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/cvtbatch.c b/backends/cvtbatch.c
deleted file mode 100644 (file)
index ba57ef8..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*  $Id: cvtbatch.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Read file list on standard input and spew out batchfiles.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-
-int
-main(int ac, char *av[]) {
-    int                i;
-    QIOSTATE   *qp;
-    char       *line;
-    const char *text;
-    char       *format;
-    char       *p, *q;
-    const char *r;
-    bool       Dirty;
-    TOKEN      token;
-    ARTHANDLE  *art;
-    int                len;
-
-    /* First thing, set up our identity. */
-    message_program_name = "cvtbatch";
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Parse JCL. */
-    format = xstrdup("nm");
-    while ((i = getopt(ac, av, "w:")) != EOF)
-       switch (i) {
-       default:
-            die("usage error");
-            break;
-       case 'w':
-           for (p = format = optarg; *p; p++) {
-               switch (*p) {
-               case FEED_BYTESIZE:
-               case FEED_FULLNAME:
-               case FEED_MESSAGEID:
-               case FEED_NAME:
-                   continue;
-               }
-                warn("ignoring %c in -w flag", *p);
-           }
-       }
-    ac -= optind;
-    av += optind;
-    if (ac)
-       die("usage error");
-
-    if (!SMinit())
-        die("cannot initialize storage manager: %s", SMerrorstr);
-
-    /* Loop over all input. */
-    qp = QIOfdopen((int)fileno(stdin));
-    while ((line = QIOread(qp)) != NULL) {
-       for (p = line; *p; p++)
-           if (ISWHITE(*p)) {
-               *p = '\0';
-               break;
-           }
-
-       if (!IsToken(line))
-           continue;
-       token = TextToToken(line);
-       if ((art = SMretrieve(token, RETR_HEAD)) == NULL)
-           continue;
-        text = wire_findheader(art->data, art->len, "Message-ID");
-       if (text == NULL) {
-           SMfreearticle(art);
-           continue;
-       }
-       len = art->len;
-       for (r = text; r < art->data + art->len; r++) {
-           if (*r == '\r' || *r == '\n')
-               break;
-       }
-       if (r == art->data + art->len) {
-           SMfreearticle(art);
-           continue;
-       }
-       q = xmalloc(r - text + 1);
-       memcpy(q, text, r - text);
-       SMfreearticle(art);
-       q[r - text] = '\0';
-
-       /* Write the desired info. */
-       for (Dirty = false, p = format; *p; p++) {
-           switch (*p) {
-           default:
-               continue;
-           case FEED_BYTESIZE:
-               if (Dirty)
-                   putchar(' ');
-               printf("%d", len);
-               break;
-           case FEED_FULLNAME:
-           case FEED_NAME:
-               if (Dirty)
-                   putchar(' ');
-               printf("%s", line);
-               break;
-           case FEED_MESSAGEID:
-               if (Dirty)
-                   putchar(' ');
-               printf("%s", q);
-               break;
-           }
-           Dirty = true;
-       }
-       free(q);
-       if (Dirty)
-           putchar('\n');
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/filechan.c b/backends/filechan.c
deleted file mode 100644 (file)
index 93e81a8..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*  $Id: filechan.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  An InterNetNews channel process that splits a funnel entry into
-**  separate files.  Originally from Robert Elz <kre@munnari.oz.au>.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-
-#include "map.h"
-
-int
-main(int ac, char *av[])
-{
-    char               buff[2048];
-    char                *p;
-    char                *next;
-    int                 i;
-    int                 fd;
-    int                        Fields;
-    const char         *Directory;
-    bool               Map;
-    FILE               *F;
-    struct stat                Sb;
-    uid_t              uid;
-    gid_t              gid;
-    uid_t              myuid;
-
-    /* First thing, set up our identity. */
-    message_program_name = "filechan";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    Fields = 1;
-    Directory = innconf->pathoutgoing;
-    Map = false;
-    myuid = geteuid();
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "d:f:m:p:")) != EOF)
-       switch (i) {
-       default:
-            die("usage error");
-            break;
-       case 'd':
-           Directory = optarg;
-           break;
-       case 'f':
-           Fields = atoi(optarg);
-           break;
-       case 'm':
-           Map = true;
-           MAPread(optarg);
-           break;
-       case 'p':
-           if ((F = fopen(optarg, "w")) == NULL)
-                sysdie("cannot fopen %s", optarg);
-           fprintf(F, "%ld\n", (long)getpid());
-           if (ferror(F) || fclose(F) == EOF)
-                sysdie("cannot fclose %s", optarg);
-           break;
-       }
-
-    /* Move, and get owner of current directory. */
-    if (chdir(Directory) < 0)
-        sysdie("cannot chdir to %s", Directory);
-    if (stat(".", &Sb) < 0)
-        sysdie("cannot stat %s", Directory);
-    uid = Sb.st_uid;
-    gid = Sb.st_gid;
-
-    /* Read input. */
-    while (fgets(buff, sizeof buff, stdin) != NULL) {
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-
-       /* Skip the right number of leading fields. */
-       for (i = Fields, p = buff; *p; p++)
-           if (*p == ' ' && --i <= 0)
-               break;
-       if (*p == '\0')
-           /* Nothing to write.  Probably shouldn't happen. */
-           continue;
-
-       /* Add a newline, get the length of all leading fields. */
-       *p++ = '\n';
-       i = p - buff;
-
-       /* Rest of the line is space-separated list of filenames. */
-       for (; *p; p = next) {
-           /* Skip whitespace, get next word. */
-           while (*p == ' ')
-               p++;
-           for (next = p; *next && *next != ' '; next++)
-               continue;
-           if (*next)
-               *next++ = '\0';
-
-           if (Map)
-               p = MAPname(p);
-           fd = open(p, O_CREAT | O_WRONLY | O_APPEND, BATCHFILE_MODE);
-           if (fd >= 0) {
-               /* Try to lock it and set the ownership right. */
-               inn_lock_file(fd, INN_LOCK_WRITE, true);
-               if (myuid == 0 && uid != 0)
-                   chown(p, uid, gid);
-
-               /* Just in case, seek to the end. */
-               lseek(fd, 0, SEEK_END);
-
-               errno = 0;
-               if (write(fd, buff, i) != i)
-                    sysdie("write failed");
-
-               close(fd);
-           }
-       }
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/inndf.c b/backends/inndf.c
deleted file mode 100644 (file)
index 6a85c86..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*  $Id: inndf.c 6677 2004-03-03 18:36:07Z hkehoe $
-**
-**  Reports free kilobytes (not disk blocks) or free inodes.
-**
-**  Written by Ian Dickinson <idickins@fore.com>
-**  Wed Jul 26 10:11:38 BST 1995 (My birthday - 27 today!)
-**
-**  inndf is a replacement for 'df | awk' in innwatch.ctl and for reporting
-**  free space in other INN scripts.  It doesn't sync, it forks less, and
-**  it's generally less complicated.
-**
-**  Usage: inndf [-i] <directory> [<directory> ...]
-**         inndf -n
-**         inndf -o
-**
-**  Compile with -lserver (ie. /usr/lib/libserver.a) if you run Sun's Online
-**  DiskSuite under SunOS 4.x.  The wrapper functions there make the system
-**  call transparent; they copy the f_spare values to the correct spots, so
-**  f_blocks, f_bfree, f_bavail can exceed 2GB.
-**
-**  Compile with -DHAVE_STATVFS for these systems:
-**          System V Release 4.x
-**          Solaris 2.x
-**          HP-UX 10.x
-**          OSF1
-**  
-**  Compile with -DHAVE_STATFS for these systems:
-**          SunOS 4.x/Solaris 1.x
-**          HP-UX 9.x
-**          Linux
-**          NeXTstep 3.x
-**
-**  (Or even better, let autoconf take care of it.)
-**  
-**  Thanks to these folks for bug fixes and porting information:
-**          Mahesh Ramachandran <rr@eel.ufl.edu>
-**          Chuck Swiger <chuck@its.com>
-**          Sang-yong Suh <sysuh@kigam.re.kr>
-**          Swa Frantzen <Swa.Frantzen@Belgium.EU.net>
-**          Brad Dickey <bdickey@haverford.edu>
-**          Taso N. Devetzis <devetzis@snet.net>
-**          Wei-Yeh Lee <weiyeh@columbia.edu>
-**          Jeff Garzik <jeff.garzik@spinne.com>
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-
-/* The portability mess.  Hide everything in macros so that the actual code
-   is relatively clean.  SysV uses statvfs, BSD uses statfs, and ULTRIX is
-   just weird (and isn't worth checking for in configure).
-
-   df_declare declares a variable of the appropriate type to pass to df_stat
-   along with a path; df_stat will return true on success, false on failure.
-   df_avail gives the number of free blocks, the size of those blocks given
-   in df_bsize (which handles SysV's weird fragment vs. preferred block size
-   thing).  df_inodes returns the free inodes. */
-#if HAVE_STATVFS
-# include <sys/statvfs.h>
-# define df_stat(p, s)  (statvfs((p), (s)) == 0)
-# define df_declare(s)  struct statvfs s
-# define df_total(s)    ((s).f_blocks)
-# define df_avail(s)    ((s).f_bavail)
-# define df_scale(s)    ((s).f_frsize == 0 ? (s).f_bsize : (s).f_frsize)
-# define df_files(s)    ((s).f_files)
-# define df_favail(s)   ((s).f_favail)
-#elif HAVE_STATFS
-# if HAVE_SYS_VFS_H
-#  include <sys/vfs.h>
-# endif
-# if HAVE_SYS_PARAM_H
-#  include <sys/param.h>
-# endif
-# if HAVE_SYS_MOUNT_H
-#  include <sys/mount.h>
-# endif
-# ifdef __ultrix__
-#  define df_stat(p, s) (statfs((p), (s)) >= 1)
-#  define df_declare(s) struct fs_data s
-#  define df_total(s)   ((s).fd_btot)
-#  define df_avail(s)   ((s).fd_bfreen)
-#  define df_scale(s)   1024
-#  define df_files(s)   ((s).fd_gtot)
-#  define df_favail(s)  ((s).fd_gfree)
-# else
-#  define df_stat(p, s) (statfs((p), (s)) == 0)
-#  define df_declare(s) struct statfs s
-#  define df_total(s)   ((s).f_blocks)
-#  define df_avail(s)   ((s).f_bavail)
-#  define df_scale(s)   ((s).f_bsize)
-#  define df_files(s)   ((s).f_files)
-#  define df_favail(s)  ((s).f_ffree)
-# endif
-#else
-# error "Platform not supported.  Neither statvfs nor statfs available."
-#endif
-
-static const char usage[] = "\
-Usage: inndf [-i] [-f filename] [-F] <directory> [<directory> ...]\n\
-       inndf -n\n\
-       inndf -o\n\
-\n\
-The first form gives the free space in kilobytes (or the count of free\n\
-inodes if -i is given) in the file systems given by the arguments.  If\n\
--f is given, the corresponding file should be a list of directories to\n\
-check in addition to the arguments.  -F uses <pathetc>/filesystems as the\n\
-file and is otherwise the same.\n\
-\n\
-The second form gives the total count of overview records stored.  The\n\
-third form gives the percentage space allocated to overview that's been\n\
-used (if the overview method used supports this query).";
-
-/*
-**  Given a path, a flag saying whether to look at inodes instead of free
-**  disk space, and a flag saying whether to format in columns, print out
-**  the amount of free space or inodes on that file system.  Returns the
-**  percentage free, which may be printed out by the caller.
-*/
-static void
-printspace(const char *path, bool inode, bool fancy)
-{
-    df_declare(info);
-    unsigned long amount;
-    double percent;
-
-    if (df_stat(path, &info)) {
-        if (inode) {
-            amount = df_favail(info);
-
-            /* This value is compared using the shell by innwatch, and some
-               shells can't cope with anything larger than the maximum value
-               of a signed long.  ReiserFS returns 2^32 - 1, however, since it
-               has no concept of inodes.  So cap the returned value at the max
-               value of a signed long. */
-            if (amount > (1UL << 31) - 1)
-                amount = (1UL << 31) - 1;
-
-           /* 2.6 kernels show 0 available and used inodes, instead. */
-           if (amount == 0 && df_files(info) == 0)
-               amount = (1UL << 31) - 1;
-        } else {
-            /* Do the multiplication in floating point to try to retain
-               accuracy if the free space in bytes would overflow an
-               unsigned long.  This should be safe until file systems larger
-               than 4TB (which may not be much longer -- we should use long
-               long instead if we have it).
-
-               Be very careful about the order of casts here; it's too
-               easy to cast back into an unsigned long a value that
-               overflows, and one then gets silently wrong results. */
-            amount = (unsigned long)
-                (((double) df_avail(info) * df_scale(info)) / 1024.0);
-        }
-    } else {
-        /* On error, free space is zero. */
-        amount = 0;
-    }
-    printf(fancy ? "%10lu" : "%lu", amount);
-    if (fancy) {
-        printf(inode ? " inodes available " : " Kbytes available ");
-        if (inode)
-            percent = 100 * ((double) df_favail(info) / df_files(info));
-        else
-            percent = 100 * ((double) df_avail(info) / df_total(info));
-        if (percent < 9.95)
-            printf("  (%3.1f%%)", percent);
-        else if (percent < 99.95)
-            printf(" (%4.1f%%)", percent);
-        else
-            printf("(%5.1f%%)", percent);
-    }
-}
-
-static void
-printspace_formatted(const char *path, bool inode)
-{
-    printf("%-40s ", path);
-    printspace(path, inode, true);
-    printf("\n");
-}
-
-static char *
-readline(QIOSTATE *qp)
-{
-    char *line, *p;
-
-    for (line = QIOread(qp); line != NULL; line = QIOread(qp)) {
-        p = strchr(line, '#');
-        if (p != NULL)
-            *p = '\0';
-        for (; *line == ' ' || *line == '\t'; line++)
-            ;
-        if (*line != '\0') {
-            for (p = line; *p != '\0' && *p != ' ' && *p != '\t'; p++)
-                ;
-            *p = '\0';
-            return line;
-        }
-    }
-    return NULL;
-}
-
-int
-main(int argc, char *argv[])
-{
-    int option, i, count;
-    unsigned long total;
-    QIOSTATE *qp;
-    char *active, *group, *line, *p;
-    char *file = NULL;
-    bool inode = false;
-    bool overview = false;
-    bool ovcount = false;
-    bool use_filesystems = false;
-
-    while ((option = getopt(argc, argv, "hinof:F")) != EOF) {
-        switch (option) {
-        default:
-            die(usage);
-        case 'h':
-            printf("%s\n", usage);
-            exit(0);
-        case 'i':
-            inode = true;
-            break;
-        case 'n':
-            ovcount = true;
-            break;
-        case 'o':
-            overview = true;
-            break;
-        case 'f':
-            if (file != NULL)
-                die("inndf: Only one of -f or -F may be given");
-            file = xstrdup(optarg);
-            break;
-        case 'F':
-            if (file != NULL)
-                die("inndf: Only one of -f or -F may be given");
-            if (!innconf_read(NULL))
-                exit(1);
-            file = concatpath(innconf->pathetc, INN_PATH_FILESYSTEMS);
-            use_filesystems = true;
-            break;
-        }
-    }
-    argc -= optind;
-    argv += optind;
-
-    if (argc == 0 && !overview && !ovcount && file == NULL)
-        die(usage);
-
-    /* Set the program name now rather than earlier so that it doesn't get
-       prepended to usage messages. */
-    message_program_name = "inndf";
-
-    /* If directories were specified, get statistics about them.  If only
-       one was given, just print out the number without the path or any
-       explanatory text; this mode is used by e.g. innwatch.  Otherwise,
-       format things nicely. */
-    if (argc == 1 && !overview && !ovcount && file == NULL) {
-        printspace(argv[0], inode, false);
-        printf("\n");
-    } else {
-        for (i = 0; i < argc; i++)
-            printspace_formatted(argv[i], inode);
-        if (file != NULL) {
-            qp = QIOopen(file);
-            if (qp == NULL) {
-                if (!use_filesystems)
-                    sysdie("can't open %s", file);
-            } else {
-                line = readline(qp);
-                while (line != NULL) {
-                    printspace_formatted(line, inode);
-                    line = readline(qp);
-                }
-                QIOclose(qp);
-            }
-            free(file);
-        }
-    }
-
-    /* If we're going to be getting information from overview, do the icky
-       initialization stuff. */
-    if (overview || ovcount) {
-        if (!use_filesystems)
-            if (!innconf_read(NULL))
-                exit(1);
-        if (!OVopen(OV_READ))
-            die("OVopen failed");
-    }
-
-    /* For the count, we have to troll through the active file and query the
-       overview backend for each group. */
-    if (ovcount) {
-        active = concatpath(innconf->pathdb, _PATH_ACTIVE);
-        qp = QIOopen(active);
-        if (qp == NULL)
-            sysdie("can't open %s", active);
-
-        total = 0;
-        group = QIOread(qp);
-        while (group != NULL) {
-            p = strchr(group, ' ');
-            if (p != NULL)
-                *p = '\0';
-            if (OVgroupstats(group, NULL, NULL, &count, NULL))
-               total += count;
-            group = QIOread(qp);
-        }
-        QIOclose(qp);
-        printf("%lu overview records stored\n", total);
-    }
-
-    /* Percentage used is simpler, but only some overview methods understand
-       that query. */
-    if (overview) {
-        if (OVctl(OVSPACE, &count)) {
-            if (count == -1)
-                printf("Space used is meaningless for the %s method\n",
-                       innconf->ovmethod);
-            else
-                printf("%d%% overview space used\n", count);
-        }
-    }
-    exit(0);
-}
diff --git a/backends/innxbatch.c b/backends/innxbatch.c
deleted file mode 100644 (file)
index 9ebfe9c..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-/*  $Id: innxbatch.c 6351 2003-05-19 02:00:06Z rra $
-**
-**  Transmit batches to remote site, using the XBATCH command
-**  Modelled after innxmit.c and nntpbatch.c
-**
-**  Invocation:
-**     innxbatch [options] <serverhost> <file> ...
-#ifdef FROMSTDIN
-**     innxbatch -i <serverhost>
-#endif FROMSTDIN
-**  will connect to serverhost's nntp port, and transfer the named files,
-**  with an xbatch command for every file. Files that have been sent
-**  successfully are unlink()ed. In case of any error, innxbatch terminates
-**  and leaves any remaining files untouched, for later transmission.
-**  Options:
-**     -D      increase debug level
-**     -v      report statistics to stdout
-#ifdef FROMSTDIN
-**     -i      read batch file names from stdin instead from command line.
-**             For each successfully transmitted batch, an OK is printed on
-**             stdout, to indicate that another file name is expected.
-#endif
-**     -t      Timeout for connection attempt
-**     -T      Timeout for batch transfers.
-**  We do not use any file locking. At worst, a batch could be transmitted
-**  twice in parallel by two independant invocations of innxbatch.
-**  To prevent this, innxbatch should be invoked by a shell script that uses
-**  shlock(1) to achieve mutual exclusion.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/timer.h"
-#include "libinn.h"
-#include "nntp.h"
-
-/*
-** Syslog formats - collected together so they remain consistent
-*/
-static char    STAT1[] =
-       "%s stats offered %lu accepted %lu refused %lu rejected %lu";
-static char    STAT2[] = "%s times user %.3f system %.3f elapsed %.3f";
-static char    CANT_CONNECT[] = "%s connect failed %s";
-static char    CANT_AUTHENTICATE[] = "%s authenticate failed %s";
-static char    XBATCH_FAIL[] = "%s xbatch failed %s";
-static char    UNKNOWN_REPLY[] = "Unknown reply after sending batch -- %s";
-static char    CANNOT_UNLINK[] = "cannot unlink %s: %m";
-/*
-**  Global variables.
-*/
-static bool            Debug = 0;
-static bool            STATprint;
-static char            *REMhost;
-static double          STATbegin;
-static double          STATend;
-static char            *XBATCHname;
-static int             FromServer;
-static int             ToServer;
-static sig_atomic_t    GotAlarm;
-static sig_atomic_t    GotInterrupt;
-static sig_atomic_t    JMPyes;
-static jmp_buf         JMPwhere;
-static unsigned long   STATaccepted;
-static unsigned long   STAToffered;
-static unsigned long   STATrefused;
-static unsigned long   STATrejected;
-
-/*
-**  Send a line to the server. \r\n will be appended
-*/
-static bool
-REMwrite(int fd, char *p)
-{
-  int          i;
-  int          err;
-  char         *dest;
-  static char          buff[NNTP_STRLEN];
-
-  for (dest = buff, i = 0; p[i]; ) *dest++ = p[i++];
-  *dest++ = '\r';
-  *dest++ = '\n';
-  *dest++ = '\0';
-
-  for (dest = buff, i+=2; i; dest += err, i -= err) {
-    err = write(fd, dest, i);
-    if (err < 0) {
-      syswarn("cannot write %s to %s", dest, REMhost);
-      return false;
-    }
-  }
-  if (Debug)
-    fprintf(stderr, "> %s\n", p);
-
-  return true;
-}
-
-/*
-**  Print transfer statistics, clean up, and exit.
-*/
-static void
-ExitWithStats(int x)
-{
-  static char          QUIT[] = "quit";
-  double               usertime;
-  double               systime;
-
-  REMwrite(ToServer, QUIT);
-
-  STATend = TMRnow_double();
-  if (GetResourceUsage(&usertime, &systime) < 0) {
-    usertime = 0;
-    systime = 0;
-  }
-
-  if (STATprint) {
-    printf(STAT1,
-       REMhost, STAToffered, STATaccepted, STATrefused, STATrejected);
-    printf("\n");
-    printf(STAT2, REMhost, usertime, systime, STATend - STATbegin);
-    printf("\n");
-  }
-
-  syslog(L_NOTICE, STAT1,
-        REMhost, STAToffered, STATaccepted, STATrefused, STATrejected);
-  syslog(L_NOTICE, STAT2, REMhost, usertime, systime, STATend - STATbegin);
-
-  exit(x);
-  /* NOTREACHED */
-}
-
-
-/*
-**  Clean up the NNTP escapes from a line.
-*/
-static char *
-REMclean(char *buff)
-{
-    char       *p;
-
-    if ((p = strchr(buff, '\r')) != NULL)
-       *p = '\0';
-    if ((p = strchr(buff, '\n')) != NULL)
-       *p = '\0';
-
-    /* The dot-escape is only in text, not command responses. */
-    return buff;
-}
-
-
-/*
-**  Read a line of input, with timeout. We expect only answer lines, so
-**  we ignore \r\n-->\n mapping and the dot escape.
-**  Return true if okay, *or we got interrupted.*
-*/
-static bool
-REMread(char *start, int size)
-{
-  char *p, *h;
-  struct timeval t;
-  fd_set rmask;
-  int i;
-
-  for (p = start; size; ) {
-    FD_ZERO(&rmask);
-    FD_SET(FromServer, &rmask);
-    t.tv_sec = 10 * 60;
-    t.tv_usec = 0;
-    i = select(FromServer + 1, &rmask, NULL, NULL, &t);
-    if (GotInterrupt) return true;
-    if (i < 0) {
-      if (errno == EINTR) continue;
-      else return false;
-    }
-    if (i == 0 || !FD_ISSET(FromServer, &rmask)) return false;
-    i = read(FromServer, p, size-1);
-    if (GotInterrupt) return true;
-    if (i <= 0) return false;
-    h = p;
-    p += i;
-    size -= i;
-    for ( ; h < p; h++) {
-      if (h > start && '\n' == *h && '\r' == h[-1]) {
-       *h = h[-1] = '\0';
-       size = 0;
-      }
-    }
-  }
-
-  if (Debug)
-    fprintf(stderr, "< %s\n", start);
-
-  return true;
-}
-
-
-/*
-**  Handle the interrupt.
-*/
-static void
-Interrupted(void)
-{
-  warn("interrupted");
-  ExitWithStats(1);
-}
-
-
-/*
-**  Send a whole xbatch to the server. Uses the global variables
-**  REMbuffer & friends
-*/
-static bool
-REMsendxbatch(int fd, char *buf, int size)
-{
-  char *p;
-  int          i;
-  int          err;
-
-  for (i = size, p = buf; i; p += err, i -= err) {
-    err = write(fd, p, i);
-    if (err < 0) {
-      syswarn("cannot write xbatch to %s", REMhost);
-      return false;
-    }
-  }
-  if (GotInterrupt) Interrupted();
-  if (Debug)
-    fprintf(stderr, "> [%d bytes of xbatch]\n", size);
-
-  /* What did the remote site say? */
-  if (!REMread(buf, size)) {
-    syswarn("no reply after sending xbatch");
-    return false;
-  }
-  if (GotInterrupt) Interrupted();
-  
-  /* Parse the reply. */
-  switch (atoi(buf)) {
-  default:
-    warn("unknown reply after sending batch -- %s", buf);
-    syslog(L_ERROR, UNKNOWN_REPLY, buf);
-    return false;
-    /* NOTREACHED */
-    break;
-  case NNTP_RESENDIT_VAL:
-  case NNTP_GOODBYE_VAL:
-    syslog(L_NOTICE, XBATCH_FAIL, REMhost, buf);
-    STATrejected++;
-    return false;
-    /* NOTREACHED */
-    break;
-  case NNTP_OK_XBATCHED_VAL:
-    STATaccepted++;
-    if (Debug) fprintf(stderr, "will unlink(%s)\n", XBATCHname);
-    if (unlink(XBATCHname)) {
-      /* probably another incarantion was faster, so avoid further duplicate
-       * work
-       */
-      syswarn("cannot unlink %s", XBATCHname);
-      syslog(L_NOTICE, CANNOT_UNLINK, XBATCHname);
-      return false;
-    }
-    break;
-  }
-  
-  /* Article sent */
-  return true;
-}
-
-/*
-**  Mark that we got interrupted.
-*/
-static RETSIGTYPE
-CATCHinterrupt(int s)
-{
-    GotInterrupt = true;
-
-    /* Let two interrupts kill us. */
-    xsignal(s, SIG_DFL);
-}
-
-
-/*
-**  Mark that the alarm went off.
-*/
-/* ARGSUSED0 */
-static RETSIGTYPE
-CATCHalarm(int s UNUSED)
-{
-    GotAlarm = true;
-    if (JMPyes)
-       longjmp(JMPwhere, 1);
-}
-
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    warn("Usage: innxbatch [-Dv] [-t#] [-T#] host file ...");
-#ifdef FROMSTDIN
-    warn("       innxbatch [-Dv] [-t#] [-T#] -i host");
-#endif
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-  int                  i;
-  char                  *p;
-  FILE                 *From;
-  FILE                 *To;
-  char                 buff[NNTP_STRLEN];
-  RETSIGTYPE           (*old)(int) = NULL;
-  unsigned int         ConnectTimeout;
-  unsigned int         TotalTimeout;
-  struct stat          statbuf;
-  int                  fd;
-  int                  err;
-  char                 *XBATCHbuffer = NULL;
-  int                  XBATCHbuffersize = 0;
-  int                  XBATCHsize;
-
-  openlog("innxbatch", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-  message_program_name = "innxbatch";
-
-  /* Set defaults. */
-  if (!innconf_read(NULL))
-      exit(1);
-  ConnectTimeout = 0;
-  TotalTimeout = 0;
-  umask(NEWSUMASK);
-
-  /* Parse JCL. */
-  while ((i = getopt(ac, av, "Dit:T:v")) != EOF)
-    switch (i) {
-    default:
-      Usage();
-      /* NOTREACHED */
-      break;
-    case 'D':
-      Debug++;
-      break;
-#ifdef FROMSTDIN
-    case 'i':
-      FromStdin = true;
-      break;
-#endif
-    case 't':
-      ConnectTimeout = atoi(optarg);
-      break;
-    case 'T':
-      TotalTimeout = atoi(optarg);
-      break;
-    case 'v':
-      STATprint = true;
-      break;
-    }
-  ac -= optind;
-  av += optind;
-
-  /* Parse arguments; host and filename. */
-  if (ac < 2)
-    Usage();
-  REMhost = av[0];
-  ac--;
-  av++;
-
-  /* Open a connection to the remote server. */
-  if (ConnectTimeout) {
-    GotAlarm = false;
-    old = xsignal(SIGALRM, CATCHalarm);
-    JMPyes = true;
-    if (setjmp(JMPwhere))
-      die("cannot connect to %s: timed out", REMhost);
-    alarm(ConnectTimeout);
-  }
-  if (NNTPconnect(REMhost, NNTP_PORT, &From, &To, buff) < 0 || GotAlarm) {
-    i = errno;
-    warn("cannot connect to %s: %s", REMhost,
-         buff[0] ? REMclean(buff): strerror(errno));
-    if (GotAlarm)
-      syslog(L_NOTICE, CANT_CONNECT, REMhost, "timeout");
-    else
-      syslog(L_NOTICE, CANT_CONNECT, REMhost,
-            buff[0] ? REMclean(buff) : strerror(i));
-    exit(1);
-  }
-
-  if (Debug)
-    fprintf(stderr, "< %s\n", REMclean(buff));
-  if (NNTPsendpassword(REMhost, From, To) < 0 || GotAlarm) {
-    i = errno;
-    syswarn("cannot authenticate with %s", REMhost);
-    syslog(L_ERROR, CANT_AUTHENTICATE,
-          REMhost, GotAlarm ? "timeout" : strerror(i));
-    /* Don't send quit; we want the remote to print a message. */
-    exit(1);
-  }
-  if (ConnectTimeout) {
-    alarm(0);
-    xsignal(SIGALRM, old);
-    JMPyes = false;
-  }
-  
-  /* We no longer need standard I/O. */
-  FromServer = fileno(From);
-  ToServer = fileno(To);
-
-#if    defined(SOL_SOCKET) && defined(SO_SNDBUF) && defined(SO_RCVBUF)
-  i = 24 * 1024;
-  if (setsockopt(ToServer, SOL_SOCKET, SO_SNDBUF, (char *)&i, sizeof i) < 0)
-    perror("cant setsockopt(SNDBUF)");
-  if (setsockopt(FromServer, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof i) < 0)
-    perror("cant setsockopt(RCVBUF)");
-#endif /* defined(SOL_SOCKET) && defined(SO_SNDBUF) && defined(SO_RCVBUF) */
-
-  GotInterrupt = false;
-  GotAlarm = false;
-
-  /* Set up signal handlers. */
-  xsignal(SIGHUP, CATCHinterrupt);
-  xsignal(SIGINT, CATCHinterrupt);
-  xsignal(SIGTERM, CATCHinterrupt);
-  xsignal(SIGPIPE, SIG_IGN);
-  if (TotalTimeout) {
-    xsignal(SIGALRM, CATCHalarm);
-    alarm(TotalTimeout);
-  }
-
-  /* Start timing. */
-  STATbegin = TMRnow_double();
-
-  /* main loop over all specified files */
-  for (XBATCHname = *av; ac && (XBATCHname = *av); av++, ac--) {
-
-    if (Debug) fprintf(stderr, "will work on %s\n", XBATCHname);
-
-    if (GotAlarm) {
-      warn("timed out");
-      ExitWithStats(1);
-    }
-    if (GotInterrupt) Interrupted();
-
-    if ((fd = open(XBATCHname, O_RDONLY, 0)) < 0) {
-      syswarn("cannot open %s, skipping", XBATCHname);
-      continue;
-    }
-
-    if (fstat(fd, &statbuf)) {
-      syswarn("cannot stat %s, skipping", XBATCHname);
-      close(i);
-      continue;
-    }
-
-    XBATCHsize = statbuf.st_size;
-    if (XBATCHsize == 0) {
-      warn("batch file %s is zero length, skipping", XBATCHname);
-      close(i);
-      unlink(XBATCHname);
-      continue;
-    } else if (XBATCHsize > XBATCHbuffersize) {
-      XBATCHbuffersize = XBATCHsize;
-      if (XBATCHbuffer) free(XBATCHbuffer);
-      XBATCHbuffer = xmalloc(XBATCHsize);
-    }
-
-    err = 0; /* stupid compiler */
-    for (i = XBATCHsize, p = XBATCHbuffer; i; i -= err, p+= err) {
-      err = read(fd, p, i);
-      if (err < 0) {
-        syswarn("error reading %s, skipping", XBATCHname);
-       break;
-      } else if (0 == err) {
-        syswarn("unexpected EOF reading %s, truncated", XBATCHname);
-       XBATCHsize = p - XBATCHbuffer;
-       break;
-      }
-    }
-    close(fd);
-    if (err < 0)
-      continue;
-
-    if (GotInterrupt) Interrupted();
-
-    /* Offer the xbatch. */
-    snprintf(buff, sizeof(buff), "xbatch %d", XBATCHsize);
-    if (!REMwrite(ToServer, buff)) {
-      syswarn("cannot offer xbatch to %s", REMhost);
-      ExitWithStats(1);
-    }
-    STAToffered++;
-    if (GotInterrupt) Interrupted();
-
-    /* Does he want it? */
-    if (!REMread(buff, (int)sizeof buff)) {
-      syswarn("no reply to XBATCH %d from %s", XBATCHsize, REMhost);
-      ExitWithStats(1);
-    }
-    if (GotInterrupt) Interrupted();
-
-    /* Parse the reply. */
-    switch (atoi(buff)) {
-    default:
-      warn("unknown reply to %s -- %s", XBATCHname, buff);
-      ExitWithStats(1);
-      /* NOTREACHED */
-      break;
-    case NNTP_RESENDIT_VAL:
-    case NNTP_GOODBYE_VAL:
-      /* Most likely out of space -- no point in continuing. */
-      syslog(L_NOTICE, XBATCH_FAIL, REMhost, buff);
-      ExitWithStats(1);
-      /* NOTREACHED */
-    case NNTP_CONT_XBATCH_VAL:
-      if (!REMsendxbatch(ToServer, XBATCHbuffer, XBATCHsize))
-       ExitWithStats(1);
-      /* NOTREACHED */
-      break;
-    case NNTP_SYNTAX_VAL:
-    case NNTP_BAD_COMMAND_VAL:
-      warn("server %s seems not to understand XBATCH: %s", REMhost, buff);
-      syslog(L_FATAL, XBATCH_FAIL, REMhost, buff);
-      break;
-    }
-  }
-  ExitWithStats(0);
-  /* NOTREACHED */
-  return 0;
-}
diff --git a/backends/innxmit.c b/backends/innxmit.c
deleted file mode 100644 (file)
index 475ce63..0000000
+++ /dev/null
@@ -1,1457 +0,0 @@
-/*  $Id: innxmit.c 6716 2004-05-16 20:26:56Z rra $
-**
-**  Transmit articles to remote site.
-**  Modified for NNTP streaming: 1996-01-03 Jerry Aguirre
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "inn/timer.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-#include "storage.h"
-
-#define OUTPUT_BUFFER_SIZE     (16 * 1024)
-
-/* Streaming extensions to NNTP.  This extension removes the lock-step
-** limitation of conventional NNTP.  Article transfer is several times
-** faster.  Negotiated and falls back to old mode if receiver refuses.
-*/
-
-/* max number of articles that can be streamed ahead */
-#define STNBUF 32
-
-/* Send "takethis" without "check" if this many articles were
-** accepted in a row.
-*/
-#define STNC 16
-
-/* typical number of articles to stream  */
-/* must be able to fopen this many articles */
-#define STNBUFL (STNBUF/2)
-
-/* number of retries before requeueing to disk */
-#define STNRETRY 5
-
-struct stbufs {                /* for each article we are procesing */
-       char *st_fname;         /* file name */
-       char *st_id;            /* message ID */
-       int   st_retry;         /* retry count */
-       int   st_age;           /* age count */
-       ARTHANDLE *art;         /* arthandle to read article contents */
-       int   st_hash;          /* hash value to speed searches */
-       long  st_size;          /* article size */
-};
-static struct stbufs stbuf[STNBUF]; /* we keep track of this many articles */
-static int stnq;       /* current number of active entries in stbuf */
-static long stnofail;  /* Count of consecutive successful sends */
-
-static int TryStream = true;   /* Should attempt stream negotation? */
-static int CanStream = false;  /* Result of stream negotation */
-static int DoCheck   = true;   /* Should check before takethis? */
-static char modestream[] = "mode stream";
-static char modeheadfeed[] = "mode headfeed";
-static long retries = 0;
-static int logRejects = false ;  /* syslog the 437 responses. */
-
-
-
-/*
-** Syslog formats - collected together so they remain consistent
-*/
-static char    STAT1[] =
-       "%s stats offered %lu accepted %lu refused %lu rejected %lu missing %lu accsize %.0f rejsize %.0f";
-static char    STAT2[] = "%s times user %.3f system %.3f elapsed %.3f";
-static char    GOT_BADCOMMAND[] = "%s rejected %s %s";
-static char    REJECTED[] = "%s rejected %s (%s) %s";
-static char    REJ_STREAM[] = "%s rejected (%s) %s";
-static char    CANT_CONNECT[] = "%s connect failed %s";
-static char    CANT_AUTHENTICATE[] = "%s authenticate failed %s";
-static char    IHAVE_FAIL[] = "%s ihave failed %s";
-
-static char    CANT_FINDIT[] = "%s can't find %s";
-static char    CANT_PARSEIT[] = "%s can't parse ID %s";
-static char    UNEXPECTED[] = "%s unexpected response code %s";
-
-/*
-**  Global variables.
-*/
-static bool            AlwaysRewrite;
-static bool            Debug;
-static bool            DoRequeue = true;
-static bool            Purging;
-static bool            STATprint;
-static bool            HeadersFeed;
-static char            *BATCHname;
-static char            *BATCHtemp;
-static char            *REMhost;
-static double          STATbegin;
-static double          STATend;
-static FILE            *BATCHfp;
-static int             FromServer;
-static int             ToServer;
-static struct history  *History;
-static QIOSTATE                *BATCHqp;
-static sig_atomic_t    GotAlarm;
-static sig_atomic_t    GotInterrupt;
-static sig_atomic_t    JMPyes;
-static jmp_buf         JMPwhere;
-static char            *REMbuffer;
-static char            *REMbuffptr;
-static char            *REMbuffend;
-static unsigned long   STATaccepted;
-static unsigned long   STAToffered;
-static unsigned long   STATrefused;
-static unsigned long   STATrejected;
-static unsigned long   STATmissing;
-static double          STATacceptedsize;
-static double          STATrejectedsize;
-
-
-/* Prototypes. */
-static ARTHANDLE *article_open(const char *path, const char *id);
-static void article_free(ARTHANDLE *);
-
-
-/*
-**  Return true if the history file has the article expired.
-*/
-static bool
-Expired(char *MessageID) {
-    return !HISlookup(History, MessageID, NULL, NULL, NULL, NULL);
-}
-
-
-/*
-**  Flush and reset the site's output buffer.  Return false on error.
-*/
-static bool
-REMflush(void)
-{
-    int                i;
-
-    if (REMbuffptr == REMbuffer) return true; /* nothing buffered */
-    i = xwrite(ToServer, REMbuffer, (int)(REMbuffptr - REMbuffer));
-    REMbuffptr = REMbuffer;
-    return i < 0 ? false : true;
-}
-
-/*
-**  Return index to entry matching this message ID.  Else return -1.
-**  The hash is to speed up the search.
-**  the protocol.
-*/
-static int
-stindex(char *MessageID, int hash) {
-    int i;
-
-    for (i = 0; i < STNBUF; i++) { /* linear search for ID */
-       if ((stbuf[i].st_id) && (stbuf[i].st_id[0])
-        && (stbuf[i].st_hash == hash)) {
-           int n;
-
-           if (strcasecmp(MessageID, stbuf[i].st_id)) continue;
-
-           /* left of '@' is case sensitive */
-           for (n = 0; (MessageID[n] != '@') && (MessageID[n] != '\0'); n++) ;
-           if (strncmp(MessageID, stbuf[i].st_id, n)) continue;
-           else break; /* found a match */
-       }
-    }
-    if (i >= STNBUF) i = -1;  /* no match found ? */
-    return (i);
-}
-
-/* stidhash(): calculate a hash value for message IDs to speed comparisons */
-static int
-stidhash(char *MessageID) {
-    char       *p;
-    int                hash;
-
-    hash = 0;
-    for (p = MessageID + 1; *p && (*p != '>'); p++) {
-       hash <<= 1;
-       if (isascii((int)*p) && isupper((int)*p)) {
-           hash += tolower(*p);
-       } else {
-           hash += *p;
-       }
-    }
-    return hash;
-}
-
-/* stalloc(): save path, ID, and qp into one of the streaming mode entries */
-static int
-stalloc(char *Article, char *MessageID, ARTHANDLE *art, int hash) {
-    int i;
-
-    for (i = 0; i < STNBUF; i++) {
-       if ((!stbuf[i].st_fname) || (stbuf[i].st_fname[0] == '\0')) break;
-    }
-    if (i >= STNBUF) { /* stnq says not full but can not find unused */
-       syslog(L_ERROR, "stalloc: Internal error");
-       return (-1);
-    }
-    if ((int)strlen(Article) >= SPOOLNAMEBUFF) {
-       syslog(L_ERROR, "stalloc: filename longer than %d", SPOOLNAMEBUFF);
-       return (-1);
-    }
-    /* allocate buffers on first use.
-    ** If filename ever is longer than SPOOLNAMEBUFF then code will abort.
-    ** If ID is ever longer than NNTP_STRLEN then other code would break.
-    */
-    if (!stbuf[i].st_fname)
-        stbuf[i].st_fname = xmalloc(SPOOLNAMEBUFF);
-    if (!stbuf[i].st_id)
-        stbuf[i].st_id = xmalloc(NNTP_STRLEN);
-    strlcpy(stbuf[i].st_fname, Article, SPOOLNAMEBUFF);
-    strlcpy(stbuf[i].st_id, MessageID, NNTP_STRLEN);
-    stbuf[i].art = art;
-    stbuf[i].st_hash = hash;
-    stbuf[i].st_retry = 0;
-    stbuf[i].st_age = 0;
-    stnq++;
-    return i;
-}
-
-/* strel(): release for reuse one of the streaming mode entries */
-static void
-strel(int i) {
-       if (stbuf[i].art) {
-            article_free(stbuf[i].art);
-           stbuf[i].art = NULL;
-       }
-       if (stbuf[i].st_id) stbuf[i].st_id[0] = '\0';
-       if (stbuf[i].st_fname) stbuf[i].st_fname[0] = '\0';
-       stnq--;
-}
-
-/*
-**  Send a line to the server, adding the dot escape and \r\n.
-*/
-static bool
-REMwrite(char *p, int i, bool escdot) {
-    int        size;
-
-    /* Buffer too full? */
-    if (REMbuffend - REMbuffptr < i + 3) {
-       if (!REMflush())
-           return false;
-       if (REMbuffend - REMbuffer < i + 3) {
-           /* Line too long -- grow buffer. */
-           size = i * 2;
-            REMbuffer = xrealloc(REMbuffer, size);
-           REMbuffend = &REMbuffer[size];
-       }
-    }
-
-    /* Dot escape, text of the line, line terminator. */
-    if (escdot && (*p == '.'))
-       *REMbuffptr++ = '.';
-    memcpy(REMbuffptr, p, i);
-    REMbuffptr += i;
-    *REMbuffptr++ = '\r';
-    *REMbuffptr++ = '\n';
-
-    return true;
-}
-
-
-/*
-**  Print transfer statistics, clean up, and exit.
-*/
-static void
-ExitWithStats(int x)
-{
-    static char                QUIT[] = "quit";
-    double             usertime;
-    double             systime;
-
-    if (!Purging) {
-       REMwrite(QUIT, strlen(QUIT), false);
-       REMflush();
-    }
-    STATend = TMRnow_double();
-    if (GetResourceUsage(&usertime, &systime) < 0) {
-       usertime = 0;
-       systime = 0;
-    }
-
-    if (STATprint) {
-       printf(STAT1, REMhost, STAToffered, STATaccepted, STATrefused,
-               STATrejected, STATmissing, STATacceptedsize, STATrejectedsize);
-       printf("\n");
-       printf(STAT2, REMhost, usertime, systime, STATend - STATbegin);
-       printf("\n");
-    }
-
-    syslog(L_NOTICE, STAT1, REMhost, STAToffered, STATaccepted, STATrefused,
-               STATrejected, STATmissing, STATacceptedsize, STATrejectedsize);
-    syslog(L_NOTICE, STAT2, REMhost, usertime, systime, STATend - STATbegin);
-    if (retries)
-       syslog(L_NOTICE, "%s %lu Streaming retries", REMhost, retries);
-
-    if (BATCHfp != NULL && unlink(BATCHtemp) < 0 && errno != ENOENT)
-        syswarn("cannot remove %s", BATCHtemp);
-    sleep(1);
-    SMshutdown();
-    HISclose(History);
-    exit(x);
-    /* NOTREACHED */
-}
-
-
-/*
-**  Close the batchfile and the temporary file, and rename the temporary
-**  to be the batchfile.
-*/
-static void
-CloseAndRename(void)
-{
-    /* Close the files, rename the temporary. */
-    if (BATCHqp) {
-       QIOclose(BATCHqp);
-       BATCHqp = NULL;
-    }
-    if (ferror(BATCHfp)
-     || fflush(BATCHfp) == EOF
-     || fclose(BATCHfp) == EOF) {
-       unlink(BATCHtemp);
-        syswarn("cannot close %s", BATCHtemp);
-       ExitWithStats(1);
-    }
-    if (rename(BATCHtemp, BATCHname) < 0) {
-        syswarn("cannot rename %s", BATCHtemp);
-       ExitWithStats(1);
-    }
-}
-
-
-/*
-**  Requeue an article, opening the temp file if we have to.  If we get
-**  a file write error, exit so that the original input is left alone.
-*/
-static void
-Requeue(const char *Article, const char *MessageID)
-{
-    int fd;
-
-    /* Temp file already open? */
-    if (BATCHfp == NULL) {
-        fd = mkstemp(BATCHtemp);
-        if (fd < 0) {
-            syswarn("cannot create a temporary file");
-            ExitWithStats(1);
-        }
-        BATCHfp = fdopen(fd, "w");
-        if (BATCHfp == NULL) {
-            syswarn("cannot open %s", BATCHtemp);
-            ExitWithStats(1);
-        }
-    }
-
-    /* Called only to get the file open? */
-    if (Article == NULL)
-       return;
-
-    if (MessageID != NULL)
-       fprintf(BATCHfp, "%s %s\n", Article, MessageID);
-    else
-       fprintf(BATCHfp, "%s\n", Article);
-    if (fflush(BATCHfp) == EOF || ferror(BATCHfp)) {
-        syswarn("cannot requeue %s", Article);
-       ExitWithStats(1);
-    }
-}
-
-
-/*
-**  Requeue an article then copy the rest of the batch file out.
-*/
-static void
-RequeueRestAndExit(char *Article, char *MessageID) {
-    char       *p;
-
-    if (!AlwaysRewrite
-     && STATaccepted == 0 && STATrejected == 0 && STATrefused == 0
-     && STATmissing == 0) {
-        warn("nothing sent -- leaving batchfile alone");
-       ExitWithStats(1);
-    }
-
-    warn("rewriting batch file and exiting");
-    if (CanStream) {   /* streaming mode has a buffer of articles */
-       int i;
-
-       for (i = 0; i < STNBUF; i++) {    /* requeue unacknowledged articles */
-           if ((stbuf[i].st_fname) && (stbuf[i].st_fname[0] != '\0')) {
-               if (Debug)
-                   fprintf(stderr, "stbuf[%d]= %s, %s\n",
-                           i, stbuf[i].st_fname, stbuf[i].st_id);
-               Requeue(stbuf[i].st_fname, stbuf[i].st_id);
-               if (Article == stbuf[i].st_fname) Article = NULL;
-               strel(i); /* release entry */
-           }
-       }
-    }
-    Requeue(Article, MessageID);
-
-    for ( ; BATCHqp; ) {
-       if ((p = QIOread(BATCHqp)) == NULL) {
-           if (QIOtoolong(BATCHqp)) {
-                warn("skipping long line in %s", BATCHname);
-               QIOread(BATCHqp);
-               continue;
-           }
-           if (QIOerror(BATCHqp)) {
-                syswarn("cannot read %s", BATCHname);
-               ExitWithStats(1);
-           }
-
-           /* Normal EOF. */
-           break;
-       }
-
-       if (fprintf(BATCHfp, "%s\n", p) == EOF
-        || ferror(BATCHfp)) {
-            syswarn("cannot requeue %s", p);
-           ExitWithStats(1);
-       }
-    }
-
-    CloseAndRename();
-    ExitWithStats(1);
-}
-
-
-/*
-**  Clean up the NNTP escapes from a line.
-*/
-static char *
-REMclean(char *buff) {
-    char       *p;
-
-    if ((p = strchr(buff, '\r')) != NULL)
-       *p = '\0';
-    if ((p = strchr(buff, '\n')) != NULL)
-       *p = '\0';
-
-    /* The dot-escape is only in text, not command responses. */
-    return buff;
-}
-
-
-/*
-**  Read a line of input, with timeout.  Also handle \r\n-->\n mapping
-**  and the dot escape.  Return true if okay, *or we got interrupted.*
-*/
-static bool
-REMread(char *start, int size) {
-    static int         count;
-    static char                buffer[BUFSIZ];
-    static char                *bp;
-    char               *p;
-    char               *q;
-    char               *end;
-    struct timeval     t;
-    fd_set             rmask;
-    int                        i;
-    char               c;
-
-    if (!REMflush())
-       return false;
-
-    for (p = start, end = &start[size - 1]; ; ) {
-       if (count == 0) {
-           /* Fill the buffer. */
-    Again:
-           FD_ZERO(&rmask);
-           FD_SET(FromServer, &rmask);
-           t.tv_sec = 10 * 60;
-           t.tv_usec = 0;
-           i = select(FromServer + 1, &rmask, NULL, NULL, &t);
-           if (GotInterrupt)
-               return true;
-           if (i < 0) {
-               if (errno == EINTR)
-                   goto Again;
-               return false;
-           }
-           if (i == 0 || !FD_ISSET(FromServer, &rmask))
-               return false;
-           count = read(FromServer, buffer, sizeof buffer);
-           if (GotInterrupt)
-               return true;
-           if (count <= 0)
-               return false;
-           bp = buffer;
-       }
-
-       /* Process next character. */
-       count--;
-       c = *bp++;
-       if (c == '\n')
-           break;
-       if (p < end)
-           *p++ = c;
-    }
-
-    /* We know we got \n; if previous char was \r, turn it into \n. */
-    if (p > start && p < end && p[-1] == '\r')
-       p[-1] = '\n';
-    *p = '\0';
-
-    /* Handle the dot escape. */
-    if (*p == '.') {
-       if (p[1] == '\n' && p[2] == '\0')
-           /* EOF. */
-           return false;
-       for (q = &start[1]; (*p++ = *q++) != '\0'; )
-           continue;
-    }
-    return true;
-}
-
-
-/*
-**  Handle the interrupt.
-*/
-static void
-Interrupted(char *Article, char *MessageID) {
-    warn("interrupted");
-    RequeueRestAndExit(Article, MessageID);
-}
-
-
-/*
-**  Returns the length of the headers.
-*/
-static int
-HeadersLen(ARTHANDLE *art, int *iscmsg) {
-    const char *p;
-    char       lastchar = -1;
-
-    /* from nnrpd/article.c ARTsendmmap() */
-    for (p = art->data; p < (art->data + art->len); p++) {
-       if (*p == '\r')
-           continue;
-       if (*p == '\n') {
-           if (lastchar == '\n') {
-               if (*(p-1) == '\r')
-                   p--;
-               break;
-           }
-           if (*(p + 1) == 'C' && strncasecmp(p + 1, "Control: ", 9) == 0)
-               *iscmsg = 1;
-       }
-       lastchar = *p;
-    }
-    return (p - art->data);
-}
-
-
-/*
-**  Send a whole article to the server.
-*/
-static bool
-REMsendarticle(char *Article, char *MessageID, ARTHANDLE *art) {
-    char       buff[NNTP_STRLEN];
-
-    if (!REMflush())
-       return false;
-    if (HeadersFeed) {
-       struct iovec vec[3];
-       char buf[20];
-       int iscmsg = 0;
-       int len = HeadersLen(art, &iscmsg);
-
-       vec[0].iov_base = (char *) art->data;
-       vec[0].iov_len = len;
-       /* Add 14 bytes, which maybe will be the length of the Bytes header */
-       snprintf(buf, sizeof(buf), "Bytes: %lu\r\n",
-                 (unsigned long) art->len + 14);
-       vec[1].iov_base = buf;
-       vec[1].iov_len = strlen(buf);
-       if (iscmsg) {
-           vec[2].iov_base = (char *) art->data + len;
-           vec[2].iov_len = art->len - len;
-       } else {
-           vec[2].iov_base = (char *) "\r\n.\r\n";
-           vec[2].iov_len = 5;
-       }
-       if (xwritev(ToServer, vec, 3) < 0)
-           return false;
-    } else
-       if (xwrite(ToServer, art->data, art->len) < 0)
-           return false;
-    if (GotInterrupt)
-       Interrupted(Article, MessageID);
-    if (Debug) {
-       fprintf(stderr, "> [ article %lu ]\n", (unsigned long) art->len);
-       fprintf(stderr, "> .\n");
-    }
-
-    if (CanStream) return true;        /* streaming mode does not wait for ACK */
-
-    /* What did the remote site say? */
-    if (!REMread(buff, (int)sizeof buff)) {
-        syswarn("no reply after sending %s", Article);
-       return false;
-    }
-    if (GotInterrupt)
-       Interrupted(Article, MessageID);
-    if (Debug)
-       fprintf(stderr, "< %s", buff);
-
-    /* Parse the reply. */
-    switch (atoi(buff)) {
-    default:
-        warn("unknown reply after %s -- %s", Article, buff);
-       if (DoRequeue)
-           Requeue(Article, MessageID);
-       break;
-    case NNTP_BAD_COMMAND_VAL:
-    case NNTP_SYNTAX_VAL:
-    case NNTP_ACCESS_VAL:
-       /* The receiving server is likely confused...no point in continuing */
-        syslog(L_FATAL, GOT_BADCOMMAND, REMhost, MessageID, REMclean(buff));
-        RequeueRestAndExit(Article, MessageID);
-        /* NOTREACHED */
-    case NNTP_RESENDIT_VAL:
-    case NNTP_GOODBYE_VAL:
-       Requeue(Article, MessageID);
-       break;
-    case NNTP_TOOKIT_VAL:
-       STATaccepted++;
-       STATacceptedsize += (double)art->len;
-       break;
-    case NNTP_REJECTIT_VAL:
-        if (logRejects)
-            syslog(L_NOTICE, REJECTED, REMhost,
-                   MessageID, Article, REMclean(buff));
-       STATrejected++;
-       STATrejectedsize += (double)art->len;
-       break;
-    }
-
-    /* Article sent, or we requeued it. */
-    return true;
-}
-\f
-
-/*
-**  Get the Message-ID header from an open article.
-*/
-static char *
-GetMessageID(ARTHANDLE *art) {
-    static char        *buff;
-    static int buffsize = 0;
-    const char *p, *q;
-
-    p = wire_findheader(art->data, art->len, "Message-ID");
-    if (p == NULL)
-       return NULL;
-    for (q = p; q < art->data + art->len; q++) {
-        if (*q == '\r' || *q == '\n')
-            break;
-    }
-    if (q == art->data + art->len)
-       return NULL;
-    if (buffsize < q - p) {
-       if (buffsize == 0)
-           buff = xmalloc(q - p + 1);
-       else
-            buff = xrealloc(buff, q - p + 1);
-       buffsize = q - p;
-    }
-    memcpy(buff, p, q - p);
-    buff[q - p] = '\0';
-    return buff;
-}
-\f
-
-/*
-**  Mark that we got interrupted.
-*/
-static RETSIGTYPE
-CATCHinterrupt(int s) {
-    GotInterrupt = true;
-
-    /* Let two interrupts kill us. */
-    xsignal(s, SIG_DFL);
-}
-
-
-/*
-**  Mark that the alarm went off.
-*/
-static RETSIGTYPE
-CATCHalarm(int s UNUSED)
-{
-    GotAlarm = true;
-    if (JMPyes)
-       longjmp(JMPwhere, 1);
-}
-
-/* check articles in streaming NNTP mode
-** return true on failure.
-*/
-static bool
-check(int i) {
-    char       buff[NNTP_STRLEN];
-
-    /* send "check <ID>" to the other system */
-    snprintf(buff, sizeof(buff), "check %s", stbuf[i].st_id);
-    if (!REMwrite(buff, (int)strlen(buff), false)) {
-        syswarn("cannot check article");
-       return true;
-    }
-    STAToffered++;
-    if (Debug) {
-       if (stbuf[i].st_retry)
-           fprintf(stderr, "> %s (retry %d)\n", buff, stbuf[i].st_retry);
-       else
-           fprintf(stderr, "> %s\n", buff);
-    }
-    if (GotInterrupt)
-       Interrupted(stbuf[i].st_fname, stbuf[i].st_id);
-
-    /* That all.  Response is checked later by strlisten() */
-    return false;
-}
-
-/* Send article in "takethis <id> streaming NNTP mode.
-** return true on failure.
-*/
-static bool
-takethis(int i) {
-    char       buff[NNTP_STRLEN];
-
-    if (!stbuf[i].art) {
-        warn("internal error: null article for %s in takethis",
-             stbuf[i].st_fname);
-        return true;
-    }
-    /* send "takethis <ID>" to the other system */
-    snprintf(buff, sizeof(buff), "takethis %s", stbuf[i].st_id);
-    if (!REMwrite(buff, (int)strlen(buff), false)) {
-        syswarn("cannot send takethis");
-        return true;
-    }
-    if (Debug)
-        fprintf(stderr, "> %s\n", buff);
-    if (GotInterrupt)
-        Interrupted((char *)0, (char *)0);
-    if (!REMsendarticle(stbuf[i].st_fname, stbuf[i].st_id, stbuf[i].art))
-        return true;
-    stbuf[i].st_size = stbuf[i].art->len;
-    article_free(stbuf[i].art); /* should not need file again */
-    stbuf[i].art = 0;          /* so close to free descriptor */
-    stbuf[i].st_age = 0;
-    /* That all.  Response is checked later by strlisten() */
-    return false;
-}
-
-
-/* listen for responses.  Process acknowledgments to remove items from
-** the queue.  Also sends the articles on request.  Returns true on error.
-** return true on failure.
-*/
-static bool
-strlisten(void)
-{
-    int                resp;
-    int                i;
-    char       *id, *p;
-    char       buff[NNTP_STRLEN];
-    int                hash;
-
-    while(true) {
-       if (!REMread(buff, (int)sizeof buff)) {
-            syswarn("no reply to check");
-           return true;
-       }
-       if (GotInterrupt)
-           Interrupted((char *)0, (char *)0);
-       if (Debug)
-           fprintf(stderr, "< %s", buff);
-
-       /* Parse the reply. */
-       resp =  atoi(buff);
-       /* Skip the 1XX informational messages */
-       if ((resp >= 100) && (resp < 200)) continue;
-       switch (resp) { /* first time is to verify it */
-       case NNTP_ERR_GOTID_VAL:
-       case NNTP_OK_SENDID_VAL:
-       case NNTP_OK_RECID_VAL:
-       case NNTP_ERR_FAILID_VAL:
-       case NNTP_RESENDID_VAL:
-           if ((id = strchr(buff, '<')) != NULL) {
-               p = strchr(id, '>');
-               if (p) *(p+1) = '\0';
-               hash = stidhash(id);
-               i = stindex(id, hash);  /* find table entry */
-               if (i < 0) { /* should not happen */
-                   syslog(L_NOTICE, CANT_FINDIT, REMhost, REMclean(buff));
-                   return (true); /* can't find it! */
-               }
-           } else {
-               syslog(L_NOTICE, CANT_PARSEIT, REMhost, REMclean(buff));
-               return (true);
-           }
-           break;
-       case NNTP_GOODBYE_VAL:
-           /* Most likely out of space -- no point in continuing. */
-           syslog(L_NOTICE, IHAVE_FAIL, REMhost, REMclean(buff));
-           return true;
-           /* NOTREACHED */
-       default:
-           syslog(L_NOTICE, UNEXPECTED, REMhost, REMclean(buff));
-           if (Debug)
-               fprintf(stderr, "Unknown reply \"%s\"",
-                                                   buff);
-           return (true);
-       }
-       switch (resp) { /* now we take some action */
-       case NNTP_RESENDID_VAL: /* remote wants it later */
-           /* try again now because time has passed */
-           if (stbuf[i].st_retry < STNRETRY) {
-               if (check(i)) return true;
-               stbuf[i].st_retry++;
-               stbuf[i].st_age = 0;
-           } else { /* requeue to disk for later */
-               Requeue(stbuf[i].st_fname, stbuf[i].st_id);
-               strel(i); /* release entry */
-           }
-           break;
-       case NNTP_ERR_GOTID_VAL:        /* remote doesn't want it */
-           strel(i); /* release entry */
-           STATrefused++;
-           stnofail = 0;
-           break;
-               
-       case NNTP_OK_SENDID_VAL:        /* remote wants article */
-           if (takethis(i)) return true;
-           stnofail++;
-           break;
-
-       case NNTP_OK_RECID_VAL: /* remote received it OK */
-           STATacceptedsize += (double) stbuf[i].st_size;
-           strel(i); /* release entry */
-           STATaccepted++;
-           break;
-               
-       case NNTP_ERR_FAILID_VAL:
-           STATrejectedsize += (double) stbuf[i].st_size;
-           if (logRejects)
-               syslog(L_NOTICE, REJ_STREAM, REMhost,
-                   stbuf[i].st_fname, REMclean(buff));
-/* XXXXX Caution THERE BE DRAGONS, I don't think this logs properly
-   The message ID is returned in the peer response... so this is redundant
-                   stbuf[i].st_id, stbuf[i].st_fname, REMclean(buff)); */
-           strel(i); /* release entry */
-           STATrejected++;
-           stnofail = 0;
-           break;
-       }
-       break;
-    }
-    return (false);
-}
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    die("Usage: innxmit [-acdHlprs] [-t#] [-T#] host file");
-}
-
-
-/*
-**  Open an article.  If the argument is a token, retrieve the article via
-**  the storage API.  Otherwise, open the file and fake up an ARTHANDLE for
-**  it.  Only fill in those fields that we'll need.  Articles not retrieved
-**  via the storage API will have a type of TOKEN_EMPTY.
-*/
-static ARTHANDLE *
-article_open(const char *path, const char *id)
-{
-    TOKEN token;
-    ARTHANDLE *article;
-    int fd, length;
-    struct stat st;
-    char *p;
-
-    if (IsToken(path)) {
-        token = TextToToken(path);
-        article = SMretrieve(token, RETR_ALL);
-        if (article == NULL) {
-            if (SMerrno == SMERR_NOENT || SMerrno == SMERR_UNINIT)
-                STATmissing++;
-            else {
-                warn("requeue %s: %s", path, SMerrorstr);
-                Requeue(path, id);
-            }
-        }
-        return article;
-    } else {
-        char *data;
-        fd = open(path, O_RDONLY);
-        if (fd < 0)
-            return NULL;
-        if (fstat(fd, &st) < 0) {
-            syswarn("requeue %s", path);
-            Requeue(path, id);
-            return NULL;
-        }
-        article = xmalloc(sizeof(ARTHANDLE));
-        article->type = TOKEN_EMPTY;
-        article->len = st.st_size;
-        data = xmalloc(article->len);
-        if (xread(fd, data, article->len) < 0) {
-            syswarn("requeue %s", path);
-            free(data);
-            free(article);
-            close(fd);
-            Requeue(path, id);
-            return NULL;
-        }
-        close(fd);
-        p = memchr(data, '\n', article->len);
-        if (p == NULL || p == data) {
-            warn("requeue %s: cannot find headers", path);
-            free(data);
-            free(article);
-            Requeue(path, id);
-            return NULL;
-        }
-        if (p[-1] != '\r') {
-            p = ToWireFmt(data, article->len, (size_t *)&length);
-            free(data);
-            data = p;
-            article->len = length;
-        }
-        article->data = data;
-        return article;
-    }
-}
-
-
-/*
-**  Free an article, using the type field to determine whether to free it
-**  via the storage API.
-*/
-static void
-article_free(ARTHANDLE *article)
-{
-    if (article->type == TOKEN_EMPTY) {
-        free((char *)article->data);
-        free(article);
-    } else
-        SMfreearticle(article);
-}
-
-
-int main(int ac, char *av[]) {
-    static char                SKIPPING[] = "Skipping \"%s\" --%s?\n";
-    int                        i;
-    char               *p;
-    ARTHANDLE          *art;
-    FILE               *From;
-    FILE               *To;
-    char               buff[8192+128];
-    char               *Article;
-    char               *MessageID;
-    RETSIGTYPE         (*old)(int) = NULL;
-    unsigned int       ConnectTimeout;
-    unsigned int       TotalTimeout;
-    int                 port = NNTP_PORT;
-    bool               val;
-    char                *path;
-
-    openlog("innxmit", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "innxmit";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-
-    ConnectTimeout = 0;
-    TotalTimeout = 0;
-    
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "lacdHprst:T:vP:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'P':
-           port = atoi(optarg);
-           break;
-       case 'a':
-           AlwaysRewrite = true;
-           break;
-       case 'c':
-           DoCheck = false;
-           break;
-       case 'd':
-           Debug = true;
-           break;
-       case 'H':
-           HeadersFeed = true;
-           break;
-        case 'l':
-            logRejects = true ;
-            break ;
-       case 'p':
-           AlwaysRewrite = true;
-           Purging = true;
-           break;
-       case 'r':
-           DoRequeue = false;
-           break;
-       case 's':
-           TryStream = false;
-           break;
-       case 't':
-           ConnectTimeout = atoi(optarg);
-           break;
-       case 'T':
-           TotalTimeout = atoi(optarg);
-           break;
-       case 'v':
-           STATprint = true;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    /* Parse arguments; host and filename. */
-    if (ac != 2)
-       Usage();
-    REMhost = av[0];
-    BATCHname = av[1];
-
-    if (chdir(innconf->patharticles) < 0)
-        sysdie("cannot cd to %s", innconf->patharticles);
-
-    val = true;
-    if (!SMsetup(SM_PREOPEN,(void *)&val))
-        die("cannot set up the storage manager");
-    if (!SMinit())
-        die("cannot initialize the storage manager: %s", SMerrorstr);
-
-    /* Open the batch file and lock others out. */
-    if (BATCHname[0] != '/') {
-        BATCHname = concatpath(innconf->pathoutgoing, av[1]);
-    }
-    if (((i = open(BATCHname, O_RDWR)) < 0) || ((BATCHqp = QIOfdopen(i)) == NULL)) {
-        syswarn("cannot open %s", BATCHname);
-       SMshutdown();
-       exit(1);
-    }
-    if (!inn_lock_file(QIOfileno(BATCHqp), INN_LOCK_WRITE, true)) {
-#if    defined(EWOULDBLOCK)
-       if (errno == EWOULDBLOCK) {
-           SMshutdown();
-           exit(0);
-       }
-#endif /* defined(EWOULDBLOCK) */
-        syswarn("cannot lock %s", BATCHname);
-       SMshutdown();
-       exit(1);
-    }
-
-    /* Get a temporary name in the same directory as the batch file. */
-    p = strrchr(BATCHname, '/');
-    *p = '\0';
-    BATCHtemp = concatpath(BATCHname, "bchXXXXXX");
-    *p = '/';
-
-    /* Set up buffer used by REMwrite. */
-    REMbuffer = xmalloc(OUTPUT_BUFFER_SIZE);
-    REMbuffend = &REMbuffer[OUTPUT_BUFFER_SIZE];
-    REMbuffptr = REMbuffer;
-
-    /* Start timing. */
-    STATbegin = TMRnow_double();
-
-    if (!Purging) {
-       /* Open a connection to the remote server. */
-       if (ConnectTimeout) {
-           GotAlarm = false;
-           old = xsignal(SIGALRM, CATCHalarm);
-            if (setjmp(JMPwhere)) {
-                warn("cannot connect to %s: timed out", REMhost);
-                SMshutdown();
-                exit(1);
-            }
-           JMPyes = true;
-           alarm(ConnectTimeout);
-       }
-       if (NNTPconnect(REMhost, port, &From, &To, buff) < 0 || GotAlarm) {
-           i = errno;
-            warn("cannot connect to %s: %s", REMhost,
-                 buff[0] ? REMclean(buff) : strerror(errno));
-           if (GotAlarm)
-               syslog(L_NOTICE, CANT_CONNECT, REMhost, "timeout");
-           else 
-               syslog(L_NOTICE, CANT_CONNECT, REMhost,
-                   buff[0] ? REMclean(buff) : strerror(i));
-           SMshutdown();
-           exit(1);
-       }
-       if (Debug)
-           fprintf(stderr, "< %s\n", REMclean(buff));
-       if (NNTPsendpassword(REMhost, From, To) < 0 || GotAlarm) {
-           i = errno;
-            syswarn("cannot authenticate with %s", REMhost);
-           syslog(L_ERROR, CANT_AUTHENTICATE,
-               REMhost, GotAlarm ? "timeout" : strerror(i));
-           /* Don't send quit; we want the remote to print a message. */
-           SMshutdown();
-           exit(1);
-       }
-       if (ConnectTimeout) {
-           alarm(0);
-           xsignal(SIGALRM, old);
-           JMPyes = false;
-       }
-
-       /* We no longer need standard I/O. */
-       FromServer = fileno(From);
-       ToServer = fileno(To);
-
-       if (TryStream) {
-           if (!REMwrite(modestream, (int)strlen(modestream), false)) {
-                syswarn("cannot negotiate %s", modestream);
-           }
-           if (Debug)
-               fprintf(stderr, ">%s\n", modestream);
-           /* Does he understand mode stream? */
-           if (!REMread(buff, (int)sizeof buff)) {
-                syswarn("no reply to %s", modestream);
-           } else {
-               if (Debug)
-                   fprintf(stderr, "< %s", buff);
-
-               /* Parse the reply. */
-               switch (atoi(buff)) {
-               default:
-                    warn("unknown reply to %s -- %s", modestream, buff);
-                   CanStream = false;
-                   break;
-               case NNTP_OK_STREAM_VAL:        /* YES! */
-                   CanStream = true;
-                   break;
-                case NNTP_AUTH_NEEDED_VAL: /* authentication refusal */
-               case NNTP_BAD_COMMAND_VAL: /* normal refusal */
-                   CanStream = false;
-                   break;
-               }
-           }
-           if (CanStream) {
-               for (i = 0; i < STNBUF; i++) { /* reset buffers */
-                   stbuf[i].st_fname = 0;
-                   stbuf[i].st_id = 0;
-                   stbuf[i].art = 0;
-               }
-               stnq = 0;
-           }
-       }
-       if (HeadersFeed) {
-           if (!REMwrite(modeheadfeed, strlen(modeheadfeed), false))
-                syswarn("cannot negotiate %s", modeheadfeed);
-           if (Debug)
-               fprintf(stderr, ">%s\n", modeheadfeed);
-           if (!REMread(buff, sizeof buff)) {
-                syswarn("no reply to %s", modeheadfeed);
-           } else {
-               if (Debug)
-                   fprintf(stderr, "< %s", buff);
-
-               /* Parse the reply. */
-               switch (atoi(buff)) {
-               case 250:               /* YES! */
-                   break;
-               case NNTP_BAD_COMMAND_VAL: /* normal refusal */
-                    die("%s not allowed -- %s", modeheadfeed, buff);
-               default:
-                    die("unknown reply to %s -- %s", modeheadfeed, buff);
-               }
-           }
-       }
-    }
-
-    /* Set up signal handlers. */
-    xsignal(SIGHUP, CATCHinterrupt);
-    xsignal(SIGINT, CATCHinterrupt);
-    xsignal(SIGTERM, CATCHinterrupt);
-    xsignal(SIGPIPE, SIG_IGN);
-    if (TotalTimeout) {
-       xsignal(SIGALRM, CATCHalarm);
-       alarm(TotalTimeout);
-    }
-
-    path = concatpath(innconf->pathdb, _PATH_HISTORY);
-    History = HISopen(path, innconf->hismethod, HIS_RDONLY);
-    free(path);
-
-    /* Main processing loop. */
-    GotInterrupt = false;
-    GotAlarm = false;
-    for (Article = NULL, MessageID = NULL; ; ) {
-       if (GotAlarm) {
-            warn("timed out");
-           /* Don't resend the current article. */
-           RequeueRestAndExit((char *)NULL, (char *)NULL);
-       }
-       if (GotInterrupt)
-           Interrupted(Article, MessageID);
-
-       if ((Article = QIOread(BATCHqp)) == NULL) {
-           if (QIOtoolong(BATCHqp)) {
-                warn("skipping long line in %s", BATCHname);
-               QIOread(BATCHqp);
-               continue;
-           }
-           if (QIOerror(BATCHqp)) {
-                syswarn("cannot read %s", BATCHname);
-               ExitWithStats(1);
-           }
-
-           /* Normal EOF -- we're done. */
-           QIOclose(BATCHqp);
-           BATCHqp = NULL;
-           break;
-       }
-
-       /* Ignore blank lines. */
-       if (*Article == '\0')
-           continue;
-
-       /* Split the line into possibly two fields. */
-       if (Article[0] == '/'
-        && Article[strlen(innconf->patharticles)] == '/'
-        && strncmp(Article, innconf->patharticles, strlen(innconf->patharticles)) == 0)
-           Article += strlen(innconf->patharticles) + 1;
-       if ((MessageID = strchr(Article, ' ')) != NULL) {
-           *MessageID++ = '\0';
-           if (*MessageID != '<'
-               || (p = strrchr(MessageID, '>')) == NULL
-               || *++p != '\0') {
-                warn("ignoring line %s %s...", Article, MessageID);
-               continue;
-           }
-       }
-
-       if (*Article == '\0') {
-           if (MessageID)
-                warn("empty file name for %s in %s", MessageID, BATCHname);
-           else
-                warn("empty file name, no message ID in %s", BATCHname);
-           /* We could do a history lookup. */
-           continue;
-       }
-
-       if (Purging && MessageID != NULL && !Expired(MessageID)) {
-           Requeue(Article, MessageID);
-           continue;
-       }
-
-        /* Drop articles with a message ID longer than NNTP_MSGID_MAXLEN to
-           avoid overrunning buffers and throwing the server on the
-           receiving end a blow from behind. */
-        if (MessageID != NULL && strlen(MessageID) > NNTP_MSGID_MAXLEN) {
-            warn("dropping article in %s: long message ID %s", BATCHname,
-                 MessageID);
-            continue;
-        }
-
-        art = article_open(Article, MessageID);
-        if (art == NULL)
-           continue;
-
-       if (Purging) {
-            article_free(art);
-           Requeue(Article, MessageID);
-           continue;
-       }
-
-       /* Get the Message-ID from the article if we need to. */
-       if (MessageID == NULL) {
-           if ((MessageID = GetMessageID(art)) == NULL) {
-                warn(SKIPPING, Article, "no message ID");
-                article_free(art);
-               continue;
-           }
-       }
-       if (GotInterrupt)
-           Interrupted(Article, MessageID);
-
-       /* Offer the article. */
-       if (CanStream) {
-           int lim;
-           int hash;
-
-           hash = stidhash(MessageID);
-           if (stindex(MessageID, hash) >= 0) { /* skip duplicates in queue */
-               if (Debug)
-                   fprintf(stderr, "Skipping duplicate ID %s\n",
-                                                           MessageID);
-                article_free(art);
-               continue;
-           }
-           /* This code tries to optimize by sending a burst of "check"
-            * commands before flushing the buffer.  This should result
-            * in several being sent in one packet reducing the network
-            * overhead.
-            */
-           if (DoCheck && (stnofail < STNC)) lim = STNBUF;
-           else                              lim = STNBUFL;
-           if (stnq >= lim) { /* need to empty a buffer */
-               while (stnq >= STNBUFL) { /* or several */
-                   if (strlisten()) {
-                       RequeueRestAndExit(Article, MessageID);
-                   }
-               }
-           }
-           /* save new article in the buffer */
-           i = stalloc(Article, MessageID, art, hash);
-           if (i < 0) {
-                article_free(art);
-               RequeueRestAndExit(Article, MessageID);
-           }
-           if (DoCheck && (stnofail < STNC)) {
-               if (check(i)) {
-                   RequeueRestAndExit((char *)NULL, (char *)NULL);
-               }
-           } else {
-                STAToffered++ ;
-               if (takethis(i)) {
-                   RequeueRestAndExit((char *)NULL, (char *)NULL);
-               }
-           }
-           /* check for need to resend any IDs */
-           for (i = 0; i < STNBUF; i++) {
-               if ((stbuf[i].st_fname) && (stbuf[i].st_fname[0] != '\0')) {
-                   if (stbuf[i].st_age++ > stnq) {
-                       /* This should not happen but just in case ... */
-                       if (stbuf[i].st_retry < STNRETRY) {
-                           if (check(i)) /* resend check */
-                               RequeueRestAndExit((char *)NULL, (char *)NULL);
-                           retries++;
-                           stbuf[i].st_retry++;
-                           stbuf[i].st_age = 0;
-                       } else { /* requeue to disk for later */
-                           Requeue(stbuf[i].st_fname, stbuf[i].st_id);
-                           strel(i); /* release entry */
-                       }
-                   }
-               }
-           }
-           continue; /* next article */
-       }
-       snprintf(buff, sizeof(buff), "ihave %s", MessageID);
-       if (!REMwrite(buff, (int)strlen(buff), false)) {
-            syswarn("cannot offer article");
-            article_free(art);
-           RequeueRestAndExit(Article, MessageID);
-       }
-       STAToffered++;
-       if (Debug)
-           fprintf(stderr, "> %s\n", buff);
-       if (GotInterrupt)
-           Interrupted(Article, MessageID);
-
-       /* Does he want it? */
-       if (!REMread(buff, (int)sizeof buff)) {
-            syswarn("no reply to ihave");
-            article_free(art);
-           RequeueRestAndExit(Article, MessageID);
-       }
-       if (GotInterrupt)
-           Interrupted(Article, MessageID);
-       if (Debug)
-           fprintf(stderr, "< %s", buff);
-
-       /* Parse the reply. */
-       switch (atoi(buff)) {
-       default:
-            warn("unknown reply to %s -- %s", Article, buff);
-           if (DoRequeue)
-               Requeue(Article, MessageID);
-           break;
-        case NNTP_BAD_COMMAND_VAL:
-        case NNTP_SYNTAX_VAL:
-        case NNTP_ACCESS_VAL:
-            /* The receiving server is likely confused...no point in continuing */
-            syslog(L_FATAL, GOT_BADCOMMAND, REMhost, MessageID, REMclean(buff));
-           RequeueRestAndExit(Article, MessageID);
-           /* NOTREACHED */
-        case NNTP_AUTH_NEEDED_VAL:
-       case NNTP_RESENDIT_VAL:
-       case NNTP_GOODBYE_VAL:
-           /* Most likely out of space -- no point in continuing. */
-           syslog(L_NOTICE, IHAVE_FAIL, REMhost, REMclean(buff));
-           RequeueRestAndExit(Article, MessageID);
-           /* NOTREACHED */
-       case NNTP_SENDIT_VAL:
-           if (!REMsendarticle(Article, MessageID, art))
-               RequeueRestAndExit(Article, MessageID);
-           break;
-       case NNTP_HAVEIT_VAL:
-           STATrefused++;
-           break;
-#if    defined(NNTP_SENDIT_LATER)
-       case NNTP_SENDIT_LATER_VAL:
-           Requeue(Article, MessageID);
-           break;
-#endif /* defined(NNTP_SENDIT_LATER) */
-       }
-
-        article_free(art);
-    }
-    if (CanStream) { /* need to wait for rest of ACKs */
-       while (stnq > 0) {
-           if (strlisten()) {
-               RequeueRestAndExit((char *)NULL, (char *)NULL);
-           }
-       }
-    }
-
-    if (BATCHfp != NULL)
-       /* We requeued something, so close the temp file. */
-       CloseAndRename();
-    else if (unlink(BATCHname) < 0 && errno != ENOENT)
-        syswarn("cannot remove %s", BATCHtemp);
-    ExitWithStats(0);
-    /* NOTREACHED */
-    return 0;
-}
diff --git a/backends/map.c b/backends/map.c
deleted file mode 100644 (file)
index 5d5bcb9..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*  $Id: map.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "libinn.h"
-#include "paths.h"
-
-#include "map.h"
-
-
-typedef struct _PAIR {
-    char       First;
-    char       *Key;
-    char       *Value;
-} PAIR;
-
-static PAIR    *MAPdata;
-static PAIR    *MAPend;
-
-
-/*
-**  Free the map.
-*/
-void
-MAPfree(void)
-{
-    PAIR       *mp;
-
-    for (mp = MAPdata; mp < MAPend; mp++) {
-       free(mp->Key);
-       free(mp->Value);
-    }
-    free(MAPdata);
-    MAPdata = NULL;
-}
-
-
-/*
-**  Read the map file.
-*/
-void
-MAPread(const char *name)
-{
-    FILE       *F;
-    int        i;
-    PAIR       *mp;
-    char       *p;
-    char               buff[BUFSIZ];
-
-    if (MAPdata != NULL)
-       MAPfree();
-
-    /* Open file, count lines. */
-    if ((F = fopen(name, "r")) == NULL) {
-       fprintf(stderr, "Can't open %s, %s\n", name, strerror(errno));
-       exit(1);
-    }
-    for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
-       continue;
-    mp = MAPdata = xmalloc((i + 1) * sizeof(PAIR));
-
-    /* Read each line; ignore blank and comment lines. */
-    fseeko(F, 0, SEEK_SET);
-    while (fgets(buff, sizeof buff, F) != NULL) {
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '\0'
-         || buff[0] == '#'
-        || (p = strchr(buff, ':')) == NULL)
-           continue;
-       *p++ = '\0';
-       mp->First = buff[0];
-       mp->Key = xstrdup(buff);
-       mp->Value = xstrdup(p);
-       mp++;
-    }
-    fclose(F);
-    MAPend = mp;
-}
-
-
-/*
-**  Look up a name in the map, return original value if not found.
-*/
-char *
-MAPname(char *p)
-{
-    PAIR       *mp;
-    char       c;
-
-    for (c = *p, mp = MAPdata; mp < MAPend; mp++)
-       if (c == mp->First && strcmp(p, mp->Key) == 0)
-           return mp->Value;
-    return p;
-}
diff --git a/backends/map.h b/backends/map.h
deleted file mode 100644 (file)
index c6fd6e7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*  $Id: map.h 5292 2002-03-10 08:59:54Z vinocur $
-**
-*/
-
-void  MAPfree(void);                    /* free the map */
-void  MAPread(const char *name);        /* read the map file */
-char *MAPname(char *p);                 /* lookup in the map */
diff --git a/backends/mod-active.in b/backends/mod-active.in
deleted file mode 100644 (file)
index 4360e0b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# batch-active-update
-# Author: David Lawrence <tale@isc.org>
-
-# Reads a series of ctlinnd newgroup/rmgroup/changegroup commands, such as
-# is output by checkgroups and actsync, and efficiently handles them all at
-# once.  Input can come from command line files or stdin, a la awk/sed.
-
-$oldact = $inn::active;         # active file location
-$oldact = $inn::active;         # active file location (same; shut up, perl -w)
-$newact = "$oldact.new$$";      # temporary name for new active file
-$actime = "$oldact.times";      # active.times file
-$pausemsg = 'batch active update, ok'; # message to be used for pausing?
-$diff_flags = '';              # Flags for diff(1); default chosen if null.
-
-$0 =~ s#^.*/##;
-
-die "$0: must run as $inn::newsuser user"
-  unless $> == (getpwnam($inn::newsuser))[2];
-
-$debug = -t STDOUT ? 1 : 0;
-
-$| = 1;                # show output as it happens (for an rsh/ssh pipe)
-
-# Guess at best flags for a condensed diff listing.  The
-# checks for alternative operating systems is incomplete.
-unless ($diff_flags) {
-  if (`diff -v 2>&1` =~ /GNU/) {
-    $diff_flags = '-U0';
-  } elsif ($^O =~ /^(dec_osf|solaris)$/) {
-    $diff_flags = '-C0';
-  } elsif ($^O eq 'nextstep') {
-    $diff_flags = '-c0';
-  } else {
-    $diff_flags = '-c';
-  }
-}
-
-print "reading list of groups to update\n" if $debug;
-
-$eval  = "while (<OLDACT>) {\n";
-$eval .= "  \$group = (split)[0];\n";
-
-while (<>) {
-  if (/^\s*\S*ctlinnd newgroup (\S+) (\S)/) {
-    $toadd{$1} = $2;
-  } elsif (/^\s*\S*ctlinnd rmgroup (\S+)/) {
-    $eval .= "  next if \$group eq '$1';\n";
-  } elsif (/^\s*\S*ctlinnd changegroup (\S+) (\S)/) {
-    $eval .= "  s/ \\S+\$/ $2/ if \$group eq '$1';\n";
-  }
-}
-
-$eval .= "  delete \$toadd{\$group};\n";
-$eval .= "  if (!print(NEWACT \$_)) {\n";
-$eval .= "    die \"\$0: writing \$newact failed (\$!), aborting\\n\";\n";
-$eval .= "  }\n";
-$eval .= "}\n";
-
-&ctlinnd("pause $pausemsg");
-
-open(OLDACT, "< $oldact") || die "$0: open $oldact: $!\n";
-open(NEWACT, "> $newact") || die "$0: open $newact: $!\n";
-
-print "rewriting active file\n" if $debug;
-eval $eval;
-for (sort keys %toadd) {
-  $add = "$_ 0000000000 0000000001 $toadd{$_}\n";
-  if (!print( NEWACT $add)) {
-    &ctlinnd("go $pausemsg");
-    die "$0: writing $newact failed ($!), aborting\n";
-  }
-}
-
-close(OLDACT) || warn "$0: close $oldact: $!\n";
-close(NEWACT) || warn "$0: close $newact: $!\n";
-
-if (!rename("$oldact", "$oldact.old")) {
-  warn "$0: rename $oldact $oldact.old: $!\n";
-}
-
-if (!rename("$newact", "$oldact")) {
-  die "$0: rename $newact $oldact: $!\n";
-}
-
-&ctlinnd("reload active 'updated from checkgroups'");
-system("diff $diff_flags $oldact.old $oldact");
-&ctlinnd("go $pausemsg");
-
-print "updating $actime\n" if $debug;
-if (open(TIMES, ">> $actime")) {
-  $time = time;
-  for (sort keys %toadd) {
-    print TIMES "$_ $time checkgroups-update\n" || last;
-  }
-  close(TIMES) || warn "$0: close $actime: $!\n";
-} else {
-  warn "$0: $actime not updated: $!\n";
-}
-
-exit 0;
-
-sub
-ctlinnd
-
-{
-  local($command) = @_;
-
-  print "ctlinnd $command\n" if $debug;
-  if (system("$inn::newsbin/ctlinnd -s $command")) {
-    die "$0: \"$command\" failed, aborting\n";
-  }
-}
diff --git a/backends/news2mail.in b/backends/news2mail.in
deleted file mode 100644 (file)
index 5f22231..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# news to mail channel backend
-#
-# INN gives us
-#      @token@ addrs
-# for each article that needs to be mailed.  We invoke sm on the
-# localhost to get the actual article and stuff
-# it down sendmail's throat.
-# 
-# This program expect to find a file that maps listname to listaddrs,
-#      @prefix@/etc/news2mail.cf
-# which must contain address mapping pairs such as
-#
-#      big-red-ants@ucsd.edu   big-red-ants-digest@ucsd.edu            
-#
-# where the first token is the name fed to us from INN, and which is
-# also placed in the To: header of the outgoing mail.  It's probably
-# the subscriber's list submittal address so that replies go to the
-# right place.  The second token is the actual address sendmail ships
-# the article to.
-#
-# In the INN newsfeeds file, you need to have a channel feed:
-#      n2m!:!*:Tc,Ac,Wn*:@prefix@/bin/news2mail
-# and a site for each of the various mailing lists you're feeding,
-# such as
-#      big-red-ants@ucsd.edu:rec.pets.redants.*:Tm:n2m!
-#
-# Error handling is nearly nonexistent.
-#
-#      - Brian Kantor, UCSD Aug 1998
-
-require 5.006;
-
-use FileHandle;
-use Sys::Syslog;
-use strict;
-
-my $cfFile = $inn::pathetc . "/news2mail.cf" ;
-my $sendmail = $inn::mta ;
-my $sm = $inn::pathbin . "/sm" ;
-my %maddr = ();
-
-#
-# the syslog calls are here but don't work on my system
-#
-openlog('news2mail', 'pid', 'mail');
-
-syslog('info', 'begin');
-
-#
-# load the list names and their mail addresses from cf file
-# #comments and blank lines are ignored
-#
-unless (open CF, "< $cfFile") {
-               syslog('notice', 'CF open failed %m');
-               die "bad CF";
-               }
-
-while ( <CF> ) {
-       next if /^#|^\s+$/;
-       my ( $ln, $ma ) = split /\s+/;
-       $maddr{ $ln } = $ma;
-       }
-close CF;
-
-#
-# for each incoming line from the INN channel
-#
-while ( <STDIN> ) {
-       chomp;
-
-       syslog('info', $_);
-
-       my ($token, $lnames) = split /\s+/, $_, 2;
-       my @addrs = split /\s+/, $lnames;
-
-       my @good = grep {  defined $maddr{$_} } @addrs;
-       my @bad  = grep { !defined $maddr{$_} } @addrs;
-
-       if (! @good) {
-               syslog('notice', "unknown listname $_");
-               next;
-               }
-
-       if (@bad) {
-               syslog('info', 'skipping unknown lists: ', join(' ', @bad));
-               }
-       mailto($token, $lnames, @maddr{@good});
-       }
-
-syslog ("info", "end") ;
-
-exit 0;
-
-sub mailto {
-       my($t, $l, @a) = @_ ;
-
-       my $sendmail = $inn::mta ;
-       $sendmail =~ s!\s*%s!! ;
-       my @command = (split (' ', $sendmail), '-ee', '-fnews', '-odq', @a);
-#      @command[0] = '/usr/local/bin/debug';
-
-       syslog('info', join(' ', @command));
-
-       unless (open(SM, '|-', @command)) {
-               syslog('notice', join(' ', '|', @command), 'failed!');
-               die "bad $sendmail";
-               }
-
-       my $smgr = "$sm -q $t |";
-
-       unless (open(SMGR, $smgr)) {
-           syslog('notice', "$smgr failed!");
-           die "bad $smgr";
-       }
-
-       # header
-       while ( <SMGR> ) {
-               chomp;
-
-               # empty line signals end of header
-               if ( /^$/ ) {
-                       print SM "To: $l\n\n";
-                       last;   
-                       }
-
-               #
-               # skip unnecessary headers
-               #
-               next if /^NNTP-Posting-Date:/i;
-               next if /^NNTP-Posting-Host:/i;
-               next if /^X-Trace:/i;
-               next if /^Xref:/i;
-               next if /^Path:/i;
-
-               #
-               # convert Newsgroups header into X-Newsgroups
-               #
-               s/^Newsgroups:/X-Newsgroups:/i;
-
-               print SM "$_\n";
-               }
-
-       # body
-       while ( <SMGR> ) {
-               print SM $_;
-       }
-
-       close(SMGR);
-       close(SM);
-       }
diff --git a/backends/ninpaths.c b/backends/ninpaths.c
deleted file mode 100644 (file)
index 95f397d..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*  $Id: ninpaths.c 6362 2003-05-31 18:35:04Z rra $
-**
-**  New inpaths reporting program.
-**
-**  Idea, data structures and part of code based on inpaths 2.5
-**  by Brian Reid, Landon Curt Noll
-**
-**  This version written by Olaf Titz, Feb. 1997.  Public domain.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <time.h>
-
-#define VERSION "3.1.1"
-
-#define MAXFNAME 1024  /* max length of file name */
-#define MAXLINE 1024   /* max length of Path line */
-#define HASH_TBL 65536 /* hash table size (power of two) */
-#define MAXHOST 128    /* max length of host name */
-#define HOSTF "%127s"  /* scanf format for host name */
-#define RECLINE 120    /* dump file line length softlimit */
-
-/* structure used to tally the traffic between two hosts */
-struct trec {
-    struct trec *rlink;                /* next in chain */
-    struct nrec *linkid;       /* pointer to... */
-    long tally;                        /* count */
-};
-
-/* structure to hold the information about a host */
-struct nrec {
-    struct nrec *link;         /* next in chain */
-    struct trec *rlink;                /* start of trec chain */
-    char *id;                  /* host name */
-    long no;                   /* identificator for dump file */
-    long sentto;               /* tally of articles sent from here */
-};
-
-struct nrec *hosthash[HASH_TBL];
-
-time_t starttime;      /* Start time */
-double atimes=0.0;     /* Sum of articles times wrt. starttime */
-long total=0,          /* Total articles processed */
-     sites=0;          /* Total sites known */
-
-/* malloc and warn if out of mem */
-void *
-wmalloc(size_t s)
-{
-    void *p=malloc(s);
-    if (!p)
-       fprintf(stderr, "warning: out of memory\n");
-    return p;
-}
-
-/* Hash function due to Glenn Fowler / Landon Curt Noll / Phong Vo */
-int
-hash(const char *str)
-{
-    unsigned long val;
-    unsigned long c;
-
-    for (val = 0; (c=(unsigned long)(*str)); ++str) {
-       val *= 16777619;        /* magic */
-       val ^= c;               /* more magic */
-    }
-    return (int)(val & (unsigned long)(HASH_TBL-1));
-}
-
-/* Look up a host in the hash table. Add if necessary. */
-struct nrec *
-hhost(const char *n)
-{
-    struct nrec *h;
-    int i=hash(n);
-
-    for (h=hosthash[i]; h; h=h->link)
-       if (!strcmp(n, h->id))
-           return h;
-    /* not there - allocate */
-    h=wmalloc(sizeof(struct nrec));
-    if (!h)
-       return NULL;
-    h->id=strdup(n);
-    if (!h->id) {
-       free(h); return NULL;
-    }
-    h->link=hosthash[i];
-    h->rlink=NULL;
-    h->no=h->sentto=0;
-    hosthash[i]=h;
-    sites++;
-    return h;
-}
-
-/* Look up a tally record between hosts. Add if necessary. */
-struct trec *
-tallyrec(struct nrec *r, struct nrec *h)
-{
-    struct trec *t;
-    for (t=r->rlink; t; t=t->rlink)
-       if (t->linkid==h)
-           return t;
-    t=wmalloc(sizeof(struct trec));
-    if (!t)
-       return NULL;
-    t->rlink=r->rlink;
-    t->linkid=h;
-    t->tally=0;
-    r->rlink=t;
-    return t;
-}
-
-
-/* Dump file format:
-   "!!NINP" <version> <starttime> <endtime> <sites> <total> <avgtime> "\n"
-   followed by <sites> S-records,
-   "!!NLREC\n"
-   [3.0]
-       followed by max. <sites>^2 L-records
-   [3.1]
-       followed by max. <sites> L-records
-   "!!NEND" <nlrecs> "\n"
-   starttime, endtime, avgtime as UNIX date
-   the records are separated by space or \n
-   an S-record is "site count"
-   [3.0]
-       an L-record is "sitea!siteb!count"
-   [3.1]
-       an L-record is ":sitea" { "!siteb,count" }...
-       ",count" omitted if count==1
-   where sitea and siteb are numbers of the S-records starting at 0
-*/
-
-int
-writedump(FILE *f)
-{
-    int i, j;
-    long n;
-    struct nrec *h;
-    struct trec *t;
-
-    if (!total) {
-       return -1;
-    }
-    fprintf(f, "!!NINP " VERSION " %lu %lu %ld %ld %ld\n",
-            (unsigned long) starttime, (unsigned long) time(NULL), sites,
-            total, (long)(atimes/total)+starttime);
-    n=j=0;
-    /* write the S-records (hosts), numbering them in the process */
-    for (i=0; i<HASH_TBL; ++i)
-       for (h=hosthash[i]; h; h=h->link) {
-           h->no=n++;
-           j+=fprintf(f, "%s %ld", h->id, h->sentto);
-           if (j>RECLINE) {
-               j=0;
-               fprintf(f, "\n");
-           } else {
-               fprintf(f, " ");
-           }
-       }
-    if (n!=sites)
-       fprintf(stderr, "internal error: sites=%ld, dumped=%ld\n", sites, n);
-
-    fprintf(f, "\n!!NLREC\n");
-
-    n=j=0;
-    /* write the L-records (links) */
-    for (i=0; i<HASH_TBL; ++i)
-       for (h=hosthash[i]; h; h=h->link)
-           if ((t=h->rlink)) {
-               j+=fprintf(f, ":%ld", h->no);
-               for (; t; t=t->rlink) {
-                   j+=fprintf(f, "!%ld", t->linkid->no);
-                   if (t->tally>1)
-                       j+=fprintf(f, ",%ld", t->tally);
-                   n++;
-               }
-               if (j>RECLINE) {
-                   j=0;
-                   fprintf(f, "\n");
-               }
-           }
-    fprintf(f, "\n!!NLEND %ld\n", n);
-    return 0;
-}
-
-/* Write dump to a named file. Substitute %d in file name with system time. */
-
-void
-writedumpfile(const char *n)
-{
-    char buf[MAXFNAME];
-    FILE *d;
-
-    if (n[0]=='-' && n[1]=='\0') {
-       writedump(stdout);
-       return;
-    }
-    snprintf(buf, sizeof(buf), n, time(0));
-    d=fopen(buf, "w");
-    if (d) {
-       if (writedump(d)<0)
-            unlink(buf);
-    } else {
-       perror("writedumpfile: fopen");
-    }
-}
-
-/* Read a dump file. */
-
-int
-readdump(FILE *f)
-{
-    int a, b;
-    long i, m, l;
-    unsigned long st, et, at;
-    long sit, tot;
-    struct nrec **n;
-    struct trec *t;
-    char c[MAXHOST];
-    char v[16];
-
-    #define formerr(i) {\
-       fprintf(stderr, "dump file format error #%d\n", (i)); return -1; }
-
-    if (fscanf(f, "!!NINP %15s %lu %lu %ld %ld %lu\n",
-              v, &st, &et, &sit, &tot, &at)!=6)
-       formerr(0);
-
-    n=calloc(sit, sizeof(struct nrec *));
-    if (!n) {
-       fprintf(stderr, "error: out of memory\n");
-       return -1;
-    }
-    for (i=0; i<sit; i++) {
-       if (fscanf(f, HOSTF " %ld ", c, &l)!=2) {
-           fprintf(stderr, "read %ld ", i);
-           formerr(1);
-       }
-       n[i]=hhost(c);
-        if (!n[i])
-            return -1;
-        n[i]->sentto+=l;
-    }
-    if ((fscanf(f, HOSTF "\n", c)!=1) ||
-       strcmp(c, "!!NLREC"))
-       formerr(2);
-    m=0;
-    if (!strncmp(v, "3.0", 3)) {
-       /* Read 3.0-format L-records */
-       while (fscanf(f, "%d!%d!%ld ", &a, &b, &l)==3) {
-           t=tallyrec(n[a], n[b]);
-           if (!t)
-                return -1;
-            t->tally+=l;
-           ++m;
-       }
-    } else if (!strncmp(v, "3.1", 3)) {
-       /* Read L-records */
-       while (fscanf(f, " :%d", &a)==1) {
-           while ((i=fscanf(f, "!%d,%ld", &b, &l))>0) {
-               t=tallyrec(n[a], n[b]);
-               if (i<2)
-                   l=1;
-               if (!t)
-                    return -1;
-                t->tally+=l;
-               ++m;
-           }
-       }
-    } else {
-       fprintf(stderr, "version %s ", v);
-       formerr(9);
-    }
-    if ((fscanf(f, "!!NLEND %ld\n", &i)!=1)
-       || (i!=m))
-       formerr(3);
-#ifdef DEBUG
-    fprintf(stderr, " dumped start %s   total=%ld atimes=%ld (%ld)\n",
-            ctime(&st), tot, at, at-st);
-#endif
-    /* Adjust the time average and total count */
-    if ((unsigned long) starttime > st) {
-       atimes+=(double)total*(starttime-st);
-       starttime=st;
-    }
-    atimes+=(double)tot*(at-starttime);
-    total+=tot;
-#ifdef DEBUG
-    fprintf(stderr, " current start %s   total=%ld atimes=%.0f (%.0f)\n\n",
-            ctime(&starttime), total, atimes, atimes/total);
-#endif
-    free(n);
-    return 0;
-}
-
-/* Read dump from a file. */
-
-int
-readdumpfile(const char *n)
-{
-    FILE *d;
-    int i;
-
-    if (n[0]=='-' && n[1]=='\0')
-       return readdump(stdin);
-
-    d=fopen(n, "r");
-    if (d) {
-       /* fprintf(stderr, "Reading dump file %s\n", n); */
-       i=readdump(d);
-       fclose(d);
-       return i;
-    } else {
-       perror("readdumpfile: fopen");
-       return -1;
-    }
-}
-
-
-/* Process a Path line. */
-
-int
-pathline(char *c)
-{
-    char *c2;
-    struct nrec *h, *r;
-    struct trec *t;
-
-    r=NULL;
-    while (*c) {
-       for (c2=c; *c2 && *c2!='!'; c2++);
-       if (c2-c>MAXHOST-1)
-           /* looks broken, dont bother with rest */
-           return 0;
-       while (*c2=='!')
-           *c2++='\0'; /* skip "!!" too */
-       h=hhost(c);
-        if (!h)
-            return -1;
-        ++h->sentto;
-        if (r && r!=h) {
-            t=tallyrec(r, h);
-            if (!t)
-                return -1;
-            ++t->tally;
-       }
-       c=c2;
-       r=h;
-    }
-    return 0;
-}
-
-/* Take Path lines from file (stdin used here). */
-
-void
-procpaths(FILE *f)
-{
-    char buf[MAXLINE];
-    char *c, *ce;
-    int v=1; /* current line is valid */
-
-    while (fgets(buf, sizeof(buf), f)) {
-       c=buf;
-       if (!strncmp(c, "Path: ", 6))
-           c+=6;
-       /* find end of line. Some broken newsreaders preload Path with
-          a name containing spaces. Chop off those entries. */
-       for (ce=c; *ce && !CTYPE(isspace, *ce); ++ce);
-       if (!*ce) {
-           /* bogus line */
-           v=0;
-       } else if (v) {
-           /* valid line */
-           for (; ce>c && *ce!='!'; --ce); /* ignore last element */
-           *ce='\0';
-           if (pathline(c)<0) /* process it */
-                /* If an out of memory condition occurs while reading
-                   Path lines, stop reading and write the dump so far.
-                   INN will restart a fresh ninpaths. */
-                return;
-           /* update average age and grand total */
-           atimes+=(time(0)-starttime);
-           ++total;
-       } else {
-           /* next line is valid */
-           v=1;
-       }
-    }
-}
-
-/* Output a report suitable for mailing. From inpaths 2.5 */
-
-void
-report(const char *hostname, int verbose)
-{
-    double avgAge;
-    int i, columns, needHost;
-    long nhosts=0, nlinks=0;
-    struct nrec *list, *relay;
-    struct trec *rlist;
-    char hostString[MAXHOST];
-    time_t t0=time(0);
-
-    if (!total) {
-       fprintf(stderr, "report: no traffic\n");
-       return;
-    }
-    /* mark own site to not report it */
-    list=hhost(hostname);
-    if (list)
-       list->id[0]='\0';
-
-    avgAge=((double)t0 - (atimes/total + (double)starttime)) /86400.0;
-    printf("ZCZC begin inhosts %s %s %d %ld %3.1f\n",
-       VERSION,hostname,verbose,total,avgAge);
-    for (i=0; i<HASH_TBL-1; i++) {
-       list = hosthash[i];
-       while (list != NULL) {
-           if (list->id[0] != 0 && list->rlink != NULL) {
-               if (verbose > 0 || (100*list->sentto > total))
-                   printf("%ld\t%s\n",list->sentto, list->id);
-           }
-           list = list->link;
-       }
-    }
-    printf("ZCZC end inhosts %s\n",hostname);
-
-    printf("ZCZC begin inpaths %s %s %d %ld %3.1f\n",
-        VERSION,hostname,verbose,total,avgAge);
-    for (i=0; i<HASH_TBL-1; i++) {
-       list = hosthash[i];
-       while (list != NULL) {
-           if (verbose > 1 || (100*list->sentto > total)) {
-               if (list->id[0] != 0 && list->rlink != NULL) {
-                   columns = 3+strlen(list->id);
-                   snprintf(hostString,sizeof(hostString),"%s H ",list->id);
-                   needHost = 1;
-                   rlist = list->rlink;
-                   while (rlist != NULL) {
-                       if (
-                            (100*rlist->tally > total)
-                         || ((verbose > 1)&&(5000*rlist->tally>total))
-                          ) {
-                           if (needHost) printf("%s",hostString);
-                           needHost = 0;
-                           relay = rlist->linkid;
-                           if (relay->id[0] != 0) {
-                             if (columns > 70) {
-                               printf("\n%s",hostString);
-                               columns = 3+strlen(list->id);
-                             }
-                             printf("%ld Z %s U ", rlist->tally, relay->id);
-                             columns += 9+strlen(relay->id);
-                           }
-                       }
-                       rlist = rlist->rlink;
-                        ++nlinks;
-                   }
-                   if (!needHost) printf("\n");
-               }
-           }
-           list = list->link;
-            ++nhosts;
-       }
-    }
-    printf("ZCZC end inpaths %s\n",hostname);
-#ifdef DEBUG
-    fprintf(stderr, "Processed %ld hosts, %ld links.\n", nhosts, nlinks);
-#endif
-}
-
-extern char *optarg;
-
-int
-main(int argc, char *argv[])
-{
-    int i;
-    int pf=0, vf=2;
-    char *df=NULL, *rf=NULL;
-
-    for (i=0; i<HASH_TBL; i++)
-       hosthash[i]=NULL;
-    starttime=time(0);
-
-    while ((i=getopt(argc, argv, "pd:u:r:v:"))!=EOF)
-       switch (i) {
-       case 'p':
-           /* read Path lines from stdin */
-           pf=1; break;
-       case 'd':
-           /* make a dump to the named file */
-           df=optarg; break;
-       case 'u':
-           /* read dump from the named file */
-           if (readdumpfile(optarg)<0)
-               exit(1);
-           break;
-       case 'r':
-           /* make a report for the named site */
-           rf=optarg; break;
-       case 'v':
-           /* control report verbosity */
-           vf=atoi(optarg); break;
-       default:
-           fprintf(stderr, "unknown option %c\n", i);
-       }
-
-    if (pf)
-       procpaths(stdin);
-    if (df)
-       writedumpfile(df);
-    if (rf)
-       report(rf, vf);
-    return 0;
-}
diff --git a/backends/nntpget.c b/backends/nntpget.c
deleted file mode 100644 (file)
index 9d40920..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*  $Id: nntpget.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Connect to a remote site, and get news from it to offer to our local
-**  server.  Read list on stdin, or get it via NEWNEWS command.  Writes
-**  list of articles still needed to stdout.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-/*
-**  All information about a site we are connected to.
-*/
-typedef struct _SITE {
-    char       *Name;
-    int                Rfd;
-    int                Wfd;
-    char       Buffer[BUFSIZ];
-    char       *bp;
-    int                Count;
-} SITE;
-
-
-/*
-**  Global variables.
-*/
-static struct iovec    SITEvec[2];
-static char            SITEv1[] = "\r\n";
-static char            READER[] = "mode reader";
-static unsigned long   STATgot;
-static unsigned long   STAToffered;
-static unsigned long   STATsent;
-static unsigned long   STATrejected;
-static struct history  *History;
-
-\f
-
-/*
-**  Read a line of input, with timeout.
-*/
-static bool
-SITEread(SITE *sp, char *start)
-{
-    char       *p;
-    char       *end;
-    struct timeval     t;
-    fd_set             rmask;
-    int                        i;
-    char               c;
-
-    for (p = start, end = &start[NNTP_STRLEN - 1]; ; ) {
-       if (sp->Count == 0) {
-           /* Fill the buffer. */
-    Again:
-           FD_ZERO(&rmask);
-           FD_SET(sp->Rfd, &rmask);
-           t.tv_sec = DEFAULT_TIMEOUT;
-           t.tv_usec = 0;
-           i = select(sp->Rfd + 1, &rmask, NULL, NULL, &t);
-           if (i < 0) {
-               if (errno == EINTR)
-                   goto Again;
-               return false;
-           }
-           if (i == 0
-            || !FD_ISSET(sp->Rfd, &rmask)
-            || (sp->Count = read(sp->Rfd, sp->Buffer, sizeof sp->Buffer)) < 0)
-               return false;
-           if (sp->Count == 0)
-               return false;
-           sp->bp = sp->Buffer;
-       }
-
-       /* Process next character. */
-       sp->Count--;
-       c = *sp->bp++;
-       if (c == '\n')
-           break;
-       if (p < end)
-           *p++ = c;
-    }
-
-    /* If last two characters are \r\n, kill the \r as well as the \n. */
-    if (p > start && p < end && p[-1] == '\r')
-       p--;
-    *p = '\0';
-    return true;
-}
-
-
-/*
-**  Send a line to the server, adding \r\n.  Don't need to do dot-escape
-**  since it's only for sending DATA to local site, and the data we got from
-**  the remote site already is escaped.
-*/
-static bool
-SITEwrite(SITE *sp, const char *p, int i)
-{
-    SITEvec[0].iov_base = (char *) p;
-    SITEvec[0].iov_len = i;
-    return xwritev(sp->Wfd, SITEvec, 2) >= 0;
-}
-
-
-static SITE *
-SITEconnect(char *host)
-{
-    FILE       *From;
-    FILE       *To;
-    SITE       *sp;
-    int                i;
-
-    /* Connect and identify ourselves. */
-    if (host)
-       i = NNTPconnect(host, NNTP_PORT, &From, &To, (char *)NULL);
-    else {
-       host = innconf->server;
-        if (host == NULL)
-            die("no server specified and server not set in inn.conf");
-       i = NNTPlocalopen(&From, &To, (char *)NULL);
-    }
-    if (i < 0)
-        sysdie("cannot connect to %s", host);
-
-    if (NNTPsendpassword(host, From, To) < 0)
-        sysdie("cannot authenticate to %s", host);
-
-    /* Build the structure. */
-    sp = xmalloc(sizeof(SITE));
-    sp->Name = host;
-    sp->Rfd = fileno(From);
-    sp->Wfd = fileno(To);
-    sp->bp = sp->Buffer;
-    sp->Count = 0;
-    return sp;
-}
-
-
-/*
-**  Send "quit" to a site, and get its reply.
-*/
-static void
-SITEquit(SITE *sp)
-{
-    char       buff[NNTP_STRLEN];
-
-    SITEwrite(sp, "quit", 4);
-    SITEread(sp, buff);
-}
-
-
-static bool
-HIShaveit(char *mesgid)
-{
-    return HIScheck(History, mesgid);
-}
-
-
-static void
-Usage(const char *p)
-{
-    warn("%s", p);
-    fprintf(stderr, "Usage: nntpget"
-            " [ -d dist -n grps [-f file | -t time -u file]] host\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    char       buff[NNTP_STRLEN];
-    char       mesgid[NNTP_STRLEN];
-    char       tbuff[SMBUF];
-    char       *msgidfile = NULL;
-    int         msgidfd;
-    const char *Groups;
-    char       *distributions;
-    char       *Since;
-    char        *path;
-    int                i;
-    struct tm  *gt;
-    struct stat        Sb;
-    SITE       *Remote;
-    SITE       *Local = NULL;
-    FILE       *F;
-    bool       Offer;
-    bool       Error;
-    bool       Verbose = false;
-    char       *Update;
-    char       *p;
-
-    /* First thing, set up our identity. */
-    message_program_name = "nntpget";
-
-    /* Set defaults. */
-    distributions = NULL;
-    Groups = NULL;
-    Since = NULL;
-    Offer = false;
-    Update = NULL;
-    if (!innconf_read(NULL))
-        exit(1);
-
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "d:f:n:t:ovu:")) != EOF)
-       switch (i) {
-       default:
-           Usage("bad flag");
-           /* NOTREACHED */
-       case 'd':
-           distributions = optarg;
-           break;
-       case 'u':
-           Update = optarg;
-           /* FALLTHROUGH */
-       case 'f':
-           if (Since)
-               Usage("only one of -f, -t, or -u may be given");
-           if (stat(optarg, &Sb) < 0)
-                sysdie("cannot stat %s", optarg);
-           gt = gmtime(&Sb.st_mtime);
-           /* Y2K: NNTP Spec currently allows only two digit years. */
-           snprintf(tbuff, sizeof(tbuff), "%02d%02d%02d %02d%02d%02d GMT",
-                   gt->tm_year % 100, gt->tm_mon + 1, gt->tm_mday,
-                   gt->tm_hour, gt->tm_min, gt->tm_sec);
-           Since = tbuff;
-           break;
-       case 'n':
-           Groups = optarg;
-           break;
-       case 'o':
-           /* Open the history file. */
-            path = concatpath(innconf->pathdb, _PATH_HISTORY);
-           History = HISopen(path, innconf->hismethod, HIS_RDONLY);
-           if (!History)
-                sysdie("cannot open history");
-            free(path);
-           Offer = true;
-           break;
-       case 't':
-           if (Since)
-               Usage("only one of -t or -f may be given");
-           Since = optarg;
-           break;
-       case 'v':
-           Verbose = true;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if (ac != 1)
-       Usage("no host given");
-
-    /* Set up the scatter/gather vectors used by SITEwrite. */
-    SITEvec[1].iov_base = SITEv1;
-    SITEvec[1].iov_len = strlen(SITEv1);
-
-    /* Connect to the remote server. */
-    if ((Remote = SITEconnect(av[0])) == NULL)
-        sysdie("cannot connect to %s", av[0]);
-    if (!SITEwrite(Remote, READER, (int)strlen(READER))
-     || !SITEread(Remote, buff))
-        sysdie("cannot start reading");
-
-    if (Since == NULL) {
-       F = stdin;
-       if (distributions || Groups)
-           Usage("no -d or -n flags allowed when reading stdin");
-    }
-    else {
-       /* Ask the server for a list of what's new. */
-       if (Groups == NULL)
-           Groups = "*";
-       if (distributions)
-           snprintf(buff, sizeof(buff), "NEWNEWS %s %s <%s>",
-                     Groups, Since, distributions);
-       else
-           snprintf(buff, sizeof(buff), "NEWNEWS %s %s", Groups, Since);
-       if (!SITEwrite(Remote, buff, (int)strlen(buff))
-        || !SITEread(Remote, buff))
-            sysdie("cannot start list");
-       if (buff[0] != NNTP_CLASS_OK) {
-           SITEquit(Remote);
-            die("protocol error from %s, got %s", Remote->Name, buff);
-       }
-
-        /* Create a temporary file. */
-        msgidfile = concatpath(innconf->pathtmp, "nntpgetXXXXXX");
-        msgidfd = mkstemp(msgidfile);
-        if (msgidfd < 0)
-            sysdie("cannot create a temporary file");
-        F = fopen(msgidfile, "w+");
-        if (F == NULL)
-            sysdie("cannot open %s", msgidfile);
-
-       /* Read and store the Message-ID list. */
-       for ( ; ; ) {
-           if (!SITEread(Remote, buff)) {
-                syswarn("cannot read from %s", Remote->Name);
-               fclose(F);
-               SITEquit(Remote);
-               exit(1);
-           }
-           if (strcmp(buff, ".") == 0)
-               break;
-           if (Offer && HIShaveit(buff))
-               continue;
-           if (fprintf(F, "%s\n", buff) == EOF || ferror(F)) {
-                syswarn("cannot write %s", msgidfile);
-               fclose(F);
-               SITEquit(Remote);
-               exit(1);
-           }
-       }
-       if (fflush(F) == EOF) {
-            syswarn("cannot flush %s", msgidfile);
-           fclose(F);
-           SITEquit(Remote);
-           exit(1);
-       }
-       fseeko(F, 0, SEEK_SET);
-    }
-
-    if (Offer) {
-       /* Connect to the local server. */
-       if ((Local = SITEconnect((char *)NULL)) == NULL) {
-            syswarn("cannot connect to local server");
-           fclose(F);
-           exit(1);
-       }
-    }
-
-    /* Loop through the list of Message-ID's. */
-    while (fgets(mesgid, sizeof mesgid, F) != NULL) {
-       STATgot++;
-       if ((p = strchr(mesgid, '\n')) != NULL)
-           *p = '\0';
-
-       if (Offer) {
-           /* See if the local server wants it. */
-           STAToffered++;
-           snprintf(buff, sizeof(buff), "ihave %s", mesgid);
-           if (!SITEwrite(Local, buff, (int)strlen(buff))
-            || !SITEread(Local, buff)) {
-                syswarn("cannot offer %s", mesgid);
-               break;
-           }
-           if (atoi(buff) != NNTP_SENDIT_VAL)
-               continue;
-       }
-
-       /* Try to get the article. */
-       snprintf(buff, sizeof(buff), "article %s", mesgid);
-       if (!SITEwrite(Remote, buff, (int)strlen(buff))
-        || !SITEread(Remote, buff)) {
-            syswarn("cannot get %s", mesgid);
-           printf("%s\n", mesgid);
-           break;
-       }
-       if (atoi(buff) != NNTP_ARTICLE_FOLLOWS_VAL) {
-          if (Offer) {
-              SITEwrite(Local, ".", 1);
-              if (!SITEread(Local, buff)) {
-                  syswarn("no reply after %s", mesgid);
-                  break;
-              }
-          }
-          continue;
-       }
-
-       if (Verbose)
-            notice("%s...", mesgid);
-
-       /* Read each line in the article and write it. */
-       for (Error = false; ; ) {
-           if (!SITEread(Remote, buff)) {
-                syswarn("cannot read %s from %s", mesgid, Remote->Name);
-               Error = true;
-               break;
-           }
-           if (Offer) {
-               if (!SITEwrite(Local, buff, (int)strlen(buff))) {
-                    syswarn("cannot send %s", mesgid);
-                   Error = true;
-                   break;
-               }
-           }
-           else
-               printf("%s\n", buff);
-           if (strcmp(buff, ".") == 0)
-               break;
-       }
-       if (Error) {
-           printf("%s\n", mesgid);
-           break;
-       }
-       STATsent++;
-
-       /* How did the local server respond? */
-       if (Offer) {
-           if (!SITEread(Local, buff)) {
-                syswarn("no reply after %s", mesgid);
-               printf("%s\n", mesgid);
-               break;
-           }
-           i = atoi(buff);
-           if (i == NNTP_TOOKIT_VAL)
-               continue;
-           if (i == NNTP_RESENDIT_VAL) {
-               printf("%s\n", mesgid);
-               break;
-           }
-            syswarn("%s to %s", buff, mesgid);
-           STATrejected++;
-       }
-    }
-
-    /* Write rest of the list, close the input. */
-    if (!feof(F))
-       while (fgets(mesgid, sizeof mesgid, F) != NULL) {
-           if ((p = strchr(mesgid, '\n')) != NULL)
-               *p = '\0';
-           printf("%s\n", mesgid);
-           STATgot++;
-       }
-    fclose(F);
-
-    /* Remove our temp file. */
-    if (msgidfile && unlink(msgidfile) < 0)
-        syswarn("cannot remove %s", msgidfile);
-
-    /* All done. */
-    SITEquit(Remote);
-    if (Offer)
-       SITEquit(Local);
-
-    /* Update timestamp file? */
-    if (Update) {
-       if ((F = fopen(Update, "w")) == NULL)
-            sysdie("cannot update %s", Update);
-       fprintf(F, "got %ld offered %ld sent %ld rejected %ld\n",
-               STATgot, STAToffered, STATsent, STATrejected); 
-       if (ferror(F) || fclose(F) == EOF)
-            sysdie("cannot update %s", Update);
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/nntpsend.in b/backends/nntpsend.in
deleted file mode 100644 (file)
index eb68718..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 5047 $
-##  Send news via NNTP by running several innxmit processes in the background.
-##  Usage:
-##     nntpsend [-n][-p][-r][-s size][-S][-t timeout][-T limit][host fqdn]...
-##     -a              Always have innxmit rewrite the batchfile
-##     -d              debug mode, run innxmits with debug as well
-##     -D              same as -d except innxmits are not debugged
-##     -p              Run innxmit with -p to prune batch files
-##     -r              innxmit, don't requeue on unexpected error code
-##     -s size         limit the =n file to size bytes
-##     -c              disable message-ID checking in streaming mode
-##     -t timeout      innxmit timeout to make connection (def: 180)
-##     -T limit        innxmit connection transmit time limit (def: forever)
-##     -P portnum      port number to use
-##     -l              innxmit, log rejected articles
-##     -N              innxmit, disable streaming mode
-##     -n              do not lock for nntpsend, do not sleep between sets
-##     -w delay        wait delay seconds just before innxmit
-##     host fqdn       send to host and qualified domain (def: nntpsend.ctl)
-##  If no "host fqdn" pairs appear on the command line, then ${CTLFILE}
-##  file is read.
-
-PROGNAME=`basename $0`
-LOCK=${LOCKS}/LOCK.${PROGNAME}
-CTLFILE=${PATHETC}/${PROGNAME}.ctl
-LOG=${MOST_LOGS}/${PROGNAME}.log
-
-##  Set defaults.
-A_FLAG=
-D_FLAG=
-NO_LOG_FLAG=
-P_FLAG=
-R_FLAG=
-S_FLAG=
-C_FLAG=
-L_FLAG=
-S2_FLAG=
-TRUNC_SIZE=
-T_FLAG=
-TIMELIMIT=
-PP_FLAG=
-NOLOCK=
-W_SECONDS=
-
-##  Parse JCL.
-MORETODO=true
-while ${MORETODO} ; do
-    case X"$1" in
-    X-a)
-       A_FLAG="-a"
-       ;;
-    X-d)
-       D_FLAG="-d"
-       NO_LOG_FLAG="true"
-       ;;
-    X-D)
-       NO_LOG_FLAG="true"
-       ;;
-    X-l)
-       L_FLAG="-l"
-       ;;
-    X-p)
-       P_FLAG="-p"
-       ;;
-    X-r)
-       R_FLAG="-r"
-       ;;
-    X-S)
-       S_FLAG="-S"
-       ;;
-    X-N)
-       S2_FLAG="-s"
-       ;;
-    X-c)
-       C_FLAG="-c"
-       ;;
-    X-s)
-       if [ -z "$2" ] ; then
-           echo "${PROGNAME}: option requires an argument -- s" 1>&2
-           exit 1
-       fi
-       TRUNC_SIZE="$2"
-       shift
-       ;;
-    X-s*)
-       TRUNC_SIZE="`echo $1 | ${SED} -e 's/-s//'`"
-       ;;
-    X-t)
-       if [ -z "$2" ] ; then
-           echo "${PROGNAME}: option requires an argument -- t" 1>&2
-           exit 1
-       fi
-       T_FLAG="-t$2"
-       shift
-       ;;
-    X-t*)
-       T_FLAG="$1"
-       ;;
-    X-P)
-       if [ -z "$2" ] ; then
-           echo "${PROGNAME}: option requires an argument -- P" 1>&2
-           exit 1
-       fi
-       PP_FLAG="-P$2"
-       shift
-       ;;
-    X-P*)
-       PP_FLAG="$1"
-       ;;
-    X-T)
-       if [ -z "$2" ] ; then
-           echo "${PROGNAME}: option requires an argument -- T" 1>&2
-           exit 1
-       fi
-       TIMELIMIT="-T$2"
-       shift
-       ;;
-    X-T*)
-       TIMELIMIT="$1"
-       ;;
-    X-n)
-       NOLOCK=true
-       ;;
-    X-w)
-       if [ -z "$2" ] ; then
-           echo "${PROGNAME}: option requires an argument -- w" 1>&2
-           exit 1
-       fi
-       W_SECONDS="$2"
-       shift
-       ;;
-    X--)
-       shift
-       MORETODO=false
-       ;;
-    X-*)
-       echo "${PROGNAME}: illegal option -- $1" 1>&2
-       exit 1
-       ;;
-    *)
-       MORETODO=false
-       ;;
-    esac
-    ${MORETODO} && shift
-done
-
-## grab the lock if not -n
-NNTPLOCK=${LOCKS}/LOCK.nntpsend
-if [ -z "${NOLOCK}" ]; then
-    shlock -p $$ -f ${NNTPLOCK} || {
-       # nothing to do
-       exit 0
-    }
-fi
-
-##  Parse arguments; host/fqdn pairs.
-INPUT=${TMPDIR}/nntpsend$$
-cp /dev/null ${INPUT}
-while [ $# -gt 0 ]; do
-    if [ $# -lt 2 ]; then
-       echo "${PROGNAME}:  Bad host/fqdn pair" 1>&2
-       rm -f ${NNTPLOCK}
-       exit 1
-    fi
-    echo "$1 $2" >>${INPUT}
-    shift
-    shift
-done
-
-##  If nothing specified on the command line, read the control file.
-if [ ! -s ${INPUT} ] ; then
-    if [ ! -r ${CTLFILE} ]; then
-       echo "${PROGNAME}: cannot read ${CTLFILE}"
-       rm -f ${NNTPLOCK}
-       exit 1
-    fi
-    ${SED} -e 's/#.*//' -e '/^$/d' -e 's/::\([^:]*\)$/:max:\1/' \
-       -e 's/:/ /g' <${CTLFILE} >${INPUT}
-fi
-
-##  Go to where the action is.
-if [ ! -d ${BATCH} ]; then
-    echo "${PROGNAME}: directory ${BATCH} not found" 1>&2
-    rm -f ${NNTPLOCK}
-    exit 1
-fi
-cd ${BATCH}
-
-##  Set up log file.
-umask 002
-if [ -z "${NO_LOG_FLAG}" ]; then
-    test ! -f ${LOG} && touch ${LOG}
-    chmod 0660 ${LOG}
-    exec >>${LOG} 2>&1
-fi
-PARENTPID=$$
-echo "${PROGNAME}: [${PARENTPID}] start"
-
-##  Set up environment.
-export BATCH PROGNAME PARENTPID INNFLAGS
-
-##  Loop over all sites.
-cat ${INPUT} | while read SITE HOST SIZE_ARG FLAGS; do
-    ## Parse the input parameters.
-    if [ -z "${SITE}" -o -z "${HOST}" ] ; then
-       echo "Ignoring bad line: ${SITE} ${HOST} ${SIZE_ARG} ${FLAGS}" 1>&2
-       continue
-    fi
-
-    ## give up early if we cannot even lock it
-    ##
-    ## NOTE: This lock is not nntpsend's lock but rather the
-    ##      lock that the parent shell of innxmit will use.
-    ##      Later on the child will take the lock from us.
-    ##
-    LOCK="${LOCKS}/LOCK.${SITE}"
-    shlock -p $$ -f "${LOCK}" || continue
-
-    ## Compute the specific parameters for this site.
-    test "${SIZE_ARG}" = "max" && SIZE_ARG=
-    if [ -n "${TRUNC_SIZE}" ]; then
-       SIZE_ARG="${TRUNC_SIZE}"
-    fi
-    ## Parse the SIZE_ARG for either MaxSize-TruncSize or TruncSize
-    case "${SIZE_ARG}" in
-    *-*) MAXSIZE="`echo ${SIZE_ARG} | ${SED} -e 's/-.*//'`";
-        SIZE="`echo ${SIZE_ARG} | ${SED} -e 's/^.*-//'`" ;;
-    *) MAXSIZE="${SIZE_ARG}";
-       SIZE="${SIZE_ARG}" ;;
-    esac
-    D_PARAM=
-    R_PARAM=
-    S_PARAM=
-    S2_PARAM=
-    C_PARAM=
-    PP_PARAM=
-    L_PARAM=
-    TIMEOUT_PARAM=
-    TIMELIMIT_PARAM=
-    if [ -z "${FLAGS}" ]; then
-       MORETODO=false
-    else
-       MORETODO=true
-       set -- ${FLAGS}
-    fi
-    while ${MORETODO} ; do
-       case "X$1" in
-       X-a)
-           ;;
-       X-d)
-           D_PARAM="-d"
-           ;;
-       X-c)
-           C_PARAM="-c"
-           ;;
-       X-p)
-           P_PARAM="-p"
-           ;;
-       X-r)
-           R_PARAM="-r"
-           ;;
-       X-S)
-           S_PARAM="-S"
-           ;;
-       X-s)
-           S2_PARAM="-s"
-           ;;
-       X-l)
-           L_PARAM="-l"
-           ;;
-       X-t)
-           if [ -z "$2" ] ; then
-               echo "${PROGNAME}: option requires an argument -- t" 1>&2
-               rm -f "${NNTPLOCK}" "${LOCK}"
-               exit 1
-           fi
-           TIMEOUT_PARAM="-t$2"
-           shift
-           ;;
-       X-t*)
-           TIMEOUT_PARAM="$1"
-           ;;
-       X-P)
-           if [ -z "$2" ] ; then
-               echo "${PROGNAME}: option requires an argument -- P" 1>&2
-               rm -f "${NNTPLOCK}" "${LOCK}"
-               exit 1
-           fi
-           PP_PARAM="-P$2"
-           shift
-           ;;
-       X-P*)
-           PP_PARAM="$1"
-           ;;
-       X-T)
-           if [ -z "$2" ] ; then
-               echo "${PROGNAME}: option requires an argument -- T" 1>&2
-               rm -f "${NNTPLOCK}" "${LOCK}"
-               exit 1
-           fi
-           TIMELIMIT_PARAM="-T$2"
-           shift
-           ;;
-       X-T*)
-           TIMELIMIT_PARAM="$1"
-           ;;
-       X-w)
-           if [ -z "$2" ] ; then
-               echo "${PROGNAME}: option requires an argument -- w" 1>&2
-           rm -f "${NNTPLOCK}" "${LOCK}"
-           exit 1
-           fi
-           W_SECONDS="$2"
-           shift
-            ;;
-       *)
-           MORETODO=false
-           ;;
-       esac
-       ${MORETODO} && shift
-    done
-    if [ -z "${SIZE}" -o -n "${A_FLAG}" ]; then
-       # rewrite batch file if we do not have a size limit
-       INNFLAGS="-a"
-    else
-       # we have a size limit, let shrinkfile rewrite the file
-       INNFLAGS=
-    fi
-    if [ -n "${D_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${D_FLAG}"
-    else
-       test -n "${D_PARAM}" && INNFLAGS="${INNFLAGS} ${D_PARAM}"
-    fi
-    if [ -n "${C_FLAG}" ]; then
-        INNFLAGS="${INNFLAGS} ${C_FLAG}"
-    else
-        test -n "${C_PARAM}" && INNFLAGS="${INNFLAGS} ${C_PARAM}"
-    fi
-    if [ -n "${P_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${P_FLAG}"
-    else
-       test -n "${P_PARAM}" && INNFLAGS="${INNFLAGS} ${P_PARAM}"
-    fi
-    if [ -n "${L_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${L_FLAG}"
-    else
-       test -n "${L_PARAM}" && INNFLAGS="${INNFLAGS} ${L_PARAM}"
-    fi
-    if [ -n "${R_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${R_FLAG}"
-    else
-       test -n "${R_PARAM}" && INNFLAGS="${INNFLAGS} ${R_PARAM}"
-    fi
-    if [ -n "${S_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${S_FLAG}"
-    else
-       test -n "${S_PARAM}" && INNFLAGS="${INNFLAGS} ${S_PARAM}"
-    fi
-    if [ -n "${S2_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${S2_FLAG}"
-    else
-       test -n "${S2_PARAM}" && INNFLAGS="${INNFLAGS} ${S2_PARAM}"
-    fi
-    if [ -n "${T_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${T_FLAG}"
-    else
-       test -n "${TIMEOUT_PARAM}" && INNFLAGS="${INNFLAGS} ${TIMEOUT_PARAM}"
-    fi
-    if [ -n "${PP_FLAG}" ]; then
-       INNFLAGS="${INNFLAGS} ${PP_FLAG}"
-    else
-       test -n "${PP_PARAM}" && INNFLAGS="${INNFLAGS} ${PP_PARAM}"
-    fi
-    if [ -n "${TIMELIMIT}" ]; then
-       INNFLAGS="${INNFLAGS} ${TIMELIMIT}"
-    else
-       test -n "${TIMELIMIT_PARAM}" \
-           && INNFLAGS="${INNFLAGS} ${TIMELIMIT_PARAM}"
-    fi
-
-    ## Flush the buffers for the site now, rather than in the child.
-    ## This helps pace the number of ctlinnd commands because the
-    ## nntpsend process does not proceed until the site flush has
-    ## been completed.
-    ##
-    # carry old unfinished work over to this task
-    BATCHFILE="${SITE}=n"
-    if [ -f "${SITE}.work" ] ; then
-       cat ${SITE}.work >>"${BATCHFILE}"
-       rm -f "${SITE}.work"
-    fi
-    # form BATCHFILE to hold the work for this site
-    if [ -f "${SITE}" ]; then
-       mv "${SITE}" "${SITE}.work"
-       if ctlinnd -s -t30 flush ${SITE} ; then
-           cat ${SITE}.work >>"${BATCHFILE}"
-           rm -f ${SITE}.work
-       else
-           # flush failed, continue if we have any batchfile to work on
-           echo "${PROGNAME}: bad flush for ${HOST} via ${SITE}"
-           if [ -f "${BATCHFILE}" ]; then
-               echo "${PROGNAME}: trying ${HOST} via ${SITE} anyway"
-           else
-               echo "${PROGNAME}: skipping ${HOST} via ${SITE}"
-               rm -f ${LOCK}
-               continue
-           fi
-       fi
-    else
-       # nothing to work on, so flush and move on
-       ctlinnd -s -t30 flush ${SITE}
-       echo "${PROGNAME}: file ${BATCH}/${SITE} for ${HOST} not found"
-       if [ -f "${BATCHFILE}" ]; then
-           echo "${PROGNAME}: trying ${HOST} via ${SITE} anyway"
-       else
-           echo "${PROGNAME}: skipping ${HOST} via ${SITE}"
-           rm -f ${LOCK}
-           continue
-       fi
-    fi
-
-    ##  Start sending this site in the background.
-    export MAXSIZE SITE HOST PROGNAME PARENTPID SIZE TMPDIR LOCK BATCHFILE W_SECONDS
-    sh -c '
-       # grab the lock from the parent
-       #
-       # This is safe because only the parent will have locked
-       # the site.  We break the lock and reclaim it.
-       rm -f ${LOCK}
-       trap "rm -f ${LOCK} ; exit 1" 1 2 3 15
-       shlock -p $$ -f ${LOCK} || {
-           WHY="`cat ${LOCK}`"
-           echo "${PROGNAME}: [${PARENTPID}:$$] ${SITE} locked ${WHY} `date`"
-           exit
-       }
-       # process the site BATCHFILE
-       if [ -f "${BATCHFILE}" ]; then
-           test -n "${SIZE}" && shrinkfile -m${MAXSIZE} -s${SIZE} -v ${BATCHFILE}
-           if [ -s ${BATCHFILE} ] ; then
-               if [ -n "${W_SECONDS}" ] ; then
-                   echo "${PROGNAME}: [${PARENTPID}:$$] sleeping ${W_SECONDS} seconds before ${SITE}"
-                   sleep "${W_SECONDS}"
-               fi
-               echo "${PROGNAME}: [${PARENTPID}:$$] begin ${SITE} `date`"
-               echo "${PROGNAME}: [${PARENTPID}:$$] innxmit ${INNFLAGS} ${HOST} ..."
-               eval innxmit ${INNFLAGS} ${HOST} ${BATCH}/${BATCHFILE}
-               echo "${PROGNAME}: [${PARENTPID}:$$] end ${SITE} `date`"
-           else
-               rm -f ${BATCHFILE}
-           fi
-       else
-           echo "${PROGNAME}: file ${BATCH}/${BATCHFILE} for ${HOST} not found"
-       fi
-       rm -f ${LOCK}
-    ' &
-done
-
-## release the nntpsend lock and clean up before we wait on child processes
-if [ -z "${NOLOCK}" ]; then
-    rm -f ${NNTPLOCK}
-fi
-rm -f ${INPUT}
-
-## wait for child processes to finish
-wait
-
-## all done
-echo "${PROGNAME}: [${PARENTPID}] stop"
-exit 0
diff --git a/backends/overchan.c b/backends/overchan.c
deleted file mode 100644 (file)
index 30bb028..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*  $Id: overchan.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Parse input to add to news overview database.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <errno.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-
-unsigned int NumArts;
-unsigned int StartTime;
-unsigned int TotOvTime;
-
-/*
- * Timer function (lifted from innd/timer.c). 
- * This function is designed to report the number of milliseconds since
- * the first invocation.  I wanted better resolution than time(), and
- * something easier to work with than gettimeofday()'s struct timeval's.
- */
-
-static unsigned gettime(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);
-}
-
-/*
-**  Process the input.  Data comes from innd in the form:
-**  @token@ data
-*/
-
-#define TEXT_TOKEN_LEN (2*sizeof(TOKEN)+2)
-static void ProcessIncoming(QIOSTATE *qp)
-{
-    char                *Data;
-    char               *p;
-    TOKEN              token;
-    unsigned int       starttime, endtime;
-    time_t             Time, Expires;
-
-    for ( ; ; ) {
-       /* Read the first line of data. */
-       if ((Data = QIOread(qp)) == NULL) {
-           if (QIOtoolong(qp)) {
-                warn("line too long");
-               continue;
-           }
-           break;
-       }
-
-       if (Data[0] != '@' || strlen(Data) < TEXT_TOKEN_LEN+2 
-           || Data[TEXT_TOKEN_LEN-1] != '@' || Data[TEXT_TOKEN_LEN] != ' ') {
-            warn("malformed token %s", Data);
-           continue;
-       }
-       token = TextToToken(Data);
-       Data += TEXT_TOKEN_LEN+1; /* skip over token and space */
-       for (p = Data; !ISWHITE(*p) ;p++) ;
-       *p++ = '\0';
-       Time = (time_t)atol(Data);
-       for (Data = p; !ISWHITE(*p) ;p++) ;
-       *p++ = '\0';
-       Expires = (time_t)atol(Data);
-       Data = p;
-       NumArts++;
-       starttime = gettime();
-       if (OVadd(token, Data, strlen(Data), Time, Expires) == OVADDFAILED)
-            syswarn("cannot write overview %s", Data);
-       endtime = gettime();
-       TotOvTime += endtime - starttime;
-    }
-    QIOclose(qp);
-}
-
-
-int main(int ac, char *av[])
-{
-    QIOSTATE           *qp;
-    unsigned int       now;
-
-    /* First thing, set up our identity. */
-    message_program_name = "overchan";
-
-    /* Log warnings and fatal errors to syslog unless we were given command
-       line arguments, since we're probably running under innd. */
-    if (ac == 0) {
-        openlog("overchan", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-        message_handlers_warn(1, message_log_syslog_err);
-        message_handlers_die(1, message_log_syslog_err);
-        message_handlers_notice(1, message_log_syslog_notice);
-    }
-       
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    umask(NEWSUMASK);
-    if (innconf->enableoverview && !innconf->useoverchan)
-        warn("overchan is running while innd is creating overview data (you"
-             " can ignore this message if you are running makehistory -F)");
-
-    ac -= 1;
-    av += 1;
-
-    if (!OVopen(OV_WRITE))
-        die("cannot open overview");
-
-    StartTime = gettime();
-    if (ac == 0)
-       ProcessIncoming(QIOfdopen(STDIN_FILENO));
-    else {
-       for ( ; *av; av++)
-           if (strcmp(*av, "-") == 0)
-               ProcessIncoming(QIOfdopen(STDIN_FILENO));
-           else if ((qp = QIOopen(*av)) == NULL)
-                syswarn("cannot open %s", *av);
-           else
-               ProcessIncoming(qp);
-    }
-    OVclose();
-    now = gettime();
-    notice("timings %u arts %u of %u ms", NumArts, TotOvTime, now - StartTime);
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/backends/send-ihave.in b/backends/send-ihave.in
deleted file mode 100644 (file)
index f1ba03c..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 2674 $
-##  SH script to send IHAVE batches out.
-
-PROGNAME=`basename $0`
-LOG=${MOST_LOGS}/${PROGNAME}.log
-
-## How many Message-ID's per message.
-PERMESSAGE=1000
-
-##  Go to where the action is, start logging
-cd $BATCH
-umask 002
-DEBUG=""
-if [ "X$1" = X-d ] ; then
-    DEBUG="-d"
-    shift
-else
-    test ! -f ${LOG} && touch ${LOG}
-    chmod 0660 ${LOG}
-    exec >>${LOG} 2>&1
-fi
-
-echo "${PROGNAME}: [$$] begin `date`"
-
-##  List of sitename:hostname pairs to send to
-if [ -n "$1" ] ; then
-    LIST="$*"
-else
-    echo "${PROGNAME}: [$$] no sites specified" >&2
-    exit 1
-fi
-
-##  Do the work...
-for SITE in ${LIST}; do
-    case $SITE in
-    *:*)
-       HOST=`expr $SITE : '.*:\(.*\)'`
-       SITE=`expr $SITE : '\(.*\):.*'`
-       ;;
-    *)
-       HOST=$SITE
-       ;;
-    esac
-    BATCHFILE=${SITE}.ihave.batch
-    LOCK=${LOCKS}/LOCK.${SITE}.ihave
-    trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-    shlock -p $$ -f ${LOCK} || {
-       echo "${PROGNAME}: [$$] ${SITE}.ihave locked by `cat ${LOCK}`"
-       continue
-    }
-
-    ##  See if any data is ready for host.
-    if [ -f ${SITE}.ihave.work ] ; then
-       cat ${SITE}.ihave.work >>${BATCHFILE}
-       rm -f ${SITE}.ihave.work
-    fi
-    if [ ! -f ${SITE}.ihave -o ! -s ${SITE}.ihave ] ; then
-       if [ ! -f ${BATCHFILE} -o ! -s ${BATCHFILE} ] ; then
-           rm -f ${LOCK}
-           continue
-       fi
-    fi
-    mv ${SITE}.ihave ${SITE}.ihave.work
-    ctlinnd -s -t30 flush ${SITE}.ihave || continue
-    cat ${SITE}.ihave.work >>${BATCHFILE}
-    rm -f ${SITE}.ihave.work
-    if [ ! -s ${BATCHFILE} ] ; then
-       echo "${PROGNAME}: [$$] no articles for ${SITE}.ihave"
-       rm -f ${BATCHFILE}
-       continue
-    fi
-
-    echo "${PROGNAME}: [$$] begin ${SITE}.ihave"
-
-    ##  Write out the batchfile as a control message, in clumps.
-    export SITE PERMESSAGE BATCHFILE
-    while test -s ${BATCHFILE} ; do
-       (
-           echo Newsgroups: to.${SITE}
-           echo Control: ihave `innconfval pathhost`
-           echo Subject: cmsg ihave `innconfval pathhost`
-           echo ''
-           ${SED} -e ${PERMESSAGE}q <${BATCHFILE}
-       ) | ${INEWS} -h
-       ${SED} -e "1,${PERMESSAGE}d" <${BATCHFILE} >${BATCHFILE}.tmp
-       mv ${BATCHFILE}.tmp ${BATCHFILE}
-    done
-    echo "${PROGNAME}: [$$] end ${SITE}.ihave"
-    rm -f ${LOCK}
-done
-
-echo "${PROGNAME}: [$$] end `date`"
diff --git a/backends/send-nntp.in b/backends/send-nntp.in
deleted file mode 100644 (file)
index 018eb6d..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 4115 $
-##  SH script to send NNTP news out.
-
-PROGNAME=`basename $0`
-LOG=${MOST_LOGS}/${PROGNAME}.log
-
-##  Go to where the action is, start logging
-cd $BATCH
-umask 002
-DEBUG=""
-if [ "X$1" = X-d ] ; then
-    DEBUG="-d"
-    shift
-else
-    test ! -f ${LOG} && touch ${LOG}
-    chmod 0660 ${LOG}
-    exec >>${LOG} 2>&1
-fi
-
-echo "${PROGNAME}: [$$] begin `date`"
-
-##  List of sitename:hostname pairs to send to
-if [ -n "$1" ] ; then
-    LIST="$*"
-else
-    echo "${PROGNAME}: [$$] no sites specified" >&2
-    exit 1
-fi
-
-##  Do the work...
-for SITE in ${LIST}; do
-    case $SITE in
-    *:*)
-       HOST=`expr $SITE : '.*:\(.*\)'`
-       SITE=`expr $SITE : '\(.*\):.*'`
-       ;;
-    *)
-       HOST=$SITE
-       ;;
-    esac
-    case $HOST in
-    *@*)
-        PORT=`expr $HOST : '\(.*\)@.*'` 
-        HOST=`expr $HOST : '.*@\(.*\)'`
-        ;;
-    *)  
-        PORT=119
-        ;;
-    esac
-    BATCHFILE=${SITE}.nntp
-    LOCK=${LOCKS}/LOCK.${SITE}
-    trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-    shlock -p $$ -f ${LOCK} || {
-       echo "${PROGNAME}: [$$] ${SITE} locked by `cat ${LOCK}`"
-       continue
-    }
-
-    ##  See if any data is ready for host.
-    if [ -f ${SITE}.work ] ; then
-       cat ${SITE}.work >>${BATCHFILE}
-       rm -f ${SITE}.work
-    fi
-    if [ ! -f ${SITE} -o ! -s ${SITE} ] ; then
-       if [ ! -f ${BATCHFILE} -o ! -s ${BATCHFILE} ] ; then
-           rm -f ${LOCK}
-           continue
-       fi
-    fi
-    mv ${SITE} ${SITE}.work
-    ctlinnd -s -t30 flush ${SITE} || continue
-    cat ${SITE}.work >>${BATCHFILE}
-    rm -f ${SITE}.work
-    if [ ! -s ${BATCHFILE} ] ; then
-       echo "${PROGNAME}: [$$] no articles for ${SITE}"
-       rm -f ${BATCHFILE}
-       continue
-    fi
-
-    echo "${PROGNAME}: [$$] begin ${SITE}"
-    time innxmit ${DEBUG} -P ${PORT} ${HOST} ${BATCH}/${BATCHFILE}
-    echo "${PROGNAME}: [$$] end ${SITE}"
-    rm -f ${LOCK}
-done
-
-echo "${PROGNAME}: [$$] end   `date`"
diff --git a/backends/send-uucp.in b/backends/send-uucp.in
deleted file mode 100644 (file)
index 8ba2937..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-#!/usr/bin/perl -w
-# fixscript will replace this line with code to load innshellvars
-
-##############################################################################
-# send-uucp.pl create news batches from the outgoing files
-#
-# Author:      Edvard Tuinder <ed@elm.net>
-#
-# Copyright (C) 1994 Edvard Tuinder - ELM Consultancy B.V.
-# Copyright (C) 1995-1997 Miquel van Smoorenburg - Cistron Internet Services
-#
-# Copyright (C) 2003 Marco d'Itri <md@linux.it>
-#   Nearly rewritten. Added syslog support, real errors checking and more.
-#
-# 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.
-##############################################################################
-
-use strict;
-use Sys::Syslog;
-
-# for compatibility with earlier versions of INN
-$inn::pathetc ||= '/etc/news';
-$inn::syslog_facility ||= 'news';
-$inn::uux ||= 'uux';
-
-# some default values
-my $MAXSIZE = 500000;
-my $MAXJOBS = 200;
-
-my %UNBATCHER = (
-    compress    => 'cunbatch',
-    bzip2       => 'bunbatch',
-    gzip        => 'gunbatch',
-);
-
-my $UUX_FLAGS = '- -z -r -gd';
-my $BATCHER_FLAGS = '';
-
-##############################################################################
-my $config_file = $inn::pathetc . '/send-uucp.cf';
-my $lockfile = $inn::locks . '/LOCK.send-uucp';
-
-openlog('send-uucp', 'pid', $inn::syslog_facility);
-
-my @sitelist;
-if (@ARGV) {
-    foreach my $site (@ARGV) {
-        my @cfg = read_cf($config_file, $site);
-        if (not @cfg) {
-            logmsg("site $site not found in the configuration", 'err');
-            next;
-        }
-        push @sitelist, @cfg;
-    }
-} else {
-    @sitelist = read_cf($config_file, undef);
-}
-
-if (not @sitelist) {
-    logmsg('nothing to do', 'debug');
-    exit 0;
-}
-
-chdir $inn::batch or logdie("Can't access $inn::batch: $!", 'crit');
-
-shlock($lockfile);
-
-run_site($_) foreach @sitelist;
-unlink $lockfile;
-exit 0;
-
-# lint food
-$inn::compress.$inn::locks.$inn::syslog_facility.$inn::have_uustat = 0 if 0;
-
-##############################################################################
-sub read_cf {
-    my ($conf_file, $site_wanted) = @_;
-
-    my $hour = (localtime time)[2];
-
-    my @sites;
-    open(CF, $conf_file) or logdie("cannot open $conf_file: $!", 'crit');
-    while (<CF>) {
-        chop;
-        s/\s*\#.*$//;
-        next if /^$/;
-
-        my ($sitespec, $compress, $size, $time) = split(/\s+/);
-        next if not $sitespec;
-
-        my ($site, $host, $funnel) = split(/:/, $sitespec);
-        $host = $site if not $host;
-        $funnel = $site if not $funnel;
-
-        $compress =~ s/_/ /g if $compress;
-
-        if ($site_wanted) {
-            if ($site eq $site_wanted) {
-                push @sites, [$site, $host, $funnel, $compress, $size];
-                last;
-            }
-            next;
-        }
-
-        if ($time) {
-            foreach my $time (split(/,/, $time)) {
-                next if $time != $hour;
-                push @sites, [$site, $host, $funnel, $compress, $size];
-            }
-        } else {
-            push @sites, [$site, $host, $funnel, $compress, $size];
-        }
-    }
-    close CF;
-    return @sites;
-}
-
-##############################################################################
-# count number of jobs in the UUCP queue for a given site
-sub count_jobs {
-    my ($site) = @_;
-
-    return 0 if not $inn::have_uustat;
-    open(JOBS, "uustat -s $site 2> /dev/null |") or logdie("cannot fork: $!");
-    my $count = grep(/ Executing rnews /, <JOBS>);
-    close JOBS;                    # ignore errors, uustat may fail
-    return $count;
-}
-
-# select the rnews label appropriate for the compressor program used
-sub unbatcher {
-    my ($compressor) = @_;
-
-    $compressor =~ s%.*/%%;   # Do not keep the complete path.
-    $compressor =~ s% .*%%;   # Do not keep the optional parameters.
-    return $UNBATCHER{$compressor} || 'cunbatch';
-}
-
-##############################################################################
-# batch articles for one site
-sub run_site {
-    my ($cfg) = @_;
-    my ($site, $host, $funnel, $compress, $size) = @$cfg;
-
-    logmsg("checking site $site", 'debug');
-    my $maxjobs = '';
-    if ($MAXJOBS) {
-        my $jobs = count_jobs($site);
-        if ($jobs >= $MAXJOBS) {
-            logmsg("too many jobs queued for $site");
-            return;
-        }
-        $maxjobs = '-N ' . ($MAXJOBS - $jobs);
-    }
-
-    $compress ||= $inn::compress;
-    $size ||= $MAXSIZE;
-
-    # if exists a .work temp file left by a previous invocation, rename
-    # it to .work.tmp, we'll append it to the current batch file once it
-    # has been renamed and flushed.
-    if (-f "$site.work") {
-        rename("$site.work", "$site.work.tmp")
-            or logdie("cannot rename $site.work: $!", 'crit');
-    }
-
-    if (not -f $site and not -f "$site.work.tmp") {
-        logmsg("no batch file for site $site", 'err');
-        return;
-    }
-
-    rename($site, "$site.work") or logdie("cannot rename $site: $!", 'crit');
-    logmsg("Flushing $funnel for site $site", 'debug');
-    ctlinnd('-t120', 'flush', $funnel);
-
-    # append the old .work temp file to the current batch file if needed
-    if (-f "$site.work.tmp") {
-        my $err = '';
-        open(OUT, ">>$site.work")
-            or logdie("cannot open $site.work: $!", 'crit');
-        open(IN, "$site.work.tmp")
-            or logdie("cannot open $site.work.tmp: $!", 'crit');
-        print OUT while <IN>;
-        close IN;
-        close OUT or logdie("cannot close $site.work: $!");;
-        unlink "$site.work.tmp"
-            or logmsg("cannot delete $site.work.tmp: $!", 'err');
-    }
-
-    if (not -s "$site.work") {
-        logmsg("no articles for $site", 'debug');
-        unlink "$site.work" or logmsg("cannot delete $site.work: $!", 'err');
-    } else {
-        if ($compress eq 'none') {
-            system "batcher -b $size $maxjobs $BATCHER_FLAGS "
-                . "-p\"$inn::uux $UUX_FLAGS %s!rnews\" $host $site.work";
-        } else {
-            system "batcher -b $size $maxjobs $BATCHER_FLAGS "
-                . "-p\"{ echo '#! " . unbatcher($compress)
-                . "' ; exec $compress; } | "
-                . "$inn::uux $UUX_FLAGS %s!rnews\" $host $site.work";
-        }
-        logmsg("batched articles for $site", 'debug');
-    }
-}
-
-##############################################################################
-sub logmsg {
-    my ($msg, $lvl) = @_;
-
-    syslog($lvl || 'notice', '%s', $msg);
-}
-
-sub logdie {
-    my ($msg, $lvl) = @_;
-
-    logmsg($msg, $lvl || 'err');
-    unlink $lockfile;
-    exit 1;
-}
-
-sub ctlinnd {
-    my ($cmd, @args) = @_;
-
-    my $st = system("$inn::newsbin/ctlinnd", '-s', $cmd, @args);
-    logdie('Cannot run ctlinnd: ' . $!) if $st == -1;
-    logdie('ctlinnd returned status ' . ($st & 255)) if $st > 0;
-}
-
-sub shlock {
-    my $lockfile = shift;
-
-    my $locktry = 0;
-    while ($locktry < 60) {
-        if (system("$inn::newsbin/shlock", '-p', $$, '-f', $lockfile) == 0) {
-            return 1;
-        }
-        $locktry++;
-        sleep 2;
-    }
-
-    my $lockreason;
-    if (open(LOCKFILE, $lockfile)) {
-        $lockreason = 'held by ' . (<LOCKFILE> || '?');
-        close LOCKFILE;
-    } else {
-        $lockreason = $!;
-    }
-    logdie("Cannot get lock $lockfile: $lockreason");
-    return undef;
-}
-
-__END__
-
-=head1 NAME
-
-send-uucp - Send Usenet articles via UUCP
-
-=head1 SYNOPSIS
-
-B<send-uucp> [I<SITE> ...]
-
-=head1 DESCRIPTION
-
-The B<send-uucp> program processes batch files written by innd(8) to send
-Usenet articles to UUCP sites.  It reads a configuration file to control how
-it behaves with various sites.  Normally, it's run periodically out of cron
-to put together batches and send them to remote UUCP sites.
-
-=head1 OPTIONS
-
-Any arguments provided to the program are interpreted as a list of sites
-specfied in F<send-uucp.cf> for which batches should be generated.  If no
-arguments are supplied then batches will be generated for all sites listed
-in that configuration file.
-
-=head1 CONFIGURATION
-
-The sites to which articles are to be sent must be configured in the
-configuration file F<send-uucp.cf>.  Each site is specified with a line of
-the form:
-
-    site[:host[:funnel]] [compressor [maxsize [batchtime]]]
-
-=over 4
-
-=item I<site>
-
-The news site name being configured.  This must match a site name 
-from newsfeeds(5).
-
-=item I<host>
-
-The UUCP host name to which batches should be sent for this site.
-If omitted, the news site name will be used as the UUCP host name.
-
-=item I<funnel>
-
-In the case of a site configured as a funnel, B<send-uucp> needs to flush
-the channel (or exploder) being used as the target of the funnel instead of
-flushing the site.  This is the way to tell B<send-uucp> the name of the
-channel or exploder to flush for this site.  If not specified, default to
-flushing the site.
-
-=item I<compressor>
-
-The compression method to use for batches.  This should be one of compress,
-gzip or none.  Arguments for the compression command may be specified by
-using C<_> instead of spaces. For example, C<gzip_-9>.  The default value is
-C<compress>.
-
-=item I<maxsize>
-
-The maximum size of a single batch before compression.  The default value is
-500,000 bytes.
-
-=item I<batchtime>
-
-A comma separated list of hours during which batches should be generated for
-a given site.  When B<send-uucp> runs, a site will only be processed if the
-current hour matches one of the hours in I<batchtime>.  The default is no
-limitation on when to generate batches.
-
-=back
-
-Fields are seperated by spaces and only the site name needs to be specified,
-with defaults being used for unspecified values.  If the first character on
-a line is a C<#> then the rest of the line is ignored.
-
-=head1 EXAMPLE
-
-Here is an example send-uucp.cf configuration file:
-
-    zoetermeer      gzip            1048576         5,18,22
-    hoofddorp       gzip            1048576         5,18,22
-    pa3ebv          gzip            1048576         5,18,22
-    drinkel         gzip            1048576         5,6,18,20,22,0,2
-    manhole         compress        1048576         5,18,22
-    owl             compress        1048576
-    able
-    pern::MYFUNNEL!
-
-This defines eight UUCP sites.  The first four use gzip compression and the
-last three use compress.  The first six use a batch size of 1MB, and the
-last site (able) uses the default of 500,000 bytes.  The zoetermeer,
-hoofddorp, pa3ebv, and manhole sites will only have batches generated for
-them during the hours of 05:00, 18:00, and 22:00, and the drinkel site will
-only have batches generated during those hours and 20:00, 00:00, and 02:00.
-There are no restrictions on when batches will be generated for owl or able.
-
-The pern site is configured as a funnel into C<MYFUNNEL!>.  B<send-uucp> will
-issue C<ctlinnd flush MYFUNNEL!> instead of C<ctlinnd flush pern>.
-
-=head1 FILES
-
-=over 4
-
-=item I<pathetc>/send-uucp.cf
-
-Configuration file specifying a list of sites to be processed.  
-
-=back
-
-=head1 NOTES
-
-The usual flags used for a UUCP feed in the I<newsfeeds> file are C<Tf,Wfb>.
-
-=head1 SEE ALSO
-
-innd(8), newsfeeds(5), uucp(8)
-
-=head1 AUTHOR
-
-This program was originally written by Edvard Tuinder <ed@elm.net> and then
-maintained and extended by Miquel van Smoorenburg <miquels@cistron.nl>.
-Marco d'Itri <md@linux.it> cleaned up the code for inclusion in INN.  This
-manual page was written by Mark Brown <broonie@sirena.org.uk>.
-
-=cut
diff --git a/backends/sendinpaths.in b/backends/sendinpaths.in
deleted file mode 100644 (file)
index aedf451..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-# fixscript will replace this line with code to load innshellvars
-#
-# Submit path statistics based on ninpaths
-# $Id: sendinpaths.in 5854 2002-11-25 17:53:06Z rra $
-
-# Assuming the ninpaths dump files are in ${MOST_LOGS}/path/inpaths.%d
-
-cd ${MOST_LOGS}/path
-ME=`${NEWSBIN}/innconfval pathhost`
-report=30
-keep=14
-TMP=""
-defaddr="pathsurvey@top1000.org top1000@anthologeek.net"
-
-# Renice to give other processes priority, since this isn't too important.
-renice 20 -p $$ > /dev/null
-
-# Make report from (up to) $report days of dumps
-LOGS=`find . -name 'inpaths.*' ! -size 0 -mtime -$report -print`
-if [ -z "$LOGS" ] ; then
-  echo "No data has been collected this month!"
-  exit 1
-fi
-
-# for check dumps
-for i in $LOGS
-do
- ninpaths -u $i -r $ME > /dev/null 2>&1
- if test $? -eq 0; then :
-  TMP="$TMP -u $i"
- fi
-done
-
-if [ "$1" = "-n" ] ; then
-  ninpaths $TMP -r $ME
-else
-  ninpaths $TMP -r $ME |\
-   $MAILCMD -s "inpaths $ME" ${1:-$defaddr}
-  # remove dumps older than $keep days
-  find . -name 'inpaths.*' -mtime +$keep -exec rm '{}' \;
-fi
-
-exit 0
diff --git a/backends/sendxbatches.in b/backends/sendxbatches.in
deleted file mode 100644 (file)
index ee8387b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-# $Id: sendxbatches.in 2674 1999-11-15 06:28:29Z rra $ 
-# By petri@ibr.cs.tu-bs.de with mods by libove@jerry.alf.dec.com
-#
-#  Script to send xbatches for a site, wrapped around innxbatch
-#  Invocation: sendxbatches <sitename> <hostname> <xbatch file name> ...
-#
-##  TODO: - we should check the amount of queued batches for the site,
-##          to prevent disk overflow due to unreachable sites.
-
-if [ $# -lt 3 ]
-then
-       echo "usage: $0 <sitename> <hostname> <xbatch file name>"
-       exit 1
-fi
-
-LOCK=${LOCKS}/LOCK.sendxbatches
-shlock -p $$ -f ${LOCK}
-if [ $? -ne 0 ]
-then
-       echo Locked by `cat ${LOCK}`
-       exit 1
-fi
-
-trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-site="$1"
-host="$2"
-shift; shift
-
-ctlinnd -s flush "$site"
-if [ $? -ne 0 ]
-then
-       echo "ctlinnd flush $site failed."
-       exit 1
-fi
-sleep 5
-$NEWSBIN/innxbatch -D -v "$host" $*
diff --git a/backends/shlock.c b/backends/shlock.c
deleted file mode 100644 (file)
index bb4c503..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*  $Id: shlock.c 6124 2003-01-14 06:03:29Z rra $
-**
-**  Produce reliable locks for shell scripts, by Peter Honeyman as told
-**  to Rich $alz.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-
-
-static bool    BinaryLock;
-
-
-/*
-**  See if the process named in an existing lock still exists by
-**  sending it a null signal.
-*/
-static bool
-ValidLock(char *name, bool JustChecking)
-{
-    int        fd;
-    int        i;
-    pid_t              pid;
-    char               buff[BUFSIZ];
-
-    /* Open the file. */
-    if ((fd = open(name, O_RDONLY)) < 0) {
-       if (JustChecking)
-           return false;
-        syswarn("cannot open %s", name);
-       return true;
-    }
-
-    /* Read the PID that is written there. */
-    if (BinaryLock) {
-       if (read(fd, (char *)&pid, sizeof pid) != sizeof pid) {
-           close(fd);
-           return false;
-       }
-    }
-    else {
-       if ((i = read(fd, buff, sizeof buff - 1)) <= 0) {
-           close(fd);
-           return false;
-       }
-       buff[i] = '\0';
-       pid = (pid_t) atol(buff);
-    }
-    close(fd);
-    if (pid <= 0)
-       return false;
-
-    /* Send the signal. */
-    if (kill(pid, 0) < 0 && errno == ESRCH)
-       return false;
-
-    /* Either the kill worked, or we're optimistic about the error code. */
-    return true;
-}
-
-
-/*
-**  Unlink a file, print a message on error, and exit.
-*/
-static void
-UnlinkAndExit(char *name, int x)
-{
-    if (unlink(name) < 0)
-        syswarn("cannot unlink %s", name);
-    exit(x);
-}
-
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: shlock [-u|-b] -f file -p pid\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    int        i;
-    char       *p;
-    int        fd;
-    char               tmp[BUFSIZ];
-    char               buff[BUFSIZ];
-    char               *name;
-    pid_t              pid;
-    bool               ok;
-    bool               JustChecking;
-
-    /* Establish our identity. */
-    message_program_name = "shlock";
-
-    /* Set defaults. */
-    pid = 0;
-    name = NULL;
-    JustChecking = false;
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "bcup:f:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'b':
-       case 'u':
-           BinaryLock = true;
-           break;
-       case 'c':
-           JustChecking = true;
-           break;
-       case 'p':
-           pid = (pid_t) atol(optarg);
-           break;
-       case 'f':
-           name = optarg;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if (ac || pid == 0 || name == NULL)
-       Usage();
-
-    /* Create the temp file in the same directory as the destination. */
-    if ((p = strrchr(name, '/')) != NULL) {
-       *p = '\0';
-       snprintf(tmp, sizeof(tmp), "%s/shlock%ld", name, (long)getpid());
-       *p = '/';
-    }
-    else
-       snprintf(tmp, sizeof(tmp), "shlock%ld", (long)getpid());
-
-    /* Loop until we can open the file. */
-    while ((fd = open(tmp, O_RDWR | O_CREAT | O_EXCL, 0644)) < 0)
-       switch (errno) {
-       default:
-           /* Unknown error -- give up. */
-            sysdie("cannot open %s", tmp);
-       case EEXIST:
-           /* If we can remove the old temporary, retry the open. */
-           if (unlink(tmp) < 0)
-                sysdie("cannot unlink %s", tmp);
-           break;
-       }
-
-    /* Write the process ID. */
-    if (BinaryLock)
-       ok = write(fd, &pid, sizeof pid) == sizeof pid;
-    else {
-       snprintf(buff, sizeof(buff), "%ld\n", (long) pid);
-       i = strlen(buff);
-       ok = write(fd, buff, i) == i;
-    }
-    if (!ok) {
-        syswarn("cannot write PID to %s", tmp);
-       close(fd);
-       UnlinkAndExit(tmp, 1);
-    }
-
-    close(fd);
-
-    /* Handle the "-c" flag. */
-    if (JustChecking) {
-       if (ValidLock(name, true))
-           UnlinkAndExit(tmp, 1);
-       UnlinkAndExit(tmp, 0);
-    }
-
-    /* Try to link the temporary to the lockfile. */
-    while (link(tmp, name) < 0)
-       switch (errno) {
-       default:
-           /* Unknown error -- give up. */
-            syswarn("cannot link %s to %s", tmp, name);
-           UnlinkAndExit(tmp, 1);
-           /* NOTREACHED */
-       case EEXIST:
-           /* File exists; if lock is valid, give up. */
-           if (ValidLock(name, false))
-               UnlinkAndExit(tmp, 1);
-           if (unlink(name) < 0) {
-                syswarn("cannot unlink %s", name);
-               UnlinkAndExit(tmp, 1);
-           }
-       }
-
-    UnlinkAndExit(tmp, 0);
-    /* NOTREACHED */
-    return 1;
-}
diff --git a/backends/shrinkfile.c b/backends/shrinkfile.c
deleted file mode 100644 (file)
index 7702ff2..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*  $Id: shrinkfile.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Shrink files on line boundaries.
-**
-**  Written by Landon Curt Noll <chongo@toad.com>, and placed in the
-**  public domain.  Rewritten for INN by Rich Salz.
-**
-**  Usage:
-**     shrinkfile [-n] [-s size [-m maxsize]] [-v] file...
-**     -n              No writes, exit 0 if any file is too large, 1 otherwise
-**     -s size         Truncation size (0 default); suffix may be k, m,
-**                     or g to scale.  Must not be larger than 2^31 - 1.
-**     -m maxsize      Maximum size allowed before truncation.  If maxsize
-**                     <= size, then it is reset to size.  Default == size.
-**     -v              Print status line.
-**
-**  Files will be shrunk an end of line boundary.  In no case will the
-**  file be longer than size bytes if it was longer than maxsize bytes.  
-**  If the first line is longer than the absolute value of size, the file 
-**  will be truncated to zero length.
-**
-**  The -n flag may be used to determine of any file is too large.  No
-**  files will be altered in this mode.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-#define MAX_SIZE       0x7fffffffUL
-
-
-/*
-**  Open a safe unique temporary file that will go away when closed.
-*/
-static FILE *
-OpenTemp(void)
-{
-    FILE       *F;
-    char        *filename;
-    int                fd;
-
-    filename = concatpath(innconf->pathtmp, "shrinkXXXXXX");
-    fd = mkstemp(filename);
-    if (fd < 0)
-        sysdie("cannot create temporary file");
-    F = fdopen(fd, "w+");
-    if (F == NULL)
-        sysdie("cannot fdopen %s", filename);
-    unlink(filename);
-    free(filename);
-    return F;
-}
-
-
-/*
-**  Does file end with \n?  Assume it does on I/O error, to avoid doing I/O.
-*/
-static int
-EndsWithNewline(FILE *F)
-{
-    int                c;
-
-    if (fseeko(F, 1, SEEK_END) < 0) {
-        syswarn("cannot seek to end of file");
-       return true;
-    }
-
-    /* return the actual character or EOF */
-    if ((c = fgetc(F)) == EOF) {
-       if (ferror(F))
-            syswarn("cannot read last byte");
-       return true;
-    }
-    return c == '\n';
-}
-
-
-/*
-**  Add a newline to location of a file.
-*/
-static bool
-AppendNewline(char *name)
-{
-    FILE       *F;
-
-    if ((F = xfopena(name)) == NULL) {
-        syswarn("cannot add newline");
-       return false;
-    }
-
-    if (fputc('\n', F) == EOF
-     || fflush(F) == EOF
-     || ferror(F)
-     || fclose(F) == EOF) {
-        syswarn("cannot add newline");
-       return false;
-    }
-
-    return true;
-}
-
-/*
-**  Just check if it is too big
-*/
-static bool
-TooBig(FILE *F, off_t maxsize)
-{
-    struct stat        Sb;
-
-    /* Get the file's size. */
-    if (fstat((int)fileno(F), &Sb) < 0) {
-        syswarn("cannot fstat");
-       return false;
-    }
-
-    /* return true if too large */
-    return (maxsize > Sb.st_size ? false : true);
-}
-
-/*
-**  This routine does all the work.
-*/
-static bool
-Process(FILE *F, char *name, off_t size, off_t maxsize, bool *Changedp)
-{
-    off_t      len;
-    FILE       *tmp;
-    struct stat        Sb;
-    char       buff[BUFSIZ + 1];
-    int                c;
-    size_t     i;
-    bool       err;
-
-    /* Get the file's size. */
-    if (fstat((int)fileno(F), &Sb) < 0) {
-        syswarn("cannot fstat");
-       return false;
-    }
-    len = Sb.st_size;
-
-    /* Process a zero size request. */
-    if (size == 0 && len > maxsize) {
-       if (len > 0) {
-           fclose(F);
-           if ((F = fopen(name, "w")) == NULL) {
-                syswarn("cannot overwrite");
-               return false;
-           }
-           fclose(F);
-           *Changedp = true;
-       }
-       return true;
-    }
-
-    /* See if already small enough. */
-    if (len <= maxsize) {
-       /* Newline already present? */
-       if (EndsWithNewline(F)) {
-           fclose(F);
-           return true;
-       }
-
-       /* No newline, add it if it fits. */
-       if (len < size - 1) {
-           fclose(F);
-           *Changedp = true;
-           return AppendNewline(name);
-       }
-    }
-    else if (!EndsWithNewline(F)) {
-       if (!AppendNewline(name)) {
-           fclose(F);
-           return false;
-       }
-    }
-
-    /* We now have a file that ends with a newline that is bigger than
-     * we want.  Starting from {size} bytes from end, move forward
-     * until we get a newline. */
-    if (fseeko(F, -size, SEEK_END) < 0) {
-        syswarn("cannot fseeko");
-       fclose(F);
-       return false;
-    }
-
-    while ((c = getc(F)) != '\n')
-       if (c == EOF) {
-            syswarn("cannot read");
-           fclose(F);
-           return false;
-       }
-
-    /* Copy rest of file to temp. */
-    tmp = OpenTemp();
-    err = false;
-    while ((i = fread(buff, 1, sizeof buff, F)) > 0)
-       if (fwrite(buff, 1, i, tmp) != i) {
-           err = true;
-           break;
-       }
-    if (err) {
-        syswarn("cannot copy to temporary file");
-       fclose(F);
-       fclose(tmp);
-       return false;
-    }
-
-    /* Now copy temp back to original file. */
-    fclose(F);
-    if ((F = fopen(name, "w")) == NULL) {
-        syswarn("cannot overwrite file");
-       fclose(tmp);
-       return false;
-    }
-    fseeko(tmp, 0, SEEK_SET);
-
-    while ((i = fread(buff, 1, sizeof buff, tmp)) > 0)
-       if (fwrite(buff, 1, i, F) != i) {
-           err = true;
-           break;
-       }
-    if (err) {
-        syswarn("cannot overwrite file");
-       fclose(F);
-       fclose(tmp);
-       return false;
-    }
-
-    fclose(F);
-    fclose(tmp);
-    *Changedp = true;
-    return true;
-}
-
-
-/*
-**  Convert size argument to numeric value.  Return -1 on error.
-*/
-static off_t
-ParseSize(char *p)
-{
-    off_t      scale;
-    unsigned long      str_num;
-    char       *q;
-
-    /* Skip leading spaces */
-    while (ISWHITE(*p))
-       p++;
-    if (*p == '\0')
-       return -1;
-
-    /* determine the scaling factor */
-    q = &p[strlen(p) - 1];
-    switch (*q) {
-    default:
-       return -1;
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-       scale = 1;
-       break;
-    case 'k': case 'K':
-       scale = 1024;
-       *q = '\0';
-       break;
-    case 'm': case 'M':
-       scale = 1024 * 1024;
-       *q = '\0';
-       break;
-    case 'g': case 'G':
-       scale = 1024 * 1024 * 1024;
-       *q = '\0';
-       break;
-    }
-
-    /* Convert string to number. */
-    if (sscanf(p, "%lud", &str_num) != 1)
-       return -1;
-    if (str_num > MAX_SIZE / scale)
-        die("size is too big");
-
-    return scale * str_num;
-}
-
-
-/*
-**  Print usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr,
-            "Usage: shrinkfile [-n] [ -m maxsize ] [-s size] [-v] file...");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    bool       Changed;
-    bool       Verbose;
-    bool       no_op;
-    FILE       *F;
-    char       *p;
-    int                i;
-    off_t      size = 0;
-    off_t      maxsize = 0;
-
-    /* First thing, set up our identity. */
-    message_program_name = "shrinkfile";
-
-    /* Set defaults. */
-    Verbose = false;
-    no_op = false;
-    umask(NEWSUMASK);
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "m:s:vn")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'n':
-           no_op = true;
-           break;
-       case 'm':
-           if ((maxsize = ParseSize(optarg)) < 0)
-               Usage();
-           break;
-       case 's':
-           if ((size = ParseSize(optarg)) < 0)
-               Usage();
-           break;
-       case 'v':
-           Verbose = true;
-           break;
-       }
-    if (maxsize < size) {
-       maxsize = size;
-    }
-    ac -= optind;
-    av += optind;
-    if (ac == 0)
-       Usage();
-
-    while ((p = *av++) != NULL) {
-       if ((F = fopen(p, "r")) == NULL) {
-            syswarn("cannot open %s", p);
-           continue;
-       }
-
-       /* -n (no_op) or normal processing */
-       if (no_op) {
-
-           /* check if too big and exit zero if it is */
-           if (TooBig(F, maxsize)) {
-               if (Verbose)
-                    notice("%s is too large", p);
-               exit(0);
-               /* NOTREACHED */
-           }
-
-       /* no -n, do some real work */
-       } else {
-           Changed = false;
-           if (!Process(F, p, size, maxsize, &Changed))
-                syswarn("cannot shrink %s", p);
-           else if (Verbose && Changed)
-                notice("shrunk %s", p);
-       }
-    }
-    if (no_op && Verbose) {
-        notice("did not find a file that was too large");
-    }
-
-    /* if -n, then exit non-zero to indicate no file too big */
-    exit(no_op ? 1 : 0);
-    /* NOTREACHED */
-}
diff --git a/contrib/Makefile b/contrib/Makefile
deleted file mode 100644 (file)
index f09ab09..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-##  $Id: Makefile 6299 2003-04-20 19:04:14Z vinocur $
-##
-##  There are no installation rules or other top-level rules for this
-##  directory as it's not properly part of INN.  Installation should be
-##  done by the user by hand for those files that they're interested in.
-
-include ../Makefile.global
-
-top           = ..
-CFLAGS        = $(GCFLAGS)
-
-ALL          = archivegz backlogstat backupfeed cleannewsgroups delayer \
-               findreadgroups makeexpctl makestorconf mlockfile newsresp \
-               pullart reset-cnfs respool showtoken stathist thdexpire \
-               tunefeed
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-clean clobber distclean:
-       rm -f *.o $(ALL)
-       rm -rf .libs
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Compilation rules.
-
-LINK           = $(LIBLD) $(LDFLAGS) -o $@
-FIX            = $(FIXSCRIPT)
-
-STORELIBS      = $(LIBSTORAGE) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
-
-expirectl:     expirectl.o     ; $(LINK) expirectl.o
-mlockfile:     mlockfile.o     ; $(LINK) mlockfile.o
-newsresp:      newsresp.o      ; $(LINK) newsresp.o $(LIBS)
-pullart:       pullart.o       ; $(LINK) pullart.o $(LIBINN)
-reset-cnfs:    reset-cnfs.o    ; $(LINK) reset-cnfs.o
-respool:       respool.o       ; $(LINK) respool.o $(STORELIBS)
-
-archivegz:       archivegz.in       $(FIX) ; $(FIX) -i archivegz.in
-backlogstat:     backlogstat.in     $(FIX) ; $(FIX) backlogstat.in
-backupfeed:      backupfeed.in      $(FIX) ; $(FIX) -i backupfeed.in
-cleannewsgroups: cleannewsgroups.in $(FIX) ; $(FIX) cleannewsgroups.in
-delayer:         delayer.in         $(FIX) ; $(FIX) -i delayer.in
-findreadgroups:  findreadgroups.in  $(FIX) ; $(FIX) findreadgroups.in
-makeexpctl:      makeexpctl.in      $(FIX) ; $(FIX) makeexpctl.in
-makestorconf:    makestorconf.in    $(FIX) ; $(FIX) makestorconf.in
-showtoken:       showtoken.in       $(FIX) ; $(FIX) -i showtoken.in
-stathist:        stathist.in        $(FIX) ; $(FIX) -i stathist.in
-thdexpire:       thdexpire.in       $(FIX) ; $(FIX) thdexpire.in
-tunefeed:        tunefeed.in        $(FIX) ; $(FIX) -i tunefeed.in
diff --git a/contrib/README b/contrib/README
deleted file mode 100644 (file)
index e7e8866..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-This directory contains unsupported contributions to INN.  Most of these
-programs are of interest to a limited set of sites, require some manual
-modifications to make work, and/or are separately maintained independent
-of INN.  Programs in here may or may not have been tested on the latest
-version of INN, so keep that in mind when trying them out.  The INN
-developers may not be able to answer bug reports for these utilities; it's
-best to send them to the original author.
-
-Volunteers who would like to take particularly useful applications in this
-directory and make them suitable for inclusion in INN proper are heartily
-encouraged, but discuss this on inn-workers@isc.org.  Sometimes there's a
-reason why this hasn't already been done or something specific that's
-needed before they can be included.
-
-Type "make <program>" to build any of the following programs and then copy
-the binary to somewhere on your PATH to use it.  For details on what each
-program does, see below, as well as the comments at the beginning of each
-file (if any).
-
-In addition to these files, also see the contrib section of the INN FTP
-site at <ftp://ftp.isc.org/isc/inn/contrib/> for more software designed
-to work with INN.
-
-                        -------------------------
-
-archivegz
-
-    A compressing version of archive, writing out .gz files instead of
-    plain text files.  May not work with the storage API without some
-    changes to use sm.
-
-backlogstat
-
-    Prints informations about the current state of innfeed's backlog, if
-    any.
-
-backupfeed
-
-    Another version of suck or pullnews that downloads posts from a remote
-    news server and offers them to the local news server.
-
-cleannewsgroups
-
-    Performs various cleanups on the newsgroups file.
-
-count_overview.pl
-
-    Counts the groups in a bunch of Xref records.
-
-delayer
-
-    Sits in a data stream and delays it by some constant period of time.
-    Mostly useful for delaying innfeed feeds to allow cancels a chance to
-    remove articles before innfeed sends them to your peers.  See the
-    beginning of the file for an example of how to use it.
-
-expirectl
-
-    Automatically builds expire.ctl based on current available disk space
-    and a template, adjusting the expiration times of groups based on a
-    weight and the available space.  Uses a template expire.ctl.ctl file;
-    see the end of expirectl.c for a sample.
-
-findreadgroups
-
-    Scans the news log files and generates a file giving readership counts
-    by newsgroup.  Used by makeexpctl and makestorconf.
-
-fixhist
-
-    Performs various cleanups and sanity checks on the history database.
-
-innconfcheck
-
-    Merges your inn.conf settings with the inn.conf man page to make it
-    easier to be sure that your settings match what you want.  Edit this
-    script to add the correct paths to the man page; see the comments at
-    the beginning of this script.
-
-makeexpctl
-
-    Generates an expire.ctl based on what newsgroups are actually read.
-    Uses data generated by findreadgroups.  This script will require
-    editing before being usable for your server.
-
-makestorconf
-
-    Generates a storage.conf file putting frequently read newsgroups into
-    timecaf rather than CNFS.  Uses data gefnerated by findreadgroups.
-    This script will require editing before being usable for your server.
-
-mkbuf
-
-    Creates a CNFS cycbuff; see the comments at the beginning of
-    this script.
-
-mlockfile
-
-    Locks files given on the command line into memory using mlock (only
-    tested on Solaris).  Useful primarily for locking the history files
-    (history.hash and history.index) into memory on a system with
-    sufficient memory to speed history lookups in innd.  This seems to
-    help some systems quite a lot and others not at all.
-
-newsresp
-
-    Opens an NNTP channel to a server and takes a peek at various response
-    times.  Can check the round-trip time and the history lookup time.
-    See the comments at the beginning of the source for more details.
-
-pullart
-
-    Attempts to pull news articles out of CNFS cycbuffs.  Useful for
-    emergency recoveries.
-
-reset-cnfs
-
-    Clears a CNFS cycbuff; see the comments at the beginning of
-    this script.
-
-respool
-
-    Takes a list of tokens on stdin and respools them, by retrieving the
-    article, storing it again, and then calling SMcancel on the previous
-    instance of the article.  Note that after running this program, you'd
-    need to rebuild the history and overview, since it doesn't update
-    either.
-
-showtoken
-
-    Decodes storage API tokens.
-
-stathist
-
-    Parses and summarizes the log files created by the history profiling
-    code.
-
-thdexpire
-
-    A dynamic expire daemon for timehash and timecaf spools.  It should
-    be started along with innd and periodically looks if news spool space
-    is getting tight, and then frees space by removing articles until
-    enough is free.  It is an adjunct to (not a replacement for) INN's
-    expire program.
-
-tunefeed
-
-    Given two active files, attempts to produce a good set of wildmat
-    patterns for newsfeeds to minimize the number of rejects.  For full
-    documentation, run "perldoc tunefeed".
diff --git a/contrib/archivegz.in b/contrib/archivegz.in
deleted file mode 100644 (file)
index e4f06b7..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/bin/perl
-# Copyright 1999 Stephen M. Benoit, Service Providers of America.
-#  See notice at end of this file.
-#
-# Filename: archivegz.pl
-# Author: Stephen M. Benoit (benoits@servicepro.com)
-# Created: Wed Apr 14 13:56:01 1999
-# Version: $Id: archivegz.in 4329 2001-01-14 13:47:52Z rra $
-#
-$RCSID='$Id: archivegz.in 4329 2001-01-14 13:47:52Z rra $ ';
-
-# Specify command line options, and decode the command line.
-
-require 'newgetopt.pl';
-require 'newusage.pl';
-@opts =
-  (
-   "help|usage;;print this message",
-   "version;;print version",
-   "a=s;;directory to archive in instead of the default",
-   "f;;directory names will be flattened out",
-   "i=s;;append one line to the index file for each article (Destination name, Message ID, Subject)",
-   "m;; Files are copied by making a link.  Not applicable, ignored",
-   "r;;Suppress stderr redirection to /var/log/news/errlog",
-   "n=s;;the news spool (source) directory (default=/var/spool/news/)",
-   "t=i;;timeout that separates batches (default 10 seconds)",
-   ";;input",
-   # Examples. 
-   # 
-   # "OPT;;Option without an argument",
-   # "OPT!;;Negatable option without an argument",
-   # "VAR=T;;Option with mandatory argumet T = s(tring),i(nteger), or f(loat).
-   # "VAR:T;;Option with optional argument.
-   # "OPT|AAA|BBB";;AAA and BBB are aliases for OPT",
-   # "VAR=T@";;Push option argument onto array @opt_VAR"
-  );
-$ignorecase = 0;
-$badopt = !&NGetOpt(&NMkOpts(@opts));
-# $badarg = (@ARGV != 0);
-if ($badarg || $badopt || $opt_help)
-  {
-    &NUsage($0,0,'',@opts);
-    exit ($badopt||$badarg);
-  } 
-if ($opt_version) {print STDERR "$RCSID\n"; exit 0}
-
-# --------------------------------------------------------------------
-
-# --- constants and defaults ---
-$NEWS_ROOT = "/var/spool/news/";
-$NEWS_ERR = "/var/log/news/errlog";
-$NEWS_ARCHIVE = $NEWS_ROOT . "news.archive/";
-$timeout = 10;
-if ($opt_t)
-  { $timeout = $opt_t;}
-if ($timeout<1) {$timeout=1;}
-
-# --------------------------------------------------------------------
-
-sub regexp_escape
-  {
-    local($data)=@_;
-
-    $data =~ s+\\+\\\\+gi; # replace \ with \\
-    $data =~ s+\/+\\\/+gi; # replace / with \/
-
-    $data =~ s/([\+\*\?\[\]\(\)\{\}\.\|])/\\$1/gi; # replace +*?[](){}.|
-
-    return $data;
-  }
-
-sub fhbits {
-  local(@fhlist) = split(' ',$_[0]);
-  local($bits);
-  for (@fhlist) {
-    vec($bits,fileno($_),1) = 1;
-  }
-  $bits;
-}
-
-sub timed_getline
-  {
-    my ($fileh,$timeout)=@_;
-    my $filehandle = (ref($fileh)
-                     ? (ref($fileh) eq 'GLOB'
-                        || UNIVERSAL::isa($fileh, 'GLOB')
-                        || UNIVERSAL::isa($fileh, 'IO::Handle'))
-                     : (ref(\$fileh) eq 'GLOB'));
-    local(*FILEH) = *$fileh{FILEHANDLE};
-
-    local($rin,$win,$ein);
-    local($rout,$wout,$eout);
-    $rin = $win = $ein = '';
-    $rin = fhbits('FILEH');
-    $ein = $rin | $win;
-    local($nfound);
-    local($offset)=0;
-    local($accum)='';
-    local($done)=0;
-    local($result);
-
-    $nfound = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
-
-    if ($nfound>0)
-      {
-       
-       # use sysread() to get characters up to end-of-line (incl.)
-       while (!$done)
-         {
-           $result = sysread(FILEH, $accum, 1, $offset);
-           if ($result<=0)
-             {
-               $done=1;
-               return undef;
-             }
-
-           if (substr($accum,$offset,1) eq "\n")
-             {
-               $done=1;
-             }
-           else
-             {
-               $offset+=$result;
-             }
-         }
-      }
-    return $accum;
-  }
-
-# --------------------------------------------------------------------
-
-# --- source spool directory ---
-if ($opt_n)
-  {
-    if ($opt_n !~ /^\//) # absolute path?
-      { $opt_n = $NEWS_ROOT . $opt_n; }
-    if ($opt_n !~ /\/$/) # must end with /
-      { $opt_n .= '/'; }
-    $NEWS_ROOT = $opt_n;
-  }
-
-# --- archive directory ---
-if ($opt_a)
-  {
-    if ($opt_a !~ /^\//) # absolute path?
-      { $opt_a = $NEWS_ROOT . $opt_a; }
-    if ($opt_a !~ /\/$/) # must end with /
-      { $opt_a .= '/'; }
-    $NEWS_ARCHIVE = $opt_a;
-  }
-
-# --- redirect stderr ---
-if (!$opt_r)
-  {
-    open(SAVEERR, ">&STDERR");
-    open(STDERR, ">>$NEWS_ERR") || die "Can't redirect stderr";
-  }
-
-# --- get input file opened ---
-if ($infilename=shift(@ARGV))
-  {
-    if ($infilename !~ /^\//) # absolute filename? 
-      {
-       $infilename = $NEWS_ROOT . $infilename;
-      }
-
-  }
-else
-  {
-    $infilename="-";
-  }
-open(INFILE,"<$infilename");
-
-$done=0;
-while (!$done)
-  {
-    %sourcefile=();
-    %destfile=();
-    %destname=();
-
-    
-    # --- loop over each line in infile ---
-    # comments start with '#', ignore blank lines, each line is a filename
-    while ($srcfile = &timed_getline(INFILE,$timeout))
-    {
-      if ($srcfile =~ /\#/) {$srcfile = $`;}
-      if ($srcfile =~ /^\s*/) {$srcfile = $';}
-      if ($srcfile =~ /\s*$/) {$srcfile = $`;}
-      if ($srcfile)  # if a filename survived all that...
-       {
-         if ($srcfile !~ /^\//) # absolute filename?
-           {
-             $srcfile = $NEWS_ROOT . $srcfile;
-           }
-         # $srcfile is now a valid, absolute filename
-         # split filename into news directory, newsgroup and article number
-         $artnum=-1;
-         $remaining=$srcfile;
-         if ($remaining =~ /\/(\d*)$/) # remove / and article number
-           { $artnum = $1; $remaining=$`;}
-         $regex = &regexp_escape($NEWS_ROOT);
-         if ($remaining =~ /^$regex/) # split off news dir
-           { $newsdir = $&; $grpdir = $';}
-         else
-           { $newsdir = ''; $grpdir = $remaining; } # ... otherwise, grp = dir
-         $newsgrp = $grpdir;
-         $newsgrp =~ s/\//\./g; # replace slash (/) with dot (.)
-         if ($opt_f)
-           {
-             $grpdir = "$newsgrp.gz";
-           }
-         else
-           { $grpdir .= "/archive.gz"; }
-         $destfile = $NEWS_ARCHIVE . $grpdir;
-
-         # print STDERR "$srcfile --> $newsgrp --> $destfile\n";
-         if ($sourcefile{$newsgrp}) {$sourcefile{$newsgrp} .= " ";}
-         $sourcefile{$newsgrp} .= $srcfile;
-         $destfile{$newsgrp} = $destfile;
-         $destname{$newsgrp} = $grpdir;
-       }
-    }
-
-    # --- is there anything to do at this time? ---
-    if (%destfile)
-      {
-
-       # --- open INDEX ---
-       if ($opt_i)
-         {
-           # make sure directory exists
-           if ($opt_i =~ /\/[^\/]*$/)
-             {
-               $dirbase=$`;
-               system("mkdir -p $dirbase");
-             }
-           open(INDEX,">>$opt_i");
-         }
-
-       # --- make sure that archive file can be written (make parent dirs) ---
-       if ($destfile{$group} =~ /\/[^\/]*$/)
-         {
-           $dirbase=$`;
-           system("mkdir -p $dirbase");
-         }
-
-       # --- process each article ---
-       foreach $group (keys(%destfile))
-         {
-           # --- gzip the concatenated document, appending archive file ---
-           open(GZIP, "|gzip -c >> $destfile{$group}") || die "Can't open gzip";
-           
-           # --- concatenate the articles, keeping header info if needed ---
-           @accum_headers=();
-           foreach $srcfile (split(/\s+/, $sourcefile{$group}))
-             {
-               # print STDERR "reading $srcfile...\n";
-               $this_doc='';
-               open(DOC, "<$srcfile");
-               while ($line=<DOC>)
-                 {
-                   $this_doc .= $line;
-                 }
-               close(DOC);
-               print GZIP $this_doc;
-               if ($opt_i)
-                 {
-                   # --- get header information and store it in index
-                   $subject=''; $mesageid=''; $destname='';
-                   if ($this_doc =~ /Subject:\s*(.*)/)
-                     { $subject = $1; }
-                   if ($subject =~ /^\s*/) {$subject = $';}
-                   if ($subject =~ /\s*$/) {$subject = $`;}
-                   if ($this_doc =~ /Message-ID:\s*(.*)/)
-                     {$messageid = $1; }
-                   if ($messageid =~ /^\s*/) {$messageid = $';}
-                   if ($messageid =~ /\s*$/) {$messageid = $`;}
-                   
-                   print INDEX "$destname{$group} $messageid $subject\n";
-                 }
-             }
-           
-           close(GZIP);
-         }
-
-       # --- close index file ---
-       if ($opt_i)
-         {
-           close(INDEX);
-         }
-      }
-
-    if (!defined($srcfile)) # file was closed
-      {
-       $done=1;
-       last;  # "break"
-      }
-    
-  }
-
-# --- restore stderr ---
-if (!$opt_r)
-  {
-    close(STDERR);
-    open(STDERR,">>&SAVEERR");
-  }
-
-# --- close input file ---
-close(INFILE);
-
-
-__END__
-# Local Variables:
-# mode: perl
-# End:
-
-# Copyright 1999 Stephen M. Benoit, Service Providers of America (SPA).
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose without fee is hereby granted without fee,
-# provided that the above copyright notice appear in all copies and that both
-# that copyright notice and this permission notice appear in supporting
-# documentation, and that the name of SPA not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  SPA makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
-# 
-# SPA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
-# SPA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
-# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/contrib/auth_pass.README b/contrib/auth_pass.README
deleted file mode 100644 (file)
index 6919fb2..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-This directory contains sample authorization programs for use with the
-'authinfo generic' command in nnrpd.
-
-The first program in here is from Doug Needham I have successfully
-tested this program when connecting to nnrpd by hand, but I've not
-taken the time to figure out how to get my newsreader to use
-'authinfo generic'.  There is no Makefile here and no serious
-testing of it, so it's not integrated. If you have success using
-it and care to share what you've done. Please drop me a note
-(<inn@isc.org>). Thanks.
-
-
----------------------------------------------------------------------------
-
-Replied: Fri, 26 Jul 1996 19:29:17 +0200
-Replied: Douglas Wade Needham <dneedham@dneedham.inhouse.compuserve.com>
-Received: by gw.home.vix.com id UAA05867; Thu, 25 Jul 1996 20:45:27 -0700 (PDT)
-Received: (from dneedham@localhost) by dneedham.inhouse.compuserve.com (8.7.4/8.6.9) id XAA21103; Thu, 25 Jul 1996 23:45:25 -0400 (EDT)
-From: Douglas Wade Needham <dneedham@dneedham.inhouse.compuserve.com>
-Message-Id: <199607260345.XAA21103@dneedham.inhouse.compuserve.com>
-Subject: A sample program for authinfo generic (for inn 1.5)
-To: inn-workers@vix.com (INN Gurus/Workers)
-Date: Thu, 25 Jul 1996 23:45:25 -0400 (EDT)
-Cc: inn@isc.org, brister@vix.com (James A. Brister)
-X-Mailer: ELM [version 2.4 PL25]
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary=%#%record%#%
-Status: U
-
---%#%record%#%
-Content-Type: text/plain; charset=US-ASCII
-Content-Transfer-Encoding: 7bit
-Content-Length: 1894      
-
-Hi folks...
-
-Finally started to get some time to clear some things from my todo list...Here
-is a sample program which can be used by "authinfo generic" to validate a user
-against the password file on the news host.  While not a great example, it does
-demonstrate how you can write an authentication program.  All I ask is that
-credit be given.
-
-A couple of notes that I have found out about these programs for those of you
-who may be interested in writing your own...
-
-1) These programs have stdin and stdout connected all the way back to the
-   reader, so they can carry on a dialog in whatever fashion they want to 
-   with the user's news reader.  This can include passing Kerberos tickets,
-   encrypted or hashed passwords, or doing a challenge-response type session
-   for authenticating the user rather than passing the password in clear-text 
-   across the network.
-
-2) Regardless of the outcome, the authentication program must send NNRPD a
-   record such as is found in nnrp.access by writing it to stderr.
-
-3) Successful authentication is indicated by a zero exit status, and
-   unsuccessful authentication is indicated by a non-zero exit status.
-
-4) Need I say it (again)...these programs can be a security hole unless care is
-   taken to avoid SUID programs and those that transmit/recieve passwords in
-   the clear (especially those that use login passwords).  We should give some
-   thought to doing a similiar program for Kerberos authentication (what sort
-   of instance should we use???) and other authentication methods such as
-   Compuserve's Distributed Authentication (guess I should do this one once the
-   standard is finialized with the IETF 8) ).
-
-Also, a question for the list as a whole... what readers easily support
-authinfo generic (including running a program at the reader's end to do things
-like challenge-response)???
-
-Well...here it is...enjoy 8)...
-
-- doug
-
-#### See auth_pass.c #####
diff --git a/contrib/auth_pass.c b/contrib/auth_pass.c
deleted file mode 100644 (file)
index 7ecf0a1..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *      auth_pass.c  ( $Revision: 6141 $ )
- *
- * Abstract: 
- *
- *     This module is the complete source for a sample "authinfo generic" 
- *     program.  This program takes a user's login name and password
- *     (supplied either as arguments or as responses to prompts) and
- *     validates them against the contents of the password database.  
- *
- *     If the user properly authenticates themselves, a nnrp.auth style
- *     record indicating the user's authenticated login and permitting
- *     reading and posting to all groups is output on stderr (for reading by
- *     nnrpd) and the program exits with a 0 status.  If the user fails to
- *     authenticate, then a record with the attempted login name and no
- *     access is output on stderr and a non-zero exit status is returned.
- *
- * Exit statuses:
- *     0       Successfully authenticated.
- *     1       getpeername() failed, returned a bad address family, or 
- *             gethostbyaddr() failed.
- *     2       Entry not found in password file.
- *     3       No permission to read passwords, or password field is '*'.
- *     4       Bad password match.
- *
- * Environment:
- *     Run by nnrpd with stdin/stdout connected to the reader and stderr
- *     connected back to nnrpd.  This program will need to be run as suid
- *     root on systems where passwords are stored in a file readable only by
- *     root. 
- *
- * Written 1996 July 6 by Douglas Wade Needham (dneedham@oucsace.cs.ohiou.edu).
- *     
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <netdb.h>
-#include <pwd.h>
-
-\f
-main(int argc, char** argv)
-/*+
- * Abstract:
- *     Main routine of the program, implementing all prompting, validation, 
- *     and status returns.
- *
- * Arguments:
- *     argc            Argument count.
- *     argv            Null terminated argument vector.
- *
- * Returns:
- *      Exits according to program status values.
- *
- * Variables:
- *     hp              Pointer to host entry.
- *     length          General integer variable
- *     password        Password given by user.
- *     peername        Hostname of the peer.
- *     pwd             Pointer to entry from passwd file.
- *     sin             Socket address structure.
- *     username        User's login name.
- */
-{
-    struct hostent *   hp;
-    int                        length;
-    char               password[256];
-    char               peername[1024];
-    struct passwd *    pwd;
-    struct sockaddr_in sin;
-    char               username[32];
-
-    /*
-     * Get the user name and password if needed.  
-     */
-    if (argc<2) {
-        fprintf(stdout, "Username: "); fflush(stdout);
-        fgets(username, sizeof(username), stdin);
-    } else {
-        strlcpy(username, argv[1], sizeof(username));
-    }
-    if (argc<3) {
-        fprintf(stdout, "Password: "); fflush(stdout);
-        fgets(password, sizeof(password), stdin);
-    } else {
-        strlcpy(password, argv[2], sizeof(password));
-    }
-    
-    /*
-     *  Strip CR's and NL's from the end.
-     */
-    length = strlen(username)-1;
-    while (username[length] == '\r' || username[length] == '\n') {
-        username[length--] = '\0';
-    }
-    length = strlen(password)-1;
-    while (password[length] == '\r' || password[length] == '\n') {
-        password[length--] = '\0';
-    }
-
-    /*
-     *  Get the hostname of the peer.
-     */
-    length = sizeof(sin);
-    if (getpeername(0, (struct sockaddr *)&sin, &length) < 0) {
-        if (!isatty(0)) {
-            fprintf(stderr, "cant getpeername()::%s:+:!*\n", username);
-            exit(1);
-        }
-        strlcpy(peername, "stdin", sizeof(peername));
-    } else if (sin.sin_family != AF_INET) {
-        fprintf(stderr, "Bad address family %ld::%s:+:!*\n",
-                (long)sin.sin_family, username);
-        exit(1);
-    } else if ((hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET)) == NULL) {
-        strlcpy(peername, inet_ntoa(sin.sin_addr), sizeof(peername));
-    } else {
-        strlcpy(peername, hp->h_name, sizeof(peername));
-    }
-   
-    /*
-     *  Get the user name in the passwd file.
-     */
-    if ((pwd = getpwnam(username)) == NULL) {
-
-        /*
-         *  No entry in the passwd file.
-         */
-        fprintf(stderr, "%s::%s:+:!*\n", peername, username);
-        exit(2);
-    }
-
-    /*
-     *  Make sure we managed to read in the password.
-     */
-    if (strcmp(pwd->pw_passwd, "*")==0) {
-
-        /*
-         *  No permission to read passwords.
-         */
-        fprintf(stderr, "%s::%s:+:!*\n", peername, username);
-        exit(3);
-    }
-
-    /*
-     *  Verify the password.
-     */
-    if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd))!=0) {
-
-        /*
-         * Password was invalid.
-         */
-        fprintf(stderr, "%s::%s:+:!*\n", peername, username);
-        exit(4);
-    }
-
-    /*
-     *  We managed to authenticate the user.
-     */
-    fprintf(stderr, "%s:RP:%s:+:*\n", peername, username);
-    exit(0);
-}
diff --git a/contrib/backlogstat.in b/contrib/backlogstat.in
deleted file mode 100644 (file)
index 70da166..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# backlogstat - display backlog to sites
-# based on bklog by bill davidsen <davidsen@tmr.com>
-
-# breaks if backlog-directory in innfeed.conf is not "innfeed"
-my $dir = "$inn::pathspool/innfeed";
-my $Revision = '1.8';
-
-use strict;
-use warnings;
-
-use Getopt::Std;
-use vars qw($opt_H $opt_h $opt_n $opt_t $opt_k $opt_S $opt_d);
-$| = 1;
-
-# option processing
-&getopts('HhntkS:d:') || &Usage;
-&Usage if $opt_h;
-
-# open the directory;
-$dir = $opt_d if $opt_d;
-print "$opt_d\n";
-chdir($dir) or die "Can't cd to $dir";
-opendir(DIR, ".") or die "Can't open dir";
-
-my %nodes;
-while (my $name = readdir(DIR)) {
-       # must be a file, correct name, non-zero size
-       my $size;
-       next unless -f $name;
-       next unless ($size = -s $name);
-       next unless $name =~ m/.*\.(in|out)put/;
-       my $io = $1;
-       (my $nodename = $name) =~ s/\..*//;
-
-       # check for only some sites wanted
-       next if ($opt_S && $nodename !~ /^${opt_S}.*/);
-       # here we do the counts if asked
-       if ($opt_n) {
-               # open the file and count lines
-               if (open(IN, "<$name")) {
-                       if ($name =~ m/.*\.input/) {
-                               my $offset = <IN> + 0;
-                               seek(IN, $offset, 0);
-                       }
-                       $size = 0;
-                       for ($size = 0; <IN> ; ++$size) {};
-                       close IN;
-               }
-       } else {
-               # get the offset on .input files
-               if ($name =~ m/.*\.input/ && open(IN, "<$name")) {
-                       my $offset = <IN> + 0;
-                       $size -= $offset;
-                       close IN;
-               }
-       }                       
-       $nodes{$nodename} = () unless defined $nodes{$nodename};
-       $nodes{$nodename}->{$io} = ( $opt_k ? $size / 1024 : $size );
-}
-closedir DIR;
-
-# output the data for each node
-if (my $numnodes = keys %nodes) {
-       if ($opt_H) {
-               if ($opt_n) {
-                       print "  <---------- posts ----------->\n";
-               } else {
-                       print "  <---------- bytes ----------->\n";
-               }
-       }
-       my $ofmt;
-       if ($opt_k) {
-               print "  input(k)  output(k)   total(k) Feed Name\n" if $opt_H;
-               $ofmt = ( $opt_n ? "%10.2f" : "%10.1f" );
-       } else {
-               print "     input     output      total Feed Name\n" if $opt_H;
-               $ofmt = "%10d";
-       }
-       for my $node (sort keys %nodes) {
-               my $hash = $nodes{$node};
-               my $size_in = $hash->{in} || 0;
-               my $size_out = $hash->{out} || 0;
-               my $size_tot = $size_in + $size_out;
-               printf "${ofmt} ${ofmt} ${ofmt} %s\n",
-                       $size_in, $size_out, $size_tot, $node;
-       }
-} else {
-       print "NO backlog!\n";
-}
-
-exit 0;
-
-sub Usage
-{
-       print "\n"
-       . "bklog - print innfeed backlog info - v$Revision\n"
-       . "\n"
-       . "Format:\n"
-       . "  bklog [ options ]\n"
-       . "\n"
-       . "Options:\n"
-       . "  -H     output a header at the top of the output\n"
-       . "  -k     scale all numbers in k (1024) units\n"
-       . "  -n     count number of arts, not bytes of backlog filesize\n"
-       . "         Note: this may be SLOW for large files!\n"
-       . "  -Sxx   Display only site names starting with xx\n"
-       . "  -d dir Use \"dir\" instead of \$pathspool/innfeed\n"
-       . "\n"
-       . "  -h     HELP - this is all, you got it!\n"
-       . "\n";
-
-       exit 1;
-}
-
-
diff --git a/contrib/backupfeed.in b/contrib/backupfeed.in
deleted file mode 100644 (file)
index 815fd74..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Date: 26 Jun 1999 17:59:00 +0200
-# From: kaih=7Jbfpa7mw-B@khms.westfalen.de (Kai Henningsen)
-# Newsgroups: news.software.nntp
-# Message-ID: <7Jbfpa7mw-B@khms.westfalen.de>
-# Subject: Re: Version of pullnews that support authentication?
-#
-# [...]
-# I'm appending a script I wrote (called backupfeed.pl for some reason). Hmm  
-# ... oh, I hereby put that into the public domain. Use as you see fit. If  
-# it breaks, you get to keep all the parts.
-# 
-# Needs the newer Net::NNTP versions for the MODE READER fix.
-# 
-# This thing is both faster and uses far less memory than suck. And it  
-# inserts a predictable Path: entry (in case the host you pull from  
-# doesn't).
-# 
-# It's in production use as a backup to regular feeds, so it specifically  
-# fetches only old articles unless you say -p 1 (default is -p 0.6666...).
-
-use strict;
-use Net::NNTP;
-use DB_File;
-use Data::Dumper;
-use Getopt::Std;
-use vars qw($Group $Host $Pos $Rc %Rc $Starttime
-           $opt_S $opt_T $opt_d $opt_p $opt_s $opt_t);
-
-my ( @groups, $localhost, $remotehost, $accepted, $rejected, $lockf,
-     $history, $acc, $rej, $his, @parms, $from, $to, $art, %err );
-
-$| = 1;
-
-$opt_S = 10;   # sleep between groups
-$opt_T = 10000;        # max running time
-$opt_d = 0;    # debugging
-$opt_p = 2/3;  # how many articles to fetch
-$opt_s = 0;    # sleep between articles
-$opt_t = 0;    # timeout for NNTP connections
-getopts("dt:p:s:S:T:");
-
-die <<USAGE if @ARGV < 2;
-Usage: $0 hostname /groups/wanted [ userid password ]
-Options:
-       -d      debugging
-       -t s    NNTP timeout
-       -p nn   how many articles (0.0 .. 1.0)
-       -s s    sleep between articles
-       -S s    sleep between groups
-       -T s    max running time
-USAGE
-
-my ($GroupsWanted, $userid, $password);
-($Host, $GroupsWanted, $userid, $password) = @ARGV;
-
-chdir("/var/local/lib/backupfeed") or die "chdir: $!";
-$lockf = "/var/lock/lock-backupfeed-$Host";
-system("/usr/lib/news/bin/shlock -p $$ -f $lockf")==0 or exit 0;
-
-open LOG, ">> /var/log/news/backupfeed.$Host" or die "normal log: $!";
-autoflush LOG;
-
-open ERR, ">> /var/log/news/backupfeed.$Host.errors" or die "error log: $!";
-autoflush ERR;
-
-print LOG scalar(localtime), " $0 starting for $Host\n";
-print ERR scalar(localtime), " $0 starting for $Host\n";
-
-open GUP, $GroupsWanted or die "Groups Wanted: $GroupsWanted: $!";
-@groups = <GUP>;
-close GUP;
-
-$Starttime = time;
-
-$localhost = Net::NNTP->new("localhost", "Debug", $opt_d, "Timeout", $opt_t, "Reader", 0) or die "localhost: $!";
-
-$remotehost = Net::NNTP->new($Host, "Debug", $opt_d, "Timeout", $opt_t) or die "remotehost: $!";
-$remotehost->reader;
-&lifecheck($remotehost, $Host);
-$remotehost->authinfo($userid, $password) if ($userid);
-&lifecheck($remotehost, $Host);
-
-tie %Rc, "DB_File", "$Host.bfrc" or die "$Host.bfrc: $!";
-
-$SIG{HUP} = 'IGNORE';
-$SIG{INT} = \&sig;
-$SIG{TERM} = \&sig;
-
-my $restart = $Rc{'=restart='};
-$restart='' unless ($restart);
-
-my @before = grep $_ lt $restart, @groups;
-my @after = grep $_ ge $restart, @groups;
-@groups = ( @after, @before );
-
-($acc, $rej, $his) = (0, 0, 0);
-foreach $Group (@groups) {
-       chomp $Group;
-       (@parms = $remotehost->group($Group)) or next;
-       &lifecheck($remotehost, $Host);
-       next if ($#parms < 3);
-       $Rc{'=restart='} = $Group;
-       print LOG scalar(localtime), " \t<$Group>\n";
-       $Rc{$Group} = 0
-               if (!defined $Rc{$Group});
-       $Rc{$Group} = 0
-               if (!$Rc{$Group});
-       $from = $parms[1];
-       $to = $parms[2];
-       $to = $from + ($to - $from) * $opt_p;
-       if ($to < $Rc{$Group}) {
-               print LOG scalar(localtime), " \t watermark high, reset\n";
-               $Rc{$Group} = $from-1;
-       }
-       $Rc{$Group} = $from-1
-               if ($from > $Rc{$Group});
-#      print LOG scalar(localtime), " \t\t",$Rc{$Group}+1,"-$to\n";
-       $remotehost->nntpstat($Rc{$Group}+1);
-#      print LOG scalar(localtime), " \t\t",$remotehost->message,"\n";
-       &lifecheck($remotehost, $Host);
-       $art = $remotehost->nntpstat;
-       &lifecheck($remotehost, $Host);
-       $remotehost->message =~ /^(\d+)/;
-       $Pos = $1;
-       $accepted=0;
-       $rejected=0;
-       $history=0;
-       &offer($art)
-               if ($art);
-       while ($art = $remotehost->next) {
-               &lifecheck($remotehost, $Host);
-               $remotehost->message =~ /^(\d+)/;
-               $Pos = $1;
-               last
-                       if ($Pos > $to);
-               &offer($art);
-       }
-       &lifecheck($remotehost, $Host);
-       print LOG scalar(localtime), " \taccepted=$accepted rejected=$rejected history=$history\n";
-       $acc+=$accepted;
-       $rej+=$rejected;
-       $his+=$history;
-       $accepted=0;
-       $rejected=0;
-       $history=0;
-       (tied %Rc)->sync;
-       sleep $opt_S if $opt_S;
-}
-
-untie %Rc;
-
-$localhost->quit;
-
-$remotehost->quit;
-
-&end0;
-
-sub offer
-{
-       system("echo $Host $Group $Pos > $Host.status");
-       if ($localhost->ihave($_[0])) {
-               &lifecheck($localhost, 'localhost');
-               my $article = $remotehost->article;
-               if (ref $article) {
-                       #open ART1, "> art1";
-                       #print ART1 @$article;
-                       #close ART1;
-                       my $i = 0;
-                       while ($i <= @$article && !($$article[$i] =~ /^Path:/i)) {
-                               $i++;
-                       }
-                       $$article[$i] =~ s/^(Path:\s*)/$1NNTP-from-$Host!/i;
-                       #open ART2, "> art2";
-                       #print ART2 @$article;
-                       #close ART2;
-                       #exit;
-                       $localhost->datasend($article);
-                       if ($localhost->dataend) {
-                               $accepted++;
-                       }
-                       else {
-                               $rejected++;
-                               $err{" local " . $localhost->code . " " . $localhost->message} ++;
-                       }
-                       $Rc{$Group} = $Pos;
-                       (tied %Rc)->sync;
-               }
-               else {
-                               $err{" remote " . $remotehost->code . " " . $remotehost->message} ++;
-               }
-               sleep $opt_s if $opt_s;
-       }
-       else {
-               if ($localhost->status == 4) {
-                       if ($localhost->code == 435) {
-                               $err{" local " . $localhost->code . " " . $localhost->message} ++;
-                       }
-                       else {
-                               $err{" local " . $localhost->code . " " . $localhost->message} ++;
-                               print LOG scalar(localtime), " local ", $localhost->code, " ", $localhost->message, "\n";
-                               &end;
-                       }
-               }
-               &lifecheck($localhost, 'localhost');
-               $history++;
-               $Rc{$Group} = $Pos;
-       }
-}
-
-sub lifecheck
-{
-       unless (defined $_[0]->code and $_[0]->code > 0) {
-               print LOG scalar(localtime), " Connection to $_[1] dropped\n";
-               print ERR scalar(localtime), " Connection to $_[1] dropped\n";
-               &end;
-       }
-       #print "time=",time," starttime=$Starttime\n";
-       kill 'TERM', $$ if time-$Starttime > $opt_T;
-}
-
-sub sig
-{
-       print LOG scalar(localtime), " Caught sig: ", Data::Dumper::Dumper(@_), "\n";
-       print ERR scalar(localtime), " Caught sig: ", Data::Dumper::Dumper(@_), "\n";
-       &end;
-}
-
-sub end
-{
-       $acc+=$accepted;
-       $rej+=$rejected;
-       $his+=$history;
-       &end0;
-}
-
-sub end0
-{
-       print LOG scalar(localtime), " $0 $Host accepted=$acc rejected=$rej history=$his\n";
-       foreach my $e (sort keys %err) {
-               print ERR $err{$e}, $e, "\n";
-       }
-       print ERR scalar(localtime), " $0 $Host accepted=$acc rejected=$rej history=$his\n";
-       close LOG;
-       close ERR;
-       unlink $lockf;
-       exit 0;
-}
diff --git a/contrib/cleannewsgroups.in b/contrib/cleannewsgroups.in
deleted file mode 100644 (file)
index daa406b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# This script cleans the newsgroups file:
-#   * Groups no longer in the active file are removed.
-#   * Duplicate entries are removed.  The last of a set of duplicates
-#     is the one retained.  That way, you could simply append the
-#     new/revised entries from a docheckgroups run and then this script
-#     will remove the old ones.
-#   * Groups with no description are removed.
-#   * Groups matching the $remove regexp are removed.
-
-$remove='';
-# $remove='^alt\.';
-
-open ACT, $inn::active  or die "Can't open $inn::active: $!\n";
-while(<ACT>) {
-    ($group) = split;
-    $act{$group} = 1 unless($remove ne "" && $group =~ /$remove/o);
-}
-close ACT;
-
-open NG, $inn::newsgroups  or die "Can't open $inn::newsgroups: $!\n";
-while(<NG>) {
-    chomp;
-    ($group, $desc) = split /\s+/,$_,2;
-    next unless(defined $act{$group});
-
-    next if(!defined $desc);
-    next if($desc =~ /^[?\s]*$/);
-    next if($desc =~ /^no desc(ription)?(\.)?$/i);
-
-    $hist{$group} = $desc;
-}
-close NG;
-
-open NG, ">$inn::newsgroups.new"  or die "Can't open $inn::newsgroups.new for write: $!\n";
-foreach $group (sort keys %act) {
-    if(defined $hist{$group}) {
-       print NG "$group\t$hist{$group}\n" or die "Can't write: $!\n";
-    }
-}
-close NG or die "Can't close: $!\n";
-
-rename "$inn::newsgroups.new", $inn::newsgroups  or die "Can't rename $inn::newsgroups.new to $inn::newsgroups: $!\n";
diff --git a/contrib/count_overview.pl b/contrib/count_overview.pl
deleted file mode 100755 (executable)
index 910938e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/local/bin/perl
-#
-# count_overview.pl:  Count the groups in a bunch of xref records.
-
-while (<>) {
-
-chop;
-@xreflist = split(/\t/); # split apart record
-
-$_ = $xreflist[$#xreflist];  # xref is last.
-
-@xreflist = reverse(split(/ /));  #break part xref line.
-
-pop @xreflist;  # get rid xref header
-pop @xreflist;
-
-while ($current = pop @xreflist) {
-       ($current) = split(/:/,$current);  #get newsgroup name
-       $groups{$current}++;  #tally
-}
-
-}
-
-# display accumulated groups and counts.
-foreach $current (sort keys %groups) {
-       printf "%-50s\t%5d\n", $current, $groups{$current};
-}
diff --git a/contrib/delayer.in b/contrib/delayer.in
deleted file mode 100644 (file)
index 4528d96..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/perl
-# -*- perl -*-
-#
-# delay lines for N seconds.
-#
-# primarily meant to be used with INN to generate a delayed feed with innfeed.
-#
-# put it into your newsfeeds file like
-#
-# innfeed-delayed!\
-#        :!*\
-#        :Tc,Wnm*,S16384:/usr/local/news/bin/delayer 60 \
-#              /usr/local/news/bin/startinnfeed -c innfeed-delayed.conf
-#
-#
-#
-# done by christian mock <cm@tahina.priv.at> sometime in july 1998,
-# and put into the public domain.
-#
-$delay = shift || die "usage: $0 delay prog-n-args\n";
-
-$timeout = $delay;
-$eof = 0;
-
-open(OUT, "|" . join(" ", @ARGV)) || die "open |prog-n-args: $!\n";
-
-#select(OUT);
-#$| = 1;
-#select(STDOUT);
-
-$rin = '';
-vec($rin,fileno(STDIN),1) = 1;
-
-while(!$eof || $#queue >= 0) {
-    if(!$eof) {
-       ($nfound,$timeleft) =
-           select($rout=$rin, undef, undef, $timeout);
-    } else {
-       sleep($timeout);
-    }
-    $now = time(); $exp = $now + $delay;
-
-    if(!$eof && vec($rout,fileno(STDIN),1)) {
-       $line = <STDIN>;
-       if(!defined $line) {    # exit NOW!
-           foreach(@queue) {
-               s/^[^:]+://g;
-               print OUT;
-           }
-           close(OUT);
-           sleep(1);
-           exit;
-       }
-       push(@queue, "$exp:$line");
-    }
-
-    if($#queue < 0) {
-       undef $timeout;
-       next;
-    }
-
-    ($first, $line) = split(/:/, $queue[0], 2);
-    while($#queue >= 0 && $first <= $now) {
-       print OUT $line;
-       shift(@queue);
-       ($first, $line) = split(/:/, $queue[0], 2);
-    }
-    $timeout = $first - $now;
-       
-}
-
diff --git a/contrib/expirectl.c b/contrib/expirectl.c
deleted file mode 100644 (file)
index 2224ad7..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * EXPIRECTL.C
- *
- * expirectl
- *
- * This program uses expire.ctl.ctl as input; please see the end of this
- * file for an example of such a file.
- */
-
-/*
- * Date: Mon, 21 Nov 1994 12:29:52 -0801
- * From: Matthew Dillon <dillon@apollo.west.oic.com>
- * Message-Id: <199411212030.MAA21835@apollo.west.oic.com>
- * To: rsalz@uunet.uu.net
- * Subject: Re:  INN is great, bug fix for BSDI
- * 
- * [...]
- *     Oh, while I'm at it, I also wrote a cute program that builds the 
- *     expire.ctl file dynamically based on available space.   Feel free
- *     to include this in the dist (or not) as you please.
- * 
- *     Basically, the expirectl programs determines the amount of disk blocks
- *     and inodes free in the spool and creates a new expire.ctl file based
- *     on an expire.ctl.ctl template.  The template specifies expiration times
- *     as a fraction of nominal.  expirectl adjusts the nominal expiration
- *     up or down based on available disk space.
- * 
- *     The idea is to make expiration as hands off as possible.  I tested
- *     it on a smaller spool and it appeared to work fine.  Currently it
- *     only works for single-partition news spools tho.  The above spool
- *     will not really exercise the program for another 14 days or so :-).
- */
-
-
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define EXPIRE_CTL_DIR "/home/news"
-#define NEWS_SPOOL     "/home/news/spool/news/."
-
-#define EXPIRE_DAYS    EXPIRE_CTL_DIR "/expire.days"
-#define EXPIRE_CTL     EXPIRE_CTL_DIR "/expire.ctl"
-#define EXPIRE_CTL_CTL EXPIRE_CTL_DIR "/expire.ctl.ctl"
-
-void
-main(int ac, char **av)
-{
-    struct statfs sfs;
-    long minFree = 100 * 1024 * 1024;
-    long minIFree = 20 * 1024;
-    long expireDays = 2;
-    time_t expireIncTime = time(NULL) - 24 * 60 * 60;
-    int modified = 0;
-    int verbose = 0;
-
-    /*
-     * options
-     */
-
-    {
-       int i;
-
-       for (i = 1; i < ac; ++i) {
-           char *ptr = av[i];
-
-           if (*ptr == '-') {
-               ptr += 2;
-               switch(ptr[-1]) {
-               case 'v':
-                   verbose = 1;
-                   break;
-               case 'f':
-                   modified = 1;
-                   break;
-               case 'n':
-                   modified = -1;
-                   break;
-               case 'b':
-                   minFree = strtol(((*ptr) ? ptr : av[++i]), &ptr, 0);
-                   if (*ptr == 'k')
-                       minFree *= 1024;
-                   if (*ptr == 'm')
-                       minFree *= 1024 * 1024;
-                   break;
-               case 'i':
-                   minIFree = strtol(((*ptr) ? ptr : av[++i]), NULL, 0);
-                   if (*ptr == 'k')
-                       minIFree *= 1024;
-                   if (*ptr == 'm')
-                       minIFree *= 1024 * 1024;
-                   break;
-               default:
-                   fprintf(stderr, "bad option: %s\n", ptr - 2);
-                   exit(1);
-               }
-           } else {
-               fprintf(stderr, "bad option: %s\n", ptr);
-               exit(1);
-           }
-       }
-    }
-
-    if (statfs("/home/news/spool/news/.", &sfs) != 0) {
-       fprintf(stderr, "expirectl: couldn't fsstat /home/news/spool/news/.\n");
-       exit(1);
-    }
-
-    /*
-     * Load /home/news/expire.days
-     */
-    
-    {
-       FILE *fi;
-       char buf[256];
-
-       if ((fi = fopen(EXPIRE_DAYS, "r")) != NULL) {
-           while (fgets(buf, sizeof(buf), fi) != NULL) {
-               if (strncmp(buf, "time", 4) == 0) {
-                   expireIncTime = strtol(buf + 4, NULL, 0);
-               } else if (strncmp(buf, "days", 4) == 0) {
-                   expireDays = strtol(buf + 4, NULL, 0);
-               }
-           }
-           fclose(fi);
-       } else {
-           if (modified >= 0)
-               modified = 1;
-           printf("creating %s\n", EXPIRE_DAYS);
-       }
-    }
-
-    /*
-     * print status
-     */
-
-    if (verbose) {
-       printf("spool: %4.2lfM / %3.2lfKinode free\n",
-           (double)sfs.f_fsize * (double)sfs.f_bavail / (1024.0 * 1024.0),
-           (double)sfs.f_ffree / 1024.0
-       );
-       printf("decrs: %4.2lfM / %3.2lfKinode\n",
-           (double)(minFree) / (double)(1024*1024),
-           (double)(minIFree) / (double)(1024)
-       );
-       printf("incrs: %4.2lfM / %3.2lfKinode\n",
-           (double)(minFree * 2) / (double)(1024*1024),
-           (double)(minIFree * 2) / (double)(1024)
-       );
-    }
-
-    /*
-     * Check limits, update as appropriate
-     */
-
-    {
-       double bytes;
-       long inodes;
-
-       bytes = (double)sfs.f_fsize * (double)sfs.f_bavail;
-       inodes = sfs.f_ffree;
-
-       if (bytes < (double)minFree || inodes < minIFree) {
-           if (--expireDays <= 0) {
-               expireDays = 1;
-               expireIncTime = time(NULL) - 24 * 60 * 60;
-           }
-           if (modified >= 0)
-               modified = 1;
-           printf("decrement expiration to %d days\n", expireDays);
-       } else if (bytes >= (double)minFree * 2.0 && inodes >= minIFree * 2) {
-           long dt = (long)(time(NULL) - expireIncTime);
-
-           if (dt >= 60 * 60 * 24 || dt < -60) {
-               ++expireDays;
-               expireIncTime = time(NULL);
-               if (modified >= 0)
-                   modified = 1;
-               printf("increment expiration to %d days\n", expireDays);
-           } else {
-               printf("will increment expiration later\n");
-           }
-       } else if (verbose) {
-           printf("expiration unchanged: %d\n", expireDays);
-       }
-    }
-
-    /*
-     * Write EXPIRE_CTL file from EXPIRE_CTL_CTL template
-     */
-
-    if (modified > 0) {
-       FILE *fi;
-       FILE *fo;
-
-       if ((fi = fopen(EXPIRE_CTL_CTL, "r")) != NULL) {
-           if ((fo = fopen(EXPIRE_CTL ".tmp", "w")) != NULL) {
-               char sbuf[2048];
-               char dbuf[4096];
-
-               while (fgets(sbuf, sizeof(sbuf), fi) != NULL) {
-                   char *base = sbuf;
-                   char *sptr;
-                   char *dptr = dbuf;
-
-                   while ((sptr = strchr(base, '[')) != NULL) {
-                       double d;
-                       int m = 0;
-
-                       bcopy(base, dptr, sptr - base);
-                       dptr += sptr - base;
-                       base = sptr;
-
-                       d = strtod(sptr + 1, &sptr);
-                       if (*sptr == '/')
-                           m = strtol(sptr + 1, &sptr, 0);
-                       if (*sptr == ']') {
-                           long v = (long)((double)expireDays * d + 0.5);
-                           if (v < 1)
-                               v = 1;
-                           if (v < m)
-                               v = m;
-                           sprintf(dptr, "%d", v);
-                           dptr += strlen(dptr);
-                           ++sptr;
-                       }
-                       base = sptr;
-                   }
-                   strcpy(dptr, base);
-                   fputs(dbuf, fo);
-               }
-               fclose(fo);
-               if (rename(EXPIRE_CTL ".tmp", EXPIRE_CTL) != 0) {
-                   fprintf(stderr, "rename(%s,%s): %s\n",
-                       EXPIRE_CTL ".tmp",
-                       EXPIRE_CTL,
-                       strerror(errno)
-                   );
-               }
-           }
-           fclose(fi);
-       }
-    }
-
-    /*
-     * Write EXPIRE_DAYS file
-     */
-    
-    if (modified > 0) {
-       FILE *fo;
-
-       if ((fo = fopen(EXPIRE_DAYS, "w")) != NULL) {
-           fprintf(fo, "time 0x%08lx\n", expireIncTime);
-           fprintf(fo, "days %d\n", expireDays);
-           fclose(fo);
-       } else {
-           fprintf(stderr, "unable to create %s\n", EXPIRE_DAYS);
-       }
-    }
-    exit(0);
-}
-
-
-/*
-
-# Start of sample expire.ctl.ctl file.
-
-# EXPIRE.CTL.CTL (EXPIRE.CTL GENERATED FROM EXPIRE.CTL.CTL !!!)
-#
-# The expire.ctl file is generated by the expirectl program from the
-# expire.ctl.ctl file.  The expirectl program calculates the proper
-# expiration based on the number of free inodes and free bytes available.
-#
-# This file is exactly expire.ctl but with the multiplier [N] replaced by 
-# a calculated value, where a multiplier of '1' nominally fills the whole
-# disk.
-#
-# Any field [N] is substituted after being multiplied by the expiration
-# time (in days).  A integer minimum can also be specified with a slash,
-# as in [N/minimum].
-#
-# expirectl is normally run just after expire is run.  Note that expirectl
-# isn't very useful for the case where you are 'catching up' on news after
-# a long period of downtime UNLESS you use the -p option to expire.
-
-/remember/:[1.2/20]
-
-##  Keep for 1-10 days, allow Expires headers to work.
-#
-*:A:1:[1.0]:[6.0]
-*.advocacy:A:1:[0.5]:[2.0]
-alt.binaries.pictures.erotica:A:1:[0.8]:[2.0]
-
-# permanent, semi-permanent
-#
-best.intro:A:never:never:never
-best.announce:A:5:60:120
-best.general:A:never:never:never
-best.bugs:A:never:never:never
-
-# End of sample expire.ctl.ctl file.
-
-*/
diff --git a/contrib/findreadgroups.in b/contrib/findreadgroups.in
deleted file mode 100644 (file)
index 4c5e8ff..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/local/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Keep track of which groups are currently being read.  Takes logfile input
-# on stdin.
-$readfile="$inn::newsetc/readgroups";
-
-$curtime = time;
-$oldtime = $curtime - 30 * 86400; # 30 days in the past
-
-if (open(RDF, $readfile)) {
-    while (<RDF>) {
-       chop;
-       @foo=split(/ /); # foo[0] should be group, foo[1] lastreadtime
-       if ($foo[1] < $oldtime) {
-           next; # skip entries that are too old.
-       }
-       $groups{$foo[0]} = $foo[1];
-    }
-    close(RDF);
-}
-
-# read input logs.
-while (<>) {
-    next unless /nnrpd/;
-    next unless / group /;
-    chop;
-    @foo = split(/ +/);
-    # group name is in the 8th field.
-    $groups{$foo[7]} = $curtime;
-}
-
-open(WRF, ">$readfile") || die "cannot open $readfile for write.\n";
-foreach $i (keys %groups) {
-    print WRF $i, " ", $groups{$i}, "\n";
-}
-
-exit(0);
diff --git a/contrib/fixhist b/contrib/fixhist
deleted file mode 100755 (executable)
index 0541a00..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/local/bin/perl
-#
-# history database sanity checker
-# David Barr <barr@math.psu.edu>
-# version 1.4
-# w/mods from: hucka@eecs.umich.edu
-# Katsuhiro Kondou <kondou@nec.co.jp>
-# version 1.1
-# Throw away history entries with:
-#   malformed lines (too long, contain nulls or special characters)
-#
-# INN Usage:
-#   ctlinnd throttle 'fixing history'
-#   ./fixhist <history >history.n
-#   makedbz -s `wc -l <history.n` -f history.n
-#      or use instructions from fixhist to avoid the `wc -l <history.n`
-#   mv history.n history
-#   mv history.n.dir history.dir
-### if TAGGED_HASH is DO or before inn2.0
-#   mv history.n.pag history.pag
-### if TAGGED_HASH is DONT
-#   mv history.n.hash history.hash
-#   mv history.n.index history.index
-### endif
-#   ctlinnd reload history x
-#   ctlinnd go 'fixing history'
-# any malformed entries will be output to stderr.
-
-
-$MAXKEYLEN=254;
-$count=0;
-
-while (<>) {
-       chop;
-       ($msgid,$dates,$arts,$xtra) = split('\t');
-       if ($xtra) {
-               &tossit();              # too many fields
-               next;
-       }
-       if (!($dates) && (($arts) || ($xtra))) {
-               &tossit();              # if not date field, then the rest
-               next;                   # should be empty
-       }
-       if (length($msgid) >= $MAXKEYLEN) {
-               &tossit();              # message-id too long
-               next;
-       }
-       if ($msgid !~ /^<[^<> ]*>$/) {
-               if ($msgid =~ /^\[[0-9A-F]{32}\]$/) {
-                       if ($arts ne "") { 
-                               if ($arts =~ /^\@[0-9A-F]{56}\@$/) {
-                                       $arts =~ s/^\@([0-9A-F]{36})([0-9A-F]{20})\@$/\@${1}\@/;
-                                       print "$msgid\t$dates\t$arts\n";
-                                       next;
-                               }
-                               if ($arts !~ /^\@[0-9A-F]{36}\@$/) {
-                                       &tossit();
-                                       next;
-                               }
-                       }
-               } else {
-                       &tossit();              # malformed msg-ids
-                       next;
-               }
-       } else {
-               if ($arts ne "" && ($arts !~ /[^\/]*\/[0-9]*/)) {
-                       &tossit();              # malformed articles list
-                       next;
-               }
-       }
-       if (/[\000-\010\012-\037\177-\237]/) { # non-control chars except tab
-               &tossit();              # illegal chars
-               next;
-       }
-       if ($dates) {
-               if ($dates =~ /[^\d~\-]/) {     # rudimentary check
-                       &tossit();              # full check would be too slow
-                       next;
-               }
-       }
-       print "$_\n";
-       $count++;
-       $0 = "history line $./$count" if $. % 50000 == 0;
-}
-print STDERR "Done.  Now run:\nmakedbz -s $count -f history.n\n";
-
-sub tossit {
-       print STDERR "$_\n";
-}
diff --git a/contrib/innconfcheck b/contrib/innconfcheck
deleted file mode 100755 (executable)
index 83a19d0..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/bin/ksh
-
-### INNCONFcheck v1.1
-
-### Revision history:
-#   v1.0  B. Galliart  (designed to work with 2.3 inn.conf man page)
-#   v1.1  B. Galliart  (optional support for using inn.conf POD src instead)
-
-### Description:
-# This script is written to inner-mix the inn.conf settings with the
-# documentation from the inn.conf man page.  The concept was shamelessly
-# ripped off of a CGI application provided at Mib Software's Usenet Rapid
-# Knowledge Transfer (http://www.mibsoftware.com/userkt/inn2.0/).
-
-# The idea is that a news administrator usually must go through the
-# task of reading the inn.conf man page in parallel with the inn.conf
-# inn.conf to confirm that the settings are set as desired.  Manually
-# matching up the two files can become troublesome.  This script should
-# make the task easier and hopefully reduce the chance a misconfiguration
-# is missed.
-
-### Known bugs:
-#   - Is very dependent on the format of the man page.  It is know NOT to
-#     work with the inn.conf man pages written before INN 2.3 and may
-#     require minor rewriting to address future revisions of inn.conf
-#     Note: this known bug is addressed via the "EDITPOD" option below
-#     but is not enabled by default (details explained below).
-#
-#   - SECURITY!  While taken from the concept of a CGI script, it is not
-#     intended to be a CGI script itself.  It is *assumed* that the
-#     inn.conf file is provided by a "trusted" source.
-
-### License: this script is provided under the same terms as the majority
-#   of INN 2.3.0 as stated in the file "inn-2.3.0/LICENSE"
-
-### Warrenty/Disclaimer: There is no warrenty provided.  For details, please
-#   refer to the file "inn-2.3.0/LICENSE" from the INN 2.3 package
-
-                             ################
-
-###  The User Modifiable Parameters/Settings:
-
-# INNCONF should be set to the actual location of the inn.conf file
-INNCONF=/usr/local/news/etc/inn.conf
-
-# INNCONFMAN should be set to the location of the inn.conf man page
-INNCONFMAN=/usr/local/news/man/man5/inn.conf.5
-
-# INNCONFPOD should be set to the location of the inn.conf POD source
-# INNCONFPOD=/usr/local/src/inn-2.3.0/doc/pod/inn.conf.pod
-INNCONFPOD=/usr/local/news/man/man5/inn.conf.pod
-
-# NROFF should be set to an approbate program for formating the man page
-# this could be the vendor provided nroff, the FSF's groff (which could be
-# used for producing PostScript output) or Earl Hood's man2html from
-# http://www.oac.uci.edu/indiv/ehood/man2html.html
-
-# NROFF=man2html
-NROFF="nroff -man"
-
-# Pager should be set to an approbate binary for making the output
-# readable in the user's desired method.  Possible settings include
-# page, more, less, ghostview, lynx, mozilla, lpr, etc.  If no pager
-# application is desire then by setting it to "cat" will cause the output
-# to continue on to stdout.
-PAGER=less
-
-# By default the script uses the inn.conf man page before being processed
-# by nroff to edit in the actual inn.conf settings.  The problem with this
-# approach is that if the format of the inn.conf man page ever changes
-# assumptions about the format that this script makes will probably break.
-# Presently, the base/orginal format of the inn.conf man page is in perl
-# POD documentation.  The formating of this file is less likely to change
-# in the future and is a cleaner format for automated editing.  However, 
-# their is some disadvantages to using this file.  First disadvantage, 
-# the POD file is not installed by INN 2.3.0 by default (see INNCONFPOD 
-# enviromental variable for setting the script to find the file in the 
-# correct location).  Second disadvantage, pod2man does not appear to 
-# support using stdin so the edited POD must be temporarily stored as a 
-# file.  Finally, the last disadvantage, the script is slower due to the 
-# added processing time of pod2man.  Weighing the advantages and 
-# disadvantages to both approaches are left to the user.  If you wish to 
-# have innconfcheck edit the POD file then change the variable below to 
-# a setting of "1", otherwise leave it with the setting of "0"
-EDITPOD=0
-
-                             ################
-
-### The Script: (non-developers should not need to go beyond this point)
-
-# All variable settings in inn.conf should not contain a comment
-# character of "#" and should have a ":" in the line.   These variable names
-# should then be matched up with the man page "items" in the inn.conf file.
-# In the INN 2.3 man page, these items appear in the following format:
-#   .Ip "\fIvariable name\fR" 4
-# Hence, if there exists an entry in the inn.conf of "verifycancels: false"
-# then the awk script will produce:
-#   s#^.Ip "\fIvarifycancels\f$" 4#.Ip "\verifycancels: false\f$" 4#
-# once piped to sed, this expression will replace the man page item to
-# include the setting from the inn.conf file.  The nroff and pager
-# applications then polish the script off to provide a documented formated
-# in a way that is easier to find incorrect setting withen.
-
-if [ $EDITPOD -eq 0 ] ; then
-
-  grep -v "#" $INNCONF | grep ":" | \
-    awk 'BEGIN { FS = ":" }  { print "s#^.Ip \042\\\\fI"$1"\\\\fR\042 4#.Ip \042\\\\fI"$0"\\\\fR\042 4#" }' | \
-    sed -f - $INNCONFMAN | $NROFF | $PAGER
-
-else
-
-# The next part is similar to above but provides working from the POD source
-# instead of from the resulting nroff/man page.  This section is discussed
-# in more detail above with the "EDITPOD" setting.
-
-  grep -v "#" $INNCONF | grep ":" | \
-    awk 'BEGIN { FS = ":" }  { print "s#=item I<"$1">#=item I<"$0">#" }' | \
-    sed -f - $INNCONFPOD > /tmp/innconfcheck-$$
-  pod2man /tmp/innconfcheck-$$ | $NROFF | $PAGER
-  rm -f /tmp/innconfcheck-$$
-
-fi
-
-# That's all.
-# EOF
diff --git a/contrib/makeexpctl.in b/contrib/makeexpctl.in
deleted file mode 100644 (file)
index 320ae1f..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/local/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Create expire.ctl script based on recently read articles.  Argument gives
-# scale factor to use to adjust expires.
-
-$readfile="$inn::pathdb/readgroups";
-
-$expirectl=$inn::expirectl;
-if (open(RDF, $readfile)) {
-    while (<RDF>) {
-       chop;
-       @foo=split(/ /); # foo[0] should be group, foo[1] lastreadtime
-       if ($foo[1] < $oldtime) {
-           next; # skip entries that are too old.
-       }
-       $groups{$foo[0]} = $foo[1];
-    }
-    close(RDF);
-}
-
-$scale = $ARGV[0];
-if ($scale <= 0) {
-    die "invalid scale parameter\n";
-}
-
-rename($expirectl, "$expirectl.OLD") || die "rename $expirectl failed!\n";
-open(OUTFILE, ">$expirectl") || die "open $expirectl for write failed!\n";
-
-print OUTFILE <<'EOF' ;
-##  expire.ctl - expire control file
-##  Format:
-##     /remember/:<keep>
-##     <patterns>:<modflag>:<keep>:<default>:<purge>
-##  First line gives history retention; other lines specify expiration
-##  for newsgroups.  Must have a "*:A:..." line which is the default.
-##     <patterns>      wildmat-style patterns for the newsgroups
-##     <modflag>       Pick one of M U A -- modifies pattern to be only
-##                     moderated, unmoderated, or all groups
-##     <keep>          Mininum number of days to keep article
-##     <default>       Default number of days to keep the article
-##     <purge>         Flush article after this many days
-##  <keep>, <default>, and <purge> can be floating-point numbers or the
-##  word "never."  Times are based on when received unless -p is used;
-##  see expire.8
-
-# How long to remember old history entries for.
-/remember/:2
-#
-EOF
-
-# defaults for most groups.
-printline("*", "A", 1);
-printline("alt*,misc*,news*,rec*,sci*,soc*,talk*,vmsnet*","U",3);
-printline("alt*,misc*,news*,rec*,sci*,soc*,talk*,vmsnet*","M",5);
-printline("comp*,gnu*,info*,ok*,ecn*,uok*", "U", 5);
-printline("comp*,gnu*,info*,ok*,ecn*,uok*", "M", 7);
-# and now handle each group that's regularly read, 
-# assinging them 3* normal max expire
-foreach $i (keys %groups) {
-    printline($i, "A", 21);
-}
-# and now put some overrides for groups which are too likely to fill spool if
-# we let them go to autoexpire. 
-printline("*binaries*,*pictures*", "A", 0.5);
-printline("control*","A",1);
-printline("control.cancel","A",0.5);
-printline("news.lists.filters,alt.nocem.misc","A",1);
-
-close(OUTFILE);
-exit(1);
-
-sub printline {
-    local($grpstr, $mflag, $len) = @_;
-    print OUTFILE $grpstr,":",$mflag,":",$len*$scale,":",$len*$scale,":",$len*$scale,"\n";
-}
diff --git a/contrib/makestorconf.in b/contrib/makestorconf.in
deleted file mode 100644 (file)
index c92bc83..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/local/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Create storage.conf script based on recently read articles.
-
-$readfile="$inn::pathdb/readgroups";
-
-$outfile="$inn::pathdb/storage.conf";
-outloop: 
-for ($level=9 ; $level >= 2; --$level) {
-  # clear groups hash.
-  foreach $i (keys %groups) {
-    delete $groups{$i};
-  }
-  if (open(RDF, "sort $readfile|")) {
-    while (<RDF>) {
-      chop;
-      next if (/^group/);      # bogus 
-      @foo=split(/ /);         # foo[0] should be group, foo[1] lastreadtime
-      @bar=split(/\./,$foo[0]);
-      if ( $level >= scalar @bar) {
-       $grf = join(".", @bar);
-      } else {
-       $grf=join(".", @bar[0..($level-1)])  . ".*";
-      }
-      $groups{$grf} = 1;
-    }
-    close(RDF);
-  }
-  $grlist = join(",",keys(%groups));
-  last outloop if (length($grlist) < 2048);
-}
-
-open(OUT, ">$outfile") || die "cant open $outfile";
-#open(OUT, ">/dev/tty");
-
-print OUT <<"EOF" ;
-method cnfs {
-       newsgroups: control,control.*
-       class: 1
-       options: MINI
-}
-
-method timecaf {
-       newsgroups: $grlist
-       class: 1
-}
-
-method cnfs {
-       newsgroups: *
-       options: MONGO
-        class: 0
-}
-EOF
-close(OUT);
-exit(0);
diff --git a/contrib/mkbuf b/contrib/mkbuf
deleted file mode 100755 (executable)
index 53e326e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/perl
-
-sub usage {
-       print STDERR "Usage: $0 <size in KB> <filename>\n";
-       exit 1;
-}
-
-usage if(@ARGV != 2);
-
-$buf1k = "\0"x1024;
-$buf1m = "$buf1k"x1024;
-
-$kb = $ARGV[0] * 1;
-&usage if($kb == 0);
-
-if($ARGV[1] eq '-') {
-       open(FILE, "|cat") or die;
-} else {
-       open(FILE, ">$ARGV[1]") or die;
-}
-
-for($i = 0; $i+1024 <= $kb; $i+=1024) {
-       print FILE $buf1m or die;
-}
-if($i < $kb) {
-       print FILE "$buf1k"x($kb-$i) or die;
-}
-
-close FILE;
diff --git a/contrib/mlockfile.c b/contrib/mlockfile.c
deleted file mode 100644 (file)
index 4bf274f..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* $Id: mlockfile.c 6014 2002-12-16 11:28:07Z alexk $ */
-
-/* Locks the files given on the command line into memory using mlock.
-   This code has only been tested on Solaris and may not work on other
-   platforms.
-
-   Contributed by Alex Kiernan <alexk@demon.net>.  */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/stropts.h>
-
-struct mlock {
-    const char *path;
-    struct stat st;
-    void *base;
-    off_t offset;
-    size_t length;
-};
-
-char *progname;
-
-int flush = 0;
-int interval = 60000;
-
-void
-inn_lock_files(struct mlock *ml)
-{
-    for (; ml->path != NULL; ++ml) {
-       int fd;
-
-       fd = open(ml->path, O_RDONLY);
-       if (fd == -1) {
-           fprintf(stderr, "%s: can't open `%s' - %s\n",
-                   progname, ml->path, strerror(errno));
-       } else {
-           struct stat st;
-
-           /* check if size, inode or device of the path have
-            * changed, if so unlock the previous file & lock the new
-            * one */
-           if (fstat(fd, &st) != 0) {
-               fprintf(stderr, "%s: can't stat `%s' - %s\n",
-                       progname, ml->path, strerror(errno));
-           } else if (ml->st.st_ino != st.st_ino ||
-                    ml->st.st_dev != st.st_dev ||
-                    ml->st.st_size != st.st_size) {
-               if (ml->base != MAP_FAILED)
-                   munmap(ml->base,
-                          ml->length ? ml->length : ml->st.st_size);
-
-               /* free everything here, so in case of failure we try
-                * again next time */
-               ml->st.st_ino = 0;
-               ml->st.st_dev = 0;
-               ml->st.st_size = 0;
-
-               ml->base = mmap(NULL,
-                               ml->length ? ml->length : st.st_size,
-                               PROT_READ,
-                               MAP_SHARED, fd, ml->offset);
-
-               if (ml->base == MAP_FAILED) {
-                   fprintf(stderr, "%s: can't mmap `%s' - %s\n",
-                           progname, ml->path, strerror(errno));
-               } else {
-                   if (mlock(ml->base,
-                             ml->length ? ml->length : st.st_size) != 0) {
-                       fprintf(stderr, "%s: can't mlock `%s' - %s\n",
-                               progname, ml->path, strerror(errno));
-                   } else {
-                       ml->st = st;
-                   }
-               }
-           } else if (flush) {
-               msync(ml->base, ml->length ? ml->length : st.st_size, MS_SYNC);
-           }
-       }
-       close (fd);
-    }
-}
-
-static void
-usage(void)
-{
-    fprintf(stderr,
-           "usage: %s [-f] [-i interval] file[@offset[:length]] ...\n",
-           progname);
-    fprintf(stderr, "    -f\tflush locked bitmaps at interval\n");
-    fprintf(stderr, "    -i interval\n\tset interval between checks/flushes\n");
-}
-
-int
-main(int argc, char *argv[])
-{
-    struct mlock *ml;
-    int i;
-
-    progname = *argv;
-    while ((i = getopt(argc, argv, "fi:")) != EOF) {
-       switch (i) {
-       case 'i':
-           interval = 1000 * atoi(optarg);
-           break;
-
-       case 'f':
-           flush = 1;
-           break;
-
-       default:
-           usage();
-           return EX_USAGE;        
-       }
-    }
-    argc -= optind;
-    argv += optind;
-
-    /* construct list of pathnames which we're to operate on, zero out
-     * the "cookies" so we lock it in core first time through */
-    ml = malloc((1 + argc) * sizeof ml);
-    for (i = 0; argc--; ++i, ++argv) {
-       char *at;
-       off_t offset = 0;
-       size_t length = 0;
-
-       ml[i].path = *argv;
-       ml[i].st.st_ino = 0;
-       ml[i].st.st_dev = 0;
-       ml[i].st.st_size = 0;
-       ml[i].base = MAP_FAILED;
-       
-       /* if we have a filename of the form ...@offset:length, only
-        * map in that portion of the file */
-       at = strchr(*argv, '@');
-       if (at != NULL) {
-           char *end;
-
-           *at++ = '\0';
-           errno = 0;
-           offset = strtoull(at, &end, 0);
-           if (errno != 0) {
-               fprintf(stderr, "%s: can't parse offset `%s' - %s\n",
-                       progname, at, strerror(errno));
-               return EX_USAGE;
-           }
-           if (*end == ':') {
-               at = end + 1;
-               errno = 0;
-               length = strtoul(at, &end, 0);
-               if (errno != 0) {
-                   fprintf(stderr, "%s: can't parse length `%s' - %s\n",
-                           progname, at, strerror(errno));
-                   return EX_USAGE;
-               }
-           }
-           if (*end != '\0') {
-               fprintf(stderr, "%s: unrecognised separator `%c'\n",
-                       progname, *end);
-               return EX_USAGE;
-           }
-       }
-       ml[i].offset = offset;
-       ml[i].length = length;      
-    }
-    ml[i].path = NULL;
-
-    /* loop over the list of paths, sleeping 60s between iterations */
-    for (;;) {
-       inn_lock_files(ml);
-       poll(NULL, 0, interval);
-    }
-    return EX_OSERR;
-}
diff --git a/contrib/newsresp.c b/contrib/newsresp.c
deleted file mode 100644 (file)
index b2931b7..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/* newsresp.c - EUnet - bilse */
-
-/*
- * From: Koen De Vleeschauwer <koen@eu.net>
- * Subject: Re: innfeed-users: innfeed: measuring server response time
- * To: jeff.garzik@spinne.com (Jeff Garzik)
- * Date: Tue, 13 May 1997 16:33:27 +0200 (MET DST)
- * Cc: innfeed-users@vix.com
- * 
- * > Is there an easy way to measure server response time, and print it out
- * > on the innfeed status page?  Cyclone's nntpTime measures login banner
- * > response time and an article add and lookup operation. 
- * > 
- * > It seems to me that innfeed could do something very similar.  It could
- * > very easily sample gettimeofday() or Time.Now to determine a remote
- * > server's average response time for lookups, lookup failures, article
- * > send throughput, whatever.
- * > 
- * > These statistics might be invaluable to developers creating advanced
- * > connection and article delivery algorithms.  If I knew, for example,
- * > that a site's article send/save throughput was really fast, but history
- * > lookups were really slow, my algorithm could reserve a channel or two
- * > for TAKETHIS-only use.
- * 
- * We use a stand-alone program which opens up an additional nntp channel
- * from time to time and takes a peek at the various response times.
- * It's also interesting to tune one's own box.
- * I've included the source code; please consider this supplied 'as is';
- * bugs and features alike. SunOS, Solaris and Irix ought to be ok;
- * eg. gcc -traditional -o newsresp ./newsresp.c -lnsl -lsocket on S0laris.
- * If a host has an uncommonly long banner you may have to change a constant 
- * somewhere; forget. Please note one has to interpret the output; 
- * eg. whether one is measuring rtt or history lookup time.
- * 
- * Basic usage is:
- * news 1 % newsresp -n 5 news.eu.net
- * ---------------------------------
- * news.eu.net is 134.222.90.2 port 119
- *  elap  diff
- *   0.0   0.0  Connecting ...
- *   0.0   0.0  OK, waiting for prompt
- *   0.0   0.0  <<< 200 EU.net InterNetNews server INN 1.5.1 17-Dec-1996 re [...]
- *   0.0   0.0  >>> ihave <244796399@a>
- *   0.0   0.0  <<< 335 
- *   0.0   0.0  >>> .
- *   0.0   0.0  <<< 437 Empty article 
- *   0.0   0.0  >>> ihave <244796398@a>
- *   0.0   0.0  <<< 335 
- *   0.0   0.0  >>> .
- *   0.0   0.0  <<< 437 Empty article 
- *   0.0   0.0  >>> ihave <244796397@a>
- *   0.0   0.0  <<< 335 
- *   0.0   0.0  >>> .
- *   0.0   0.0  <<< 437 Empty article 
- *   0.0   0.0  >>> ihave <244796396@a>
- *   0.1   0.0  <<< 335 
- *   0.1   0.0  >>> .
- *   0.1   0.0  <<< 437 Empty article 
- *   0.1   0.0  >>> ihave <244796395@a>
- *   0.1   0.0  <<< 335 
- *   0.1   0.0  >>> .
- *   0.1   0.0  <<< 437 Empty article 
- *   0.1   0.0  >>> quit
- *   0.1   0.0  <<< 205 . 
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <errno.h>
-
-#define NNTPPORT 119
-struct sockaddr_in sock_in;
-int sock;
-char buf[1024];
-
-main(argc,argv)
-int argc;
-char *argv[];
-{
-  int errflg = 0, c;
-  extern char *optarg;
-  extern int optind;
-  struct hostent *host;
-  unsigned long temp;
-  unsigned numart = 1;
-  struct protoent *tcp_proto;
-  char **whoP;
-
-  while ( (c = getopt(argc,argv,"n:")) != -1 )
-    switch ( c ) {
-    case 'n': sscanf(optarg,"%u",&numart); break;
-    default : errflg++;
-  }
-  if ( numart == 0 || optind == argc )
-    errflg++;
-  if ( errflg ) {
-    fprintf(stderr,"Usage: %s [-n articles] host ...\n",argv[0]);
-    exit(1);
-  }
-
-  if ( (tcp_proto = getprotobyname("tcp")) == 0 )
-    fatal("getprotobyname");
-  for ( whoP = argv+optind; *whoP != 0; whoP++ ) {
-    if ( (sock = socket(PF_INET,SOCK_STREAM,tcp_proto->p_proto)) < 0 )
-      fatal("socket");
-    temp = inet_addr(*whoP);
-    if ( temp != (unsigned long) -1 ) {
-      sock_in.sin_addr.s_addr = temp;
-      sock_in.sin_family = AF_INET;
-    }
-    else {
-      host = gethostbyname(*whoP);
-      if ( host ) {
-       sock_in.sin_family = host->h_addrtype;
-       memcpy(&sock_in.sin_addr,host->h_addr,host->h_length);
-      }
-      else {
-       fprintf(stderr,"gethostbyname can't find %s\n",*whoP);
-       exit(1);
-      }
-    }
-    sock_in.sin_port = htons(NNTPPORT);
-    printf("---------------------------------\n%s is %s port %d\n",
-              *whoP,inet_ntoa(sock_in.sin_addr),ntohs(sock_in.sin_port));
-    punt(numart);
-    close(sock);
-  }
-}
-
-error(what)
-char *what;
-{
-  ptime(); fflush(stdout);
-  perror(what);
-}
-
-fatal(what)
-char *what;
-{
-  error(what);
-  exit(2);
-}
-
-ierror(how,what)
-char *how, *what;
-{
-  printf("Expected %s, bailing out.\n",how);
-}
-
-ifatal(how,what)
-char *how, *what;
-{
-  ierror(how,what);
-  exit(1);
-}
-
-unsigned do_time(start)
-unsigned start;
-{
-  struct timeval now;
-
-  gettimeofday(&now,(struct timezone *)0);
-  return ( now.tv_sec*1000 + now.tv_usec/1000 - start );
-}
-
-
-unsigned start, elapsed, diff;
-
-ptime()
-{
-  diff = elapsed;
-  elapsed = do_time(start);
-  diff = elapsed - diff;
-  printf("%5.1f %5.1f  ",((float)elapsed)/1000.0,((float)diff)/1000.0);
-}
-
-massagebuff(bread,buf)
-int bread;
-char *buf;
-{
-  char *p;
-
-  if ( bread > 55 )
-    strcpy(buf+55," [...]\n");
-  else
-    buf[bread] = '\0';
-  for ( p = buf; *p != '\0'; )
-    if ( *p != '\r' )  /* We like to do it RISC style. */
-      p++;
-    else {
-      *p = ' ';
-      p++;
-    }
-}
-
-punt(numart)
-int numart;
-{
-  static char ihave[32],
-             dot[] = ".\r\n",
-             quit[] = "quit\r\n";
-  struct timeval start_tv;
-  int bread;
-
-  printf(" elap  diff\n");
-  diff = elapsed = 0;
-  gettimeofday(&start_tv,(struct timezone *)0);
-  start = start_tv.tv_sec*1000 + start_tv.tv_usec/1000;
-
-  ptime();
-  printf("Connecting ...\n");
-  if ( connect(sock,(struct sockaddr*)&sock_in,sizeof(sock_in)) < 0 ) {
-    error("connect");
-    return(-1);
-  }
-  ptime();
-  printf("OK, waiting for prompt\n");
-
-  if ( (bread=read(sock,buf,sizeof(buf))) < 0 ) {
-    error("read socket");
-    return(-1);
-  }
-  massagebuff(bread,buf);
-  ptime();
-  printf("<<< %s",buf);
-  if ( strncmp(buf,"200",3) != 0 && strncmp(buf,"201",3) != 0 ) {
-    ierror("200 or 201",buf);
-    return(-1);
-  }
-
-  do {
-    snprintf(ihave,sizeof(ihave),"ihave <%u@a>\r\n",start+numart);
-    ptime();
-    printf(">>> %s",ihave);
-    if ( write(sock,ihave,strlen(ihave)) != strlen(ihave) ) {
-      error("write socket");
-      return(-1);
-    }
-
-    if ( (bread=read(sock,buf,sizeof(buf))) < 0 ) {
-      error("read socket");
-      return(-1);
-    }
-    massagebuff(bread,buf);
-    ptime();
-    printf("<<< %s",buf);
-    if ( strncmp(buf,"335",3) != 0 && strncmp(buf,"435",3) != 0 ) {
-      ierror("335 or 435 ",buf);
-      return(-1);
-    }
-
-    if ( strncmp(buf,"335",3) == 0 ) {
-      ptime();
-      printf(">>> %s",dot);
-      if ( write(sock,dot,sizeof(dot)-1) != sizeof(dot)-1 ) {
-       error("write socket");
-       return(-1);
-      }
-
-      if ( (bread=read(sock,buf,sizeof(buf))) < 0 ) {
-       error("read socket");
-       return(-1);
-      }
-      massagebuff(bread,buf);
-      ptime();
-      printf("<<< %s",buf);
-      if ( strncmp(buf,"437",3) != 0 && strncmp(buf,"235",3) != 0 ) {
-       ierror("437 or 235",buf);
-       return(-1);
-      }
-    }
-  } while ( --numart != 0 );
-
-  ptime();
-  printf(">>> %s",quit);
-  if ( write(sock,quit,sizeof(quit)-1) != sizeof(quit)-1 ) {
-    error("write socket");
-    return(-1);
-  }
-
-  if ( (bread=read(sock,buf,sizeof(buf))) < 0 ) {
-    error("read socket");
-    return(-1);
-  }
-  massagebuff(bread,buf);
-  ptime();
-  printf("<<< %s",buf);
-  if ( strncmp(buf,"205",3) != 0 ) {
-    ierror("205",buf);
-    return(-1);
-  }
-  return(0);
-}
diff --git a/contrib/pullart.c b/contrib/pullart.c
deleted file mode 100644 (file)
index 6b06099..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-June 14, 1999
-
-Recover text articles from cyclic buffers
-Articles start with  "\0Path:"
-and end with "\r\n.\r\n"
-
-Tested with INND 2.2 under AIX 4.2
-
-rifkin@uconn.edu
-*/
-/*
-(1) Pull 16 bytes at a time
-(2) Last 7 bytes must be \000\000\000Path
-(3) When found, print "\nPath";
-(4) print subsequent bytes until \r\n.\r\n found
-*/
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define INFILE     1
-#define FILEPREFIX 2
-#define HEADER     3
-#define STRING     4
-
-/*  String buffer size  */
-#define NBUFF 512
-
-#define MAX_ART_SIZE 2200000
-
-
-#define WRITEMSG printf ("File %s line %i\n", __FILE__, __LINE__); \
-       fflush(stdout);
-
-#define WRITEVAR(VAR_NAME,VAR_TYPE) \
-      { \
-      printf ("FILE %s LINE %i :", __FILE__, __LINE__); \
-      printf ("%s = ", #VAR_NAME); \
-      printf (#VAR_TYPE, (VAR_NAME) ); \
-      printf ("\n"); \
-      }
-
-#define WRITETXT(TEXT)  \
-       printf ("FILE %s LINE %i \"%s\"\n", __FILE__, __LINE__, TEXT); \
-       fflush(stdout);
-
-#if 0
-#define WRITEMSG
-#define WRITEVAR(X,Y)
-#endif
-
-
-int WriteArticle (char *, int, char *, char *, char *, int);
-
-
-char ArtHead[7] = {0, 0, 0, 'P', 'a', 't', 'h'};
-char ArtTail[5] = {'\r', '\n', '.', '\r', '\n'};
-int  LenTail    = 5;
-
-int main (int argc, char *argv[])
-       {
-       FILE *Infile;
-       int   NumTailCharFound;
-       bool  ReadingArticle = false;
-       char  buffer[32];
-       char *obuffer = NULL;
-       char *header  = NULL;
-       char *string  = NULL;
-       int   osize = MAX_ART_SIZE;
-       int   opos  = 0;
-       int   i;
-       int   nchar;
-       int   fileno = 0;
-       int   artno  = 0;
-       
-       /*  Check number of args  */
-       if (argc<3)
-               {
-               printf ("Usage: pullart <cycbuff> <fileprefix> [<header> <string>]\n");
-               printf ("  Read cycbuffer <cycbuff> and print all articles whose\n");
-               printf ("   article header <header> contains <string>.\n");
-               printf ("  Articles are written to files name <fileprefix>.nnnnnn\n");
-               printf ("   where nnnnnn is numbered sequentially from 0.\n");
-               printf ("  If <header> and <string> not specified, all articles\n");
-               printf ("   are written.\n");
-               printf (" Examples:\n");
-               printf ("  pullart /news3/cycbuff.3 alt.rec  Newsgroup: alt.rec\n");
-               printf ("  pullart /news3/cycbuff.3  all\n");
-               printf ("  pullart firstbuff  article Subject bluejay\n");
-               return 0;
-               }
-
-       /*  Allocate output buffer  */
-       obuffer = (char *) calloc (osize+1, sizeof(char));
-       if (obuffer==NULL)
-               {
-               printf ("Cannot allocate obuffer[]\n");
-               return 1;
-               }
-
-
-       /*  Open input file  */
-       Infile = fopen (argv[INFILE], "rb");
-       if (Infile==NULL)
-               {
-               printf ("Cannot open input file.\n");
-               return 1;
-               }
-
-
-if (argc>=4) header = argv[HEADER];
-if (argc>=5) string = argv[STRING];
-if (*header=='\0') header=NULL;
-if (*string=='\0') string=NULL;
-
-/*test*/
-printf ("filename <%s>\n", argv[INFILE]);
-printf ("fileprefix <%s>\n", argv[FILEPREFIX]);
-printf ("header <%s>\n", header);
-printf ("string <%s>\n", string);
-
-
-       /*  Skip first 0x38000 16byte buffers  */
-       i = fseek (Infile, 0x38000L, SEEK_SET);
-
-       /*  Read following 16 byte buffers  */
-       ReadingArticle = false;
-       NumTailCharFound = 0;
-       nchar=0;
-       artno=0;
-       while ( 0!=fread(buffer, 16, 1, Infile) )
-               {
-
-               nchar+=16;
-
-               /*  Found start of article, start writing to obuffer  */
-               if (0==memcmp(buffer+9, ArtHead, 7))
-                       {
-                       ReadingArticle = true;
-                       memcpy (obuffer, "Path", 4);
-                       opos = 4;
-                       continue;
-                       }
-
-               /*  Currnetly reading article  */
-               if (ReadingArticle)
-                       {
-                       for (i=0; i<16; i++)
-                               {
-
-                               /*  Article too big, drop it and move on  */
-                               if (opos>=osize)
-                                       {
-                                       printf 
-                                               ("article number %i bigger than buffer size %i.\n", 
-                                               artno+1, osize);
-                                       artno++;
-                                       ReadingArticle=false;
-                                       break;
-                                       }
-
-                               /*  Add current character to output buffer, but remove \r  */
-                               if ('\r' != buffer[i])
-                                       obuffer[opos++] = buffer[i];
-
-                               /*  Check for article ending sequence  */
-                               if (buffer[i]==ArtTail[NumTailCharFound])
-                                       {
-                                       NumTailCharFound++;
-                                       }
-                               else
-                                       NumTailCharFound=0;
-
-                               /*  End found, write article, reset for next  */
-                               if (NumTailCharFound==LenTail)
-                                       {
-                                       ReadingArticle = false;
-                                       NumTailCharFound = 0;
-
-                                       /*  Add trailing \0 to buffer  */
-                                       obuffer[opos+1] = '\0';
-
-                                       fileno += WriteArticle 
-                                               (obuffer, opos, argv[FILEPREFIX], 
-                                               header, string, fileno);
-                                       artno++;
-                                       break;
-                                       }
-                               }
-                       
-                       }
-
-               }
-
-       close (Infile);
-
-       return 0;
-       }
-
-
-
-/*
-Writes article stored in buff[] if it has a
-"Newsgroups:" header line which contains *newsgroup
-Write to a file named  fileprefix.fileno
-*/
-int
-WriteArticle 
-(char *buff, int n, char *fileprefix, char *headerin, char *string, int fileno)
-       {
-       char *begptr;
-       char *endptr;
-       char *newsptr;
-       char savechar;
-       char header[NBUFF];
-       char filename[NBUFF];
-       FILE *outfile;
-
-
-       /*  Prevent buffer overflow due to fileprefix too long  */
-       if (strlen(fileprefix)>384)
-               {
-               printf 
-               ("program error: cannot have file prefix greater then 384 characters\n");
-               exit(1);
-               }
-
-       /*  
-       Is header here?  Search if header string requested, leave if not found  
-       */
-       if (headerin!=NULL)
-               {
-               /*  Find \nHEADER  */
-                strlcpy(header, "\n", sizeof(header));
-                strlcat(header, headerin, sizeof(header));
-
-               begptr = strstr (buff, header);
-               
-               /*  return if Header name not found  */
-               if (begptr==NULL)
-                       {
-                       return 0;
-                       }
-
-               /*  
-               Header found. What about string?
-               Search if string requested, leave if not found  
-               */
-               if (string!=NULL)
-                       {
-                       /*  Find end of header line  */
-                       begptr++;
-                       endptr = strchr (begptr, '\n');
-
-                       /*  Something is wrong, end of header not found, do not write
-                        *  article  
-                       */
-                       if (endptr==NULL)
-                               return 0;
-
-                       /*  Temporarily make string end a null char  */
-                       savechar = *endptr;
-                       *endptr = '\0';
-                       newsptr = strstr (begptr, string);
-
-                       /*  Requested newsgroup not found  */
-                       if (newsptr==NULL)
-                               return 0;
-
-                       /*  Restore character at end of header string  */
-                       *endptr = savechar;
-                       }
-                       /*  No string specified  */
-
-               }
-       /*  No header specified  */
-
-       /*  Open file, write buffer, close file  */
-       snprintf (filename, sizeof(filename), "%s.%06i", fileprefix, fileno);
-
-       outfile = fopen (filename, "wt");
-       if (outfile==NULL) {
-               printf ("Cannot open file name %s\n", filename);
-               exit(1);
-               }
-
-       while (n--)
-               fprintf (outfile, "%c", *buff++);
-
-       close (outfile);
-
-       /*  Return number of files written  */
-       return 1;
-       }
diff --git a/contrib/reset-cnfs.c b/contrib/reset-cnfs.c
deleted file mode 100644 (file)
index 18bb334..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Quick and Dirty Hack to reset a CNFS buffer without having to DD the
- * Entire Thing from /dev/zero again. */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <stdio.h>
-
-/* uncomment the below for LARGE_FILES support */ 
-/* #define LARGE_FILES */
-
-int main(int argc, char *argv[])
-{
-    int fd;
-    int i, j;
-    char buf[512];
-#ifdef LARGE_FILES 
-    struct stat64 st; 
-#else 
-    struct stat st; 
-#endif
-    int numwr;
-
-    bzero(buf, sizeof(buf));
-    for (i = 1; i < argc; i++) {
-#ifdef LARGE_FILES 
-       if ((fd = open(argv[i], O_LARGEFILE | O_RDWR, 0664)) < 0) 
-#else 
-       if ((fd = open(argv[i], O_RDWR, 0664)) < 0) 
-#endif
-           fprintf(stderr, "Could not open file %s: %s\n", argv[i], strerror(errno));
-       else {
-#ifdef LARGE_FILES 
-           if (fstat64(fd, &st) < 0) { 
-#else 
-           if (fstat(fd, &st) < 0) { 
-#endif
-               fprintf(stderr, "Could not stat file %s: %s\n", argv[i], strerror(errno));
-           } else {
-               /* each bit in the bitfield is 512 bytes of data.  Each byte
-                * has 8 bits, so calculate as 512 * 8 bytes of data, plus
-                * fuzz. buf has 512 bytes in it, therefore containing data for
-                * (512 * 8) * 512 bytes of data. */
-               numwr = (st.st_size / (512*8) / sizeof(buf)) + 50;
-               printf("File %s: %u %u\n", argv[i], st.st_size, numwr);
-               for (j = 0; j < numwr; j++) {
-                   if (!(j % 100))
-                       printf("\t%d/%d\n", j, numwr);
-                   write(fd, buf, sizeof(buf));
-               }
-           }
-           close(fd);
-       }
-    }
-}
diff --git a/contrib/respool.c b/contrib/respool.c
deleted file mode 100644 (file)
index 71ed2bd..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-** Refile articles into the storage manager under the current storage.conf
-** rules, deleting articles from their old place in the spool.
-** Written 10-09-99 by rmtodd@servalan.servalan.com
-**
-** Note that history and overview will have to be rebuilt for the moved
-** articles to be visible after they're moved.
-*/
-
-/* include foo needed by libinn/storage manager */
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-char *ME;
-
-static void
-ProcessLine(char *line)
-{
-    char *tokenptr;
-    int len;
-    ARTHANDLE *art;
-    ARTHANDLE newart;
-    TOKEN token, newtoken;
-    char *arttmp;
-    time_t arrived;
-
-    tokenptr = line;
-    
-    /* zap newline at end of tokenptr, if present. */
-    len = strlen(tokenptr);
-    if (tokenptr[len-1] == '\n') {
-       tokenptr[len-1] = '\0';
-    }
-
-    token = TextToToken(tokenptr);
-    if ((art = SMretrieve(token, RETR_ALL)) == NULL) return;
-
-    len = art->len;
-    arrived = art->arrived;
-    arttmp = xmalloc(len);
-    memcpy(arttmp, art->data, len);
-    SMfreearticle(art);
-    if (!SMcancel(token)) {
-       fprintf(stderr, "%s: cant cancel %s:%s\n", ME, tokenptr, SMerrorstr);
-       return;
-    }
-
-    newart.data = arttmp;
-    newart.len = len;
-    newart.arrived = (time_t) 0; /* set current time */
-    newart.token = (TOKEN *)NULL;
-
-    newtoken = SMstore(newart);
-    if (newtoken.type == TOKEN_EMPTY) {
-       fprintf(stderr, "%s: cant store article:%s\n", ME, SMerrorstr);
-       return;
-    }
-    free(arttmp);
-    printf("refiled %s ",TokenToText(token));
-    printf("to %s\n", TokenToText(newtoken));
-    return;
-}
-
-int
-main(int argc UNUSED, char *argv[])
-{
-    bool       one = true;
-    char       buff[SMBUF];
-
-    ME = argv[0];
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    if (!SMsetup(SM_PREOPEN, &one) || !SMsetup(SM_RDWR, (void *)&one)) {
-       fprintf(stderr, "can't init storage manager");
-       exit(1);
-    }
-    if (!SMinit()) {
-       fprintf(stderr, "Can't init storage manager: %s", SMerrorstr);
-    }
-    while (fgets(buff, SMBUF, stdin)) {
-       ProcessLine(buff);
-    }
-    printf("\nYou will now need to rebuild history and overview for the moved"
-           "\narticles to be visible again.\n");
-    exit(0);
-}
diff --git a/contrib/sample.init.script b/contrib/sample.init.script
deleted file mode 100644 (file)
index 104ca48..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/sbin/sh
-
-# This is a simple, bare-bones example of a SysV-style init.d script for INN.
-
-case $1 in
-
-start)
-       su news -c /usr/local/news/bin/rc.news
-       ;;
-
-stop)
-       su news -c '/usr/local/news/bin/rc.news stop'
-       ;;
-
-esac
-
-exit 0
-
diff --git a/contrib/showtoken.in b/contrib/showtoken.in
deleted file mode 100644 (file)
index 4f513ce..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/perl -w
-# showtoken - decode SM tokens
-# Olaf Titz, 1999. Marco d'Itri, 2000. Public domain.
-# Takes tokens on stdin and write them along with a decoded form on stdout.
-
-use strict;
-
-my ($pathspool, %NG);
-
-my @types = ('trash', '', 'timehash', 'cnfs', 'timecaf', 'tradspool');
-
-if ($ARGV[0]) {
-       $pathspool = $ARGV[0];
-       if (open(MAP, "$pathspool/tradspool.map")) {
-               while (<MAP>) {
-                       my ($ng, $gnum) = split;
-                       $NG{$gnum} = $ng;
-               }
-               close MAP;
-       }
-}
-
-$| = 1;
-while (<STDIN>) {
-       chomp;
-       next if not /^@.+@/;
-       print "$_ ";
-       splittoken($_);
-}
-
-sub splittoken {
-       my $t = shift;
-
-       $t =~ tr/@//d;
-       $t = pack('H*', $t);
-       my ($type, $class, $token, $index, $offset, $overlen, $cancelled) =
-               unpack('C C a16 CLnc', $t);
-
-       if (not $types[$type]) {
-               print "type=$type unknown!\n";
-               next;
-       }
-       print "type=$types[$type] class=$class ";
-
-       if ($type == 0) {               # trash
-       } elsif ($type == 2) {  # timehash
-               my ($time, $seq) = unpack('Nn', $token);
-               my ($a, $b, $c, $d) = unpack('CCCC', $token);
-               printf 'time=%08lX seq=%04X file=time-%02x/%02x/%02x/%04x-%02x%02x',
-                       $time, $seq, $class, $b, $c, $seq, $a, $d;
-       } elsif ($type == 3) {  # cnfs
-               my ($buffn, $offset, $cnum) = unpack('A8NN', $token);
-               printf 'buffer=%s offset=%x cycnum=%x', $buffn, $offset * 512, $cnum;
-       } elsif ($type == 4) {  # timecaf
-               my ($time, $seq) = unpack('Nn', $token);
-               my (undef, $b, $c, $d) = unpack('CCCC', $token);
-               printf 'time=%06lX seq=%04X caf=timecaf-%02x/%02x/%02x%02x.CF',
-                       $time, $seq, $class, $c, $b, $d;
-       } elsif ($type == 5) {  # tradspool
-               my ($gnum, $art) = unpack('NN', $token);
-               printf 'ng=%08X art=%d', $gnum, $art;
-               print "file=articles/$NG{$gnum}/$art" if $NG{$gnum};
-       } else {
-               die "invalid type $type";
-       }
-       print " over=$index offset=$offset overlen=$overlen cancelled=$cancelled"
-               if length $t > 36;
-       print "\n";
-}
-__END__
-# Format of a token:
-#  1   type
-#  1   class
-# 16   token
-#  1   index
-#  4   offset
-#  2   overlen
-#  2   cancelled
-# The fields "index" and following are not available with OV3 (INN 2.3 up)
-#
-# the "token" field is:
-# for type=0 (trash) ignored
-# for type=2 (timehash)
-#  4   time
-#  2   seqnum
-# for type=3 (cnfs)
-#  8   cycbuffname
-#  4   offset/512
-#  4   cycnum
-# for type=4 (timecaf)
-#  4   time
-#  2   seqnum
-# for type=5 (tradspool)
-#  4   ngnum
-#  4   artnum
diff --git a/contrib/stathist.in b/contrib/stathist.in
deleted file mode 100644 (file)
index c34c911..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/perl -w
-
-# Parse log files created by innd history profiler
-# 2001/01/29 - Fabien Tassin
-
-use strict;
-use FileHandle;
-
-my $file = shift || "stathist.log";
-if ($file eq '-h' || $file eq '--help') {
-  print "Usage: stathist [logfile]\n";
-  exit 0;
-}
-
-sub parse {
-  my $file = shift;
-
-  my $f = new FileHandle $file;
-  unless (defined $f) {
-    print STDERR "Can't open file: $!\n";
-    return {};
-  }
-  my $data = {};
-  my $begin = 1;
-  my @stack = ();
-  while (defined (my $line = <$f>)) {
-    next if $begin && $line !~ / HIS(havearticle|write|setup) begin/;
-    $begin = 0;
-    chomp $line;
-    my @c = split /[\[\]\(\) ]+/, $line;
-    ($c[4] eq 'begin') && do {
-      push @stack, $c[3];
-      my $d = $data;
-      for my $l (@stack) {
-       unless (defined $$d{$l}) {
-         $$d{$l}{'min'} = 1E10;
-         $$d{$l}{'total'} = $$d{$l}{'count'} = $$d{$l}{'max'} = 0;
-       }
-       $d = $$d{$l}
-      }
-    } ||
-    ($c[4] eq 'end') && do {
-      my $d = $data;
-      for my $l (@stack) {
-       $d = $$d{$l};
-      }
-      $$d{'count'}++;
-      $$d{'total'} += $c[5];
-      $$d{'min'} = $c[5] if $$d{'min'} > $c[5];
-      $$d{'max'} = $c[5] if $$d{'max'} < $c[5];
-      pop @stack;
-    };
-  }
-  $f->close;
-  $data;
-}
-
-sub report {
-  my $data = shift;
-  my $inc = shift;
-
-  unless (defined $inc) {
-    printf "%-16s %10s %14s %10s %10s %10s\n\n", "Function", "Invoked",
-      "Total(s)", "Min(ms)", "Avg(ms)", "Max(ms)";
-    $inc = 0;
-  }
-
-  for my $key (sort keys %$data) {
-    next unless $key =~ m/^HIS/;
-    printf "%-16s %10d %14.6f %10.3f %10.3f %10.3f\n", ('  ' x $inc) . $key,
-      $$data{$key}{'count'}, $$data{$key}{'total'}, $$data{$key}{'min'} * 1000,
-      $$data{$key}{'total'} / $$data{$key}{'count'} * 1000,
-      $$data{$key}{'max'} * 1000;
-    &report($$data{$key}, $inc + 1)
-  }
-}
-
-my $data = &parse($file);
-&report($data);
diff --git a/contrib/thdexpire.in b/contrib/thdexpire.in
deleted file mode 100644 (file)
index 93b09bf..0000000
+++ /dev/null
@@ -1,647 +0,0 @@
-#!/usr/bin/perl -w
-# fixscript will replace this line with require innshellvars.pl
-$ID='$Id: thdexpire.in 4572 2001-02-24 22:31:05Z rra $$';
-
-use POSIX ":fcntl_h";
-use SDBM_File;
-use Getopt::Std;
-
-# With the -M switch this program installs its own man page.
-#-----------------------------------------------------------------------------
-
-=head1 NAME
-
-thdexpire - dynamic expire daemon for timehash and timecaf storage
-
-=head1 SYNOPSIS
-
-B<thdexpire>
-[ B<-t> I<minutes> ]
-[ B<-f> I<kilobytes> ]
-[ B<-i> I<inodes> ]
-[ B<-m> I<mindays> ]
-[ B<-x> I<minseconds> ]
-[ B<-N> ]
-[ B<-v> I<level> ]
-
-B<thdexpire -r>
-
-=head1 DESCRIPTION
-
-This is a daemon, to be started along with B<innd>, which periodically
-looks if news spool space is getting tight, and frees space by removing
-articles until enough is free. It is an adjunct (not a replacement) to
-INNs B<expire> program.
-
-=head2 Setting Up
-
-=over 4
-
-=item 1.
-
-Configure your storage classes carefully. Let the default go in class
-100 and choose the storage classes as relative (percent) retention
-times. E.g. if you want to give C<alt.binaries.*> a fifth of the
-default time, put them in class 20. Storage classes above 200 are
-ignored by this program. 0 expires immediately. An example is given
-in L<"EXAMPLES">.
-
-=item 2.
-
-Set up your F<expire.ctl> in a way that it puts only a maximum cap on
-retention times. Run B<expire> from B<news.daily> as usual. However,
-it should only expire articles which have an Expires line or are in
-classes above 200. See L<"EXAMPLES">.
-
-=item 3.
-
-Ensure to start this daemon along with B<innd>.
-
-=item 4.
-
-To get information and statistics, run B<thdexpire -r> (in parallel to
-a running daemon). This will show you the current actual retention
-times.
-
-=back
-
-=head2 How It Works
-
-B<thdexpire> works directly on the spool. It assumes the layout
-described in the timehash and timecaf sections of L<storage.conf(5)> as of
-INN-2.x-CURRENT (Dec. 5, 1998). For every storage class associated
-with timehash/timecaf, B<thdexpire> keeps a I<work time> which is the
-modification time of the oldest article/CAF file in this class. This
-time is chosen so that the difference of the work time of class N to
-now (i.e. the I<retention time> for class N) will be N/100 of the
-retention time of class 100. The work time of all classes is
-continuously adjusted as time goes by. Articles and CAF files which
-are older than the work time are deleted.
-
-=head1 OPTIONS
-
-=over 8
-
-=item B<-t> I<minutes>
-
-Check for free space every I<minutes> minutes (default 30).
-
-=item B<-f> I<kilobytes>
-
-Leave I<kilobytes> kilobytes of free disk space on each spool
-filesystem (default 50000).
-
-=item B<-i> I<inodes>
-
-Leave I<inodes> inodes free on each spool filesystem (default 5000).
-
-=item B<-m> I<mindays>
-
-Set the minimum normal holding time for class 100 to I<mindays> days
-(default 7).
-
-=item B<-x> I<minseconds>
-
-Set the absolute minimum holding time for any article to I<minseconds>
-seconds (default 86400, i.e. 1 day).
-
-=item B<-N>
-
-Do not delete any articles, just print what would be done.
-
-=item B<-v> I<level>
-
-Set the verbosity level. Values from 1 to 3 are meaningful, where
-higher levels are mostly for debugging.
-
-=item B<-r>
-
-Do not run as a daemon, instead print a report from the database (see
-L<FILES>) on the available storage classes, current expire times and
-other stuff.
-
-=back
-
-=head1 EXAMPLES
-
-Here is an example F<storage.conf> file:
-
- # Large postings in binary groups are expired fast:
- # 20% retention time
- method timehash {
-   newsgroups: *.binaries.*,*.binaer.*,*.dateien.*,alt.mag.*
-   size: 30000
-   class: 20
- }
-
- # Local groups and *.answers groups don't expire at all with
- # thdexpire. These are handled by Expires lines and a cutoff
- # in expire.ctl.
- method timehash {
-   newsgroups: *.answers,news.announce.*,local.*
-   class: 201
- }
-
- # Expires lines are honored if they dont exceed 90 days.
- # Exempt those postings from thdexpire handling.
- method timehash {
-   newsgroups: *
-   expires: 1d,90d
-   class: 202
- }
-
- # Default: should be class 100 because thdexpire bases its
- # calculations thereupon.
- method timecaf {
-   newsgroups: *
-   class: 100
- }
-
-And here is an F<expire.ctl> which fits:
-
- # Our local groups are held 6 months
- local.*:A:7:180:180
- # Everything else is handled by thdexpire, or Expires lines
- *:A:7:never:never
-
-Note that B<thdexpire> does not actually use these files, they just
-configure other parts of the news system in an appropriate way.
-
-=head1 FILES
-
-=over 4
-
-=item F<E<lt>inn::pathdbE<gt>/thdexpstat.{dir,pag}>
-
-Holds state information like classes, expire times, oldest articles.
-When this file is missing, it will be rebuilt the next time the daemon
-is started, which basically means scanning the spool directories to
-find the oldest articles. With the B<-r> option, the contents of this
-file are printed.
-
-=item F<E<lt>inn::innddirE<gt>/thdexpire.pid>
-
-Contains the PID of the running daemon.
-
-=back
-
-=head1 SIGNALS
-
-I<SIGINT> or I<SIGTERM> can be sent to the daemon at any time, causing
-it to gracefully exit immediately.
-
-=head1 SEE ALSO
-
-L<expire(8)>, L<news.daily(8)>, L<storage.conf(5)>
-
-=head1 NOTES
-
-This version needs the B<inndf> program supplied with newer releases of INN.
-
-The filenames for timecaf were wrong in older versions of the INN
-documentation. This program uses the true filenames, as found by
-reading the INN source.
-
-=head1 DIAGNOSTICS
-
-Any error messages are printed on standard error. Normal progress
-messages, as specified by the B<-v> option, are printed on standard
-output.
-
-=head1 BUGS
-
-Storage classes which are in I<storage.conf> but not on disk (i.e.
-which have never been filed into) when the daemon starts are ignored.
-
-The code is ugly and uses too many global variables.
-Should probably rewrite it in C.
-
-=head1 RESTRICTIONS
-
-Directories which are left empty are not removed.
-
-The overview database is not affected by B<thdexpire>, it has to be
-cleaned up by the daily regular B<news.daily> run. This may need a
-patch to B<expire>.
-
-=head1 AUTHOR
-
-Olaf Titz <olaf@bigred.inka.de>. Use and distribution of this work is
-permitted under the same terms as the B<INN> package.
-
-=head1 HISTORY
-
-Inspired by the old B<dexpire> program for the traditional spool.
-
-June 1998: wrote the first version for timehash.
-
-November 1998: added code for timecaf, works on multiple spool
-filesystems, PODed documentation.
-
-July 1999: bugfixes.
-
-=cut
-
-#-----------------------------------------------------------------------------
-
-chdir $inn::spool || die "chdir $inn::spool: $!";
-$opt_r=0;      # make a report
-$opt_t=30;     # check interval in minutes
-$opt_f=50000;  # required space in kilobytes
-$opt_i=5000;   # required space in inodes
-$opt_m=7;      # minimum normal (class 100) time in days
-$opt_x=86400;  # absolute minimum hold time in seconds
-$opt_N=0;      # dont actually delete articles
-$opt_v=0;      # verbosity level
-$opt_M=0;      # install man page
-getopts("rt:f:i:m:x:Nv:M");
-
-$_=$inn::pathdb; $_=$inn::pathnews; # shut up warning
-$sfile="$inn::pathdb/thdexpstat";
-$ID=~/ ([^,]+,v [^ ]+)/; $ID=$1;
-
-if ($opt_M) {
-    print "Installing thdexpire(8) man page\n";
-    $0=~m:^(.*)/([^/]+)$:;
-    chdir $1 || die "chdir $1";
-    exec "pod2man --section=8 --center='Contributed News Software'" .
-      " --release='$ID' $2 >$inn::pathnews/man/man8/thdexpire.8";
-}
-
-if ($opt_r) {
-    tie(%S, SDBM_File, $sfile, O_RDONLY, 0664) || die "open $sfile: $!";
-    &report;
-    untie %S;
-    exit 0;
-}
-
-(system "shlock", "-p", $$, "-f", "$inn::innddir/thdexpire.pid")>>8==0
-  || die "Already running";
-tie(%S, SDBM_File, $sfile, O_RDWR|O_CREAT, 0664) || die "open $sfile: $!";
-$SIG{'TERM'}=$SIG{'INT'}='finish';
-$|=1;
-printf "%s starting at %s\n", $ID, &wtime(time) if ($opt_v>0);
-
-undef @c;
-$NOW=time; $ac=$cc=0;
-opendir(CD, ".") || &err("opendir $inn::spool: $!");
-while ($cd=readdir(CD), defined($cd)) {
-    $cd=~/^time(caf)?-([0-9a-f][0-9a-f])$/i || next;
-    $c{hex($2)}=1 unless hex($2)>200;
-}
-closedir CD;
-@classes=sort {$a<=>$b} keys %c;
-foreach $c (@classes) {
-    &initclass($c);
-    $S{"work$;$c"}=$S{"oldest$;$c"}&0xFFFFFF00;
-}
-
-$S{"classes"}=join(",", @classes);
-$S{"inittime"}=time;
-$S{"ID"}=$ID;
-printf "Checked %d articles, %d CAFs in %d seconds\n", $ac, $cc, time-$NOW
-  if ($ac+$cc>0 && $opt_v>0);
-
-chdir $inn::spool || die "chdir $inn::spool: $!";
-while (1) {
-    $S{"lastrun"}=$NOW=time;
-    printf "%s\n", &wtime($NOW) if ($opt_v>0);
-    $nt=0;
-    foreach $c (@classes) {
-       $t=($NOW-$S{"work$;$c"})*100/$c;
-       $nt=$t if ($nt<$t);
-    }
-    printf "Normal time (class 100): %s\n", &xtime($NOW-$nt)
-        if ($opt_v>0);
-    if ($nt<$opt_m*24*60*60) {
-       printf " capped at minimum %d days\n", $opt_m
-         if ($opt_v>0);
-       $nt=$opt_m*24*60*60;
-    }
-    if ($nt>180*24*60*60) {
-       print " capped at maximum 180 days\n"
-         if ($opt_v>0);
-       $nt=180*24*60*60;
-    }
-    $S{"normaltime"}=$nt;
-    $decrement=$opt_t*60;
-    $pass=$need=0;
-    $x="/";
-    undef %needk; undef %needi;
-    foreach $c (@classes) {
-       $Dart{$c}=$Dcaf{$c}=$Dkb{$c}=$Dino{$c}=0;
-       $y=sprintf("time-%02x", $c);
-       if (-d $y) {
-           @S=stat(_);
-           if ($#S>=0) {
-               $dev{$y}=$S[0];
-               unless (defined($needk{$S[0]})) {
-                   $x.=" $y";
-                   $needk{$S[0]}=$needi{$S[0]}=-1;
-               }
-           }
-       }
-       $y=sprintf("timecaf-%02x", $c);
-       if (-d $y) {
-           @S=stat(_);
-           if ($#S>=0) {
-               $dev{$y}=$S[0];
-               unless (defined($needk{$S[0]})) {
-                   $x.=" $y";
-                   $needk{$S[0]}=$needi{$S[0]}=-1;
-               }
-           }
-       }
-    }
-    if (open(D, "inndf $x |")) {
-       while (<D>) {
-           @S=split(/\s+/, $_);
-           $needk{$dev{$S[0]}}=$opt_f-$S[1] unless ($S[0] eq "/");
-       }
-       close D;
-    }
-    if (open(D, "inndf -i $x |")) {
-       while (<D>) {
-           @S=split(/\s+/, $_);
-           $needi{$dev{$S[0]}}=$opt_i-$S[1] unless ($S[0] eq "/");
-       }
-       close D;
-    }
-    foreach $c (keys %needk) {
-       printf "Device %d needs to free %d kilobytes, %d inodes\n",
-              $c, $needk{$c}<0?0:$needk{$c}, $needi{$c}<0?0:$needi{$c}
-           if ($opt_v>0 && ($needk{$c}>0 || $needi{$c}>0));
-       if ($needk{$c}>0 || $needi{$c}>0) {
-           ++$need;
-       }
-    }
-    if ($opt_v>0 && $need<=0) {
-       print "  (nothing to do)\n";
-       $tt=0;
-    } else {
-       $error=0;
-       while (!$error && $need>0) {
-           if ($S{"normaltime"}-$decrement<$opt_m*24*60*60) {
-               print "  Normal time hit minimum\n" if ($opt_v>0);
-               last;
-           }
-           $S{"normaltime"}-=$decrement;
-           printf "  normal time (100) becomes %ld\n", $S{"normaltime"}
-           if ($opt_v>2);
-           ++$pass;
-           $Dart=$Dcaf=$Dkb=$Dino=$need=0;
-           foreach $c (keys %needk) {
-               if ($needk{$c}>0 || $needi{$c}>0) {
-                   ++$need;
-               }
-           }
-           if ($need) {
-               foreach $c (@classes) {
-                   &worktime($c, $NOW-($S{"normaltime"}*$c/100));
-                   $Dart+=$dart; $Dcaf+=$dcaf; $Dkb+=$dbb>>10; $Dino+=$dino;
-                   $Dart{$c}+=$dart; $Dcaf{$c}+=$dcaf;
-                   $Dkb{$c}+=$dbb>>10; $Dino{$c}+=$dino;
-                   last if ($error);
-               }
-           }
-           if ($Dart+$Dcaf) {
-               printf "  pass %d deleted %d arts, %d CAFs, %d kb\n",
-                      $pass, $Dart, $Dcaf, $Dkb if ($opt_v>1);
-               $decrement-=$decrement>>2 if ($decrement>10*60);
-           } else {
-               $decrement+=$decrement>>1 if ($decrement<4*60*60);
-           }
-       }
-       $Dkb=$Dart=$Dcaf=$Dino=0;
-       foreach $c (@classes) {
-           printf "  class %3d: deleted %6d arts %6d CAFs %10d kb\n",
-                  $c, $Dart{$c}, $Dcaf{$c}, $Dkb{$c} if ($opt_v>1);
-           $Dkb+=$Dkb{$c}; $Dart+=$Dart{$c}; $Dcaf+=$Dcaf{$c};
-       }
-       $tt=time-$NOW;
-       printf " deleted %d articles, %d CAFs, %d kb in %d seconds\n",
-               $Dart, $Dcaf, $Dkb, time-$NOW if ($opt_v>0);
-       if ($tt>$opt_t*60) {
-           printf STDERR "Round needed %d seconds, interval is %d\n",
-           $tt, $opt_t*60;
-           $tt=$opt_t*60;
-       }
-    }
-    sleep $opt_t*60-$tt;
-}
-&finish(0);
-
-
-sub initclass
-{
-    my $C=shift;
-    if (!$S{"blocksize$;$C$;CAF"}) {
-       # Determine filesystem blocksize
-       # unfortunately no way in perl to statfs
-       my $x=sprintf("%s/timecaf-%02x/test%d", $inn::spool, $C, $$);
-       if (open(A, ">$x")) {
-           print A "X" x 4096;
-           close A;
-           @S=stat $x;
-           $#S>=12 || die "stat: $!";
-           if ($S[12]) {
-               $S{"blocksize$;$C$;CAF"}=$S[7]/$S[12];
-           } else {
-               $S{"blocksize$;$C$;CAF"}=512;
-               warn "hack around broken stat blocksize";
-           }
-           unlink $x;
-       }
-    }
-    return if ($S{"oldest$;$C"});
-    my $oldest=time;
-    $S{"oldest$;$C"}=$oldest;
-    my $base=sprintf("%s/time-%02x", $inn::spool, $C);
-    my $count=0;
-    if (chdir $base) {
-       printf "Finding oldest in class %d (%s)\n", $C, $base if ($opt_v>0);
-       opendir(D0, ".");
-       while ($d1=readdir(D0), defined($d1)) {
-           $d1=~/^[0-9a-f][0-9a-f]$/ || next;
-           chdir $d1;
-           opendir(D1, ".") || next;
-           while ($d2=readdir(D1), defined($d2)) {
-               $d2=~/^[0-9a-f][0-9a-f]$/ || next;
-               chdir $d2;
-               opendir(D2, ".") || next;
-               while ($a=readdir(D2), defined($a)) {
-                   $a=~/^\./ && next;
-                   @S=stat($a);
-                   $oldest=$S[9] if ($S[9]<$oldest);
-                   ++$count;
-               }
-               closedir D2;
-               chdir "..";
-           }
-           closedir D1;
-           chdir "..";
-       }
-       closedir D0;
-       $ac+=$count;
-    }
-    $base=sprintf("%s/timecaf-%02x", $inn::spool, $C);
-    if (chdir $base) {
-       printf "Finding oldest in class %d (%s)\n", $C, $base if ($opt_v>0);
-       opendir(D0, ".");
-       while ($d1=readdir(D0), defined($d1)) {
-           $d1=~/^[0-9a-f][0-9a-f]$/ || next;
-           chdir $d1;
-           opendir(D1, ".") || next;
-           while ($a=readdir(D1), defined($a)) {
-               $a=~/^\./ && next;
-               @S=stat($a);
-               $oldest=$S[9] if ($S[9]<$oldest);
-               ++$count;
-           }
-           closedir D1;
-           chdir "..";
-       }
-       closedir D0;
-       $cc+=$count;
-    }
-    $S{"count$;$C"}=$count;
-    $S{"oldest$;$C"}=$oldest;
-}
-
-sub worktime
-{
-    my $C=shift;
-    my $goal=shift;
-    $goal&=0xFFFFFF00;
-    printf "  goal for class %d becomes %s\n", $C, &xtime($goal)
-      if ($opt_v>2);
-    if ($goal>$NOW-$opt_x) {
-       printf "  goal for class %d cut off\n", $C
-         if ($opt_v>1);
-       $error=1;
-       return;
-    }
-    $dart=$dcaf=$dbb=$dino=0;
-    $hdir=sprintf("time-%02x", $C);
-    $cdir=sprintf("timecaf-%02x", $C);
-    while (($_=$S{"work$;$C"})<$goal) {
-       printf "  running: %08x\n", $_ if ($opt_v>2);
-       ($aa,$bb,$cc) = (($_>>24)&0xFF, ($_>>16)&0xFF, ($_>>8)&0xFF);
-       $dir=sprintf("%s/%02x/%02x", $hdir, $bb, $cc);
-       $pat=sprintf("[0-9a-f]{4}-%02x[0-9a-f]{2}", $aa);
-       if (opendir(D, $dir)) {
-           while ($_=readdir(D), defined($_)) {
-               /^$pat$/ || next;
-               $art="$dir/$_";
-               @S=stat($art);
-               if ($#S>=7) {
-                   if ($opt_N) {
-                       print "   would delete $art" if ($opt_v>2);
-                   } else {
-                       print "   deleting $art" if ($opt_v>2);
-                       unlink $art;
-                   }
-                   ++$dart; ++$dino;
-                   printf " %d kb\n", $S[7]>>10 if ($opt_v>2);
-                   $dbb+=$S[7];
-                   $needk{$dev{$hdir}}-=$S[7]>>10;
-                   $needi{$dev{$hdir}}--;
-               }
-           }
-       } else {
-           printf "  (no dir %s)\n", $dir if ($opt_v>2);
-       }
-       $caf=sprintf("%s/%02x/%02x%02x.CF", $cdir, $bb, $aa, $cc);
-       @S=stat($caf);
-       if ($#S>=12) {
-           if ($opt_N) {
-               print "   would delete $caf" if ($opt_v>2);
-           } else {
-               print "   deleting $caf" if ($opt_v>2);
-               unlink $caf;
-           }
-           $y=0;
-           if (open(C, $caf)) {
-               # try to find how much there is in the CAF
-               sysread(C, $_, 16);
-               @C=unpack("a4LLL", $_);
-               if ($C[0] eq "CRMT") {
-                   $y=$C[3]-$C[1];
-                   $dart+=$y;
-               }
-               close C;
-           }
-           ++$dcaf; ++$dino;
-           if ($S[12]) {
-               $x=$S[12]*$S{"blocksize$;$C$;CAF"};
-           } else {
-               $x=$S[7];
-               warn "hack around broken stat blocksize";
-           }
-           printf " %d arts %d kb\n", $y, $x>>10 if ($opt_v>2);
-           $dbb+=$x;
-           $needk{$dev{$cdir}}-=$x>>10;
-           $needi{$dev{$cdir}}--;
-       }
-       $S{"work$;$C"}+=0x100;
-       $S{"oldest$;$C"}=$S{"work$;$C"} unless ($opt_N);
-    }
-}
-
-sub report
-{
-    $NOW=time;
-    my $cc=$S{"classes"};
-    my $nt=$S{"normaltime"};
-    unless ($cc && $nt) {
-       print "Not initialized.\n";
-       return;
-    }
-    printf "Version: %s (this: %s)\n", $S{"ID"}, $ID;
-    printf "Started at: %s\n", &xtime($S{"inittime"}) if ($S{"inittime"});
-    printf "Last run: %s\n", &xtime($S{"lastrun"}) if ($S{"lastrun"});
-    printf "Classes: %s\n", $cc;
-    foreach $c (split(/,/, $cc)) {
-       printf "Class %d:\n", $c;
-       #printf "  Initial count %d articles\n", $S{"count$;$c"};
-       printf "  Oldest article: %s\n", &xtime($S{"oldest$;$c"});
-       printf "  Expiring at:    %s\n", &xtime($S{"work$;$c"});
-       printf "  Normal time:    %s\n", &xtime($NOW-$nt*$c/100);
-       printf "  Filesystem block size (CAF): %d\n", $S{"blocksize$;$c$;CAF"};
-    }
-}
-
-sub wtime
-{
-    my $t=shift;
-    my @T=localtime($t);
-    sprintf("%04d-%02d-%02d %02d:%02d",
-           $T[5]+1900, $T[4]+1, $T[3], $T[2], $T[1]);
-}
-
-sub xtime
-{
-    my $t=shift;
-    if ($NOW-$t<0 || $NOW-$t>350*24*60*60) {
-       return &wtime($t);
-    }
-    my @T=localtime($t);
-    my @D=gmtime($NOW-$t);
-    sprintf("%04d-%02d-%02d %02d:%02d (%dd %dh %dm)",
-           $T[5]+1900, $T[4]+1, $T[3], $T[2], $T[1],
-           $D[7], $D[2], $D[1]);
-}
-
-sub err
-{
-    printf STDERR "%s\n", shift;
-    &finish(0);
-}
-
-sub finish
-{
-    untie(%S);
-    unlink "$inn::innddir/thdexpire.pid";
-    exit 0;
-}
-#-----------------------------------------------------------------------------
diff --git a/contrib/tunefeed.in b/contrib/tunefeed.in
deleted file mode 100644 (file)
index 52616ae..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#!/usr/bin/perl
-$version = q$Id: tunefeed.in 4329 2001-01-14 13:47:52Z rra $;
-#
-# tunefeed -- Compare active files with a remote site to tune a feed.
-#             Copyright 1998 by Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-############################################################################
-# Site configuration
-############################################################################
-
-# A list of hierarchies in the Big Eight.
-%big8 = map { $_ => 1 } qw(comp humanities misc news rec sci soc talk);
-
-# A list of hierarchies that are considered global and not language
-# hierarchies.
-%global = map { $_ => 1 } qw(bionet bit biz borland ddn gnu gov ieee info
-                             linux k12 microsoft netscape tnn vmsnet);
-
-# The pattern matching local-only hierarchies (that we should disregard when
-# doing feed matching).
-%ignore = map { $_ => 1 } qw(clari control junk);
-
-
-############################################################################
-# Modules and declarations
-############################################################################
-
-require 5.003;
-
-use Getopt::Long qw(GetOptions);
-
-use strict;
-use vars qw(%big8 $days %global %ignore $threshold %traffic $version);
-
-
-############################################################################
-# Active file hashing and analysis
-############################################################################
-
-# Read in an active file, putting those groups into a hash where the key is
-# the name of the group and the value is always 1.  If the optional third
-# argument is true, exclude any groups in the hierarchies listed in %local
-# and use this active file to store traffic information (in a rather
-# simple-minded fashion).
-sub hash {
-    my ($file, $hash, $local) = @_;
-    open (ACTIVE, $file) or die "$0: cannot open $file: $!\n";
-    local $_;
-    while (<ACTIVE>) {
-        my ($group, $high, $low, $flags) = split;
-        next if ($flags =~ /^=|^x/);
-        my $hierarchy = (split (/\./, $group, 2))[0];
-        next if ($local && $ignore{$hierarchy});
-        $$hash{$group} = 1;
-        $traffic{$group} = ($high - $low) / $days if $local;
-    }
-    close ACTIVE;
-}
-
-# Read in a file that gives traffic statistics.  We assume it's in the form
-# group, whitespace, number of articles per day, and we just read it
-# directly into the %traffic hash.
-sub traffic {
-    my ($file) = @_;
-    open (TRAFFIC, $file) or die "$0: cannot open $file: $!\n";
-    local $_;
-    while (<TRAFFIC>) {
-        my ($group, $traffic) = split;
-        $traffic{$group} = $traffic;
-    }
-    close TRAFFIC;
-}
-
-# Pull off the first X nodes of a group name.
-sub prefix {
-    my ($group, $count) = @_;
-    my @group = split (/\./, $group);
-    splice (@group, $count);
-    join ('.', @group);
-}
-
-# Find the common hierarchical prefix of a list.
-sub common {
-    my (@list) = @_;
-    my @prefix = split (/\./, shift @list);
-    local $_;
-    while (defined ($_ = shift @list)) {
-        my @group = split /\./;
-        my $i;
-        $i++ while ($prefix[$i] && $prefix[$i] eq $group[$i]);
-        if ($i <= $#prefix) { splice (@prefix, $i) }
-    }
-    join ('.', @prefix);
-}
-
-# Given two lists, a list of groups that the remote site does have and a
-# list of groups that the remote site doesn't have, in a single hierarchy,
-# perform a smash.  The object is to find the minimal pattern that expresses
-# just the groups they want.  We're also given the common prefix of all the
-# groups in the have and exclude lists, and a flag indicating whether we're
-# coming in with a positive assumption (all groups sent unless excluded) or
-# a negative assumption (no groups sent unless added).
-sub smash {
-    my ($have, $exclude, $top, $positive) = @_;
-    my (@positive, @negative);
-    my $level = ($top =~ tr/././) + 1;
-    
-    # Start with the positive assumption.  We make copies of our @have and
-    # @exclude arrays since we're going to be needing the virgin ones again
-    # later for the negative assumption.  If we're coming in with the
-    # negative assumption, we have to add a wildcarded entry to switch
-    # assumptions, and we also have to deal with the cases where there is a
-    # real group at the head of the hierarchy.
-    my @have = @$have;
-    my @exclude = @$exclude;
-    if ($top eq $have[0]) {
-        shift @have;
-        push (@positive, "$top*") unless $positive;
-    } else {
-        if ($top eq $exclude[0]) {
-            if ($positive && $traffic{$top} > $threshold) {
-                push (@positive, "!$top");
-            }
-            shift @exclude;
-        }
-        push (@positive, "$top.*") unless $positive;
-    }
-
-    # Now that we've got things started, keep in mind that we're set up so
-    # that every group will be sent *unless* it's excluded.  So we step
-    # through the list of exclusions.  The idea here is to pull together all
-    # of the exclusions with the same prefix (going one level deeper into
-    # the newsgroup names than we're currently at), and then find all the
-    # groups with the same prefix that the remote site *does* want.  If
-    # there aren't any, then we can just exclude that whole prefix provided
-    # that we're saving enough traffic to make it worthwhile (checked
-    # against the threshold).  If there are, and if the threshold still
-    # makes it worthwhile to worry about this, we call this sub recursively
-    # to compute the best pattern for that prefix.
-    while (defined ($_ = shift @exclude)) {
-        my ($prefix) = prefix ($_, $level + 1);
-        my @drop = ($_);
-        my @keep;
-        my $traffic = $traffic{$_};
-        while ($exclude[0] =~ /^\Q$prefix./) {
-            $traffic += $traffic{$exclude[0]};
-            push (@drop, shift @exclude);
-        }
-        $prefix = common (@drop);
-        my $saved = $traffic;
-        while (@have && $have[0] le $prefix) { shift @have }
-        while ($have[0] =~ /^\Q$prefix./) {
-            $traffic += $traffic{$have[0]};
-            push (@keep, shift @have);
-        }
-        next unless $saved > $threshold;
-        if (@keep) {
-            $traffic{"$prefix*"} = $traffic;
-            push (@positive, smash (\@keep, \@drop, $prefix, 1));
-        } elsif (@drop == 1) {
-            push (@positive, "!$_");
-        } elsif ($prefix eq $_) {
-            push (@positive, "!$prefix*");
-        } else {
-            push (@positive, "!$prefix.*");
-        }
-    }
-
-    # Now we do essentially the same thing, but from the negative
-    # perspective (adding a wildcard pattern as necessary to make sure that
-    # we're not sending all groups and then finding the groups we are
-    # sending and trying to smash them into minimal wildcard patterns).
-    @have = @$have;
-    @exclude = @$exclude;
-    if ($top eq $exclude[0]) {
-        shift @exclude;
-        push (@negative, "!$top*") if $positive;
-    } else {
-        if ($top eq $have[0]) {
-            push (@negative, $top) unless $positive;
-            shift @have;
-        }
-        push (@negative, "!$top.*") if $positive;
-    }
-
-    # This again looks pretty much the same as what we do for the positive
-    # case; the primary difference is that we have to make sure that we send
-    # them every group that they want, so we still err on the side of
-    # sending too much, rather than too little.
-    while (defined ($_ = shift @have)) {
-        my ($prefix) = prefix ($_, $level + 1);
-        my @keep = ($_);
-        my @drop;
-        my $traffic = $traffic{$_};
-        while ($have[0] =~ /^\Q$prefix./) {
-            $traffic += $traffic{$have[0]};
-            push (@keep, shift @have);
-        }
-        $prefix = common (@keep);
-        while (@exclude && $exclude[0] le $prefix) { shift @exclude }
-        my $saved = 0;
-        while ($exclude[0] =~ /^\Q$prefix./) {
-            $saved += $traffic{$exclude[0]};
-            push (@drop, shift @exclude);
-        }
-        if (@drop && $saved > $threshold) {
-            $traffic{"$prefix*"} = $traffic + $saved;
-            push (@negative, smash (\@keep, \@drop, $prefix, 0));
-        } elsif (@keep == 1) {
-            push (@negative, $_);
-        } elsif ($prefix eq $_) {
-            push (@negative, "$prefix*");
-        } else {
-            push (@negative, "$prefix.*");
-        }
-    }
-
-    # Now that we've built both the positive and negative case, we decide
-    # which to return.  We want the one that's the most succinct, and if
-    # both descriptions are equally succinct, we return the negative case on
-    # the grounds that it's likely to send less of what they don't want.
-    (@positive < @negative) ? @positive : @negative;
-}
-
-
-############################################################################
-# Output
-############################################################################
-
-# We want to sort Big Eight ahead of alt.* ahead of global non-language
-# hierarchies ahead of regionals and language hierarchies.
-sub score {
-    my ($hierarchy) = @_;
-    if ($big8{$hierarchy})      { return 1 }
-    elsif ($hierarchy eq 'alt') { return 2 }
-    elsif ($global{$hierarchy}) { return 3 }
-    else                        { return 4 }
-}
-
-# Our special sort routine for hierarchies.  It calls score to get a
-# hierarchy score and sorts on that first.
-sub by_hierarchy {
-    (score $a) <=> (score $b) || $a cmp $b;
-}
-
-# Given a reference to a list of patterns, output it in some reasonable
-# form.  Currently, this is lines prefixed by a tab, with continuation lines
-# like INN likes to have in newsfeeds, 76 column margin, and with a line
-# break each time the hierarchy score changes.
-sub output {
-    my ($patterns) = @_;
-    my ($last, $line);
-    for (@$patterns) {
-        my ($hierarchy) = /^!?([^.]+)/;
-        my $score = score $hierarchy;
-        $line += 1 + length $_;
-        if (($last && $score > $last) || $line > 76) {
-            print ",\\\n\t";
-            $line = 8 + length $_;
-        } elsif ($last) {
-            print ',';
-        } else {
-            print "\t";
-            $line += 8;
-        }
-        print;
-        $last = $score;
-    }
-    print "\n";
-}
-
-
-############################################################################
-# Main routine
-############################################################################
-
-# Clean up the name of this program for error messages.
-my $fullpath = $0;
-$0 =~ s%.*/%%;
-
-# Parse the command line.  Our argument is the path to an active file (we
-# tell the difference by seeing if it contains a /).
-my ($help, $print_version);
-Getopt::Long::config ('bundling');
-GetOptions ('help|h'        => \$help,
-            'days|d=i'      => \$days,
-            'threshold|t=i' => \$threshold,
-            'version|v'     => \$print_version) or exit 1;
-
-# Set a default for the minimum threshold traffic required to retain an
-# exclusion, and assume that active file differences represent one day of
-# traffic unless told otherwise.
-$threshold = (defined $threshold) ? $threshold : 250;
-$days ||= 1;
-
-# If they asked for our version number, abort and just print that.
-if ($print_version) {
-    my ($program, $ver) = (split (' ', $version))[1,2];
-    $program =~ s/,v$//;
-    die "$program $ver\n";
-}
-
-# If they asked for help, give them the documentation.
-if ($help) {
-    print "Feeding myself to perldoc, please wait....\n";
-    exec ('perldoc', '-t', $fullpath) or die "$0: can't fork: $!\n";
-}
-
-# Hash the active files, skipping groups we ignore in the local one.  Make
-# sure we have our two files listed first.
-unless (@ARGV == 2 || @ARGV == 3) {
-    die "Usage: $0 [-hv] [-t <threshold>] <local> <remote> [<traffic>]\n";
-}
-my (%local, %remote);
-hash (shift, \%local, 1);
-hash (shift, \%remote);
-traffic (shift) if @ARGV;
-
-# Now, we analyze the differences between the two feeds.  We're trying to
-# build a pattern of what *we* should send *them*, so stuff that's in
-# %remote and not in %local doesn't concern us.  Rather, we're looking for
-# stuff that we carry that they don't, since that's what we'll want to
-# exclude from a full feed.
-my (%have, %exclude, %count, $have, $exclude, $positive);
-for (sort keys %local) {
-    my ($hierarchy) = (split /\./);
-    $count{$hierarchy}++;
-    $traffic{"$hierarchy*"} += $traffic{$_};
-    if ($remote{$_}) { push (@{$have{$hierarchy}}, $_); $have++       }
-    else             { push (@{$exclude{$hierarchy}}, $_); $exclude++ }
-}
-my @patterns;
-if ($have > $exclude * 4) {
-    push (@patterns, "*");
-    $positive = 1;
-}
-for (sort by_hierarchy keys %count)  {
-    if ($have{$_} && !$exclude{$_}) {
-        push (@patterns, "$_.*") unless $positive;
-    } elsif ($exclude{$_} && !$have{$_}) {
-        push (@patterns, "!$_.*") if $positive;
-    } else {
-        push (@patterns, smash ($have{$_}, $exclude{$_}, $_, $positive));
-    }
-}
-output (\@patterns);
-__END__
-
-
-############################################################################
-# Documentation
-############################################################################
-
-=head1 NAME
-
-tunefeed - Build a newsgroups pattern for a remote feed
-
-=head1 SYNOPSIS
-
-B<tunefeed> [B<-hv>] [B<-t> I<threshold>] [B<-d> I<days>] I<local>
-I<remote> [I<traffic>]
-
-=head1 DESCRIPTION
-
-Given two active files, B<tunefeed> generates an INN newsfeeds pattern for
-a feed from the first site to the second, that sends the second site
-everything in its active file carried by the first site but tries to
-minimize the number of rejected articles.  It does this by noting
-differences between the two active files and then trying to generate
-wildcard patterns that cover the similarities without including much (or
-any) unwanted traffic.
-
-I<local> and I<remote> should be standard active files.  You can probably
-get the active file of a site that you feed (provided they're running INN)
-by connecting to their NNTP port and typing C<LIST ACTIVE>.
-
-B<tunefeed> makes an effort to avoid complex patterns when they're of
-minimal gain.  I<threshold> is the number of messages per day at which to
-worry about excluding a group; if a group the remote site doesn't want to
-receive gets below that number of messages per day, then that group is
-either sent or not sent depending on which choice results in the simplest
-(shortest) wildcard pattern.  If you want a pattern that exactly matches
-what the remote site wants, use C<-t 0>.
-
-Ideally, B<tunefeed> likes to be given the optional third argument,
-I<traffic>, which points at a file listing traffic numbers for each group.
-The format of this file is a group name, whitespace, and then the number
-of messages per day it receives.  Without such a file, B<tunefeed> will
-attempt to guess traffic by taking the difference between the high and low
-numbers in the active file as the amount of traffic in that group per day.
-This will almost always not be accurate, but it should at least be a
-ballpark figure.  If you know approximately how many days of traffic the
-active file numbers represent, you can tell B<tunefeed> this information
-using the B<-d> flag.
-
-B<tunefeed>'s output will look something like:
-
-        comp.*,humanities.classics,misc.*,news.*,rec.*,sci.*,soc.*,talk.*,\
-        alt.*,!alt.atheism,!alt.binaries.*,!alt.nocem.misc,!alt.punk*,\
-        !alt.sex*,!alt.video.dvd,\
-        bionet.*,biz.*,gnu.*,vmsnet.*,\
-        ba.*,!ba.jobs.agency,ca.*,sbay.*
-
-(with each line prefixed by a tab, and with standard INN newsfeeds
-continuation syntax).  Due to the preferences of the author, it will also
-be sorted as Big Eight, then alt.*, then global non-language hierarchies,
-then regional and language hierarchies.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Print out this documentation (which is done simply by feeding the script
-to C<perldoc -t>.
-
-=item B<-v>, B<--version>
-
-Print out the version of B<tunefeed> and exit.
-
-=item B<-d> I<days>, B<--days>=I<days>
-
-Assume that the difference between the high and low numbers in the active
-file represent I<days> days of traffic.
-
-=item B<-t> I<threshold>, B<--threshold>=I<threshold>
-
-Allow any group with less than I<threshold> articles per day in traffic to
-be either sent or not sent depending on which choice makes the wildcard
-patterns simpler.  If a threshold isn't specified, the default value is
-250.
-
-=back
-
-=head1 BUGS
-
-This program takes a long time to run, not to mention being a nasty memory
-hog.  The algorithm is thorough, but definitely not very optimized, and
-isn't all that friendly.
-
-Guessing traffic from active file numbers is going to produce very skewed
-results on sites with expiration policies that vary widely by group.
-
-There is no way to optimize for size in avoiding rejections, only quantity
-of articles.
-
-There should be a way to turn off the author's idiosyncratic ordering of
-hierarchies, or to specify a different ordering, without editing this
-script.
-
-This script should attempt to retrieve the active file from the remote
-site automatically if so desired.
-
-This script should be able to be given some existing wildcard patterns and
-take them into account when generating new ones.
-
-=head1 CAVEATS
-
-Please be aware that your neighbor's active file may not accurately
-represent the groups they wish to receive from you.  As with everything,
-choices made by automated programs like this one should be reviewed by a
-human and the remote site should be notified, and if they have sent
-explicit patterns, those should be honored instead.  I definitely do *not*
-recommend running this program on any sort of automated basis.
-
-=head1 AUTHOR
-
-Russ Allbery E<lt>rra@stanford.eduE<gt>
-
-=cut
diff --git a/control/Makefile b/control/Makefile
deleted file mode 100644 (file)
index 0d99310..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-##  $Id: Makefile 6806 2004-05-18 01:18:57Z rra $
-
-include ../Makefile.global
-
-top          = ..
-
-ALL          = controlbatch controlchan docheckgroups gpgverify perl-nocem \
-               pgpverify signcontrol
-
-MAN          = ../doc/man/perl-nocem.8 ../doc/man/pgpverify.1
-
-all: $(ALL)
-
-install: all
-       for F in $(ALL) ; do \
-           $(CP_XPUB) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for M in modules/*.pl ; do \
-           $(CP_RPUB) $$M $D$(PATHCONTROL)/`basename $$M` ; \
-       done
-
-man: $(MAN)
-
-clean clobber distclean:
-       rm -f $(ALL)
-
-profiled: all
-depend:
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Build rules.
-
-FIX = $(FIXSCRIPT)
-
-controlbatch:  controlbatch.in  $(FIX) ; $(FIX) controlbatch.in
-controlchan:   controlchan.in   $(FIX) ; $(FIX) controlchan.in
-docheckgroups: docheckgroups.in $(FIX) ; $(FIX) docheckgroups.in
-gpgverify:     gpgverify.in     $(FIX) ; $(FIX) gpgverify.in
-perl-nocem:    perl-nocem.in    $(FIX) ; $(FIX) perl-nocem.in
-pgpverify:     pgpverify.in     $(FIX) ; $(FIX) pgpverify.in
-signcontrol:   signcontrol.in   $(FIX) ; $(FIX) -i signcontrol.in
-
-../doc/man/perl-nocem.8: perl-nocem
-       $(POD2MAN) -s 8 $? > $@
-
-../doc/man/pgpverify.1: pgpverify
-       $(POD2MAN) -s 1 $? > $@
diff --git a/control/controlbatch.in b/control/controlbatch.in
deleted file mode 100644 (file)
index 72035a8..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-########################################################################
-# controlbatch - Run controlchan against a batch file.
-#
-# Command usage:  controlbatch [feedsite batchfile]
-# Defaults are feedsite: controlchan!, batchfile: ${BATCH}/controlchan!
-########################################################################
-#
-# This script will run controlchan against a batch file.  You can use
-# it to clear occasional backlogs while running controls from a
-# channel, or even skip the channel and run control messages as a file
-# feed.
-#
-########################################################################
-#
-# If you're doing the channel thing, you might want to put something
-# like this in your crontab to do a cleanup in the wee hours:
-#
-#      00 04 * * *     @prefix@/bin/controlbatch
-#
-########################################################################
-#
-# If you would rather skip the channel and just process controls each
-# hour in a batch, use this newsfeeds entry instead of the "stock"
-# version:
-#
-# controlchan!\
-#      :!*,control,control.*,!control.cancel\
-#      :Tf,Wnsm:
-#
-# And, a crontab entry something like this:
-#
-#      30 * * * *     @prefix@/bin/controlbatch
-#
-########################################################################
-
-batchlock="${LOCKS}/LOCK.controlbatch"
-mypid=$$
-
-# A concession to INN 1.x
-if [ me${PATHBIN}ow = meow ] ; then
-       PATHBIN=${NEWSBIN}
-       export PATHBIN
-fi
-
-# See if we have no arguments and should use the defaults. If there are
-# arguments, make sure we have enough to attempt something useful.
-if [ me${1}ow != meow ] ; then
-       if [ me${2}ow = meow ] ; then
-               echo "Usage: ${0} [feedsite batchfile]" >&2
-               exit 0
-       else
-               feedsite=${1}
-               batchfile=${2}
-       fi
-else
-       feedsite=controlchan\!
-       batchfile=controlchan\!
-fi
-
-# Check if any other copies of controlbatch are running.  If we are not
-# alone, give up here and now.
-${PATHBIN}/shlock -p $mypid -f ${batchlock} || exit 0
-
-cd ${BATCH}
-
-if [ -s ${batchfile}.work ] ; then
-       cat ${batchfile}.work >>${batchfile}.doit
-       rm -f ${batchfile}.work
-fi
-
-if [ -s ${batchfile} ] ; then
-       mv ${batchfile} ${batchfile}.work
-       if ${PATHBIN}/ctlinnd -s -t30 flush ${feedsite} ; then
-               cat ${batchfile}.work >>${batchfile}.doit
-               rm -f ${batchfile}.work
-       fi
-fi
-
-if [ -s ${batchfile}.doit ] ; then
-       ${PATHBIN}/controlchan \
-               < ${batchfile}.doit >> ${MOST_LOGS}/controlbatch.log 2>&1
-       # if you want extra assurance that nothing gets lost...
-       # cat ${batchfile}.doit >> ${batchfile}.done
-       rm -f ${batchfile}.doit
-fi
-
-rm -f ${batchlock}
diff --git a/control/controlchan.in b/control/controlchan.in
deleted file mode 100644 (file)
index 7fe7338..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-#! /usr/bin/perl -w
-require "/usr/local/news/lib/innshellvars.pl";
-
-##  $Id: controlchan.in 7591 2006-11-22 07:20:46Z eagle $
-##
-##  Channel feed program to route control messages to an appropriate handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-##
-##  Give this program its own newsfeed.  Make sure that you've created
-##  the newsgroup control.cancel so that you don't have to scan through
-##  cancels, which this program won't process anyway.
-##
-##  Make a newsfeeds entry like this:
-##
-##  controlchan!\
-##     :!*,control,control.*,!control.cancel\
-##     :Tc,Wnsm\
-##     :@prefix@/bin/controlchan
-
-require 5.004_03;
-use strict;
-
-delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-# globals
-my ($cachedctl, $curmsgid);
-my $lastctl = 0;
-my $use_syslog = 0;
-my $debug = 0;
-
-# setup logging ###########################################################
-# do not log to syslog if stderr is connected to a console
-if (not -t 2) {
-    eval { require INN::Syslog; import INN::Syslog; $use_syslog = 1; };
-    eval { require Sys::Syslog; import Sys::Syslog; $use_syslog = 1; }
-        unless $use_syslog;
-}
-
-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|freebsd|darwin/;
-    openlog('controlchan', 'pid', $inn::syslog_facility);
-}
-logmsg('starting');
-
-# load modules from the control directory #################################
-opendir(CTL, $inn::controlprogs)
-    or logdie("Cannot open $inn::controlprogs: $!", 'crit');
-foreach (readdir CTL) {
-    next if not /^([a-z\.]+\.pl)$/ or not -f "$inn::controlprogs/$_";
-    eval { require "$inn::controlprogs/$1" };
-    if ($@) {
-        $@ =~ s/\n/  /g;
-        logdie($@, 'crit');
-    }
-    logmsg("loaded $inn::controlprogs/$1", 'debug');
-}
-closedir CTL;
-
-# main loop ###############################################################
-while (<STDIN>) {
-    chop;
-    my ($token, $sitepath, $msgid) = split(/\s+/, $_);
-    next if not defined $token;
-    $sitepath ||= '';
-    $curmsgid = $msgid || '';
-
-    my $artfh = open_article($token);
-    next if not defined $artfh;
-
-    # suck in headers and body, normalize the strange ones
-    my (@headers, @body, %hdr);
-    if (not parse_article($artfh, \@headers, \@body, \%hdr)) {
-        close $artfh;
-        next;
-    }
-    close $artfh or logdie('sm died with status ' . ($? >> 8));
-
-    next if not exists $hdr{control};
-
-    $curmsgid = $hdr{'message-id'};
-    my $sender = cleanaddr($hdr{sender} || $hdr{from});
-    my $replyto = cleanaddr($hdr{'reply-to'} || $hdr{from});
-
-    my (@progparams, $progname);
-    if ($hdr{control} =~ /\s/) {
-        $hdr{control} =~ /^(\S+)\s+(.+)?/;
-        $progname = lc $1;
-        @progparams = split(/\s+/, lc $2) if $2;
-    } else {
-        $progname = lc $hdr{control};
-    }
-
-    next if $progname eq 'cancel';
-
-    if ($progname !~ /^([a-z]+)$/) {
-        logmsg("Naughty control in article $curmsgid ($progname)");
-        next;
-    }
-    $progname = $1;
-
-    # Do we want to process the message?  Let's check the permissions.
-    my ($action, $logname, $newsgrouppats) =
-        ctlperm($progname, $sender, $progparams[0],
-                $token, \@headers, \@body);
-
-    next if $action eq 'drop';
-
-    if ($action eq '_pgpfail') {
-        my $type = '';
-        if ($progname and $progname eq 'newgroup') {
-            if ($progparams[1] and $progparams[1] eq 'moderated') {
-                $type = 'm ';
-            } else {
-                $type = 'y ';
-            }
-        }
-        logmsg("skipping $progname $type$sender"
-            . "(pgpverify failed) in $curmsgid");
-        next;
-    }
-
-    # used by checkgroups. Convert from perl regexp to grep regexp.
-    if (local $_ = $newsgrouppats) {
-        s/\$\|/|/g;
-        s/[^\\]\.[^*]/?/g;
-        s/\$//;
-        s/\.\*/*/g;
-        s/\\([\$\+\.])/$1/g;
-        $progparams[0] = $_;
-    }
-
-    # find the appropriate module and call it
-    my $subname = "control_$progname";
-    my $subfind = \&$subname;
-    if (not defined &$subfind) {
-        if ($logname) {
-            logger($logname, "Unknown control message by $sender",
-                \@headers, \@body);
-        } else {
-            logmsg("Unknown \"$progname\" control by $sender");
-        }
-        next;
-    }
-
-    my $approved = $hdr{approved} ? 1 : 0;
-    logmsg("$subname, " . join(' ', @progparams)
-        . " $sender $replyto $token, $sitepath, $action"
-        . ($logname ? "=$logname" : '') .", $approved");
-
-    &$subfind(\@progparams, $sender, $replyto, $sitepath,
-        $action, $logname, $approved, \@headers, \@body);
-}
-
-closelog() if $use_syslog;
-exit 0;
-
-print $inn::most_logs.$inn::syslog_facility.$inn::mta.
-    $inn::newsmaster.$inn::locks; # lint food
-
-# misc functions ##########################################################
-sub parse_article {
-    my ($artfh, $headers, $body, $hdr) = @_;
-    my $h;
-    my %uniquehdr = map { $_ => 1 }    qw(date followup-to from message-id
-        newsgroups path reply-to subject sender);
-
-    while (<$artfh>) {
-        s/\r?\n$//;
-        last if /^$/;
-        push @$headers, $_;
-        if (/^(\S+):\s+(.+)/) {
-            $h = lc $1;
-            if (exists $hdr->{$h}) {
-                if (exists $uniquehdr{$h}) {
-                    logmsg("Multiple $1 headers in article $curmsgid");
-                    return 0;
-                }
-                $hdr->{$h} .= ' ' . $2;
-            } else {
-                $hdr->{$h} = $2;
-            }
-            next;
-        } elsif (/^\s+(.+)/) {
-            if (defined $h) {
-                $hdr->{$h} .= ' ' . $1;
-                next;
-            }
-        }
-        logmsg("Broken headers in article $curmsgid");
-        return 0;
-    }
-
-    # article is empty or does not exist
-    return 0 if not @$headers;
-
-    chop (@$body = <$artfh>);
-    return 1;
-}
-
-# Strip a mail address, innd-style.
-sub cleanaddr {
-    local $_ = shift;
-    s/(\s+)?\(.*\)(\s+)?//g;
-    s/.*<(.*)>.*/$1/;
-    s/[^-a-zA-Z0-9+_.@%]/_/g;    # protect MTA
-    s/^-/_/;                    # protect MTA
-    return $_;
-}
-
-# Read and cache control.ctl.
-sub readctlfile {
-    my $mtime = (stat($inn::ctlfile))[9];
-    return $cachedctl if $lastctl == $mtime;    # mtime has not changed.
-    $lastctl = $mtime;
-
-    my @ctllist;
-    open(CTLFILE, $inn::ctlfile)
-        or logdie("Cannot open $inn::ctlfile: $!", 'crit');
-    while (<CTLFILE>) {
-        chop;
-        # Not a comment or blank? Convert wildmat to regex
-        next if not /^(\s+)?[^\#]/ or /^$/;
-        if (not /:(?:doit|doifarg|drop|log|mail|verify-.*)(?:=.*)?$/) {
-            s/.*://;
-            logmsg("$_ is not a valid action for control.ctl", 'err');
-            next;
-        }
-        # Convert to a : separated list of regexps
-        s/^all:/*:/i;
-        s/([\$\+\.])/\\$1/g;
-        s/\*/.*/g;
-        s/\?/./g;
-        s/(.*)/^$1\$/;
-        s/:/\$:^/g;
-        s/\|/\$|^/g;
-        push @ctllist, $_;
-    }
-    close CTLFILE;
-
-    logmsg('warning: control.ctl is empty!', 'err') if not @ctllist;
-    return $cachedctl = [ reverse @ctllist ];
-}
-
-# Parse a control message's permissions.
-sub ctlperm {
-    my ($type, $sender, $newsgroup, $token, $headers, $body) = @_;
-
-    my $action = 'drop';    # default
-    my ($logname, $hier);
-
-    # newgroup and rmgroup require newsgroup names; check explicitly for that
-    # here and return drop if the newsgroup is missing (to avoid a bunch of
-    # warnings from undefined values later on in permission checking).
-    if ($type eq 'newgroup' or $type eq 'rmgroup') {
-        unless ($newsgroup) {
-            return ('drop', undef, undef);
-        }
-    }
-
-    my $ctllist = readctlfile();
-    foreach (@$ctllist) {
-        my @ctlline = split /:/;
-        # 0: type  1: from@addr  2: group.*  3: action
-        if ($type =~ /$ctlline[0]/ and $sender =~ /$ctlline[1]/i and
-            ($type !~ /(?:new|rm)group/ or $newsgroup =~ /$ctlline[2]/)) {
-            $action = $ctlline[3];
-            $action =~ s/\^(.+)\$/$1/;
-            $action =~ s/\\//g;
-            $hier = $ctlline[2] if $type eq 'checkgroups';
-            last;
-        }
-    }
-
-    ($action, $logname) = split(/=/, $action);
-
-    if ($action =~ /^verify-(.+)/) {
-        my $keyowner = $1;
-        if ($inn::pgpverify and $inn::pgpverify =~ /^(?:true|on|yes)$/i) {
-            my $pgpresult = defined &local_pgpverify ?
-                local_pgpverify($token, $headers, $body) : pgpverify($token);
-            if ($keyowner eq $pgpresult) {
-                $action = 'doit';
-            } else {
-                $action = '_pgpfail';
-            }
-        } else {
-            $action = 'mail';
-        }
-    }
-
-    return ($action, $logname, $hier);
-}
-
-# Write stuff to a log or send mail to the news admin.
-sub logger {
-    my ($logfile, $message, $headers, $body) = @_;
-
-    if ($logfile eq 'mail') {
-        my $mail = sendmail($message);
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n" . join ('', map { s/^~/~~/; "$_\n" } @$body)
-            if $body;
-        close $mail or logdie("Cannot send mail: $!");
-        return;
-    }
-
-    if ($logfile =~ /^([^.\/].*)/) {
-        $logfile = $1;
-    } else {
-        logmsg("Invalid log file: $logfile", 'err');
-        $logfile = 'control';
-    }
-
-    $logfile = "$inn::most_logs/$logfile.log" unless $logfile =~ /^\//;
-    my $lockfile = $logfile;
-    $lockfile =~ s#.*/##;
-    $lockfile = "$inn::locks/LOCK.$lockfile";
-    shlock($lockfile);
-
-    open(LOGFILE, ">>$logfile") or logdie("Cannot open $logfile: $!");
-    print LOGFILE "$message\n";
-    foreach (@$headers, '', @$body, '') {
-        print LOGFILE "    $_\n";
-    }
-    close LOGFILE;
-    unlink $lockfile;
-}
-
-# write to syslog or errlog
-sub logmsg {
-    my ($msg, $lvl) = @_;
-
-    return if $lvl and $lvl eq 'debug' and not $debug;
-    if ($use_syslog) {
-        syslog($lvl || 'notice', '%s', $msg);
-    } else {
-        print STDERR (scalar localtime) . ": $msg\n";
-    }
-}
-
-# log a message and then die
-sub logdie {
-    my ($msg, $lvl) = @_;
-
-    $msg .= " ($curmsgid)" if $curmsgid;
-    logmsg($msg, $lvl || 'err');
-    exit 1;
-}
-
-# wrappers executing external programs ####################################
-
-# Open an article appropriately to our storage method (or lack thereof).
-sub open_article {
-    my $token = shift;
-
-    if ($token =~ /^\@.+\@$/) {
-        my $pid = open(ART, '-|');
-        logdie('Cannot fork: ' . $!) if $pid < 0;
-        if ($pid == 0) {
-            exec("$inn::newsbin/sm", '-q', $token) or
-                logdie("Cannot exec sm: $!");
-        }
-        return *ART;
-    } else {
-        return *ART if open(ART, $token);
-        logmsg("Cannot open article $token: $!");
-    }
-    return undef;
-}
-
-sub pgpverify {
-    my $token = shift;
-
-    if ($token =~ /^\@.+\@$/) {
-        open(PGPCHECK, "$inn::newsbin/sm -q $token "
-            . "| $inn::newsbin/pgpverify |") or goto ERROR;
-    } else {
-        open(PGPCHECK, "$inn::newsbin/pgpverify < $token |") or goto ERROR;
-    }
-    my $pgpresult = <PGPCHECK>;
-    close PGPCHECK or goto ERROR;
-    $pgpresult ||= '';
-    chop $pgpresult;
-    return $pgpresult;
-ERROR:
-    logmsg("pgpverify failed: $!", 'debug');
-    return '';
-}
-
-sub ctlinnd {
-    my ($cmd, @args) = @_;
-
-    my $st = system("$inn::newsbin/ctlinnd", '-s', $cmd, @args);
-    logdie('Cannot run ctlinnd: ' . $!) if $st == -1;
-    logdie('ctlinnd returned status ' . ($st & 255)) if $st > 0;
-}
-
-sub shlock {
-    my $lockfile = shift;
-
-    my $locktry = 0;
-    while ($locktry < 60) {
-        if (system("$inn::newsbin/shlock", '-p', $$, '-f', $lockfile) == 0) {
-            return 1;
-        }
-        $locktry++;
-        sleep 2;
-    }
-
-    my $lockreason;
-    if (open(LOCKFILE, $lockfile)) {
-        $lockreason = 'held by ' . (<LOCKFILE> || '?');
-        close LOCKFILE;
-    } else {
-        $lockreason = $!;
-    }
-    logdie("Cannot get lock $lockfile: $lockreason");
-    return undef;
-}
-
-# If $body is not defined, returns a file handle which must be closed.
-# Don't forget checking the return value of close().
-# $addresses may be a scalar or a reference to a list of addresses.
-# If not defined, $inn::newsmaster is the default.
-# parts of this code stolen from innmail.pl
-sub sendmail {
-    my ($subject, $addresses, $body) = @_;
-    $addresses = [ $addresses || $inn::newsmaster ] if not ref $addresses;
-    $subject ||= '(no subject)';
-
-    # fix up all addresses
-    my @addrs = map { s#[^-a-zA-Z0-9+_.@%]##g; $_ } @$addresses;
-
-    my $sm = $inn::mta;
-    if ($sm =~ /%s/) {
-        $sm = sprintf($sm, join(' ', @addrs));
-    } else {
-        $sm .= ' ' . join(' ', @addrs);
-    }
-
-    # fork and spawn the MTA whitout using the shell
-    my $pid = open(MTA, '|-');
-    logdie('Cannot fork: ' . $!) if $pid < 0;
-    if ($pid == 0) {
-        exec(split(/\s+/, $sm)) or logdie("Cannot exec $sm: $!");
-    }
-
-    print MTA 'To: ' . join(",\n\t", @addrs) . "\nSubject: $subject\n\n";
-    return *MTA if not defined $body;
-    $body = join("\n", @$body) if ref $body eq 'ARRAY';
-    print MTA $body . "\n";
-    close MTA or logdie("Execution of $sm failed: $!");
-    return 1;
-}
diff --git a/control/docheckgroups.in b/control/docheckgroups.in
deleted file mode 100644 (file)
index cee70d6..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 7743 $
-##  Script to execute checkgroups text; results to stdout.
-
-T=${TMPDIR}
-
-cat /dev/null >${T}/$$out
-
-##  Copy the article without headers, append local newsgroups.
-cat >${T}/$$msg
-test -f ${LOCALGROUPS} && cat ${LOCALGROUPS} >>${T}/$$msg
-
-##  Get the top-level newsgroup names from the message and turn it into
-##  an egrep pattern.
-PATS=`${SED} <${T}/$$msg \
-       -e 's/[         ].*//' -e 's/\..*//' \
-       -e 's/^!//' -e '/^$/d' \
-       -e 's/^/^/' -e 's/$/[.  ]/' \
-    | sort -u \
-    | (tr '\012' '|' ; echo '' )\
-    | ${SED} -e 's/|$//'`
-
-${EGREP} "${PATS}" ${ACTIVE} | ${EGREP} "${1:-.}" | ${SED} 's/ .*//' | sort >${T}/$$active
-${EGREP} "${PATS}" ${T}/$$msg | ${EGREP} "${1:-.}" | ${SED} 's/[       ].*//' | sort >${T}/$$newsgrps
-
-comm -13 ${T}/$$active ${T}/$$newsgrps >${T}/$$missing
-comm -23 ${T}/$$active ${T}/$$newsgrps >${T}/$$remove
-
-${EGREP} "${PATS}" ${ACTIVE} | ${EGREP} "${1:-.}" | ${SED} -n '/ m$/s/ .*//p' | sort >${T}/$$amod.all
-${EGREP} "${PATS}" ${T}/$$msg | ${EGREP} "${1:-.}" | ${SED} 's/\r\?$//' |
-${SED} -n '/(Moderated)$/s/[   ].*//p' | sort >${T}/$$ng.mod
-
-comm -12 ${T}/$$missing ${T}/$$ng.mod >${T}/$$add.mod
-comm -23 ${T}/$$missing ${T}/$$ng.mod >${T}/$$add.unmod
-cat ${T}/$$add.mod ${T}/$$add.unmod >>${T}/$$add
-
-comm -23 ${T}/$$amod.all ${T}/$$remove >${T}/$$amod
-comm -13 ${T}/$$ng.mod ${T}/$$amod >${T}/$$ismod
-comm -23 ${T}/$$ng.mod ${T}/$$amod >${T}/$$nm.all
-comm -23 ${T}/$$nm.all ${T}/$$add >${T}/$$notmod
-
-${EGREP} "${PATS}" ${NEWSGROUPS} | ${EGREP} "${1:-.}" | ${SED} 's/[    ]\+/    /' | sort >${T}/$$localdesc
-${EGREP} "${PATS}" ${T}/$$msg | ${EGREP} "${1:-.}" | ${SED} 's/\r\?$//' |
-${SED} 's/[    ]\+/    /' | sort >${T}/$$newdesc
-
-if ! (head -1 ${T}/$$newdesc | egrep " [[:digit:]]+ [[:digit:]]+ " > /dev/null) ; then
-  comm -13 ${T}/$$localdesc ${T}/$$newdesc >${T}/$$missingdesc
-  comm -23 ${T}/$$localdesc ${T}/$$newdesc >${T}/$$removedesc
-fi
-
-if [ -s ${T}/$$remove ] ; then
-    (
-       echo "# The following newsgroups are non-standard."
-       ${SED} "s/^/#   /" ${T}/$$remove
-       echo "# You can remove them by executing the commands:"
-       for i in `cat ${T}/$$remove` ; do
-           echo "      ${PATHBIN}/ctlinnd rmgroup $i"
-           ${EGREP} "^$i       " ${NEWSGROUPS} >>${T}/$$ngdel
-       done
-       echo ''
-    ) >>${T}/$$out
-fi
-
-if [ -s ${T}/$$add ] ; then
-    (
-       echo "# The following newsgroups were missing and should be added."
-       ${SED} "s/^/#   /" ${T}/$$add
-       echo "# You can do this by executing the command(s):"
-       for i in `cat ${T}/$$add.unmod` ; do
-           echo "      ${PATHBIN}/ctlinnd newgroup $i y ${FROM}"
-           ${EGREP} "^$i       " ${T}/$$msg >>${T}/$$ngadd
-       done
-       for i in `cat ${T}/$$add.mod` ; do
-           echo "      ${PATHBIN}/ctlinnd newgroup $i m ${FROM}"
-           ${EGREP} "^$i       " ${T}/$$msg >>${T}/$$ngadd
-       done
-       echo ''
-    ) >>${T}/$$out
-fi
-
-if [ -s ${T}/$$ismod ] ; then
-    (
-       echo "# The following groups are incorrectly marked as moderated:"
-       ${SED} "s/^/#   /" ${T}/$$ismod
-       echo "# You can correct this by executing the following:"
-       for i in `cat ${T}/$$ismod` ; do
-           echo "      ${PATHBIN}/ctlinnd changegroup $i y"
-           ${EGREP} "^$i       " ${T}/$$msg >>${T}/$$ngchng
-       done
-       echo ''
-    ) >>${T}/$$out
-fi
-
-if [ -s ${T}/$$notmod ] ; then
-    (
-       echo "# The following groups are incorrectly marked as unmoderated:"
-       ${SED} "s/^/#   /" ${T}/$$notmod
-       echo "# You can correct this by executing the following:"
-       for i in `cat ${T}/$$notmod` ;do
-           echo "      ${PATHBIN}/ctlinnd changegroup $i m"
-           ${EGREP} "^$i       " ${T}/$$msg >>${T}/$$ngchng
-       done
-       echo ''
-    ) >>${T}/$$out
-fi
-
-if [ -s ${T}/$$removedesc ] ; then
-    (
-        echo "# The following newsgroups descriptions are obsolete."
-        ${SED} "s/^/#  /" ${T}/$$removedesc
-        echo "# You can remove them by editing ${NEWSGROUPS}."
-        echo ''
-    ) >>${T}/$$out
-fi
-
-if [ -s ${T}/$$missingdesc ] ; then
-    (
-        echo "# The following newsgroups descriptions were missing and should be added."
-        ${SED} "s/^/#  /" ${T}/$$missingdesc
-        echo "# You can add them by editing ${NEWSGROUPS}."
-        echo ''
-    ) >>${T}/$$out
-fi
-
-
-test -s ${T}/$$out && {
-    cat ${T}/$$out
-    echo 'exit # so you can feed this message into the shell'
-    echo "# And remember to update ${NEWSGROUPS}."
-    test -s ${T}/$$ngdel && {
-       echo "# Remove these lines:"
-       ${SED} "s/^/#   /" ${T}/$$ngdel
-       echo ''
-    }
-    test -s ${T}/$$ngadd && {
-       echo "# Add these lines:"
-       ${SED} "s/^/#   /" ${T}/$$ngadd
-       echo ''
-    }
-    test -s ${T}/$$ngchng && {
-       echo "# Change these lines:"
-       ${SED} "s/^/#   /" ${T}/$$ngchng
-       echo ''
-    }
-}
-
-rm -f ${T}/$$*
diff --git a/control/gpgverify.in b/control/gpgverify.in
deleted file mode 100644 (file)
index f3aecea..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/perl -w
-require '/etc/news/innshellvars.pl';
-
-# written April 1996, tale@isc.org (David C Lawrence)
-# mostly rewritten 2001-03-21 by Marco d'Itri <md@linux.it>
-#
-# requirements:
-# - GnuPG
-# - perl 5.004_03 and working Sys::Syslog
-# - syslog daemon
-#
-# There is no locking because gpg is supposed to not need it and controlchan
-# will serialize control messages processing anyway.
-
-require 5.004_03;
-use strict;
-
-# if you keep your keyring somewhere that is not the default used by gpg,
-# change the location below.
-my $keyring;
-if ($inn::newsetc && -d "$inn::newsetc/pgp") {
-  $keyring = $inn::newsetc . '/pgp/pubring.gpg';
-}
-
-# If you have INN and the script is able to successfully include your
-# innshellvars.pl file, the value of the next two variables will be
-# overridden.
-my $tmpdir = '/var/log/news/';
-my $syslog_facility = 'news';
-
-# 1: print PGP output
-my $debug = 0;
-#$debug = 1 if -t 1;
-
-### Exit value:
-### 0  good signature
-### 1  no signature
-### 2  unknown signature
-### 3  bad signature
-### 255 problem not directly related to gpg analysis of signature
-
-##############################################################################
-################ NO USER SERVICEABLE PARTS BELOW THIS COMMENT ################
-##############################################################################
-my $tmp = ($inn::pathtmp ? $inn::pathtmp : $tmpdir) . "/pgp$$";
-$syslog_facility = $inn::syslog_facility if $inn::syslog_facility;
-
-my $nntp_format = 0;
-$0 =~ s#^.*/##;                # trim /path/to/prog to prog
-
-die "Usage: $0 < message\n" if $#ARGV != -1;
-
-# Path to gpg binary
-my $gpg;
-if ($inn::gpgv) { 
-    $gpg = $inn::gpgv;
-} else {
-    foreach (split(/:/, $ENV{PATH}), qw(/usr/local/bin /opt/gnu/bin)) {
-       if (-x "$_/gpgv") {
-            $gpg = "$_/gpgv"; last;
-       }
-    }
-}
-fail('cannot find the gpgv binary') if not $gpg;
-
-# this is, by design, case-sensitive with regards to the headers it checks.
-# it's also insistent about the colon-space rule.
-my ($label, $value, %dup, %header);
-while (<STDIN>) {
-    # if a header line ends with \r\n, this article is in the encoding
-    # it would be in during an NNTP session. some article storage
-    # managers keep them this way for efficiency.
-    $nntp_format = /\r\n$/ if $. == 1;
-    s/\r?\n$//;
-
-    last if /^$/;
-    if (/^(\S+):[ \t](.+)/) {
-        ($label, $value) = ($1, $2);
-        $dup{$label} = 1 if $header{$label};
-        $header{$label} = $value;
-    } elsif (/^\s/) {
-        fail("non-header at line $.: $_") unless $label;
-        $header{$label} .= "\n$_";
-    } else {
-        fail("non-header at line $.: $_");
-    }
-}
-
-my $pgpheader = 'X-PGP-Sig';
-$_ = $header{$pgpheader};
-exit 1 if not $_; # no signature
-
-# the $sep value means the separator between the radix64 signature lines
-# can have any amount of spaces or tabs, but must have at least one space
-# or tab, if there is a newline then the space or tab has to follow the
-# newline. any number of newlines can appear as long as each is followed
-# by at least one space or tab. *phew*
-my $sep = "[ \t]*(\n?[ \t]+)+";
-# match all of the characters in a radix64 string
-my $r64 = '[a-zA-Z0-9+/]';
-fail("$pgpheader not in expected format")
-    unless /^(\S+)$sep(\S+)(($sep$r64{64})+$sep$r64+=?=?$sep=$r64{4})$/;
-
-my ($version, $signed_headers, $signature) = ($1, $3, $4);
-$signature =~ s/$sep/\n/g;
-
-my $message = "-----BEGIN PGP SIGNED MESSAGE-----\n\n"
-            . "X-Signed-Headers: $signed_headers\n";
-
-foreach $label (split(',', $signed_headers)) {
-    fail("duplicate signed $label header, can't verify") if $dup{$label};
-    $message .= "$label: ";
-    $message .= $header{$label} if $header{$label};
-    $message .= "\n";
-}
-$message .= "\n";                # end of headers
-
-while (<STDIN>) {                # read body lines
-    if ($nntp_format) {
-        # check for end of article; some news servers (eg, Highwind's
-        # "Breeze") include the dot-CRLF of the NNTP protocol in the
-        # article data passed to this script
-        last if $_ eq ".\r\n";
-
-        # remove NNTP encoding
-        s/^\.\./\./;
-        s/\r\n$/\n/;
-    }
-
-    s/^-/- -/;            # pgp quote ("ASCII armor") dashes
-    $message .= $_;    
-}
-
-$message .=
-    "\n-----BEGIN PGP SIGNATURE-----\n" .
-    "Version: $version\n" .
-    $signature .
-    "\n-----END PGP SIGNATURE-----\n";
-
-open(TMP, ">$tmp") or fail("open $tmp: $!");
-print TMP $message;
-close TMP or errmsg("close $tmp: $!");
-
-my $opts = '--quiet --status-fd=1 --logger-fd=1';
-$opts .= " --keyring=$keyring" if $keyring;
-
-open(PGP, "$gpg $opts $tmp |") or fail("failed to execute $gpg: $!");
-
-undef $/;
-$_ = <PGP>;
-
-unlink $tmp or errmsg("unlink $tmp: $!");
-
-if (not close PGP) {
-    if ($? >> 8) {
-        my $status = $? >> 8;
-        errmsg("gpg exited status $status") if $status > 1;
-    } else {
-        errmsg('gpg died on signal ' . ($? & 255));
-    }
-}
-
-print STDERR $_ if $debug;
-
-my $ok = 255;        # default exit status
-my $signer;
-if (/^\[GNUPG:\]\s+GOODSIG\s+\S+\s+(\S+)/m) {
-    $ok = 0;
-    $signer = $1;
-} elsif (/^\[GNUPG:\]\s+NODATA/m or /^\[GNUPG:\]\s+UNEXPECTED/m) {
-    $ok = 1;
-} elsif (/^\[GNUPG:\]\s+NO_PUBKEY/m) {
-    $ok = 2;
-} elsif (/^\[GNUPG:\]\s+BADSIG\s+/m) {
-    $ok = 3;
-}
-
-print "$signer\n" if $signer;
-exit $ok;
-
-sub errmsg {
-    my $msg = $_[0];
-
-    eval 'use Sys::Syslog qw(:DEFAULT setlogsock)';
-    die "$0: cannot use Sys::Syslog: $@ [$msg]\n" if $@;
-
-    die "$0: cannot set syslog method [$msg]\n"
-        if not (setlogsock('unix') or setlogsock('inet'));
-
-    $msg .= " processing $header{'Message-ID'}" if $header{'Message-ID'};
-
-    openlog($0, 'pid', $syslog_facility);
-    syslog('err', '%s', $msg);
-    closelog();
-}
-
-sub fail {
-    errmsg($_[0]);
-    unlink $tmp;
-    exit 255;
-}
-
-__END__
-
-# Copyright 2000 by Marco d'Itri
-
-# License of the original version distributed by David C. Lawrence:
-
-# Copyright (c) 1996 UUNET Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-#    must display the following acknowledgement:
-#      This product includes software developed by UUNET Technologies, Inc.
-# 4. The name of UUNET Technologies ("UUNET") may not be used to endorse or
-#    promote products derived from this software without specific prior
-#    written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY UUNET ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED.  IN NO EVENT SHALL UUNET BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-# OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/control/modules/checkgroups.pl b/control/modules/checkgroups.pl
deleted file mode 100644 (file)
index 56366ad..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-##  $Id: checkgroups.pl 7743 2008-04-06 10:04:43Z iulius $
-##
-##  checkgroups control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_checkgroups {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($newsgrouppats) = @$par;
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("checkgroups by $sender");
-        print $mail "$sender posted the following checkgroups message:\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail <<END;
-
-If you want to process it, feed the body
-of the message to docheckgroups while logged
-in as user ID "$inn::newsuser":
-
-$inn::pathbin/docheckgroups '$newsgrouppats' <<zRbJ
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        print $mail "zRbJ\n";
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "checkgroups by $sender", $headers, $body);
-        } else {
-            logmsg("checkgroups by $sender");
-        }
-    } elsif ($action eq 'doit') {
-        if (defined &local_docheckgroups) {
-            local_docheckgroups($body, $newsgrouppats, $log, $sender);
-        } else {
-            docheckgroups($body, $newsgrouppats, $log, $sender);
-        }
-    }
-}
-
-sub docheckgroups {
-    my ($body, $newsgrouppats, $log, $sender) = @_;
-
-    my $tempfile = "$inn::tmpdir/checkgroups.$$";
-    open(TEMPART, ">$tempfile.art")
-        or logdie("Cannot open $tempfile.art: $!");
-    print TEMPART map { s/^~/~~/; "$_\n" } @$body;
-    close TEMPART;
-
-    open(OLDIN, '<&STDIN') or die $!;
-    open(OLDOUT, '>&STDOUT') or die $!;
-    open(STDIN, "$tempfile.art") or die $!;
-    open(STDOUT, ">$tempfile") or die $!;
-    my $st = system("$inn::pathbin/docheckgroups", $newsgrouppats);
-    logdie('Cannot run docheckgroups: ' . $!) if $st == -1;
-    logdie('docheckgroups returned status ' . ($st & 255)) if $st > 0;
-    close(STDIN);
-    close(STDOUT);
-    open(STDIN, '<&OLDIN') or die $!;
-    open(STDOUT, '>&OLDOUT') or die $!;
-
-    open(TEMPFILE, $tempfile) or logdie("Cannot open $tempfile: $!");
-    my @output = <TEMPFILE>;
-    chop @output;
-    # There is no need to send an empty mail.
-    if ($#output > 0) {
-        logger($log || 'mail', "checkgroups by $sender", \@output);
-    } else {
-        logmsg("checkgroups by $sender processed (no change)");
-    }
-    close TEMPFILE;
-    unlink($tempfile, "$tempfile.art");
-}
-
-1;
diff --git a/control/modules/ihave.pl b/control/modules/ihave.pl
deleted file mode 100644 (file)
index a64c235..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-##  $Id: ihave.pl 4932 2001-07-19 00:32:56Z rra $
-##
-##  ihave control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_ihave {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("ihave by $sender");
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie('Cannot send mail: ' . $!);
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "ihave $sender", $headers, $body);
-        } else {
-            logmsg("ihave $sender");
-        }
-    } elsif ($action eq 'doit') {
-        my $tempfile = "$inn::tmpdir/ihave.$$";
-        open(GREPHIST, "|grephistory -i > $tempfile")
-            or logdie('Cannot run grephistory: ' . $!);
-       foreach (@$body) {
-            print GREPHIST "$_\n";
-        }
-        close GREPHIST;
-
-        if (-s $tempfile) {
-            my $inews = open("$inn::inews -h")
-                or logdie('Cannot run inews: ' . $!);
-            print $inews "Newsgroups: to.$site\n"
-               . "Subject: cmsg sendme $inn::pathhost\n"
-               . "Control: sendme $inn::pathhost\n\n";
-            open(TEMPFILE, $tempfile) or logdie("Cannot open $tempfile: $!");
-            print $inews $_ while <TEMPFILE>;  
-            close $inews or die $!;
-            close TEMPFILE;
-        }
-        unlink $tempfile;
-    }
-}
-
-1;
diff --git a/control/modules/newgroup.pl b/control/modules/newgroup.pl
deleted file mode 100644 (file)
index 94eef22..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-##  $Id: newgroup.pl 7849 2008-05-25 17:11:32Z iulius $
-##
-##  newgroup control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_newgroup {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($groupname, $modflag) = @$par;
-
-    $modflag ||= '';
-    my $modcmd = $modflag eq 'moderated' ? 'm' : 'y';
-
-    my $errmsg;
-    $errmsg= local_checkgroupname($groupname) if defined &local_checkgroupname;
-    if ($errmsg) {
-        $errmsg = checkgroupname($groupname) if $errmsg eq 'DONE';
-
-        if ($log) {
-            logger($log, "skipping newgroup ($errmsg)", $headers, $body);
-        } else {
-            logmsg("skipping newgroup ($errmsg)");
-        }
-        return;
-    }
-
-    # Scan active to see what sort of change we are making.
-    open(ACTIVE, $inn::active) or logdie("Cannot open $inn::active: $!");
-    my @oldgroup;
-    while (<ACTIVE>) {
-        next unless /^(\Q$groupname\E)\s\d+\s\d+\s(\w)/;
-        @oldgroup = split /\s+/;
-        last;
-    }
-    close ACTIVE;
-    
-    my $status;
-    my $ngdesc = 'No description.';
-    my $olddesc = '';    
-    my $ngname = $groupname;
-
-    # If there is a tag line, search whether the description has changed.
-    my $found = 0;
-    my $ngline = '';
-    foreach (@$body) {
-        if ($found) {
-            # It is the line which contains the description.
-            $ngline = $_;
-            last;
-        }
-        $found = 1 if $_ =~ /^For your newsgroups file:\s*$/;
-    }
-    
-    if ($found) {
-      ($ngname, $ngdesc) = split(/\s+/, $ngline, 2);
-      if ($ngdesc) {
-          $ngdesc =~ s/\s+$//;
-          $ngdesc =~ s/\s+\(moderated\)\s*$//i;
-          $ngdesc .= ' (Moderated)' if $modflag eq 'moderated';
-      }
-      # Scan newsgroups to see the previous description, if any.
-      open(NEWSGROUPS, $inn::newsgroups)
-          or logdie("Cannot open $inn::newsgroups: $!");
-      while (<NEWSGROUPS>) {
-          if (/^\Q$groupname\E\s+(.*)/) {
-              $olddesc = $1;
-              last;
-          }
-      }
-      close NEWSGROUPS;
-    }
-
-    if (@oldgroup) {
-        if ($oldgroup[3] eq 'm' and $modflag ne 'moderated') {
-            $status = 'be made unmoderated';
-        } elsif ($oldgroup[3] ne 'm' and $modflag eq 'moderated') {
-            $status = 'be made moderated';
-        } else {
-            if ($ngdesc eq $olddesc) {
-                $status = 'no change';
-            } else {
-                $status = 'have a new description';
-            }
-        }
-    } elsif (not $approved) {
-        $status = 'unapproved';
-    } else {
-        $status = 'be created';
-    }
-
-    if ($action eq 'mail' and $status !~ /(no change|unapproved)/) {
-        my $mail = sendmail("newgroup $groupname $modcmd $sender");
-        print $mail <<END;
-$sender asks for $groupname
-to $status.
-
-If this is acceptable, type:
-  $inn::newsbin/ctlinnd newgroup $groupname $modcmd $sender
-
-And do not forget to update the corresponding description in your
-newsgroups file.
-
-The control message follows:
-
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "skipping newgroup $groupname $modcmd"
-                . " $sender (would $status)", $headers, $body);
-        } else {
-            logmsg("skipping newgroup $groupname $modcmd $sender"
-                . " (would $status)");
-        }
-    } elsif ($action eq 'doit' and $status ne 'unapproved') {
-        if ($status ne 'no change') {
-            # The status 'be made (un)moderated' prevails over
-            # 'have a new description' so it is executed.
-            ctlinnd('newgroup', $groupname, $modcmd, $sender)
-                if $status ne 'have a new description';
-            # We know the description has changed.
-            update_desc($ngname, $ngdesc) if $ngdesc and $ngname eq $groupname;
-        }
-        
-        if ($log) {
-            logger($log, "newgroup $groupname $modcmd $status $sender",
-                   $headers, $body) if ($log ne 'mail' or $status ne 'no change');
-        }
-    }
-    return;
-}
-
-sub update_desc {
-    my ($name, $desc) = @_;
-    shlock("$inn::locks/LOCK.newsgroups");
-    my $tempfile = "$inn::newsgroups.$$";
-    open(NEWSGROUPS, $inn::newsgroups)
-        or logdie("Cannot open $inn::newsgroups: $!");
-    open(TEMPFILE, ">$tempfile") or logdie("Cannot open $tempfile: $!");
-    while (<NEWSGROUPS>) {
-        next if (/^\Q$name\E\s+(.*)/);
-        print TEMPFILE $_;
-    }
-    # We now write a pretty line for the description.
-    if (length $name < 8) {
-        print TEMPFILE "$name\t\t\t$desc\n";
-    } elsif (length $name < 16) {
-        print TEMPFILE "$name\t\t$desc\n";
-    } else {
-        print TEMPFILE "$name\t$desc\n";
-    }
-    close TEMPFILE;
-    close NEWSGROUPS;
-    rename($tempfile, $inn::newsgroups)
-        or logdie("Cannot rename $tempfile: $!");
-    unlink("$inn::locks/LOCK.newsgroups", $tempfile);
-}
-
-# Check the group name.  This is partially derived from C News.
-# Some checks are commented out if I think they're too strict or
-# language-dependent.  Your mileage may vary.
-sub checkgroupname {
-    local $_ = shift;
-
-    # whole-name checking
-    return 'Empty group name' if /^$/;
-    return 'Whitespace in group name' if /\s/;
-    return 'Unsafe group name' if /[\`\/:;]/;
-    return 'Bad dots in group name' if /^\./ or /\.$/ or /\.\./;
-#    return 'Group name does not begin/end with alphanumeric'
-#        if (/^[a-zA-Z0-9].+[a-zA-Z0-9]$/;
-    return 'Group name begins in control., junk. or to.' if /^(?:control|junk|to)\./;
-#    return 'Group name too long' if length $_ > 128;
-
-    my @components = split(/\./);
-    # prevent alt.a.b.c.d.e.f.g.w.x.y.z...
-    return 'Too many components' if $#components > 9;
-
-    # per-component checking
-    for (my $i = 0; $i <= $#components; $i++) {
-        local $_ = $components[$i];
-        return 'all-numeric name component' if /^[0-9]+$/;
-#        return 'name component starts with non-alphanumeric' if /^[a-zA-Z0-9]/;
-#        return 'name component does not contain letter' if not /[a-zA-Z]/;
-        return "`all' or `ctl' used as name component" if /^(?:all|ctl)$/;
-#        return 'name component longer than 30 characters' if length $_ > 30;
-#        return 'uppercase letter(s) in name' if /[A-Z]/;
-        return 'illegal character(s) in name' if /[^a-z0-9+_\-.]/;
-        # sigh, c++ etc must be allowed
-        return 'repeated punctuation in name' if /--|__|\+\+./;
-#        return 'repeated component(s) in name' if ($i + 2 <= $#components
-#            and $_ eq $components[$i + 1] and $_ eq $components[$i + 2]);
-    }
-    return '';
-}
-
-1;
diff --git a/control/modules/rmgroup.pl b/control/modules/rmgroup.pl
deleted file mode 100644 (file)
index d78b014..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-##  $Id: rmgroup.pl 7743 2008-04-06 10:04:43Z iulius $
-##
-##  rmgroup control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_rmgroup {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($groupname) = @$par;
-
-    # Scan active to see what sort of change we are making.
-    open(ACTIVE, $inn::active) or logdie("Cannot open $inn::active: $!");
-    my @oldgroup;
-    while (<ACTIVE>) {
-        next unless /^(\Q$groupname\E)\s\d+\s\d+\s(\w)/;
-        @oldgroup = split /\s+/;
-        last;
-    }
-    close ACTIVE;
-    my $status;
-    if (not @oldgroup) {
-        $status = 'no change';
-    } elsif (not $approved) {
-        $status = 'unapproved';
-    } else {
-        $status = 'removed';
-    }
-
-    if ($action eq 'mail' and $status !~ /(no change|unapproved)/) {
-        my $mail = sendmail("rmgroup $groupname $sender");
-        print $mail <<END;
-$sender asks for $groupname
-to be $status.
-
-If this is acceptable, type:
-  $inn::newsbin/ctlinnd rmgroup $groupname
-
-And do not forget to remove the corresponding description, if any,
-from your newsgroups file.
-
-The control message follows:
-
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "skipping rmgroup $groupname"
-                . " $sender (would be $status)", $headers, $body);
-        } else {
-            logmsg("skipping rmgroup $groupname $sender (would be $status)");
-        }
-    } elsif ($action eq 'doit' and $status !~ /(no change|unapproved)/) {
-        ctlinnd('rmgroup', $groupname);
-        # Update newsgroups too.
-        shlock("$inn::locks/LOCK.newsgroups");
-        open(NEWSGROUPS, $inn::newsgroups)
-            or logdie("Cannot open $inn::newsgroups: $!");
-        my $tempfile = "$inn::newsgroups.$$";
-        open(TEMPFILE, ">$tempfile") or logdie("Cannot open $tempfile: $!");
-        while (<NEWSGROUPS>) {
-            print TEMPFILE $_ if not /^\Q$groupname\E\s/;
-        }
-        close TEMPFILE;
-        close NEWSGROUPS;
-        rename($tempfile, $inn::newsgroups)
-            or logdie("Cannot rename $tempfile: $!");
-        unlink "$inn::locks/LOCK.newsgroups";
-        unlink $tempfile;
-
-        logger($log, "rmgroup $groupname $status $sender", $headers, $body)
-            if $log;
-    }
-}
-
-1;
diff --git a/control/modules/sendme.pl b/control/modules/sendme.pl
deleted file mode 100644 (file)
index d53ab5a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-##  $Id: sendme.pl 4932 2001-07-19 00:32:56Z rra $
-##
-##  sendme control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_sendme {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("sendme by $sender");
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie('Cannot send mail: ' . $!);
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "sendme $sender", $headers, $body);
-        } else {
-            logmsg("sendme from $sender");
-        }
-    } elsif ($action eq 'doit') {
-        my $tempfile = "$inn::tmpdir/sendme.$$";
-        open(GREPHIST, "|grephistory -s > $tempfile")
-            or logdie("Cannot run grephistory: $!");
-       foreach (@$body) {
-            print GREPHIST "$_\n";
-       }
-        close GREPHIST or logdie("Cannot run grephistory: $!");
-
-        if (-s $tempfile and $site =~ /^[a-zA-Z0-9.-_]+$/) {
-            open(TEMPFILE, $tempfile) or logdie("Cannot open $tempfile: $!");
-            open(BATCH, ">>$inn::batch/$site.work")
-                or logdie("Cannot open $inn::batch/$site.work: $!");
-            print BATCH $_ while <TEMPFILE>;
-            close BATCH;
-            close TEMPFILE;
-        }
-        unlink $tempfile;
-    }
-}
-
-1;
diff --git a/control/modules/sendsys.pl b/control/modules/sendsys.pl
deleted file mode 100644 (file)
index 6f086ba..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-##  $Id: sendsys.pl 4932 2001-07-19 00:32:56Z rra $
-##
-##  sendsys control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_sendsys {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($where) = @$par;
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("sendsys $sender");
-        print $mail <<END;
-$sender has requested that you send a copy
-of your newsgroups file.
-
-If this is acceptable, type:
-  $inn::mailcmd -s "sendsys reply from $inn::pathhost" $replyto < $inn::newsfeeds
-
-The control message follows:
-
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "sendsys $sender", $headers, $body);
-        } else {
-            logmsg("sendsys $sender");
-        }
-    } elsif ($action =~ /^(doit|doifarg)$/) {
-        if ($action eq 'doifarg' and $where ne $inn::pathhost) {
-            logmsg("skipped sendsys $sender");
-            return;
-        }
-        my $mail = sendmail("sendsys reply from $inn::pathhost", $replyto);
-        open(NEWSFEEDS, $inn::newsfeeds)
-            or logdie("Cannot open $inn::newsfeeds: $!");
-        print $mail $_ while <NEWSFEEDS>;
-        print $mail "\n";
-        close NEWSFEEDS;
-        close $mail or logdie("Cannot send mail: $!");
-
-        logger($log, "sendsys $sender to $replyto", $headers, $body) if $log;
-    }
-}
-
-1;
diff --git a/control/modules/senduuname.pl b/control/modules/senduuname.pl
deleted file mode 100644 (file)
index a2f71e5..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-##  $Id: senduuname.pl 4932 2001-07-19 00:32:56Z rra $
-##
-##  senduuname control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_senduuname {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($where) = @$par;
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("senduuname $sender");
-        print $mail <<END;
-$sender has requested information about your UUCP name.
-
-If this is acceptable, type:
-  uuname | $inn::mailcmd -s "senduuname reply from $inn::pathhost" $replyto
-
-The control message follows:
-
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "senduuname $sender", $headers, $body);
-        } else {
-            logmsg("senduuname $sender");
-        }
-    } elsif ($action =~ /^(doit|doifarg)$/) {
-        if ($action eq 'doifarg' and $where ne $inn::pathhost) {
-            logmsg("skipped senduuname $sender");
-            return;
-        }
-        my $mail = sendmail("senduuname reply from $inn::pathhost", $replyto);
-        open(UUNAME, 'uuname|') or logdie("Cannot run uuname: $!");
-        print $mail $_ while <UUNAME>;
-        close UUNAME or logdie("Cannot run uuname: $!");
-        close $mail or logdie("Cannot send mail: $!");
-
-        logger($log, "senduuname $sender to $replyto", $headers, $body) if $log;
-    }
-}
-
-1;
diff --git a/control/modules/version.pl b/control/modules/version.pl
deleted file mode 100644 (file)
index f06096f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-##  $Id: version.pl 4932 2001-07-19 00:32:56Z rra $
-##
-##  version control message handler.
-##
-##  Copyright 2001 by Marco d'Itri <md@linux.it>
-##
-##  Redistribution and use in source and binary forms, with or without
-##  modification, are permitted provided that the following conditions
-##  are met:
-##
-##   1. Redistributions of source code must retain the above copyright
-##      notice, this list of conditions and the following disclaimer.
-##
-##   2. Redistributions in binary form must reproduce the above copyright
-##      notice, this list of conditions and the following disclaimer in the
-##      documentation and/or other materials provided with the distribution.
-
-use strict;
-
-sub control_version {
-    my ($par, $sender, $replyto, $site, $action, $log, $approved,
-        $headers, $body) = @_;
-    my ($where) = @$par;
-
-    my $version = $inn::version || '(unknown version)';
-
-    if ($action eq 'mail') {
-        my $mail = sendmail("version $sender");
-        print $mail <<END;
-$sender has requested information about your
-news software version.
-
-If this is acceptable, type:
-  echo "InterNetNews $version" | $inn::mailcmd -s "version reply from $inn::pathhost" $replyto
-
-The control message follows:
-
-END
-        print $mail map { s/^~/~~/; "$_\n" } @$headers;
-        print $mail "\n";
-        print $mail map { s/^~/~~/; "$_\n" } @$body;
-        close $mail or logdie("Cannot send mail: $!");
-    } elsif ($action eq 'log') {
-        if ($log) {
-            logger($log, "version $sender", $headers, $body);
-        } else {
-            logmsg("version $sender");
-        }
-    } elsif ($action =~ /^(doit|doifarg)$/) {
-        if ($action eq 'doifarg' and $where ne $inn::pathhost) {
-            logmsg("skipped version $sender");
-            return;
-        }
-        sendmail("version reply from $inn::pathhost", $replyto,
-            [ "InterNetNews $version\n" ]);
-
-        logger($log, "version $sender to $replyto", $headers, $body) if $log;
-    }
-}
-
-1;
diff --git a/control/perl-nocem.in b/control/perl-nocem.in
deleted file mode 100644 (file)
index 968d80a..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-#!/usr/bin/perl -w
-# fixscript will replace this line with require innshellvars.pl
-
-##############################################################################
-# perl-nocem - a NoCeM-on-spool implementation for INN 2.x.
-# Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>
-# Copyright 2001 by Marco d'Itri <md@linux.it>
-# This program is licensed under the terms of the GNU General Public License.
-#
-# List of changes:
-#
-# 2002: Patch by Steven M. Christey for untrusted printf input.
-# 2007: Patch by Christoph Biedl for checking a timeout.
-# Documentation improved by Jeffrey M. Vinocur (2002), Russ Allbery (2006)
-# and Julien Elie (2007).
-#
-##############################################################################
-
-require 5.00403;
-use strict;
-
-# XXX FIXME I haven't been able to load it only when installed.
-# If nobody can't fix it just ship the program with this line commented.
-#use Time::HiRes qw(time);
-
-my $keyring = $inn::pathetc . '/pgp/ncmring.gpg';
-
-# XXX To be moved to a config file.
-#sub local_want_cancel_id {
-#    my ($group, $hdrs) = @_;
-#
-## Hippo has too many false positives to be useful outside of pr0n groups
-#    if ($hdrs->{issuer} =~ /(?:Ultra|Spam)Hippo/) {
-#        foreach (split(/,/, $group)) {
-#            return 1 if /^alt\.(?:binar|sex)/;
-#        }
-#        return 0;
-#    }
-#    return 1;
-#}
-
-# no user serviceable parts below this line ###################################
-
-# global variables
-my ($working, $got_sighup, $got_sigterm, @ncmperm, $cancel);
-my $use_syslog = 0;
-my $log_open = 0;
-my $nntp_open = 0;
-my $last_cancel = 0;
-my $socket_timeout = $inn::peertimeout - 100;
-
-my $logfile = $inn::pathlog . '/perl-nocem.log';
-
-# initialization and main loop ###############################################
-
-eval { require Sys::Syslog; import Sys::Syslog; $use_syslog = 1; };
-
-if ($use_syslog) {
-    eval "sub Sys::Syslog::_PATH_LOG { '/dev/log' }" if $^O eq 'dec_osf';
-    Sys::Syslog::setlogsock('unix') if $^O =~ /linux|dec_osf/;
-    openlog('nocem', '', $inn::syslog_facility);
-}
-
-if (not $inn::gpgv) {
-    logmsg('cannot find the gpgv binary', 'err');
-    sleep 5;
-    exit 1;
-}
-
-if ($inn::version and not $inn::version =~ /^INN 2\.[0123]\./) {
-    $cancel = \&cancel_nntp;
-} else {
-    $cancel = \&cancel_ctlinnd;
-}
-
-$SIG{HUP}  = \&hup_handler;
-$SIG{INT}  = \&term_handler;
-$SIG{TERM} = \&term_handler;
-$SIG{PIPE} = \&term_handler;
-
-logmsg('starting up');
-
-unless (read_ctlfile()) {
-    sleep 5;
-    exit 1;
-}
-
-while (<STDIN>) {
-    chop;
-    $working = 1;
-    do_nocem($_);
-    $working = 0;
-    term_handler() if $got_sigterm;
-    hup_handler() if $got_sighup;
-}
-
-logmsg('exiting because of EOF', 'debug');
-exit 0;
-
-##############################################################################
-
-# Process one NoCeM notice.
-sub do_nocem {
-    my $token = shift;
-    my $start = time;
-
-    # open the article and verify the notice
-    my $artfh = open_article($token);
-    return if not defined $artfh;
-    my ($msgid, $nid, $issuer, $nocems) = read_nocem($artfh);
-    close $artfh;
-    return unless $nocems;
-
-    &$cancel($nocems);
-    logmsg("Articles cancelled: " . join(' ', @$nocems), 'debug');
-    my $diff = (time - $start) || 0.01;
-    my $nr = scalar @$nocems;
-    logmsg(sprintf("processed notice %s by %s (%d ids, %.5f s, %.1f/s)",
-        $nid, $issuer, $nr, $diff, $nr / $diff));
-}
-
-# - Check if it is a PGP signed NoCeM notice
-# - See if we want it
-# - Then check PGP signature
-sub read_nocem {
-    my $artfh = shift;
-
-    # Examine the first 200 lines to see if it is a PGP signed NoCeM.
-    my $ispgp = 0;
-    my $isncm = 0;
-    my $inhdr = 1;
-    my $i = 0;
-    my $body = '';
-    my ($from, $msgid);
-    while (<$artfh>) {
-        last if $i++ > 200;
-        s/\r\n$/\n/;
-        if ($inhdr) {
-            if (/^$/) {
-                $inhdr = 0;
-            } elsif (/^From:\s+(.*)\s*$/i) {
-                $from =  $1;
-            } elsif (/^Message-ID:\s+(<.*>)/i) {
-                $msgid = $1;
-            }
-        } else {
-            $body .= $_;
-            $ispgp = 1 if /^-----BEGIN PGP SIGNED MESSAGE-----/;
-            if (/^\@\@BEGIN NCM HEADERS/) {
-                $isncm = 1;
-                last;
-            }
-        }
-    }
-
-    # must be a PGP signed NoCeM.
-    if (not $ispgp) {
-        logmsg("Article $msgid: not PGP signed", 'debug');
-        return;
-    }
-    if (not $isncm) {
-        logmsg("Article $msgid: not a NoCeM", 'debug');
-        return;
-    }
-
-    # read the headers of this NoCeM, and check if it's supported.
-    my %hdrs;
-    while (<$artfh>) {
-        s/\r\n/\n/;
-        $body .= $_;
-        last if /^\@\@BEGIN NCM BODY/;
-        my ($key, $val) = /^([^:]+)\s*:\s*(.*)$/;
-        $hdrs{lc $key} = $val;
-    }
-    foreach (qw(action issuer notice-id type version)) {
-        next if $hdrs{$_};
-        logmsg("Article $msgid: missing $_ pseudo header", 'debug');
-        return;
-    }
-    return if not supported_nocem($msgid, \%hdrs);
-
-    # decide if we want it.
-    if (not want_nocem(\%hdrs)) {
-        logmsg("Article $msgid: unwanted ($hdrs{issuer}/$hdrs{type})", 'debug');
-        return;
-    }
-# XXX want_hier() not implemented
-#    if ($hdrs{hierarchies} and not want_hier($hdrs{hierarchies})) {
-#        logmsg("Article $msgid: unwanted hierarchy ($hdrs{hierarchies})",
-#            'debug');
-#        return;
-#    }
-
-    # We do want it, so read the entire article.  Also copy it to
-    # a temp file so that we can check the PGP signature when done.
-    my $tmpfile = "$inn::pathtmp/nocem.$$";
-    if (not open(OFD, ">$tmpfile")) {
-        logmsg("cannot open temp file $tmpfile: $!", 'err');
-        return;
-    }
-    print OFD $body;
-    undef $body;
-
-    # process NoCeM body.
-    my $inbody = 1;
-    my @nocems;
-    my ($lastid, $lastgrp);
-    while (<$artfh>) {
-        s/\r\n$/\n/;
-        print OFD;
-        $inbody = 0 if /^\@\@END NCM BODY/;
-        next if not $inbody or /^#/;
-
-        my ($id, $grp) = /^(\S*)\s+(\S+)/;
-        next if not $grp;
-        if ($id) {
-            push @nocems, $lastid
-                if $lastid and want_cancel_id($lastgrp, \%hdrs);
-            $lastid = $id;
-            $lastgrp = $grp;
-        } else {
-            $lastgrp .= ',' . $grp;
-        }
-    }
-    push @nocems, $lastid if $lastid and want_cancel_id($lastgrp, \%hdrs);
-    close OFD;
-
-    # at this point we need to verify the PGP signature.
-    return if not @nocems;
-    my $e = pgp_check($hdrs{issuer}, $msgid, $tmpfile);
-    unlink $tmpfile;
-    return if not $e;
-
-    return ($msgid, $hdrs{'notice-id'}, $hdrs{issuer}, \@nocems);
-}
-
-# XXX not implemented: code to discard notices for groups we don't carry
-sub want_cancel_id {
-    my ($group, $hdrs) = @_;
-
-    return local_want_cancel_id(@_) if defined &local_want_cancel_id;
-    1;
-}
-
-# Do we actually want this NoCeM?
-sub want_nocem {
-    my $hdrs = shift;
-
-    foreach (@ncmperm) {
-        my ($issuer, $type) = split(/\001/);
-        if ($hdrs->{issuer} =~ /$issuer/i) {
-            return 1 if '*' eq $type or lc $hdrs->{type} eq $type;
-        }
-    }
-    return 0;
-}
-
-sub supported_nocem {
-    my ($msgid, $hdrs) = @_;
-
-    if ($hdrs->{version} !~ /^0\.9[0-9]?$/) {
-        logmsg("Article $msgid: version $hdrs->{version} not supported",
-            'debug');
-        return 0;
-    }
-    if ($hdrs->{action} ne 'hide') {
-        logmsg("Article $msgid: action $hdrs->{action} not supported",
-            'debug');
-        return 0;
-    }
-    return 1;
-}
-
-# Check the PGP signature on an article.
-sub pgp_check {
-    my ($issuer, $msgid, $art) = @_;
-
-    # fork and spawn a child
-    my $pid = open(PFD, '-|');
-    if (not defined $pid) {
-        logmsg("pgp_check: cannot fork: $!", 'err');
-        return 0;
-    }
-    if ($pid == 0) {
-        open(STDERR, '>&STDOUT');
-        exec($inn::gpgv, '--status-fd=1',
-            $keyring ? '--keyring=' . $keyring : '', $art);
-        exit 126;
-    }
-
-    # Read the result and check status code.
-    local $_ = join('', <PFD>);
-    my $status = 0;
-    if (not close PFD) {
-        if ($? >> 8) {
-            $status = $? >> 8;
-        } else {
-            logmsg("Article $msgid: $inn::gpgv killed by signal " . ($? & 255));
-            return 0;
-        }
-    }
-#    logmsg("Command line was: $inn::gpgv --status-fd=1"
-#         . ($keyring ? ' --keyring=' . $keyring : '') . " $art", 'debug');
-#    logmsg("Full PGP output: >>>$_<<<", 'debug');
-
-    if (/^\[GNUPG:\]\s+GOODSIG\s+\S+\s+(.*)/m) {
-        return 1 if $1 =~ /\Q$issuer\E/;
-        logmsg("Article $msgid: signed by $1 instead of $issuer");
-    } elsif (/^\[GNUPG:\]\s+NO_PUBKEY\s+(\S+)/m) {
-        logmsg("Article $msgid: $issuer (ID $1) not in keyring");
-    } elsif (/^\[GNUPG:\]\s+BADSIG\s+\S+\s+(.*)/m) {
-        logmsg("Article $msgid: bad signature from $1");
-    } elsif (/^\[GNUPG:\]\s+BADARMOR/m or /^\[GNUPG:\]\s+UNEXPECTED/m) {
-        logmsg("Article $msgid: malformed signature");
-    } elsif (/^\[GNUPG:\]\s+ERRSIG\s+(\S+)/m) {
-        # safety net: we get there if we don't know about some token
-        logmsg("Article $msgid: unknown error (ID $1)");
-    } else {
-        # some other error we don't know about happened.
-        # 126 is returned by the child if exec fails.
-        s/ at \S+ line \d+\.\n$//; s/\n/_/;
-        logmsg("Article $msgid: $inn::gpgv exited "
-            . (($status == 126) ? "($_)" : "with status $status"), 'err');
-    }
-    return 0;
-}
-
-# Read article.
-sub open_article {
-    my $token = shift;
-    
-    if ($token =~ /^\@.+\@$/) {
-        my $pid = open(ART, '-|');
-        if ($pid < 0) {
-            logmsg('Cannot fork: ' . $!, 'err');
-            return undef;
-        }
-        if ($pid == 0) {
-            exec("$inn::newsbin/sm", '-q', $token) or
-                logmsg("Cannot exec sm: $!", 'err');
-            return undef;
-        }
-        return *ART;
-    } else {
-        return *ART if open(ART, $token);
-        logmsg("Cannot open article $token: $!", 'err');
-    }
-    return undef;
-}
-
-# Cancel a number of Message-IDs.  We use ctlinnd to do this,
-# and we run up to 15 of them at the same time (10 usually).
-sub cancel_ctlinnd {
-    my @ids = @{$_[0]};
-
-    while (@ids > 0) {
-        my $max = @ids <= 15 ? @ids : 10;
-        for (my $i = 1; $i <= $max; $i++) {
-            my $msgid = shift @ids;
-            my $pid;
-            sleep 5 until (defined ($pid = fork));
-            if ($pid == 0) {
-                exec "$inn::pathbin/ctlinnd", '-s', '-t', '180',
-                    'cancel', $msgid;
-                exit 126;
-            }
-#            logmsg("cancelled: $msgid [$i/$max]", 'debug');
-        }
-        #    Now wait for all children.
-        while ((my $pid = wait) > 0) {
-            next unless $?;
-            if ($? >> 8) {
-                logmsg("Child $pid died with status " . ($? >> 8), 'err');
-            } else {
-                logmsg("Child $pid killed by signal " . ($? & 255), 'err');
-            }
-        }
-    }
-}
-
-sub cancel_nntp {
-    my $ids = shift;
-    my $r;
-    
-    if ($nntp_open and time - $socket_timeout > $last_cancel) {
-        logmsg('Close socket for timeout');
-        close (NNTP);
-        $nntp_open = 0;
-    }
-    if (not $nntp_open) {
-        use Socket;
-        if (not socket(NNTP, PF_UNIX, SOCK_STREAM, 0)) {
-            logmsg("socket: $!", 'err');
-            goto ERR;
-        }
-        if (not connect(NNTP, sockaddr_un($inn::pathrun . '/nntpin'))) {
-            logmsg("connect: $!", 'err');
-            goto ERR;
-        }
-        if (($r = <NNTP>) !~ /^200 /) {
-            $r =~ s/\r\n$//;
-            logmsg("bad reply from server: $r", 'err');
-            goto ERR;
-        }
-        select NNTP; $| = 1; select STDOUT;
-        print NNTP "MODE CANCEL\r\n";
-        if (($r = <NNTP>) !~ /^284 /) {
-            $r =~ s/\r\n$//;
-            logmsg("MODE CANCEL not supported: $r", 'err');
-            goto ERR;
-        }
-        $nntp_open = 1;
-    }
-    foreach (@$ids) {
-        print NNTP "$_\r\n";
-        if (($r = <NNTP>) !~ /^289/) {
-            $r =~ s/\r\n$//;
-            logmsg("cannot cancel $_: $r", 'err');
-            goto ERR;
-        }
-    }
-    $last_cancel = time;
-    return;
-
-ERR:
-    # discard unusable socket
-    close (NNTP);
-    logmsg('Switching to ctlinnd...', 'err');
-    cancel_ctlinnd($ids);
-    $cancel = \&cancel_ctlinnd;
-}
-
-sub read_ctlfile {
-    my $permfile = $inn::pathetc . '/nocem.ctl';
-
-    unless (open(CTLFILE, $permfile)) {
-        logmsg("Cannot open $permfile: $!", 'err');
-        return 0;
-    }
-    while (<CTLFILE>) {
-        chop;
-        s/^\s+//; s/\s+$//;
-        next if /^#/ or /^$/;
-        my ($issuer, $type) = split(/:/, lc $_);
-        logmsg("Cannot parse nocem.ctl line <<$_>>", 'err')
-            if not $issuer and $type;
-        $type =~ s/\s//g;
-        push @ncmperm, "$issuer\001$_" foreach split(/,/, $type);
-    }
-    close CTLFILE;
-    return 1;
-}
-
-sub logmsg {
-    my ($msg, $lvl) = @_;
-
-    if (not $use_syslog) {
-        if ($log_open == 0) {
-            open(LOG, ">>$logfile") or die "Cannot open log: $!";
-            $log_open = 1;
-            select LOG; $| = 1; select STDOUT;
-        }
-        $lvl ||= 'notice';
-        print LOG "$lvl: $msg\n";
-        return;
-    }
-    syslog($lvl || 'notice', '%s', $msg);
-}
-
-sub hup_handler {
-    $got_sighup = 1;
-    return if $working;
-    close LOG;
-    $log_open = 0;
-}
-
-sub term_handler {
-    $got_sigterm = 1;
-    return if $working;
-    logmsg('exiting because of signal');
-    exit 1;
-}
-
-# lint food
-print $inn::pathrun.$inn::pathlog.$inn::pathetc.$inn::newsbin.$inn::pathbin
-    .$inn::pathtmp.$inn::peertimeout.$inn::syslog_facility;
-
-__END__
-
-=head1 NAME
-
-perl-nocem - A NoCeM-on-spool implementation for S<INN 2.x>
-
-=head1 SYNOPSIS
-
-perl-nocem
-
-=head1 DESCRIPTION
-
-NoCeM, which is pronounced I<No See 'Em>, is a protocol enabling
-authenticated third-parties to issue notices which can be used
-to cancel unwanted articles (like spam and articles in moderated
-newsgroups which were not approved by their moderators).  It can
-also be used by readers as a I<third-party killfile>.  It is
-intended to eventually replace the protocol for third-party cancel
-messages.
-
-B<perl-nocem> processes third-party, PGP-signed article cancellation
-notices.  It is possible not to honour all NoCeM notices but only those
-which are sent by people whom you trust (that is to say if you trust
-the PGP key they use to sign their NoCeM notices).  Indeed, it is up
-to you to decide whether you wish to honour their notices, depending
-on the criteria they use.
-
-Processing NoCeM notices is easy to set up:
-
-=over 4
-
-=item 1.
-
-Import the keys of the NoCeM issuers you trust in order to check
-the authenticity of their notices.  You can do:
-
-    gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg \
-        --no-options --allow-non-selfsigned-uid --no-permission-warning \
-        --batch --import <key-file>
-
-where <pathetc> is the value of the I<pathetc> parameter set in F<inn.conf>
-and <key-file> the file containing the key(s) to import.  The keyring
-must be located in I<pathetc>/pgp/ncmring.gpg (create the directory
-before using B<gpg>).  For old PGP-generated keys, you may have to use
-B<--allow-non-selfsigned-uid> if they are not properly self-signed,
-but anyone creating a key really should self-sign the key.  Current
-PGP implementations do this automatically.
-
-The keys of NoCeM issuers can be found in the web site of I<The NoCeM Registry>:
-L<http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html>.  You can even
-download there a unique file which contains all the keys.
-
-=item 2.
-
-Create a F<nocem.ctl> config file in I<pathetc> indicating the NoCeM issuers
-and notices you want to follow.  This permission file contains lines like:
-
-    annihilator-1:*
-    clewis@ferret.ocunix:mmf
-    stephane@asynchrone:mmf,openproxy,spam
-
-This will remove all articles for which the issuer (first part of the line,
-before the colon C<:>) has issued NoCeM notices corresponding to the
-criteria specified after the colon.
-
-You will also find information about that on the web site of
-I<The NoCeM Registry>.
-
-=item 3.
-
-Add to the F<newsfeeds> file an entry like this one in order to feed
-B<perl-nocem> the NoCeM notices posted to alt.nocem.misc and
-news.lists.filters:
-
-    nocem!\
-        :!*,alt.nocem.misc,news.lists.filters\
-        :Tc,Wf,Ap:<pathbin>/perl-nocem
-
-with the correct path to B<perl-nocem>, located in <pathbin>.  Then, reload
-the F<newsfeeds> file (C<ctlinnd reload newsfeeds 'NoCeM channel feed'>).
-
-Note that you should at least carry news.lists.filters on your news
-server (or other newsgroups where NoCeM notices are sent) if you wish
-to process them.
-
-=item 4.
-
-Everything should now work.  However, do not hesitate to manually test
-B<perl-nocem> with a NoCeM notice, using:
-
-    grephistory '<Message-ID>' | perl-nocem
-
-Indeed, B<perl-nocem> expects tokens on its standard input, and
-B<grephistory> can easily give it the token of a known article,
-thanks to its Message-ID.
-
-=back
-
-When you have verified that everything works, you can eventually turn
-off regular spam cancels, if you want, not processing any longer
-cancels containing C<cyberspam> in the Path: header (see the
-I<refusecybercancels> parameter in F<inn.conf>).
-
-=head1 FILES
-
-=over 4
-
-=item I<pathbin>/perl-nocem
-
-The Perl script itself used to process NoCeM notices.
-
-=item I<pathetc>/nocem.ctl
-
-The configuration file which specifies the NoCeM notices to be processed.
-
-=item I<pathetc>/pgp/ncmring.gpg
-
-The keyring which contains the public keys of trusted NoCeM issuers.
-
-=back
-
-=head1 BUGS
-
-The Subject: header is not checked for the @@NCM string and there is no
-check for the presence of the References: header.
-
-The Newsgroups: pseudo header is not checked, but this can be done in
-local_want_cancel_id().
-
-The Hierarchies: header is ignored.
-
-=head1 HISTORY
-
-Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>.
-
-Copyright 2001 by Marco d'Itri <md@linux.it>.
-
-$Id: perl-nocem.in 7733 2008-04-06 09:16:20Z iulius $
-
-=head1 SEE ALSO
-
-gpgv(1), grephistory(1), inn.conf(5), newsfeeds(5), pgp(1).
-
-=cut
diff --git a/control/pgpverify.in b/control/pgpverify.in
deleted file mode 100644 (file)
index feee446..0000000
+++ /dev/null
@@ -1,876 +0,0 @@
-#! /usr/bin/perl -w
-# do '@LIBDIR@/innshellvars.pl';
-# If running inside INN, uncomment the above and point to innshellvars.pl.
-#
-# Written April 1996, <tale@isc.org> (David C Lawrence)
-# Currently maintained by Russ Allbery <rra@stanford.edu>
-# Version 1.27, 2005-07-02
-#
-# NOTICE TO INN MAINTAINERS:  The version that is shipped with INN is the
-# same as the version that I make available to the rest of the world
-# (including non-INN sites), so please make all changes through me.
-#
-# This program requires Perl 5, probably at least about Perl 5.003 since
-# that's when FileHandle was introduced.  If you want to use this program
-# and your Perl is too old, please contact me (rra@stanford.edu) and tell
-# me about it; I want to know what old versions of Perl are still used in
-# practice.
-#
-# Changes from 1.26 -> 1.27
-# -- Default to pubring.gpg when trustedkeys.gpg is not found in the
-#    default key location, for backward compatibility.
-#
-# Changes from 1.25 -> 1.26
-# -- Return the correct status code when the message isn't verified
-#    instead of always returning 255.
-#
-# Changes from 1.24 -> 1.25
-# -- Fix the -test switch to actually do something.
-# -- Improve date generation when logging to standard output.
-#
-# Changes from 1.23 -> 1.24
-# -- Fix bug in the recognition of wire-format articles.
-#
-# Changes from 1.15 -> 1.23
-# -- Bump version number to match CVS revision number.
-# -- Replaced all signature verification code with code that uses detached
-#    signatures.  Signatures generated by GnuPG couldn't be verified using
-#    attached signatures without adding a Hash: header, and this was the
-#    path of least resistance plus avoids munging problems in the future.
-#    Code taken from PGP::Sign.
-#
-# Changes from 1.14 -> 1.15
-# -- Added POD documentation.
-# -- Fixed the -test switch so that it works again.
-# -- Dropped Perl 4 compatibility and reformatted.  Now passes use strict.
-#
-# Changes from 1.13.1 -> 1.14
-# -- Native support for GnuPG without the pgpgpg wrapper, using GnuPG's
-#    program interface by Marco d'Itri.
-# -- Always use Sys::Syslog without any setlogsock call for Perl 5.6.0 or
-#    later, since Sys::Syslog in those versions of Perl uses the C library
-#    interface and is now portable.
-# -- Default to expecting the key ring in $inn'newsetc/pgp if it exists.
-# -- Fix a portability problem for Perl 4 introduced in 1.12.
-#
-# Changes from 1.13 -> 1.13.1
-# -- Nothing functional, just moved the innshellvars.pl line to the head of
-#    the script, to accomodate the build process of INN.
-#
-# Changes from 1.12 -> 1.13
-# -- Use INN's syslog_facility if available.
-#
-# Changes from 1.11 -> 1.12
-# -- Support for GnuPG.
-# -- Use /usr/ucb/logger, if present, instead of /usr/bin/logger (the latter
-#    of which, on Solaris at least, is some sort of brain damaged POSIX.2
-#    command which doesn't use syslog).
-# -- Made syslog work for dec_osf (version 4, at least).
-# -- Fixed up priority of '.' operator vs bitwise operators.
-#
-# Changes from 1.10 -> 1.11
-# -- Code to log error messages to syslog.
-#    See $syslog and $syslog_method configurable variables.
-# -- Configurably allow date stamp on stderr error messages.
-# -- Added locking for multiple concurrent pgp instances.
-# -- More clear error message if pgp exits abnormally.
-# -- Identify PGP 5 "BAD signature" string.
-# -- Minor diddling for INN (path to innshellvars.pl changed).
-#
-# Changes from 1.9 -> 1.10
-# -- Minor diddling for INN 2.0:  use $inn'pathtmp if it exists, and
-#    work with the new subst method to find innshellvars.pl.
-# -- Do not truncate the tmp file when opening, in case it is really
-#    linked to another file.
-#
-# Changes from 1.8 -> 1.9
-# -- Match 'Bad signature' pgp output to return exit status 3 by removing
-#    '^' in regexp matched on multiline string.
-#
-# Changes from 1.7 -> 1.8
-# -- Ignore final dot-CRLF if article is in NNTP format.
-#
-# Changes from 1.6 -> 1.7
-# -- Parse PGP 5.0 'good signature' lines.
-# -- Allow -test switch; prints pgp input and output.
-# -- Look for pgp in INN's innshellvars.pl.
-# -- Changed regexp delimiters for stripping $0 to be compatible with old
-#    Perl.
-#
-# Changes from 1.5 -> 1.6
-# -- Handle articles encoded in NNTP format ('.' starting line is doubled,
-#    \r\n at line end) by stripping NNTP encoding.
-# -- Exit 255 with pointer to $HOME or $PGPPATH if pgp can't find key
-#    ring.  (It probably doesn't match the necessary error message with
-#    ViaCrypt PGP.)
-# -- Failures also report Message-ID so the article can be looked up to
-#    retry.
-#
-# Changes from 1.4 -> 1.5
-# -- Force English language for 'Good signature from user' by passing
-#    +language=en on pgp command line, rather than setting the
-#    environment variable LANGUAGE to 'en'.
-#
-# Changes from 1.3 -> 1.4
-# -- Now handles wrapped headers that have been unfolded.
-#    (Though I do believe news software oughtn't be unfolding them.)
-# -- Checks to ensure that the temporary file is really a file, and
-#    not a link or some other weirdness.
-
-# Path to the GnuPG gpgv binary, if you have GnuPG.  If you do, this will
-# be used in preference to PGP.  For most current control messages, you
-# need a version of GnuPG that can handle RSA signatures.  If you have INN
-# and the script is able to successfully include your innshellvars.pl
-# file, the value of $inn::gpgv will override this.
-# $gpgv = '/usr/local/bin/gpgv';
-
-# Path to pgp binary; for PGP 5.0, set the path to the pgpv binary.  If
-# you have INN and the script is able to successfully include your
-# innshellvars.pl file, the value of $inn::pgp will override this.
-$pgp = '/usr/local/bin/pgp';
-
-# If you keep your keyring somewhere that is not the default used by pgp,
-# uncomment the next line and set appropriately.  If you have INN and the
-# script is able to successfully include your innshellvars.pl file, this
-# will be set to $inn::newsetc/pgp if that directory exists unless you set
-# it explicitly.  GnuPG will use a file named pubring.gpg in this
-# directory.
-# $keyring = '/path/to/your/pgp/config';
-
-# If you have INN and the script is able to successfully include your
-# innshellvars.pl file, the value of $inn::pathtmp and $inn::locks will
-# override these.
-$tmpdir = "/tmp";
-$lockdir = $tmpdir;
-
-# How should syslog be accessed?
-#
-# As it turns out, syslogging is very hard to do portably in versions of
-# Perl prior to 5.6.0.  Sys::Syslog should work without difficulty in
-# 5.6.0 or later and will be used automatically for those versions of Perl
-# (unless $syslog_method is '').  For earlier versions of Perl, 'inet' is
-# all that's available up to version 5.004_03.  If your syslog does not
-# accept UDP log packets, such as when syslogd runs with the -l flag,
-# 'inet' will not work.  A value of 'unix' will try to contact syslogd
-# directly over a Unix domain socket built entirely in Perl code (no
-# subprocesses).  If that is not working for you, and you have the
-# 'logger' program on your system, set this variable to its full path name
-# to have a subprocess contact syslogd.  If the method is just "logger",
-# the script will search some known directories for that program.  If it
-# can't be found & used, everything falls back on stderr logging.
-#
-# You can test the script's syslogging by running "pgpverify <
-# /some/text/file" on a file that is not a valid news article.  The
-# "non-header at line #" error should be syslogged.
-#
-# $syslog_method = 'unix';    # Unix doman socket, Perl 5.004_03 or higher.
-# $syslog_method = 'inet';    # UDP to port 514 of localhost.
-# $syslog_method = '';        # Don't ever try to do syslogging.
-$syslog_method = 'logger';    # Search for the logger program.
-
-# The next two variables are the values to be used for syslog's facility
-# and level to use, as would be found in syslog.conf.  For various
-# reasons, it is impossible to economically have the script figure out how
-# to do syslogging correctly on the machine.  If you have INN and the
-# script is able to successfully include you innshellvars.pl file, then
-# the value of $inn::syslog_facility will override this value of
-# $syslog_facility; $syslog_level is unaffected.
-$syslog_facility = 'news';
-$syslog_level = 'err';
-
-# Prepend the error message with a timestamp?  This is only relevant if
-# not syslogging, when errors go to stderr.
-#
-# $log_date = 0;  # Zero means don't do it.
-# $log_date = 1;  # Non-zero means do it.
-$log_date = -t STDOUT; # Do it if STDOUT is to a terminal.
-
-# End of configuration section.
-
-
-require 5;
-
-use strict;
-use vars qw($gpgv $pgp $keyring $tmp $tmpdir $lockdir $syslog_method
-            $syslog_facility $syslog_level $log_date $test $messageid);
-
-use Fcntl qw(O_WRONLY O_CREAT O_EXCL);
-use FileHandle;
-use IPC::Open3 qw(open3);
-use POSIX qw(strftime);
-
-# Turn on test mode if the first argument is '-test'.
-if (@ARGV && $ARGV[0] eq '-test') {
-  shift @ARGV;
-  $test = 1;
-}
-
-# Not syslogged, such an error is almost certainly from someone running
-# the script manually.
-die "Usage: $0 < message\n" if @ARGV != 0;
-
-# Grab various defaults from innshellvars.pl if running inside INN.
-$pgp = $inn::pgp
-    if $inn::pgp && $inn::pgp ne "no-pgp-found-during-configure";
-$gpgv = $inn::gpgv if $inn::gpgv;
-$tmp = ($inn::pathtmp ? $inn::pathtmp : $tmpdir) . "/pgp$$";
-$lockdir = $inn::locks if $inn::locks;
-$syslog_facility = $inn::syslog_facility if $inn::syslog_facility;
-if (! $keyring && $inn::newsetc) {
-  $keyring = $inn::newsetc . '/pgp' if -d $inn::newsetc . '/pgp';
-}
-
-# Trim /path/to/prog to prog for error messages.
-$0 =~ s%^.*/%%;
-
-# Make sure that the signature verification program can be executed.
-if ($gpgv) {
-  if (! -x $gpgv) {
-    &fail("$0: $gpgv: " . (-e _ ? "cannot execute" : "no such file") . "\n");
-  }
-} elsif (! -x $pgp) {
-  &fail("$0: $pgp: " . (-e _ ? "cannot execute" : "no such file") . "\n");
-}
-
-# Parse the article headers and generate the PGP message.
-my ($nntp_format, $header, $dup) = &parse_header();
-exit 1 unless $$header{'X-PGP-Sig'};
-my ($message, $signature, $version)
-    = &generate_message($nntp_format, $header, $dup);
-if ($test) {
-  print "-----MESSAGE-----\n$message\n-----END MESSAGE-----\n\n";
-  print "-----SIGNATURE-----\n$signature\n-----SIGNATURE-----\n\n";
-}
-
-# The call to pgp needs to be locked because it tries to both read and
-# write a file named randseed.bin but doesn't do its own locking as it
-# should, and the consequences of a multiprocess conflict is failure to
-# verify.
-my $lock;
-unless ($gpgv) {
-  $lock = "$lockdir/LOCK.$0";
-  until (&shlock($lock) > 0) {
-    sleep(2);
-  }
-}
-
-# Verify the message.
-my ($ok, $signer) = pgp_verify($signature, $version, $message);
-unless ($gpgv) {
-  unlink ($lock) or &errmsg("$0: unlink $lock: $!\n");
-}
-print "$signer\n" if $signer;
-unless ($ok == 0) {
-  &errmsg("$0: verification failed\n");
-}
-exit $ok;
-
-
-# Parse the article headers and return a flag saying whether the message
-# is in NNTP format and then two references to hashes.  The first hash
-# contains all the header/value pairs, and the second contains entries for
-# every header that's duplicated.  This is, by design, case-sensitive with
-# regards to the headers it checks.  It's also insistent about the
-# colon-space rule.
-sub parse_header {
-  my (%header, %dup, $label, $value, $nntp_format);
-  while (<>) {
-    # If the first header line ends with \r\n, this article is in the
-    # encoding it would be in during an NNTP session.  Some article
-    # storage managers keep them this way for efficiency.
-    $nntp_format = /\r\n$/ if $. == 1;
-    s/\r?\n$//;
-
-    last if /^$/;
-    if (/^(\S+):[ \t](.+)/) {
-      ($label, $value) = ($1, $2);
-      $dup{$label} = 1 if $header{$label};
-      $header{$label} = $value;
-    } elsif (/^\s/) {
-      &fail("$0: non-header at line $.: $_\n") unless $label;
-      $header{$label} .= "\n$_";
-    } else {
-      &fail("$0: non-header at line $.: $_\n");
-    }
-  }
-  $messageid = $header{'Message-ID'};
-  return ($nntp_format, \%header, \%dup);
-}
-
-# Generate the PGP message to verify.  Takes a flag indicating wire
-# format, the hash of headers and header duplicates returned by
-# parse_header and returns a list of three elements.  The first is the
-# message to verify, the second is the signature, and the third is the
-# version number.
-sub generate_message {
-  my ($nntp_format, $header, $dup) = @_;
-
-  # The regexp below might be too strict about the structure of PGP
-  # signature lines.
-
-  # The $sep value means the separator between the radix64 signature lines
-  # can have any amount of spaces or tabs, but must have at least one
-  # space or tab; if there is a newline then the space or tab has to
-  # follow the newline.  Any number of newlines can appear as long as each
-  # is followed by at least one space or tab.  *phew*
-  my $sep = "[ \t]*(\n?[ \t]+)+";
-
-  # Match all of the characters in a radix64 string.
-  my $r64 = '[a-zA-Z0-9+/]';
-
-  local $_ = $$header{'X-PGP-Sig'};
-  &fail("$0: X-PGP-Sig not in expected format\n")
-    unless /^(\S+)$sep(\S+)(($sep$r64{64})+$sep$r64+=?=?$sep=$r64{4})$/;
-
-  my ($version, $signed_headers, $signature) = ($1, $3, $4);
-  $signature =~ s/$sep/\n/g;
-  $signature =~ s/^\s+//;
-
-  my $message = "X-Signed-Headers: $signed_headers\n";
-  my $label;
-  foreach $label (split(",", $signed_headers)) {
-    &fail("$0: duplicate signed $label header, can't verify\n")
-      if $$dup{$label};
-    $message .= "$label: ";
-    $message .= "$$header{$label}" if $$header{$label};
-    $message .= "\n";
-  }
-  $message .= "\n";             # end of headers
-
-  while (<>) {                  # read body lines
-    if ($nntp_format) {
-      # Check for end of article; some news servers (eg, Highwind's
-      # "Breeze") include the dot-CRLF of the NNTP protocol in the article
-      # data passed to this script.
-      last if $_ eq ".\r\n";
-
-      # Remove NNTP encoding.
-      s/^\.\./\./;
-      s/\r\n$/\n/;
-    }
-    $message .= $_;
-  }
-
-  # Strip off all trailing whitespaces for compatibility with the way that
-  # pgpverify used to work, using attached signatures.
-  $message =~ s/[ \t]+\n/\n/g;
-
-  return ($message, $signature, $version);
-}
-
-# Check a detached signature for given data.  Takes a signature block (in
-# the form of an ASCII-armored string with embedded newlines), a version
-# number (which may be undef), and the message.  We return an exit status
-# and the key id if the signature is verified.  0 means good signature, 1
-# means bad data, 2 means an unknown signer, and 3 means a bad signature.
-# In the event of an error, we report with errmsg.
-#
-# This code is taken almost verbatim from PGP::Sign except for the code to
-# figure out the PGP style.
-sub pgp_verify {
-  my ($signature, $version, $message) = @_;
-  chomp $signature;
-
-  # Ignore SIGPIPE, since we're going to be talking to PGP.
-  local $SIG{PIPE} = 'IGNORE';
-
-  # Set the PGP style based on whether $gpgv is set.
-  my $pgpstyle = ($gpgv ? 'GPG' : 'PGP2');
-
-  # Because this is a detached signature, we actually need to save both
-  # the signature and the data to files and then run PGP on the signature
-  # file to make it verify the signature.  Because this is a detached
-  # signature, though, we don't have to do any data mangling, which makes
-  # our lives much easier.  It would be nice to do this without having to
-  # use temporary files, but I don't see any way to do so without running
-  # into mangling problems.
-  #
-  # PGP v5 *requires* there be some subheader or another.  *sigh*.  So we
-  # supply one if Version isn't given.  :)
-  my $umask = umask 077;
-  my $filename = $tmpdir . '/pgp' . time . '.' . $$;
-  my $sigfile = new FileHandle "$filename.asc", O_WRONLY|O_EXCL|O_CREAT;
-  unless ($sigfile) {
-    &errmsg ("Unable to open temp file $filename.asc: $!\n");
-    return (255, undef);
-  }
-  if ($pgpstyle eq 'PGP2') {
-    print $sigfile "-----BEGIN PGP MESSAGE-----\n";
-  } else {
-    print $sigfile "-----BEGIN PGP SIGNATURE-----\n";
-  }
-  if (defined $version) {
-    print $sigfile "Version: $version\n";
-  } elsif ($pgpstyle ne 'GPG') {
-    print $sigfile "Comment: Use GnuPG; it's better :)\n";
-  }
-  print $sigfile "\n", $signature;
-  if ($pgpstyle eq 'PGP2') {
-    print $sigfile "\n-----END PGP MESSAGE-----\n";
-  } else {
-    print $sigfile "\n-----END PGP SIGNATURE-----\n";
-  }
-  close $sigfile;
-
-  # Signature saved.  Now save the actual message.
-  my $datafile = new FileHandle "$filename", O_WRONLY|O_EXCL|O_CREAT;
-  unless ($datafile) {
-    &errmsg ("Unable to open temp file $filename: $!\n");
-    unlink "$filename.asc";
-    return (255, undef);
-  }
-  print $datafile $message;
-  close $datafile;
-
-  # Figure out what command line we'll be using.
-  my @command;
-  if ($pgpstyle eq 'GPG') {
-    @command = ($gpgv, qw/--quiet --status-fd=1 --logger-fd=1/);
-  } else {
-    @command = ($pgp, '+batchmode', '+language=en');
-  }
-
-  # Now, call PGP to check the signature.  Because we've written
-  # everything out to a file, this is actually fairly simple; all we need
-  # to do is grab stdout.  PGP prints its banner information to stderr, so
-  # just ignore stderr.  Set PGPPATH if desired.
-  #
-  # For GnuPG, use pubring.gpg if an explicit keyring was configured or
-  # found.  Otherwise, use trustedkeys.gpg in the default keyring location
-  # if found and non-zero, or fall back on pubring.gpg.  This is
-  # definitely not the logic that I would use if writing this from
-  # scratch, but it has the most backward compatibility.
-  local $ENV{PGPPATH} = $keyring if ($keyring && $pgpstyle ne 'GPG');
-  if ($pgpstyle eq 'GPG') {
-    if ($keyring) {
-      push (@command, "--keyring=$keyring/pubring.gpg");
-    } else {
-      my $home = $ENV{GNUPGHOME} || $ENV{HOME};
-      $home .= '/.gnupg' if $home;
-      if ($home && ! -s "$home/trustedkeys.gpg" && -f "$home/pubring.gpg") {
-        push (@command, "--keyring=pubring.gpg");
-      }
-    }
-  }
-  push (@command, "$filename.asc");
-  push (@command, $filename);
-  my $input = new FileHandle;
-  my $output = new FileHandle;
-  my $pid = eval { open3 ($input, $output, $output, @command) };
-  if ($@) {
-    &errmsg ($@);
-    &errmsg ("Execution of $command[0] failed.\n");
-    unlink ($filename, "$filename.asc");
-    return (255, undef);
-  }
-  close $input;
-
-  # Check for the message that gives us the key status and return the
-  # appropriate thing to our caller.  This part is a zoo due to all of the
-  # different formats used.  GPG has finally done the right thing and
-  # implemented a separate status stream with parseable data.
-  #
-  # MIT PGP 2.6.2 and PGP 6.5.2:
-  #   Good signature from user "Russ Allbery <rra@stanford.edu>".
-  # ViaCrypt PGP 4.0:
-  #   Good signature from user:  Russ Allbery <rra@stanford.edu>
-  # PGP 5.0:
-  #   Good signature made 1999-02-10 03:29 GMT by key:
-  #     1024 bits, Key ID 0AFC7476, Created 1999-02-10
-  #      "Russ Allbery <rra@stanford.edu>"
-  #
-  # Also, PGP v2 prints out "Bad signature" while PGP v5 uses "BAD
-  # signature", and PGP v6 reverts back to "Bad signature".
-  local $_;
-  local $/ = '';
-  my $signer;
-  my $ok = 255;
-  while (<$output>) {
-    print if $test;
-    if ($pgpstyle eq 'GPG') {
-      if (/\[GNUPG:\]\s+GOODSIG\s+\S+\s+(\S+)/) {
-        $ok = 0;
-        $signer = $1;
-      } elsif (/\[GNUPG:\]\s+NODATA/ || /\[GNUPG:\]\s+UNEXPECTED/) {
-        $ok = 1;
-      } elsif (/\[GNUPG:\]\s+NO_PUBKEY/) {
-        $ok = 2;
-      } elsif (/\[GNUPG:\]\s+BADSIG\s+/) {
-        $ok = 3;
-      }
-    } else {
-      if (/^Good signature from user(?::\s+(.*)|\s+\"(.*)\"\.)$/m) {
-        $signer = $+;
-        $ok = 0;
-        last;
-      } elsif (/^Good signature made .* by key:\n.+\n\s+\"(.*)\"/m) {
-        $signer = $1;
-        $ok = 0;
-        last;
-      } elsif (/^\S+: Good signature from \"(.*)\"/m) {
-        $signer = $1;
-        $ok = 0;
-        last;
-      } elsif (/^(?:\S+: )?Bad signature /im) {
-        $ok = 3;
-        last;
-      }
-    }
-  }
-  close $input;
-  waitpid ($pid, 0);
-  unlink ($filename, "$filename.asc");
-  umask $umask;
-  return ($ok, $signer || '');
-}
-
-# Log an error message, attempting syslog first based on $syslog_method
-# and falling back on stderr.
-sub errmsg {
-  my ($message) = @_;
-  $message =~ s/\n$//;
-
-  my $date = '';
-  if ($log_date) {
-    $date = strftime ('%Y-%m-%d %T ', localtime);
-  }
-
-  if ($syslog_method && $] >= 5.006) {
-    eval "use Sys::Syslog";
-    $syslog_method = 'internal';
-  }
-
-  if ($syslog_method eq "logger") {
-    my @loggers = ('/usr/ucb/logger', '/usr/bin/logger',
-                   '/usr/local/bin/logger');
-    my $try;
-    foreach $try (@loggers) {
-      if (-x $try) {
-        $syslog_method = $try;
-        last;
-      }
-    }
-    $syslog_method = '' if $syslog_method eq 'logger';
-  }
-
-  if ($syslog_method ne '' && $syslog_method !~ m%/logger$%) {
-    eval "use Sys::Syslog";
-  }
-
-  if ($@ || $syslog_method eq '') {
-    warn $date, "$0: trying to use Perl's syslog: $@\n" if $@;
-    warn $date, $message, "\n";
-    warn $date, "... while processing $messageid\n"
-      if $messageid;
-
-  } else {
-    $message .= " processing $messageid"
-      if $messageid;
-
-    if ($syslog_method =~ m%/logger$%) {
-      unless (system($syslog_method, "-i", "-p",
-                     "$syslog_facility.$syslog_level", $message) == 0) {
-        if ($? >> 8) {
-          warn $date, "$0: $syslog_method exited status ",  $? >>  8, "\n";
-        } else {
-          warn $date, "$0: $syslog_method died on signal ", $? & 255, "\n";
-        }
-        $syslog_method = '';
-        &errmsg($message);
-      }
-
-    } else {
-      # setlogsock arrived in Perl 5.004_03 to enable Sys::Syslog to use a
-      # Unix domain socket to talk to syslogd, which is the only way to do
-      # it when syslog runs with the -l switch.
-      if ($syslog_method eq "unix") {
-        if ($^O eq "dec_osf" && $] >= 5) {
-          eval 'sub Sys::Syslog::_PATH_LOG { "/dev/log" }';
-        }
-        if ($] <= 5.00403 || ! eval "setlogsock('unix')") {
-          warn $date, "$0: cannot use syslog_method 'unix' on this system\n";
-          $syslog_method = '';
-          &errmsg($message);
-          return;
-        }
-      }
-
-      # Unfortunately, there is no way to definitively know in this
-      # program if the message was logged.  I wish there were a way to
-      # send a message to stderr if and only if the syslog attempt failed.
-      &openlog($0, 'pid', $syslog_facility);
-      &syslog($syslog_level, $_[0]);
-      &closelog();
-    }
-  }
-}
-
-sub fail {
-  &errmsg($_[0]);
-  exit 255;
-}
-
-# Get a lock in essentially the same fashion as INN's shlock.  return 1 on
-# success, 0 for normal failure, -1 for abnormal failure.  "normal
-# failure" is that a lock is apparently in use by someone else.
-sub shlock {
-  my ($file) = @_;
-  my ($ltmp, $pid);
-
-  unless (defined(&ENOENT)) {
-    eval "require POSIX qw(:errno_h)";
-    if ($@) {
-      # values taken from BSD/OS 3.1
-      sub ENOENT {  2 }
-      sub ESRCH  {  3 }
-      sub EEXIST { 17 }
-    }
-  }
-
-  $ltmp = ($file =~ m%(.*/)%)[0] . "shlock$$";
-
-  # This should really attempt to use another temp name.
-  -e $ltmp && (unlink($ltmp) || return -1);
-
-  open(LTMP, ">$ltmp") || return -1;
-  print LTMP "$$\n" || (unlink($ltmp), return -1);
-  close(LTMP) || (unlink($ltmp), return -1);
-
-  if (!link($ltmp, $file)) {
-    if ($! == &EEXIST) {
-      if (open(LOCK, "<$file")) {
-        $pid = <LOCK>;
-        if ($pid =~ /^\d+$/ && (kill(0, $pid) == 1 || $! != &ESRCH)) {
-          unlink($ltmp);
-          return 0;
-        }
-
-        # OK, the pid in the lockfile is not a number or no longer exists.
-        close(LOCK);            # silent failure is ok here
-
-        # Unlink failed.
-        if (unlink($file) != 1 && $! != &ENOENT) {
-          unlink($ltmp);
-          return 0;
-        }
-
-      # Check if open failed for reason other than file no longer present.
-      } elsif ($! != &ENOENT) {
-        unlink($ltmp);
-        return -1;
-      }
-
-      # Either this process unlinked the lockfile because it was bogus, or
-      # between this process's link() and open() the other process holding
-      # the lock unlinked it.  This process can now try to acquire.
-      if (! link($ltmp, $file)) {
-        unlink($ltmp);
-        return $! == &EEXIST ? 0 : -1; # Maybe another proc grabbed the lock.
-      }
-
-    } else {                    # First attempt to link failed.
-      unlink($ltmp);
-      return 0;
-    }
-  }
-  unlink($ltmp);
-  return 1;
-}
-
-=head1 NAME
-
-pgpverify - Cryptographically verify Usenet control messages
-
-=head1 SYNOPSIS
-
-B<pgpverify> [B<-test>] < I<message>
-
-=head1 DESCRIPTION
-
-The B<pgpverify> program reads (on standard input) a Usenet control
-message that has been cryptographically signed using the B<signcontrol>
-program (or some other program that produces a compatible format).
-B<pgpverify> then uses a PGP implementation to determine who signed the
-control message.  If the control message has a valid signature,
-B<pgpverify> prints (to stdout) the user ID of the key that signed the
-message.  Otherwise, it exits with a non-zero exit status.
-
-If B<pgpverify> is installed as part of INN, it uses INN's configuration
-to determine what signature verification program to use, how to log
-errors, what temporary directory to use, and what keyring to use.
-Otherwise, all of those parameters can be set by editing the beginning of
-this script.
-
-By default, when running as part of INN, B<pgpverify> expects the PGP key
-ring to be found in I<pathetc>/pgp (as either F<pubring.pgp> or
-F<pubring.gpg> depending on whether PGP or GnuPG is used to verify
-signatures).  If that directory doesn't exist, it will fall back on using
-the default key ring, which is in a F<.pgp> or F<.gnupg> subdirectory of
-the running user's home directory.
-
-INN, when using GnuPG, configures B<pgpverify> to use B<gpgv>, which by
-default expects keys to be in a keyring named F<trustedkeys.gpg>, since it
-doesn't implement trust checking directly.  B<pgpverify> uses that file if
-present but falls back to F<pubring.gpg> if it's not found.  This bypasses
-the trust model for checking keys, but is compatible with the way that
-B<pgpverify> used to behave.  Of course, if a keyring is found in
-I<pathetc>/pgp or configured at the top of the script, that overrides all of
-this behavior.
-
-=head1 OPTIONS
-
-The B<-test> flag causes B<pgpverify> to print out the input that it is
-passing to PGP (which is a reconstructed version of the input that
-supposedly created the control message) as well as the output from PGP's
-analysis of the message.
-
-=head1 EXIT STATUS
-
-B<pgpverify> may exit with the following statuses:
-
-=over 4
-
-=item 0Z<>
-
-The control message had a good PGP signature.
-
-=item 1
-
-The control message had no PGP signature.
-
-=item 2
-
-The control message had an unknown PGP signature.
-
-=item 3
-
-The control message had a bad PGP signature.
-
-=item 255
-
-A problem occurred not directly related to PGP analysis of signature.
-
-=back
-
-=head1 ENVIRONMENT
-
-B<pgpverify> does not modify or otherwise alter the environment before
-invoking the B<pgp> or B<gpgv> program.  It is the responsibility of the
-person who installs B<pgpverify> to ensure that when B<pgp> or B<gpgv>
-runs, it has the ability to locate and read a PGP key file that contains
-the PGP public keys for the appropriate Usenet hierarchy administrators.
-B<pgpverify> can be pointed to an appropriate key ring by editing
-variables at the beginning of this script.
-
-=head1 NOTES
-
-Historically, Usenet news server administrators have configured their news
-servers to automatically honor Usenet control messages based on the
-originator of the control messages and the hierarchies for which the
-control messages applied.  For example, in the past, David Lawrence always
-issued control messages for the S<"Big 8"> hierarchies (comp, humanities,
-misc, news, rec, sci, soc, talk).  Usenet news administrators would
-configure their news server software to automatically honor newgroup and
-rmgroup control messages that originated from David Lawrence and applied
-to any of the S<Big 8> hierarchies.
-
-Unfortunately, Usenet news articles (including control messages) are
-notoriously easy to forge.  Soon, malicious users realized they could
-create or remove (at least temporarily) any S<Big 8> newsgroup they wanted by
-simply forging an appropriate control message in David Lawrence's name.
-As Usenet became more widely used, forgeries became more common.
-
-The B<pgpverify> program was designed to allow Usenet news administrators
-to configure their servers to cryptographically verify control messages
-before automatically acting on them.  Under the B<pgpverify> system, a Usenet
-hierarchy maintainer creates a PGP public/private key pair and
-disseminates the public key.  Whenever the hierarchy maintainer issues a
-control message, he uses the B<signcontrol> program to sign the control
-message with the PGP private key.  Usenet news administrators configure
-their news servers to run the B<pgpverify> program on the appropriate
-control messages, and take action based on the PGP key User ID that signed
-the control message, not the name and address that appear in the control
-message's From: or Sender: headers.
-
-Thus, appropriate use of the B<signcontrol> and B<pgpverify> programs
-essentially eliminates the possibility of malicious users forging Usenet
-control messages that sites will act upon, as such users would have to
-obtain the PGP private key in order to forge a control message that would
-pass the cryptographic verification step.  If the hierarchy administrators
-properly protect their PGP private keys, the only way a malicious user
-could forge a validly-signed control message would be by breaking the
-public key encryption algorithm, which (at least at this time) is believed
-to be prohibitively difficult for PGP keys of a sufficient bit length.
-
-=head1 HISTORY
-
-B<pgpverify> was written by David C Lawrence <tale@isc.org>.  Manual page
-provided by James Ralston.  It is currently maintained by Russ Allbery
-<rra@stanford.edu>.
-
-=head1 COPYRIGHT AND LICENSE
-
-David Lawrence wrote:  "Our lawyer told me to include the following.  The
-upshot of it is that you can use the software for free as much as you
-like."
-
-Copyright (c) 1996 UUNET Technologies, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-=over 4
-
-=item 1.
-
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-
-=item 2.
-
-Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation
-and/or other materials provided with the distribution.
-
-=item 3.
-
-All advertising materials mentioning features or use of this software must
-display the following acknowledgement:
-
-  This product includes software developed by UUNET Technologies, Inc.
-
-=item 4.
-
-The name of UUNET Technologies ("UUNET") may not be used to endorse or
-promote products derived from this software without specific prior written
-permission.
-
-=back
-
-THIS SOFTWARE IS PROVIDED BY UUNET "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
-NO EVENT SHALL UUNET BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-=head1 SEE ALSO
-
-gpgv(1), pgp(1).
-
-L<ftp://ftp.isc.org/pub/pgpcontrol/> is where the most recent versions of
-B<signcontrol> and B<pgpverify> live, along with PGP public keys used for
-hierarchy administration.
-
-=cut
-
-# Local variables:
-# cperl-indent-level: 2
-# fill-column: 74
-# End:
diff --git a/control/signcontrol.in b/control/signcontrol.in
deleted file mode 100644 (file)
index c1951e7..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-#! /usr/bin/perl -w
-# written April 1996, tale@isc.org (David C Lawrence)
-# Currently maintained by Russ Allbery <rra@stanford.edu>
-# Version 1.8, 2003-07-06
-#
-# Changes from 1.6 -> 1.8
-# -- Added support for GnuPG.
-# -- Replace signing code with code from PGP::Sign that generates detached
-#    signatures instead.  Otherwise, GnuPG signatures with DSA keys could
-#    not be verified.  Should still work the same as before with RSA keys.
-# -- Thanks to new signing code, no longer uses a temporary file.
-# -- Only lock when using PGP; GnuPG shouldn't need it.
-#
-# Changes from 1.5 -> 1.6
-# -- eliminated subprocess use (except pgp, of course).
-# -- interlock against competing signing processes.
-# -- allow optional headers; see $use_or_add.
-# -- added simple comments about why particular headers are signed.
-# -- made error messages a tad more helpful for situations when it is hard
-#    to know what message was trying to be signed (such as via an "at"
-#    job).
-# -- set $action, $group, $moderated to "" to prevent unusued variable
-#    warnings in the event a Control header can't be parsed.
-# -- moved assignment of $pgpend out of loop.
-#
-# Changes from 1.4 -> 1.5
-# -- need to require Text::Tabs to get 'expand' for tabs in checkgroups.
-#
-# Changes from 1.3 -> 1.4
-# -- added checkgroups checking.
-# -- added group name in several error messages (for help w/batch
-#    processing).
-# -- disabled moderator address checking.
-# -- adjusted newsgroups line (ie, tabbing fixed) now correctly
-#    substituted into control message.
-#
-# Changes from 1.2.3 -> 1.3
-# -- skip minor pgp signature headers like "charset:" after "version:"
-#    header and until the empty line that starts the base64 signature block.
-
-# CONFIGURATION
-
-# PGP variables.
-#
-# $pgp can be set to the path to GnuPG to use GnuPG instead.  The program
-# name needs to end in gpg so that signcontrol knows GnuPG is being used.
-#
-# STORING YOUR PASS PHRASE IN A FILE IS A POTENTIAL SECURITY HOLE.
-# make sure you know what you're doing if you do it.
-# if you don't use pgppassfile, you can only use this script interactively.
-# if you DO use pgppassfile, it is possible that someone could steal
-#  your passphrase either by gaining access to the file or by seeing
-#  the environment of a running pgpverify program.
-#
-# $pgplock is used because pgp does not guard itself against concurrent
-# read/write access to its randseed.bin file.  A writable file is needed;
-# The default value is to use the .pgp/config.txt file in the home
-# directory of the user running the program.  Note that this will only
-# work to lock against other instances of signcontrol, not all pgp uses.
-# $pgplock is not used if $pgp ends in 'gpg' since GnuPG doesn't need
-# this.
-$pgpsigner = 'INSERT_YOUR_PGP_USERID';
-$pgppassfile = '';      # file with pass phrase for $pgpsigner
-$pgp = "/usr/local/bin/pgp";
-$pgpheader = "X-PGP-Sig";
-$pgplock = (getpwuid($<))[7] . '/.pgp/config.txt';
-
-# this program is strict about always wanting to be consistent about what
-# headers appear in the control messages.  the defaults for the
-# @... arrays are reasonable, but you should edit the force values.
-
-# these headers are acceptable in input, but they will be overwritten with
-# these values.  no sanity checking is done on what you put here.  also,
-# Subject: is forced to be the Control header prepending by "cmsg".  also,
-# Newsgroups: is forced to be just the group being added/removed.
-#             (but is taken as-is for checkgroups)
-$force{'Path'} = 'bounce-back';
-$force{'From'} = 'YOUR_ADDRESS_AND_NAME';
-$force{'Approved'} = 'ADDRESS_FOR_Approved_HEADER';
-$force{'X-Info'}='ftp://ftp.isc.org/pub/pgpcontrol/README.html'
-               . "\n\t"
-               . 'ftp://ftp.isc.org/pub/pgpcontrol/README';
-
-# these headers are acceptable in input, or if not present then will be
-# created with the given value.  None are enabled by default, because they
-# should not be necessary.  Setting one to a null string will pass through
-# any instance of it found in the input, but not generate one if it is
-# missing.  If you set any $default{} variables, you must also put it in
-# @orderheaders below.
-#
-# Note that Distribution nearly never works correctly, so use it only if
-# you are really sure the propagation of the article will be limited as
-# you intend.  This normally means that you control all servers the
-# distribution will go to with an iron fist.
-#
-# $use_or_add{'Reply-To'} = 'YOUR_REPLY_ADDRESS';
-# $use_or_add{'Oranization'} = 'YOUR_ORGANIZATION';
-# $use_or_add{'Distribution'} = 'MESSAGE_DISTRIBUTION';
-
-# host for message-id; this could be determined automatically based on
-# where it is run, but consistency is the goal here
-$id_host = 'FULL_HOST_NAME';
-
-# headers to sign.  Sender is included because non-PGP authentication uses
-# it.  The following should always be signed:
-#  Subject    -- some older news systems use it to identify the control action.
-#  Control    -- most news systems use this to determine what to do.
-#  Message-ID -- guards against replay attacks.
-#  Date       -- guards against replay attacks.
-#  From       -- used by news systems as part of authenticating the message.
-#  Sender     -- used by news systems as part of authenticating the message.
-@signheaders = ('Subject', 'Control', 'Message-ID', 'Date', 'From', 'Sender');
-
-# headers to remove from real headers of final message.
-# If it is a signed header, it is signed with an empty value.
-# set to () if you do not want any headers removed.
-@ignoreheaders = ('Sender');
-
-# headers that will appear in final message, and their order of
-# appearance.  all _must_ be set, either in input or via the $force{} and
-# $use_or_add{} variables above.
-# (exceptions: Date, Lines, Message-ID are computed by this program)
-# if header is in use_or_add with a null value, it will not appear in output.
-# several are required by the news article format standard; if you remove
-# these, your article will not propagate:
-#   Path, From, Newsgroups, Subject, Message-ID, Date
-# if you take out these, your control message is not very useful:
-#   Control, Approved
-# any headers in @ignoreheaders also in @orderheaders are silently dropped.
-# any non-null header in the input but not in @orderheaders or @ignoreheaders
-#   is an error.
-# null headers are silently dropped.
-@orderheaders =
-  ('Path', 'From', 'Newsgroups', 'Subject', 'Control', 'Approved',
-   'Message-ID', 'Date', 'Lines', 'X-Info', $pgpheader);
-
-# this program tries to help you out by not letting you sign erroneous
-# names, especially ones that are so erroneous they run afoul of naming
-# standards.
-#
-# set to match only hierarchies you will use it on
-# include no '|' for a single hierarchy (eg, "$hierarchies = 'uk';").
-
-$hierarchies = 'HIERARCHIES';
-
-# the draft news article format standard says:
-#   "subsequent components SHOULD begin with a letter"
-# where "SHOULD" means:
-#   means that the item is a strong recommendation: there may be
-#   valid reasons to ignore it  in  unusual  circumstances,  but
-#   this  should  be  done  only after careful study of the full
-#   implications and a firm conclusion  that  it  is  necessary,
-#   because  there are serious disadvantages to doing so. 
-# as opposed to "MUST" which means:
-#   means that the item is an absolute requirement of the specification
-# MUST is preferred, but might not be acceptable if you have legacy
-# newsgroups that have name components that begin with a letter, like
-# news.announce.newgroups does with comp.sys.3b1 and 17 other groups.
-
-$start_component_with_letter = 'MUST';
-
-## END CONFIGURATION
-
-use Fcntl qw(F_SETFD);
-use FileHandle;
-use IPC::Open3 qw(open3);
-use POSIX qw(setlocale strftime LC_TIME);
-use Text::Tabs;                 # to get 'expand' for tabs in checkgroups
-
-$0 =~ s#^.*/##;
-
-die "Usage: $0 < message\n" if @ARGV > 0;
-
-umask(0022);                    # flock needs a writable file, if we create it
-if ($pgp !~ /gpg$/) {
-  open(LOCK, ">>$pgplock") || die "$0: open $lock: $!, exiting\n";
-  flock(LOCK, 2);               # block until locked
-}
-
-&setgrouppat;
-
-$die = '';
-
-&readhead;
-&readbody;
-
-if ($die) {
-  if ($group) {
-    die "$0: ERROR PROCESSING ${action}group $group:\n", $die;
-  } elsif ($action eq 'check') {
-    die "$0: ERROR PROCESSING checkgroups:\n", $die;
-  } elsif ($header{'Subject'}) {
-    die "$0: ERROR PROCESSING Subject: $header{'Subject'}\n", $die;
-  } else {
-    die $die;
-  } 
-}
-
-&signit;
-
-if ($pgp !~ /gpg$/) {
-  close(LOCK) || warn "$0: close $lock: $!\n";
-}
-exit 0;
-
-sub
-setgrouppat
-
-{
-  my ($hierarchy, $plain_component, $no_component);
-  my ($must_start_letter, $should_start_letter);
-  my ($eval);
-
-  # newsgroup name checks based on RFC 1036bis (not including encodings) rules:
-  #  "component MUST contain at least one letter"
-  #  "[component] MUST not contain uppercase letters"
-  #  "[component] MUST begin with a letter or digit"
-  #  "[component] MUST not be longer than 14 characters"
-  #  "sequences 'all' and 'ctl' MUST not be used as components"
-  #  "first component MUST begin with a letter"
-  # and enforcing "subsequent components SHOULD begin with a letter" as MUST
-  # and enforcing at least a 2nd level group (can't use to newgroup "general")
-  #
-  # DO NOT COPY THIS PATTERN BLINDLY TO OTHER APPLICATIONS!
-  #   It has special construction based on the pattern it is finally used in.
-
-  $plain_component = '[a-z][-+_a-z\d]{0,13}';
-  $no_component = '(.*\.)?(all|ctl)(\.|$)';
-  $must_start_letter = '(\.' . $plain_component . ')+';
-  $should_start_letter = '(\.(?=\d*[a-z])[a-z\d]+[-+_a-z\d]{0,13})+';
-
-  $grouppat = "(?!$no_component)($hierarchies)";
-  if ($start_component_with_letter eq 'SHOULD') {
-    $grouppat .= $should_start_letter;
-  } elsif ($start_component_with_letter eq 'MUST') {
-    $grouppat .= $must_start_letter;
-  } else {
-    die "$0: unknown value configured for \$start_component_with_letter\n";
-  }
-
-  foreach $hierarchy (split(/\|/, $hierarchies)) {
-    die "$0: hierarchy name $hierarchy not standards-compliant\n"
-      if $hierarchy !~ /^$plain_component$/o;
-  }
-
-  $eval = "\$_ = 'test'; /$grouppat/;";
-  eval $eval;
-  die "$0: bad regexp for matching group names:\n $@" if $@;
-}
-
-sub
-readhead
-
-{
-  my($head, $label, $value);
-  local($_, $/);
-
-  $/ = "";
-  $head = <STDIN>;              # get the whole news header
-  $die .= "$0: continuation lines in headers not allowed\n"
-    if $head =~ s/\n[ \t]+/ /g; # rejoin continued lines
-
-  for (split(/\n/, $head)) {
-    if (/^(\S+): (.*)/) {
-      $label = $1;
-      $value = $2;
-
-      $die .= "$0: duplicate header $label\n" if $header{$label};
-
-      $header{$label} = $value;
-      $header{$label} =~ s/^\s+//;
-      $header{$label} =~ s/\s+$//;
-    } elsif (/^$/) {
-      ;                           # the empty line separator(s)
-    } else {
-      $die .= "$0: non-header line:\n  $_\n";
-    }
-  }
-
-  $header{'Message-ID'} = '<' . time . ".$$\@$id_host>";
-
-  setlocale(LC_TIME, "C");
-  $header{'Date'} = strftime("%a, %d %h %Y %T -0000", gmtime);
-
-  for (@ignoreheaders) {
-    $die .= "ignored header $_ also has forced value set\n" if $force{$_};
-    $header{$_} = '';
-  }
-
-  for (@orderheaders) {
-    $header{$_} = $force{$_} if defined($force{$_});
-    next if /^(Lines|\Q$pgpheader\E)$/; # these are set later
-    unless ($header{$_}) {
-      if (defined($use_or_add{$_})) {
-        $header{$_} = $use_or_add{$_} if $use_or_add{$_} ne '';
-      } else {
-        $die .= "$0: missing $_ header\n";
-      }
-    }
-  }
-
-  $action = $group = $moderated = "";
-  if ($header{'Control'}) {
-    if ($header{'Control'} =~ /^(new)group (\S+)( moderated)?$/o ||
-        $header{'Control'} =~ /^(rm)group (\S+)()$/o ||
-        $header{'Control'} =~ /^(check)groups()()$/o) {
-      ($action, $group, $moderated) = ($1, $2, $3);
-      $die .= "$0: group name $group is not standards-compliant\n"
-        if $group !~ /^$grouppat$/ && $action eq 'new';
-      $die .= "$0: no group to rmgroup on Control: line\n"
-        if ! $group && $action eq 'rm';
-      $header{'Subject'} = "cmsg $header{'Control'}";
-      $header{'Newsgroups'} = $group unless $action eq 'check';
-    } else {
-      $die .= "$0: bad Control format: $header{'Control'}\n";
-    }
-  } else {
-    $die .= "$0: can't verify message content; missing Control header\n";
-  }
-}
-
-sub
-readbody
-
-{
-  local($_, $/);
-  local($status, $ngline, $fixline, $used, $desc, $mods);
-
-  undef $/;
-  $body = $_ = <STDIN>;
-  $header{'Lines'} = $body =~ tr/\n/\n/ if $body;
-
-  # the following tests are based on the structure of a
-  # news.announce.newgroups newgroup message; even if you comment out the
-  # "first line" test, please leave the newsgroups line and moderators
-  # checks
-  if ($action eq 'new') {
-    $status = $moderated ? 'a\smoderated' : 'an\sunmoderated';
-    $die .= "$0: nonstandard first line in body for $group\n"
-      if ! /^\Q$group\E\sis\s$status\snewsgroup\b/;
-
-    my $intro = "For your newsgroups file:\n";
-    $ngline =
-      (/^$intro\Q$group\E[ \t]+(.+)\n(\n|\Z(?!\n))/mi)[0];
-    if ($ngline) {
-      $_ = $group;
-      $desc = $1;
-      $fixline = $_;
-      $fixline .= "\t" x ((length) > 23 ? 1 : (4 - ((length) + 1) / 8));
-      $used = (length) < 24 ? 24 : (length) + (8 - (length) % 8);
-      $used--;
-      $desc =~ s/ \(Moderated\)//i;
-      $desc =~ s/\s+$//;
-      $desc =~ s/\w$/$&./;
-      $die .= "$0: $group description too long\n" if $used + length($desc) > 80;
-      $fixline .= $desc;
-      $fixline .= ' (Moderated)' if $moderated;
-      $body =~ s/^$intro(.+)/$intro$fixline/mi;
-    } else {
-      $die .= "$0: $group newsgroup line not formatted correctly\n";
-    }
-    # moderator checks are disabled; some sites were trying to
-    # automatically maintain aliases based on this, which is bad policy.
-    if (0 && $moderated) {
-      $die .= "$0: $group submission address not formatted correctly\n"
-        if $body !~ /\nGroup submission address:   ?\S+@\S+\.\S+\n/m;
-      $mods = "( |\n[ \t]+)\\([^)]+\\)\n\n";
-      $die .= "$0: $group contact address not formatted correctly\n"
-        if $body !~ /\nModerator contact address:  ?\S+@\S+\.\S+$mods/m;
-    }
-  }
-  # rmgroups have freeform bodies
-
-  # checkgroups have structured bodies
-  if ($action eq 'check') {
-    for (split(/\n/, $body)) {
-      my ($group, $description) = /^(\S+)\t+(.+)/;
-      $die .= "$0: no group:\n  $_\n"           unless $group;
-      $die .= "$0: no description:\n  $_\n"     unless $description;
-      $die .= "$0: bad group name \"$group\"\n" if $group !~ /^$grouppat$/;
-      $die .= "$0: tab in description\n"        if $description =~ /\t/;
-      s/ \(Moderated\)$//;
-      $die .= "$0: $group line too long\n"      if length(expand($_)) > 80;
-    }
-  }
-}
-
-# Create a detached signature for the given data.  The first argument
-# should be a key id, the second argument the PGP passphrase (which may be
-# null, in which case PGP will prompt for it), and the third argument
-# should be the complete message to sign.
-#
-# In a scalar context, the signature is returned as an ASCII-armored block
-# with embedded newlines.  In array context, a list consisting of the
-# signature and the PGP version number is returned.  Returns undef in the
-# event of an error, and the error text is then stored in @ERROR.
-#
-# This function is taken almost verbatim from PGP::Sign except the PGP
-# style is determined from the name of the program used.
-sub pgp_sign {
-  my ($keyid, $passphrase, $message) = @_;
-
-  # Ignore SIGPIPE, since we're going to be talking to PGP.
-  local $SIG{PIPE} = 'IGNORE';
-
-  # Determine the PGP style.
-  my $pgpstyle = 'PGP2';
-  if    ($pgp =~ /pgps$/) { $pgpstyle = 'PGP5' }
-  elsif ($pgp =~ /gpg$/)  { $pgpstyle = 'GPG'  }
-
-  # Figure out what command line we'll be using.  PGP v6 and PGP v2 use
-  # compatible syntaxes for what we're trying to do.  PGP v5 would have,
-  # except that the -s option isn't valid when you call pgps.  *sigh*
-  my @command;
-  if ($pgpstyle eq 'PGP5') {
-    @command = ($pgp, qw/-baft -u/, $keyid);
-  } elsif ($pgpstyle eq 'GPG') {
-    @command = ($pgp, qw/--detach-sign --armor --textmode -u/, $keyid,
-                qw/--force-v3-sigs --pgp2/);
-  } else {
-    @command = ($pgp, qw/-sbaft -u/, $keyid);
-  }
-
-  # We need to send the password to PGP, but we don't want to use either
-  # the command line or an environment variable, since both may expose us
-  # to snoopers on the system.  So we create a pipe, stick the password in
-  # it, and then pass the file descriptor to PGP.  PGP wants to know about
-  # this in an environment variable; GPG uses a command-line flag.
-  # 5.005_03 started setting close-on-exec on file handles > $^F, so we
-  # need to clear that here (but ignore errors on platforms where fcntl or
-  # F_SETFD doesn't exist, if any).
-  #
-  # Make sure that the file handles are created outside of the if
-  # statement, since otherwise they leave scope at the end of the if
-  # statement and are automatically closed by Perl.
-  my $passfh = new FileHandle;
-  my $writefh = new FileHandle;
-  local $ENV{PGPPASSFD};
-  if ($passphrase) {
-    pipe ($passfh, $writefh);
-    eval { fcntl ($passfh, F_SETFD, 0) };
-    print $writefh $passphrase;
-    close $writefh;
-    if ($pgpstyle eq 'GPG') {
-      push (@command, '--batch', '--passphrase-fd', $passfh->fileno);
-    } else {
-      push (@command, '+batchmode');
-      $ENV{PGPPASSFD} = $passfh->fileno;
-    }
-  }
-
-  # Fork off a pgp process that we're going to be feeding data to, and tell
-  # it to just generate a signature using the given key id and pass phrase.
-  my $pgp = new FileHandle;
-  my $signature = new FileHandle;
-  my $errors = new FileHandle;
-  my $pid = eval { open3 ($pgp, $signature, $errors, @command) };
-  if ($@) {
-    @ERROR = ($@, "Execution of $command[0] failed.\n");
-    return undef;
-  }
-
-  # Write the message to the PGP process.  Strip all trailing whitespace
-  # for compatibility with older pgpverify and attached signature
-  # verification.
-  $message =~ s/[ \t]+\n/\n/g;
-  print $pgp $message;
-
-  # All done.  Close the pipe to PGP, clean up, and see if we succeeded.
-  # If not, save the error output and return undef.
-  close $pgp;
-  local $/ = "\n";
-  my @errors = <$errors>;
-  my @signature = <$signature>;
-  close $signature;
-  close $errors;
-  close $passfh if $passphrase;
-  waitpid ($pid, 0);
-  if ($? != 0) {
-    @ERROR = (@errors, "$command[0] returned exit status $?\n");
-    return undef;
-  }
-
-  # Now, clean up the returned signature and return it, along with the
-  # version number if desired.  PGP v2 calls this a PGP MESSAGE, whereas
-  # PGP v5 and v6 and GPG both (more correctly) call it a PGP SIGNATURE,
-  # so accept either.
-  while ((shift @signature) !~ /-----BEGIN PGP \S+-----\n/) {
-    unless (@signature) {
-      @ERROR = ("No signature from PGP (command not found?)\n");
-      return undef;
-    }
-  }
-  my $version;
-  while ($signature[0] ne "\n" && @signature) {
-    $version = $1 if ((shift @signature) =~ /^Version:\s+(.*?)\s*$/);
-  }
-  shift @signature;
-  pop @signature;
-  $signature = join ('', @signature);
-  chomp $signature;
-  undef @ERROR;
-  return wantarray ? ($signature, $version) : $signature;
-}
-
-sub
-signit
-
-{
-  my($head, $header, $signheaders, $pgpflags, $pgpbegin, $pgpend);
-
-  # Form the message to be signed.
-  $signheaders = join(",", @signheaders);
-  $head = "X-Signed-Headers: $signheaders\n";
-  foreach $header (@signheaders) {
-    $head .= "$header: $header{$header}\n";
-  }
-  my $message = "$head\n$body";
-
-  # Get the passphrase if available.
-  my $passphrase;
-  if ($pgppassfile && -f $pgppassfile) {
-    $pgppassfile =~ s%^(\s)%./$1%;
-    if (open (PGPPASS, "< $pgppassfile\0")) {
-      $passphrase = <PGPPASS>;
-      close PGPPASS;
-      chomp $passphrase;
-    }
-  }
-
-  # Sign the message, getting the signature and PGP version number.
-  my ($signature, $version) = pgp_sign ($pgpsigner, $passphrase, $message);
-  unless ($signature) {
-    die "@ERROR\n$0: could not generate signature\n";
-  }
-
-  # GnuPG has version numbers containing spaces, which breaks our header
-  # format.  Find just some portion that contains a digit.
-  ($version) = ($version =~ /(\S*\d\S*)/);
-
-  # Put the signature into the headers.
-  $signature =~ s/^/\t/mg;
-  $header{$pgpheader} = "$version $signheaders\n$signature";
-
-  for (@ignoreheaders) {
-    delete $header{$_} if defined $header{$_};
-  }
-
-  $head = '';
-  foreach $header (@orderheaders) {
-    $head .= "$header: $header{$header}\n" if $header{$header};
-    delete $header{$header};
-  }
-
-  foreach $header (keys %header) {
-    die "$0: unexpected header $header left in header array\n";
-  }
-
-  print STDOUT $head;
-  print STDOUT "\n";
-  print STDOUT $body;
-}
-
-# Our lawyer told me to include the following.  The upshot of it is that
-# you can use the software for free as much as you like.
-
-# Copyright (c) 1996 UUNET Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-#    must display the following acknowledgement:
-#      This product includes software developed by UUNET Technologies, Inc.
-# 4. The name of UUNET Technologies ("UUNET") may not be used to endorse or
-#    promote products derived from this software without specific prior
-#    written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY UUNET ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED.  IN NO EVENT SHALL UUNET BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-# OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Local variables:
-# cperl-indent-level: 2
-# fill-column: 74
-# End:
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644 (file)
index 838c48d..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-inn2 (2.4.5-5) unstable; urgency=medium
-
-  * Added patches u_*: bug fixes from SVN chosen by the upstream maintainer:
-    - misc innreport bugs
-    - incorrect TLS error handling
-    - correctly initialize the status file IP address variables
-    - do not send a duplicate reply when TLS negotiation fails
-    - correct the permissions checking for XHDR and XPAT
-    - do not send a duplicate reply to XOVER/XHDR/XPAT in a empty group
-  * Install again our own sasl.conf with the correct paths.
-  * Document in README.Debian that STARTTLS and MODE READER do not work
-    together. (Closes: #503495)
-  * Added patch typo_inn_conf_man fixes a typo in inn.conf(5).
-    (Closes: #507256)
-  * Updated the md5.c license in debian/copyright.
-
- -- Marco d'Itri <md@linux.it>  Mon, 15 Dec 2008 00:50:17 +0100
-
-inn2 (2.4.5-4) unstable; urgency=low
-
-  * Backported fixes from SVN: honour the Ad newsfeeds flag and create a
-    valid SV for the article body which will correctly match regexps.
-
- -- Marco d'Itri <md@linux.it>  Wed, 10 Sep 2008 01:36:04 +0200
-
-inn2 (2.4.5-3) unstable; urgency=medium
-
-  * Do not FTBFS with old versions of find. (Closes: #495508)
-
- -- Marco d'Itri <md@linux.it>  Thu, 28 Aug 2008 04:21:48 +0200
-
-inn2 (2.4.5-2) unstable; urgency=medium
-
-  * Rebuilt with libdb4.6-dev.
-
- -- Marco d'Itri <md@linux.it>  Sun, 27 Jul 2008 19:23:55 +0200
-
-inn2 (2.4.5-1) unstable; urgency=low
-
-  * New upstream STABLE release.
-
- -- Marco d'Itri <md@linux.it>  Tue, 01 Jul 2008 01:18:29 +0200
-
-inn2 (2.4.4r-1) unstable; urgency=low
-
-  * New upstream STABLE release. (For real, this time.)
-  * On 32 bit architectures, build a new inn2-lfs package with Larges
-    Files Support enabled. (Closes: #433751)
-  * Enabled support for Kerberos. (Closes: #478775)
-  * Rebuilt with perl 5.10. (Closes: #479244)
-  * Removed usage of debconf.
-
- -- Marco d'Itri <md@linux.it>  Sun, 11 May 2008 12:31:56 +0200
-
-inn2 (2.4.4-1) unstable; urgency=low
-
-  * New upstream STABLE snapshot.
-    + Rotates innfeed.log. (Closes: #407752)
-    + Make inews not fail if MODE READER fails because the connection has
-      not been authenticated yet. (Closes: #475059)
-  * Removed S from Default-Stop in the init script. (Closes: #471081)
-  * Updated debconf translation: pt. (Closes: #444720)
-  * Fixed a typo in the name of debian/inn2.logcheck.violations.ignore.
-  * Stop overwriting active.times(5) with a symlink, inn now has it.
-  * Fixed many minor issues pointed out by Julien Ã‰lie. (Closes: #455882)
-  * Removed patches merged upstream: daemonize-ovdb_init,
-    fix-crash-on-reload, hashfeeds.
-  * Remove /var/lib/news/ on purge. (Closes: #455104)
-
- -- Marco d'Itri <md@linux.it>  Mon, 14 Apr 2008 22:01:48 +0200
-
-inn2 (2.4.3+20070806-1) unstable; urgency=low
-
-  * New upstream STABLE snapshot.
-  * Package converted to quilt.
-  * Added patch fix-crash-on-reload to fix segfaults when reloading
-    incoming.conf (Closes: #361073, #429802, #430190, #430191)
-  * Added patch daemonize-ovdb_init to make ovdb_init properly close
-    stdin/out/err when it becomes a daemon. (Closes: #433522)
-  * Added patch inndstart-sockets-v6only to suppress a startup warning
-    about an already opened socket.
-  * Fixed the bzip2 path in bunbatch. (Closes: #419429)
-  * Removed patches merged upstream: ckpasswd_use_libdb, fix_radius.conf,
-    innfeed-fix-getaddrinfo, innfeed-force-ipv4, libdb-4.4.
-  * Use --as-needed to not link superfluous libraries.
-  * New debconf translations: pt, nl. (Closes: #414921, #415511)
-  * Added a logcheck file. (Closes: #405536)
-
- -- Marco d'Itri <md@linux.it>  Tue, 07 Aug 2007 16:35:06 +0200
-
-inn2 (2.4.3-1) unstable; urgency=low
-
-  * New upstream release. (Closes: #381415)
-    + Fixes nnrpd when "localmaxartsize: 0". (Closes: #357370)
-  * Removed support for his64v6 and cnfs64, which do not work anyway.
-    ****** I am looking for a co-maintainer interested in adding ******
-    ****** support to build a inn2-lfs package.                  ******
-  * Switched to libdb4.4.
-  * New debconf translations: vi, cs, sv. (Closes: #314245, #315211, #339811)
-  * Pre-Depends on debconf-2.0 too. (Closes: #331859)
-  * Added to innfeed support for a "force-ipv4" configuration option.
-    Based on a patch contributed by Henning Makholm. (Closes: #336264)
-  * Added to innfeed support for hashed feeds.
-  * pgpverify: try harder to find the home directory. (Closes: #307765)
-  * Moved nnrpd-ssl to the main package.
-  * Added support for libdb to ckpasswd. (Closes: #380644)
-  * Use FHS paths in the perl-nocem documentation. (Closes: #365639)
-  * Create /var/run/news in the init script if it does not exist.
-
- -- Marco d'Itri <md@linux.it>  Fri, 18 Aug 2006 11:19:21 +0200
-
-inn2 (2.4.2-3) unstable; urgency=high
-
-  * Fixed upgrades on systems with a non-default pathdb. (Closes: #306765)
-  * Added the showtoken program. (Closes: #306837)
-
- -- Marco d'Itri <md@linux.it>  Sat, 14 May 2005 15:03:56 +0200
-
-inn2 (2.4.2-2) unstable; urgency=medium
-
-  * New upstream snapshot (20050407).
-  * Stop providing the inn package. (Closes: #288659)
-  * Made postinst continue when makehistory or makedbz fail. (Closes: #292167)
-  * Switched to libdb4.3.
-
- -- Marco d'Itri <md@linux.it>  Fri,  8 Apr 2005 14:51:22 +0200
-
-inn2 (2.4.2-1) unstable; urgency=low
-
-  * New upstream release.
-    + Removed patch innreport_nnrpd-ssl.
-    + Fixed news2mail, CNFS buffers reporting. (Closes: #282664, #276819)
-
- -- Marco d'Itri <md@linux.it>  Fri, 24 Dec 2004 17:05:33 +0100
-
-inn2 (2.4.1+20040820-2) unstable; urgency=medium
-
-  * New upstream snapshot (upstream/patches/20040820-to-20040929.diff).
-    + make Norbert Tretkowski happy. (Closes: #255324)
-    + fix inn2-ssl segfaults on ia64. (Closes: #270875)
-  * Conflict with inn and cnews instead of news-transport-system.
-    (Closes: #269874)
-
- -- Marco d'Itri <md@linux.it>  Wed, 29 Sep 2004 17:24:18 +0200
-
-inn2 (2.4.1+20040820-1) unstable; urgency=medium
-
-  * New upstream snapshot.
-    + Fixes headers folding in the overview. (Closes: #190207)
-    + Fixes headers for articles mailed to moderators. (Closes: #249151)
-  * Added a default CA file name to sasl.conf. (Closes: #250201)
-  * New patch innreport_nnrpd-ssl: makes innreport correctly parse the
-    nnrpd-ssl log entries. (Closes: #250252)
-  * New debconf translations: de, ja. (Closes: #263030, #251100)
-
- -- Marco d'Itri <md@linux.it>  Fri, 20 Aug 2004 19:32:20 +0200
-
-inn2 (2.4.1+20040403-1) unstable; urgency=medium
-
-  * New upstream snapshot. (Closes: #141750)
-  * Switched to db4.2. (Closes: #241584)
-  * Added catalan debconf template. (Closes: #236668)
-  * Removed the patches fix_bindaddress, default-storage.diff and
-    fix_reiserfs26.diff because they have been merged upstream.
-  * Removed the patch libdb41-fix.diff because it's not needed anymore.
-
- -- Marco d'Itri <md@linux.it>  Sat,  3 Apr 2004 21:00:31 +0200
-
-inn2 (2.4.1-2) unstable; urgency=medium
-
-  * Fix bindaddress. (Closes: #183812)
-  * Fix paths in inn2-ssl. (Closes: #229181)
-
- -- Marco d'Itri <md@linux.it>  Sat, 24 Jan 2004 17:13:43 +0100
-
-inn2 (2.4.1-1) unstable; urgency=high
-
-  * New upstream release.
-    + Fixes buffer overflow, maybe remotely exploitable. (Closes: #226772)
-  * Add workaround for 2.6.x reiserfs brokeness. (Closes: #225940)
-  * Use pgpverify from -CURRENT to add useless DSA support. (Closes: #222634)
-  * Source package converted to DBS.
-
- -- Marco d'Itri <md@linux.it>  Thu,  8 Jan 2004 20:30:49 +0100
-
-inn2 (2.4.0+20031130-1) unstable; urgency=low
-
-  * New upstream STABLE snapshot. (Closes: #213946)
-  * Added russian and spanish debconf messages. (Closes: #219235, #220884)
-  * Replaces: inn2-dev to improve upgrades from woody. (Closes: #217219)
-  * Added a new his64v6 history method with LFS support. Untested!
-    (Closes: #215877)
-
- -- Marco d'Itri <md@linux.it>  Sun, 30 Nov 2003 22:54:02 +0100
-
-inn2 (2.4.0+20030912-1) unstable; urgency=low
-
-  * New upstream STABLE snapshot.
-  * Add again a default storage method to storage.conf. (Closes: #205001)
-  * Fix the getlist command line in actsyncd. (Closes: #206283)
-  * Added a new cnfs64 method for large cycbufs. The on disk format is not
-    compatible with 32-bit cycbufs. The storage tokens are not compatible
-    with the tokens of a standard inn package built with --enable-largefiles
-    (but they could be converted, let me know if you want to try this).
-    This is basically untested and may trash the data you feed it. Please
-    let me know if this works for you or not. (Closes: #206828)
-
- -- Marco d'Itri <md@linux.it>  Fri, 12 Sep 2003 14:07:06 +0200
-
-inn2 (2.4.0+20030808-1) unstable; urgency=medium
-
-  * New upstream snapshot.
-  * Fix readers.conf(5) and ckpasswd(8). (Closes: #202098, #202300)
-  * Fix innupgrade invocation in postinst. (Closes: #202978)
-  * Misc debconf-related fixes courtesy of Christian Perrier
-    <bubulle@debian.org>. (Closes: #200517, #200518)
-  * Added polish, spanish and french debconf messages.
-    (Closes: #202155, #201627)
-
- -- Marco d'Itri <md@linux.it>  Fri,  8 Aug 2003 13:56:23 +0200
-
-inn2 (2.4.0-3) unstable; urgency=medium
-
-  * Add db_stop to postinst.
-  * Fixed inn.conf path in postinst. (Closes: #198578)
-
- -- Marco d'Itri <md@linux.it>  Wed, 25 Jun 2003 15:15:54 +0200
-
-inn2 (2.4.0-2) unstable; urgency=medium
-
-  * Install all headers in /usr/include/inn. (Closes: #198463, #198464)
-  * Added debconf support, patch by <arturcz@hell.pl>.
-
- -- Marco d'Itri <md@linux.it>  Mon, 23 Jun 2003 19:19:37 +0200
-
-inn2 (2.4.0-1) unstable; urgency=medium
-
-  * New upstream release. (Closes: #182751, #188740, #193967, #194273, #198395)
-  * send-uucp.pl is now send-uucp.
-  * Switched from db4.0 to db4.1.
-  * postinst should not fail if innd cannot start. (Closes: #189966)
-  * Depend on perlapi-5.8.0. (Closes: #187717, #192411)
-  * Depend on inn2-inews >= 2.3.999+20030227-1. (Closes: #196137)
-  * Do not scare admins with wrong postinsg messages. (Closes: #183103)
-  * Corrected typo in innupgrade. (Closes: #194444)
-  * Added fr.* to /etc/news/moderators. (Closes: #190202)
-
- -- Marco d'Itri <md@linux.it>  Fri, 20 Jun 2003 18:39:21 +0200
-
-inn2 (2.3.999+20030227-1) unstable; urgency=low
-
-  * New upstream snapshot:
-    * Fix expireover segfaults. (Closes: #180462, #179898)
-    * Create /var/log/news/path. (Closes: #180168, #180602)
-  * Build-Depends on libssl-dev. (Closes: #180662)
-  * Fix missing feed name in the log. (Closes: #178842, #181740)
-  * Fix news2mail. (Closes: #181086)
-  * Fix minor bugs in the init script. (Closes: #180866, #180867)
-
- -- Marco d'Itri <md@linux.it>  Thu, 27 Feb 2003 19:11:57 +0100
-
-inn2 (2.3.999+20030205-2) unstable; urgency=low
-
-  * New upstream snapshot. (Closes: #179294)
-  * Add a new inn2-ssl package. (Closes: #163672)
-  * Move wildmat(3) from inn2-dev to inn2. (Closes: #179441)
-  * Downgraded to extra priority.
-    Most people do not need a local news server, and definitely not INN 2.x.
-  * Create /var/{lib,run}/news in postinst.
-
- -- Marco d'Itri <md@linux.it>  Thu,  6 Feb 2003 15:18:02 +0100
-
-inn2 (2.3.999+20030125-3) unstable; urgency=low
-
-  * Fix rnews breakage. (Closes: #178673)
-  * Remove hardcoded paths of egrep, awk, sed, sort, wget. (Closes: #176749)
-
- -- Marco d'Itri <md@linux.it>  Tue, 28 Jan 2003 01:48:03 +0100
-
-inn2 (2.3.999+20030125-2) unstable; urgency=low
-
-  * Fix broken ctlinnd. (Closes: #178588)
-
- -- Marco d'Itri <md@linux.it>  Mon, 27 Jan 2003 19:41:03 +0100
-
-inn2 (2.3.999+20030125-1) unstable; urgency=low
-
-  * BEWARE: this is a -CURRENT snapshot. If it breaks you keep both pieces!
-    (Closes: #172212, #174938, #176336).
-  * Make innreport generate valid HTML. (Closes: #166372)
-  * Pre-Depends on inn2-inews. (Closes: #166804)
-  * Update gnu.* data in control.ctl. (Closes: #167581)
-  * Do not ship rnews suid root! (Closes: #171757)
-  * Install /usr/share/doc/inn2/INSTALL.gz (Closes: #174493)
-
- -- Marco d'Itri <md@linux.it>  Thu, 16 Jan 2003 01:12:53 +0100
-
-inn2 (2.3.3+20020922-5) unstable; urgency=medium
-
-  * Fixed pathtmp (Closes: #162686).
-  * Check if the usenet user exists before adding a mail alias
-    (Closes: #162731).
-  * Fixed a path in sendinpaths (Closes: #163022).
-
- -- Marco d'Itri <md@linux.it>  Mon,  7 Oct 2002 20:24:16 +0200
-
-inn2 (2.3.3+20020922-4) unstable; urgency=low
-
-  * Applied OVDB fixes, courtesy of Ian Hastie @clara.net (Closes: #162643).
-
- -- Marco d'Itri <md@linux.it>  Sat, 28 Sep 2002 16:46:57 +0200
-
-inn2 (2.3.3+20020922-3) unstable; urgency=low
-
-  * Fixed absolute path in Makefile (Closes: #162538).
-
- -- Marco d'Itri <md@linux.it>  Fri, 27 Sep 2002 19:12:10 +0200
-
-inn2 (2.3.3+20020922-1) unstable; urgency=low
-
-  * New STABLE CVS snapshot (Closes: #128725, #137175, #157808, #159105).
-  * Made some changes to make INN compile with perl 5.8.0. May be broken.
-  * Fix inndf to convert the "infinite" inodes of reiserfs to 2^31 - 1
-    (Closes: #124101).
-  * Suggests: gnupg instead of pgp.
-  * Brand new init script which uses ctlinnd.
-  * Removed debian changes to use mkstemp. INN uses a private temp
-    directory anyway.
-  * Conflicts+Replaces: ninpaths, added the scripts from the inpaths package.
-  * Do not depend anymore on libdb3-util, which is only needed by OVDB.
-  * Removed signcontrol.
-  * Changed control.* and junk groups to status n.
-  * Added gpgverify script (Closes: #131412).
-  * Added bunbatch script (Closes: #136860).
-  * Added /usr/share/doc/inn2/INSTALL.gz (Closes: #156685).
-  * Added buildinnkeyring script which downloads PGP keys from ftp.isc.org
-    (Closes: #86989).
-
- -- Marco d'Itri <md@linux.it>  Sun, 22 Sep 2002 21:05:18 +0200
diff --git a/debian/changelog.old b/debian/changelog.old
deleted file mode 100644 (file)
index 9adc435..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-inn2 (2.3.999+20030114-1) unstable; urgency=low
-
-  * BEWARE: this is a -CURRENT snapshot. If it breaks you keep both pieces!
-    (Closes: #172212, #174938).
-  * Make innreport generate valid HTML. (Closes: #166372)
-  * Pre-Depends on inn2-inews. (Closes: #166804)
-  * Update gnu.* data in control.ctl. (Closes: #167581)
-  * Do not ship rnews suid root! (Closes: #171757)
-  * Install /usr/share/doc/inn2/INSTALL.gz (Closes: #174493)
-
- -- Marco d'Itri <md@linux.it>  Thu, 16 Jan 2003 01:12:53 +0100
-
-inn2 (2.3.3+20020922-5) unstable; urgency=medium
-
-  * Fixed pathtmp (Closes: #162686).
-  * Check if the usenet user exists before adding a mail alias
-    (Closes: #162731).
-  * Fixed a path in sendinpaths (Closes: #163022).
-
- -- Marco d'Itri <md@linux.it>  Mon,  7 Oct 2002 20:24:16 +0200
-
-inn2 (2.3.3+20020922-4) unstable; urgency=low
-
-  * Applied OVDB fixes, courtesy of Ian Hastie @clara.net (Closes: #162643).
-
- -- Marco d'Itri <md@linux.it>  Sat, 28 Sep 2002 16:46:57 +0200
-
-inn2 (2.3.3+20020922-3) unstable; urgency=low
-
-  * Fixed absolute path in Makefile (Closes: #162538).
-
- -- Marco d'Itri <md@linux.it>  Fri, 27 Sep 2002 19:12:10 +0200
-
-inn2 (2.3.3+20020922-1) unstable; urgency=low
-
-  * New STABLE CVS snapshot (Closes: #128725, #137175, #157808, #159105).
-  * Made some changes to make INN compile with perl 5.8.0. May be broken.
-  * Fix inndf to convert the "infinite" inodes of reiserfs to 2^31 - 1
-    (Closes: #124101).
-  * Suggests: gnupg instead of pgp.
-  * Brand new init script which uses ctlinnd.
-  * Removed debian changes to use mkstemp. INN uses a private temp
-    directory anyway.
-  * Conflicts+Replaces: ninpaths, added the scripts from the inpaths package.
-  * Do not depend anymore on libdb3-util, which is only needed by OVDB.
-  * Removed signcontrol.
-  * Changed control.* and junk groups to status n.
-  * Added gpgverify script (Closes: #131412).
-  * Added bunbatch script (Closes: #136860).
-  * Added /usr/share/doc/inn2/INSTALL.gz (Closes: #156685).
-  * Added buildinnkeyring script which downloads PGP keys from ftp.isc.org
-    (Closes: #86989).
-
- -- Marco d'Itri <md@linux.it>  Sun, 22 Sep 2002 21:05:18 +0200
-
-inn2 (2.3.3-1) unstable; urgency=low
-
-  * new upstream version
-  * use 'unset' not 'declare -x' GZIP to clear environment in innshellvars, 
-    closes: #136156, #136495, #136557, #142464
-  * add a warning to inn.conf comments about avoiding tabs after values, 
-    closes: #112657, #112665
-  * modify cron.d to test for presence of programs before running them, 
-    closes: #136563
-  * modify init.d to redirect rc.news output to /var/log/news/rc.news so that
-    inn2 daemonizes properly when run manually with the positive side effect
-    that the startup messages now comply with Debian policy,
-    closes: #140794, #116716, #134459
-  * deliver more upstream doc files, closes: #141963
-  * procps is priority required, but not marked essential, so we need to 
-    depend on it so innwatch can use 'uptime', closes: #146135
-  * add a clause to postinst to make sure /var/spool/news has appropriate
-    owner/group/perms
-
- -- Bdale Garbee <bdale@gag.com>  Fri, 24 May 2002 00:49:08 -0600
-
-inn2 (2.3.2-3) unstable; urgency=low
-
-  * apply patch from rene@seindal.dk to pullnews.in to keep a missing group 
-    from killing a run, closes: #133571
-  * apply patch from falcon@wysocki.lodz.pdi.net to dbprocs.in so that ovdb 
-    will work correctly with libdb3, and add a runtime dependency on 
-    libdb3-util to the inn2 package, closes: #128855
-  * add manpage symlinks, closes: #99543, #99578
-  * ensure backoff directory exists during postinst, closes: #127050
-  * clean up some of the lintian warnings
-
- -- Bdale Garbee <bdale@gag.com>  Sat, 16 Feb 2002 15:06:20 -0700
-
-inn2 (2.3.2-2) unstable; urgency=low
-
-  * edit provided buffindexed.conf to reflect our path structure
-  * apply patch to mailpost.in provided by Paul Seelig to prevent message
-    posting failures by stripping Received lines, closes: #120267
-  * add remaining /etc files to conffiles, closes: #110647
-  * make sure /var/log/news/OLD is news.news in postinst, closes: #116715
-  * slightly tighten permissions on /var/run/news, closes: #117773
-  * fix missing quotes around command in init.d,closes: #120105
-  * explicitly unexport GZIP in innshellvars before defining it to avoid
-    clashes with GZIP set in external environment, closes: #120381
-  * eliminate the task-news-server binary package
-
- -- Bdale Garbee <bdale@gag.com>  Wed, 26 Dec 2001 16:02:44 -0700
-
-inn2 (2.3.2-1) unstable; urgency=low
-
-  * new upstream version, closes: #98247, #101601
-  * remove authprogs/pwcheck.c and modify authprogs/Makefile in orig.tar.gz
-    since we don't use it and license is non-DFSG-compliant!  Closes: #103477
-  * make inn2-inews conflict with cnews, closes: #97662
-  * modify news.daily to use tempfile(1) for safe tempfile creation,
-    closes: #104517
-  * improve several instances of unsafe temp file handling using relevant
-    patches from the Debian security team, closes: #83734
-  * patch to fix expireover seg faults from Andrew Stribblehill, closes: #95096
-  * make 'server' in inn.conf be 'localhost' by default, closes: #90908
-  * add a note in the sample newsfeeds file indicating that nntplink is not
-    part of INN, closes: #88120
-  * depend on awk, closes: #87618  Note, I will *not* change the compress
-    definition in innshellvars, see README.Debian for details.
-  * only execute rnews in cron if it exists, so that removing but not purging
-    inn2 doesn't generate excessive email, closes: #89853
-  * postinst forces owner of default log files to be correct, closes: #98490
-  * enable support for ovdb, closes: #96612
-  * remove references to non-existent newslog(8) man page, clean up wildmat(5)
-    references, closes: #90993
-  * apply patches from Tollef Fog Heen for gnupg use in signcontrol and use
-    safer temp file handling, closes: #99021, #99242
-  * the inn2 package really can't do anything about the way conffiles are
-    handled by dpkg when moving from inn to inn2.  inn and inn2 are distinct
-    packages to Debian, despite their similar heritage, closes: #97443
-
- -- Bdale Garbee <bdale@gag.com>  Fri, 10 Aug 2001 13:48:38 -0600
-
-inn2 (2.3.1-4) unstable; urgency=low
-
-  * make /etc/news/filter/* conffiles, closes: #85315
-  * update build-depends, changing perl5 to libperl-dev
-
- -- Bdale Garbee <bdale@gag.com>  Tue, 20 Feb 2001 15:30:56 -0700
-
-inn2 (2.3.1-3) unstable; urgency=low
-
-  * conflict with current and prior versions of suck, since they use innxmit
-    in a way that no longer works, resulting in data loss as per bug 83727.
-    Reassign that bug to suck for implementation of a real solution.
-  * update the init.d script to use rc.news as upstream intends for start and 
-    stop operations, since it handles the current set of INN daemons better 
-    than our previous attempt to use start-stop-daemon does, closes: #84438
-  * tag /etc/news/send-uucp.cf as a conffile, closes: #83282
-
- -- Bdale Garbee <bdale@gag.com>  Mon,  5 Feb 2001 16:04:12 -0700
-
-inn2 (2.3.1-2) unstable; urgency=low
-
-  * update send-uucp.pl's idea of where innshellvars.pl is, closes: #83194
-  * go back to symlinks instead of moving inews and rnews, closes: #83224
-  * have preinst clean up /usr/lib/news/bin/filter dregs, closes: #83515
-  * have inn2-inews conflict/replace inn2 prior to 2.3.1 to account for moving
-    some files, closes: #83622
-
- -- Bdale Garbee <bdale@gag.com>  Tue, 30 Jan 2001 17:32:17 -0700
-
-inn2 (2.3.1-1) unstable; urgency=low
-
-  * new upstream release.  thank you Marco d'Itri <md@Linux.IT> for help with 
-    this update
-  * revert send-uucp to the upstream version, deliver Perl version as
-    send-uucp.pl, closes: #81074
-  * add manual page for send-uucp.pl written by Mark Brown, closes: #81073
-  * in 2.3.0-1, we accidentally shipped active, active.times, and newsgroups
-    as real files in /var/lib/news.  Hack the preinst and postinst to protect
-    the files in place, and fix the mess.  While we're at it, fix a few other
-    details in the postinst.  Closes: #81274
-  * update preinst warning and README.Debian to add an explicit pointer to the
-    NEWS file, which documents the 2.2 to 2.3 changes.  Fix a few out of date
-    items in README.Debian.  Closes: #81069
-  * fix path of required file in send-uucp.pl, closes: #81075
-  * move rnews and dependencies to the inn2-inews package, closes: #81268
-  * freshen PGPKEYS file from ftp.isc.org, fixes fr.* key and adds a new one,
-    closes: #81272
-  * pgpverify: use /etc/news/pgp as pgp/gnupg config dir and the syslog
-    socket instead of logger. (Md)
-  * innd/cc.c: added perl filter status patch (used by cleanfeed). (Md)
-  * debian/cron.d: added entry to reload incoming.conf and sample entries
-    for send-nntp and send-uucp.pl. (Md)  closes: #81269
-  * debian/init.d: first try to gracefully shut down innd with ctlinnd. (Md)
-  * Changed /usr/lib/news/bin/filter to /etc/news/filter. (Md) closes: #81273
-  * Moved back the whole /etc/news/scripts to the standard location in
-    /usr/lib/news, none of these files is a conffile. (Md)  This improves the
-    postinst questioning considerably, closes: #81072
-  * Fixed permissions of many binaries and config files. (Md) closes: #82002
-  * inews is not installed suid (suggested by upstream maintainer). (Md)
-  * Renamed send-uucp.pl.1 to send-uucp.pl.8. (Md)
-  * lose the "Recommends: trn | news-reader" on the inn2 package, it's not
-    particularly useful, and gets in the way for dedicated servers
-  * drop the "Suggests: inn2-dev" from inn2, the few who need it will find it,
-    and it confuses new users
-  * minor patch for actsyncd, closes: #80973
-  * inews now supports a -p option to set the port, closes: #22242, #68875
-  * touch the /var/lib/news/.news.daily file in the postinst to squelch the 
-    email about it being missing before nightly cron runs begin. closes: #76195
-  * suidregister is obsolete.  newer dpkg's include 'dpkg-statoverride', which
-    is a superior solution requiring nothing from the package.  closes: #81310
-  * configure storage.conf for tradspool configuration by default
-  * modify configure/configure.in slightly so build hostname isn't embedded
-    in inn.conf, et al
-  * don't force alt.test to exist, not all servers want it
-  * add code to the preinst to clean up the scripts tagged as conffiles that
-    will still be around from 2.3.0-1.  Sigh.
-
- -- Bdale Garbee <bdale@gag.com>  Mon, 22 Jan 2001 17:23:45 -0700
-
-inn2 (2.3.0-1) unstable; urgency=low
-
-  * new upstream version, closes: #69623
-  *   sendbatch appears to be fixed now, closes: #69561
-  *   innreport now appears to use png if gif isn't available, closes: #76169 
-  * thanks to John Goerzen for help cleaning up this release
-  * hack around need to have pgp installed at build time, closes: #69745
-  * add sanity checks for syslog files in the postinst, closes: #74707
-  * move all the scripts in /usr/lib/news that must be conffiles into /etc,
-    backfilling symlinks.  Closes: #57150
-  * built against perl-5.6, closes: #80703
-  * can't duplicate removal problem, closes: #77419
-  * update pgpverify's default notion of where to find pgp, closes: #78989
-  * ship the Perl send-uucp from Miquel van Smoorenburg, closes: #77836
-  * give inews more reasonable owner/group/perms, closes: #70856
-  * add another warning to the preinst since some file format changes defy
-    reasonable automation across the upgrade from pre-2.3.0 to 2.3.0, and some
-    manual actions will likely be required.
-  * as of 2.3.0, innshellvars now codes 'compress' as the path for the compress
-    program instead of an ugly token reporting that compress wasn't found if
-    there is no compress available at build time.  This will work if the 
-    non-free 'ncompress' package is installed.  Since some news sites still 
-    don't use gzip for uucp batches, this is probably the right default.  Note
-    added to the README.Debian file.
-    Closes: #77030
-
- -- Bdale Garbee <bdale@gag.com>  Thu, 28 Dec 2000 16:17:47 -0700
-
-inn2 (2.2.3-3) unstable; urgency=low
-
-  * leave the real inews executable in /usr/lib/news/bin, and symlink to it
-    from /usr/bin instead of moving it, to reduce breakage.  Closes: #68999
-  * do the same thing with rnews, for good measure
-
- -- Bdale Garbee <bdale@gag.com>  Mon, 14 Aug 2000 02:58:39 -0600
-
-inn2 (2.2.3-2) unstable; urgency=medium
-
-  * patch from upstream that fixes remote denial of service, closes: #66638
-  * provide /usr/sbin/ctlinnd as a symlink so ctlinnd is in root's path, 
-    closes: #67730
-  * update the README.Debian file to explain the situation with 'compress'
-    and indicate willingness to receive patch suggestions for making inn2
-    work better with uucp article transport, closes: #64284, #67629
-
- -- Bdale Garbee <bdale@gag.com>  Sun, 13 Aug 2000 22:39:21 -0600
-
-inn2 (2.2.3-1) unstable; urgency=low
-
-  * new upstream release, closes: #67635, #65492, #59345, #64405
-  * ensure control.cancel exists since we like usecontrolchan=true, 
-    closes: #57555
-  * add some verbage to the README.Debian about anacron, closes: #59664
-  * some of the code proposed by Raphael Bossek for the init.d is only
-    relevant for a 1.X to 2.X upgrade, and the rest could take quite a
-    while during boot.  I therefore don't think this belongs in init.d.
-    I'm adding the interesting checks to the postinst, closes: #62045
-  * provide PGPKEYS and some text about it in the README.Debian file,
-    closes: #66756
-
- -- Bdale Garbee <bdale@gag.com>  Tue, 25 Jul 2000 01:23:14 -0600
-
-inn2 (2.2.2.2000.01.31-4) frozen unstable; urgency=low
-
-  * add code to the postinst that calls 'hostname --fqdn' to make sure we can
-    determine the FQDN before we try to start the daemon.  Not doing this 
-    caused installs to fail on poorly-configured systems.  Closes: #64681
-  * target frozen since this was tagged important, and could indeed cause an
-    install or upgrade to fail in some (relatively rare?) cases.
-
- -- Bdale Garbee <bdale@gag.com>  Fri, 26 May 2000 21:32:01 -0600
-
-inn2 (2.2.2.2000.01.31-3) frozen unstable; urgency=low
-
-  * target frozen since these are release critical
-  * fix a variety of permission problems including /var/lib/news, 
-    closes: #61077
-  * permit world execute of /usr/bin/rnews, closes: #61409
-
- -- Bdale Garbee <bdale@gag.com>  Thu,  6 Apr 2000 23:17:56 -0600
-
-inn2 (2.2.2.2000.01.31-2) frozen unstable; urgency=low
-
-  * target frozen since one of these is release critical
-  * fix owner, group, and permissions of /var/run/news on fresh installs,
-    closes: #61030
-  * minor tweak to default inn.conf so build host isn't the value of pathhost
-    on new installs, closes: #60779
-  * fix owner, group, and permissions of /usr/bin/rnews so that it actually
-    works, closes: #58964
-
- -- Bdale Garbee <bdale@gag.com>  Fri, 24 Mar 2000 01:01:57 -0700
-
-inn2 (2.2.2.2000.01.31-1) frozen unstable; urgency=low
-
-  * target frozen since some of the bug fixes here qualify as release critical
-  * roll to current stable CVS snapshot to acquire bug fixes (some significant)
-    since 2.2.2 release, closes: #55581
-  * tag many scripts in /usr/lib/news/ as conffiles, so changes aren't lost on
-    upgrades.  This makes particularly good sense given the apparent upstream 
-    attitude that whacking scripts to configure a system is reasonable.  Add
-    lintian overrides since it calls conffiles under /usr errors.
-    Closes: #55723, #56385
-  * have inn2 "provide inn" so that other packages that depend on inn don't
-    get frustrated with us, closes: #56040
-  * add -L to innflags and turn controlchan on in default inn.conf (to match
-    what we're shipping in default newsfeeds file), closes: #56383, #56384
-  * don't remove /usr/lib/news explicitly in postrm, since other packages need
-    it, closes: #55467
-
- -- Bdale Garbee <bdale@gag.com>  Mon, 31 Jan 2000 23:48:44 -0700
-
-inn2 (2.2.2-4) frozen unstable; urgency=low
-
-  * change package names from inn to inn2 as part of Debian INN peace project,
-    which will reinstate 1.7.2 as 'inn'.  Target frozen so we ship both 1.7.2
-    and 2.2.2 with potato!
-  * add suitable conflicts with inn 1.X packages, leaving check for old 
-    versions in preinst along since it does no harm
-  * add task-news-server to help new installs target inn2 by default
-
- -- Bdale Garbee <bdale@gag.com>  Wed, 19 Jan 2000 11:07:16 -0700
-
-inn (2.2.2-3) frozen unstable; urgency=low
-
-  * target frozen since this fixes multiple release-critical bugs
-  * inewsinn needs to provide inews, closes: #55349
-  * fix rnews path in all innshellvars flavors, closes: #55307
-  * since rnews uses nnrpdpostport, inews should also, closes: #54975
-  * allow inews to work when talking to servers that require authentication
-    for the "mode reader" command, closes: #31145
-  * add some more information to README.Debian, and include an explicit 
-    pointer to it from the upgrade check in the preinst
-  * remove needless leftover example maintainer scripts in debian/Examples
-
- -- Bdale Garbee <bdale@gag.com>  Sun, 16 Jan 2000 14:43:12 -0700
-
-inn (2.2.2-2) unstable; urgency=low
-
-  * move more config files and related man pages from package inn to inewsinn
-    so that inews works correctly, closes: #55159
-  * flag /etc/cron.d/inn as a conffile
-  * reviewing / closing bugs in inn reported against prior versions that are
-    fixed or no longer relevant in 2.2.2 ...
-  * innwatch startup is cleaner than it used to be, closes: #21586, #32416
-  * logging id different than it used to be, closes: #24504
-  * expire.ctl doesn't have sequence problem any more, closes: #37737
-  * Old hosts.nntp and hosts.nntp.nolimit are merged, closes: #48739
-  * nntpsend.ctl no longer specifies the path, closes: #49673
-  * startup works fine now, closes: #51944
-  * control.ctl template is new, and correct, closes: #54526
-  * crosspost and overview directories are correct, closes: #55062
-  * history corruption problem should be long since fixed, closes: #11614
-  * client timeout is set to 10 minutes in /etc/news/inn.conf file by default,
-    which seems pretty reasonable, and is easy to change.  Closes: #12358
-  * the ancient problem with ctlinnd rmgroup appears fixed, closes: #12559
-  * the current GetFQDN code appears to be coded to work in more cases than 
-    it once was, closes: #29695
-  * we use a cron.d script now, so send-uucp, et al, can be scheduled on any
-    desired interval.  Closes: #43016
-
- -- Bdale Garbee <bdale@gag.com>  Sat, 15 Jan 2000 01:18:17 -0700
-
-inn (2.2.2-1) unstable; urgency=low
-
-  * New upstream release.  Enough has changed since the 1.7.2 release that
-    this is repackaged entirely from scratch.  
-    Closes: #25936, #26255, #43546, #52672, #43896, #54609, #54759
-  * patch lib/parsedate.y to include "y2k fix" relating to acceptance of
-    articles with year of 1900.  Closes: #53813
-  * postinst no longer prompts on upgrades, closes: #26659, #44918, #37888
-  * much newer innfeed, now integrated with inn sources, closes: #14326
-  * install docs revised, formatted version provided, closes: #43898
-  * large warning in preinst about upgrades from prior revisions of Debian
-    INN package requiring manual intervention.  The degree of assistance
-    will improve in future uploads, but may never be fully automatic.
-
- -- Bdale Garbee <bdale@gag.com>  Wed, 22 Dec 1999 02:22:33 -0700
-
-inn (1.7.2-12) unstable; urgency=low
-
-  * update to reflect current policy
-  * inndstart *is* provided setuid root, closes: #51944
-  * fix path in nntpsend.ctl.5, closes: #49673
-  * if we're upgrading, don't stop to ask user, just use existing config
-    information, closes: #44918
-  * deliver Install.txt instead of Install.ms into the doc directory, 
-    closes: #43898
-
- -- Bdale Garbee <bdale@gag.com>  Sun,  5 Dec 1999 20:46:07 -0700
-
-inn (1.7.2-11) unstable; urgency=high
-
-  * patch to inews.c to fix buffer overrun problem from Martin Schulze
-
- -- Bdale Garbee <bdale@gag.com>  Mon,  6 Sep 1999 13:35:19 -0600
-
-inn (1.7.2-10) unstable; urgency=low
-
-  * rebuild to depend on perl 5.005, closes 41469, 41925, 41943.
-  * update postinst text to eliminate version bogosity, closes 41585.
-  * fix sample sendbatch, closes 41596
-  * fix source-archive clause in sample newsfeeds file, closes 37862.
-  * document nntpport, closes 28588.
-  * fix type of inet_addr to reflect current libc.
-
- -- Bdale Garbee <bdale@gag.com>  Mon,  2 Aug 1999 01:22:23 -0600
-
-inn (1.7.2-9) unstable; urgency=low
-
-  * fold in Roman Hodek's changes from his 6.1 NMU, closing 38621.  This
-    fixes an ugly i386 dependency in the way inn calls Perl.
-  * update perl dependency managment to try and cope with new perl policy
-
- -- Bdale Garbee <bdale@gag.com>  Sat, 17 Jul 1999 17:13:05 -0600
-
-inn (1.7.2-6) unstable; urgency=low
-
-  * new maintainer
-  * clean up a few lintian complaints
-  * folding in changes from Christian Kurz that he called -5.  We'll call this
-    -6 even though his changes were not widely distributed, just to avoid any
-    confusion:
-
-      Removed X-Server-Date-Patch as it's not needed.
-      default moderation address add to /etc/news/moderators (closes: #24549)
-      Inn now depends on perl (closes: #27754, #32313)
-      Added gunbatch for gzipped batches (closes: #29899)
-      Changed debian/rules so inncheck runs without errors.
-      Added Perl-Support to Inn (closes: #26254)
-      Changed the examples
-
- -- Bdale Garbee <bdale@gag.com>  Wed, 26 May 1999 15:18:53 -0600
-
-inn (1.7.2-4) frozen unstable; urgency=medium
-
-  * Fixes:
-    #21583: inn: inn must replace inewsinn
-    #20763: inn sends me `not running' and `now running' each night
-    #21342: inn: install probs
-    #21582: inn: incorrect prerm fail-upgrade action
-    #21584: inn: postinst doesn't know abort-upgrade
-    #20048: inn: poison and REMEMBER_TRASH patch
-    #21644: inn: a way to not receive certain groups
-  * Wrt bug #20763: the ctlinnd timeout in innwatch has been increased
-    to 300 seconds (5 minutes). Hopefully that is enough.. There is no
-    good alternative, the fact that INN is slow while renumbering is
-    a basic design flaw. (Though the abp-scheduler patch might help)
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Fri, 22 May 1998 19:52:55 +0200
-
-inn (1.7.2-3) frozen unstable; urgency=medium
-
-  * Move moderators from inewsinn to inn. The server should keep the
-    moderators data, not inews.
-  * Fix lib/clientactive.c (still yucky, but should work..)
-  * Include latest pgpverify script, 1.9, and manpage
-  * Fix security hole (/tmp/pgp$$) in pgpverify script
-  * Fixes:
-    #18579: I can't uninstall INN package
-    #19776: inn.prerm buggy typos bah!
-    #18724: inn: /etc/init.d/inn contains sed that never terminates
-    #19206: inn: Crontab modifications not preserved
-    #20423: inn: error in removing
-    #20653: inn: Bug in send-uucp.pl, patch included
-    #20792: INN: Wrong sfnet maintainer
-    #20436: inn: on line 16 of the prerm script there is "fi" instead of "esac"
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Wed, 15 Apr 1998 17:34:23 +0200
-
-inn (1.7.2-2) unstable; urgency=low
-
-  * Change over to new crontab -l method
-  * Fix (pre|post)(inst|rm) scripts in several ways
-  * Fix inewsinn inn.conf installation
-  * Set NNRP_DBZINCORE_DELAY to -1
-  * Fix lintian warnings
-    Fixes:
-    #18120: inn: Inn's crontab file should be a conffile
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Thu, 19 Feb 1998 22:46:25 +0100
-
-inn (1.7.2-1) unstable; urgency=low
-
-  * New upstream version
-  * Fix crontab -l | tail +4
-  * Fixes bugs:
-    #15889: /etc/news/inn.conf missing
-    #16128: manpage uncompressed
-    #15103: egrep incorrectly searched in /bin by innshellvars*
-    #14404: /usr/doc/$(PACKAGE)/copyright should not be compressed
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Thu,  5 Feb 1998 12:52:14 +0100
-
-inn (1.7-1) unstable; urgency=low
-
-  * New upstream version
-  * Fixed bugs:
-    #9264: Unresolved dependency report for inn
-    #9315: inn: /etc/news/innshellvars* add /usr/ucb to the PATH
-    #9832: INN 1.5.1-1 throttled rmgroup really shreds active file ?
-    #10196: inn: inews complains about missnig subject header when there is one
-    #10505: Moderated postings fail 
-    #11042: error in /usr/doc/inn/inn-README
-    #11057: inn: Confusing/dangerous instructions
-    #11453: inn: max signature length
-    #11691: libc6
-    #11851: inn: Documentation for send-uucp.pl
-    #11852: inn: nntpsend looks for wrong config file
-    #11900: INN creates `local.*' by default
-    #11948: inn: nntpsend does not works
-    #12513: inewsinn should insert a linebreak
-    #13161: inn-makehistory - Bus error
-    #13425: inn: egrep moved to /bin
-    #13488: inewsinn: directs user to docs in a package it doesn't require
-    #13616: /etc/init.d/inn, /etc/news/hosts.nntp.nolimit are not conffiles
-    #13781: Can't feed by send-uucp.pl with ihave/sendme.
-    #13831: inn: scanlogs depends on hard coded path for egrep
-    #13899: inn: inn uses /usr/bin/egrep, grep doesn't provide that any longer
-  * Added BUFFSET fix
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Wed, 22 Oct 1997 14:08:37 +0200
-
-inn (1.5.1-5) unstable; urgency=high
-
-  * Fixed sendbatch script (comment in between backtics is illegal)
-  * libc6 version
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Wed, 10 Sep 1997 16:31:37 +0200
-
-inn (1.5.1-4) stable unstable; urgency=high
-
-  * Add new security patch (with fixed STRCPY): inn-1.5.1-bufferoverflow.patch4
-  * Applied null-pointer.patch from Michael Shields
-  * Upped SIG_MAXLINES in configdata.h to 8
-  * Fix inn-README (perl example). Fixes bug #11042
-  * Update inn-README and postinst to fix bug #11057
-  * Make ctlinnd addhist work in paused mode, and fail in throttled mode
-  * Change ID string
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Thu, 21 Aug 1997 12:37:48 +0200
-
-inn (1.5.1-3) stable unstable; urgency=high
-
-  * Add changelogs to docdir
-  * innshellvars*: change /usr/ucb -> /usr/sbin (Bug#9315)
-  * Changed Recommends: pgp to Suggests: (Bug#9264)
-  * Fix inews to fallback on local moderators file (Bug#10505)
-  * Fix buffer overruns all over the place
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Thu, 24 Jul 1997 18:29:33 +0200
-
-inn (1.5.1-2) frozen unstable; urgency=high
-
-  * Added security-patch.05 (mailx tilde exploit)
-  * inewsinn no longer conflicts: inn so installation should no
-    longer remove your original inn-1.4 package (and configuration).
-    Expect some dpkg trouble when upgrading from 1.4unoff4 to 1.5.1-2 though.
-  * Always create .incoming/.outgoing symlinks for backwards compat.
-  * Do not change ownerships/modes of existing directories
-  * Fix ownerships/modes of rnews, innd, inndstart, in.nnrpd
-  * Fix /etc/init.d/inn to comply with console messages standard
-  * Fix /usr/lib/news/bin/sendbatch
-  * Fix scanlogs not to nuke active file if log/news/OLD isn't there
-  * Console messages are a bit more standard now
-  * Use start-stop-daemon to kill innwatch in /etc/init.d/inn
-  * Fixed up inncheck - it almost doesn't complain anymore
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Mon, 28 Apr 1997 13:58:16 +0200
-
-inn (1.5.1-1) unstable; urgency=low
-
-  * Upgraded to 1.5.1
-  * Fixed Bug#6387: expire-with-symlinks problem
-  * Fixed Bug#6246: inewsinn reconfigures on update
-  * Moved /var/spool/news,/var/lib/news back into package
-  * Saves removed conffiles in preinst, restores in postinst
-  * Set LIKE_PULLERS to DO
-  * Remove manpage stubs that are now real manpages
-  * Fix options to sendmail in _PATH_SENDMAIL
-  * Removed subdirectories from debian/
-  * create /var/log/news/OLD in postinst
-  * Fixed most if not all other outstanding bugs
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Wed, 5 Feb 1997 10:58:16 +0100
-
-inn (1.5-1) unstable; urgency=low
-
-  * Upgraded to 1.5
-  * Undid most patches to 1.4unoff4 because they are in 1.5 proper.
-  * Added security patch
-  * Added X-Server-Date: patch
-  * inn now depends on inewsinn
-  * Fixed all other outstanding bugs (well, almost).
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Tue, 17 Dec 1996 16:56:37 +0100
-
-inn (1.4unoff4-2) unstable; urgency=low
-
-  * Added inn-dev package for libinn.a and manpages.
-  * Increased hash table size in expire.c to 2048 (was 128)
-  * Moved ctlinnd to /usr/sbin
-  * Moved to new source packaging scheme
-
- -- Miquel van Smoorenburg <miquels@cistron.nl>  Wed, 06 Oct 1996 15:38:30 +0200
-
-INN (1.4unoff4-1) - Miquel van Smoorenburg <miquels@cistron.nl>
-
- * Took out the Linux 1.2 patches I put in unoff3.
- * added the 64 bits patch (for Linux/Alpha)
- * There are some other minor patches for Linux/Alpha
- * Added "xmode" as alias for "mode"
- * Using MMAP and setsockopt() now - NEEDS 1.3 kernel !
-
-INN (1.4unoff3-1) - Miquel van Smoorenburg <miquels@cistron.nl>
-
- * Took inn1.4sec-8 and 1.4unoff3, folded in some Linux and
-   other patches.
- * Changed all makefiles to support a "prefix" variable for install
- * Removed the hacks in debian.rules for installation
- * Locks are in /var/run/innd
- * Rewrote post install script.
-
-inn (1.4sec-8); priority=MEDIUM
-
- * postinst configuration completely redone.  It now sets up a minimal
-   local installation for you.
- * prerm now exists and shuts the server down.
- * init scripts changed to System V scheme.
- * Descriptions in control files expanded.
- * Package now contains /var/lock/news, and uses /var/log (not /var/adm).
- * inewsinn postinst looks at and can write /etc/mailname.
-
-INN 1.4sec Debian 7 - iwj
-
-* libinn.a, <inn/*.h>, inn-sys2nf and inn-feedone installed
-  (in /usr/lib, /usr/include and /usr/bin).
-
-INN 1.4sec Debian 6 - iwj
-
-* innwatch now started by /etc/rc.misc/news.
-* inewsinn postinst minor typos fixed.
-* Leftover file `t' removed from source and diff distributions.
-
-INN 1.4sec Debian 5 - iwj
-
-* Added documentation about making active and history files.
-* Added monthly makehistory -ru crontab run.
-* Made postinst always do  crontab -u news /etc/news/crontab  .
-* Removed HAVE_UNIX_DOMAIN - AF_UNIX+SOCK_DGRAM still broken in Linux.
-* Fixed /usr/lib/news/bin/inncheck to conform to our permissions scheme.
-* Added manpage links for makeactive(8), makehistory(8), newsrequeue(8).
-* /var/adm/news now part of package.
-
-INN 1.4sec Debian 4 - iwj
-
-* Added $|=1 to inewsinn postinst script; a few cosmetic fixes.
-
-INN 1.4sec Debian 3 - iwj
-
-* Removed `inet' groups from distrib.pats.
-* Put more version number information in ../*.{deb,gz} filenames.
-* Added Package_Revision field to `control' file.
-* Rationalised debian.rules somewhat, and added `build' stamp file.
-* Permissions rationalised.
-* Changed /etc/rc.d/rc.news to /etc/rc.misc/news.
-* postinst calls Perl as /usr/bin/perl.
-* Added this Changelog.
-
-INN 1.4sec Debian 2 - iwj
-* inews moved to /usr/bin; rnews moved to /usr/sbin.
-* fixed nntpsend not to use PPID variable (it's a bash builtin).
-
-INN 1.4sec Debian 1 - iwj
-Initial release, completely untested.
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index b8626c4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-4
diff --git a/debian/inn2-dev.files b/debian/inn2-dev.files
deleted file mode 100644 (file)
index 229c7f7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/include/inn/
-usr/share/man/man3/
-usr/lib/news/libinn.a
-usr/lib/news/libstorage.a
-usr/lib/news/libinnhist.a
diff --git a/debian/inn2-dev.links b/debian/inn2-dev.links
deleted file mode 100644 (file)
index 00ac8c2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/share/man/man3/dbz.3 usr/share/man/man3/dbzclose.3
-usr/share/man/man3/dbz.3 usr/share/man/man3/dbzinit.3
-usr/share/man/man3/dbz.3 usr/share/man/man3/dbzfetch.3
-usr/share/man/man3/dbz.3 usr/share/man/man3/dbzstore.3
diff --git a/debian/inn2-inews.files b/debian/inn2-inews.files
deleted file mode 100644 (file)
index c9833a1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-etc/news/distrib.pats
-etc/news/inn.conf
-etc/news/moderators
-etc/news/passwd.nntp
-usr/lib/news/bin/inews
-usr/lib/news/bin/rnews
-usr/lib/news/bin/rnews.libexec
-usr/share/man/man1/inews.1
-usr/share/man/man1/rnews.1
-usr/share/man/man5/distrib.pats.5
-usr/share/man/man5/inn.conf.5 
-usr/share/man/man5/moderators.5
-usr/share/man/man5/passwd.nntp.5
diff --git a/debian/inn2-inews.links b/debian/inn2-inews.links
deleted file mode 100644 (file)
index feaeeb3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib/news/bin/inews usr/bin/inews
-usr/lib/news/bin/rnews usr/bin/rnews
diff --git a/debian/inn2.README.Debian b/debian/inn2.README.Debian
deleted file mode 100644 (file)
index 61adc45..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-Some random notes about the Debian INN 2.X package.  
-
-If you are upgrading from a previous version, please review the information
-near the top of the NEWS file to learn what has changed, and what you may
-need to do to update your system.  
-
-If you plan to use INN at home you should really consider running INN 1.x,
-which you can find in the inn package.
-
-INN 2.X is substantially different in terms of configuration file contents
-and filesystem layout than previous versions.  The Debian INN package installs
-a minimal but functional local-only server configuration.  Configuring feeds
-to/from other servers, and many other details, is up to you.
-
-You will want to review the information in /usr/share/doc/inn2 to get started
-on configuring the installation for your needs.  All of the configuration files
-in /etc/news are flagged as 'conffiles' in the packaging system, so your work
-should not be overwritten without your permission if/when you upgrade the inn 
-package in the future.  In particular, make sure to update /etc/news/inn.conf
-to put in your organization name and related information before you establish
-any network connections if you don't want to be embarrassed.
-
-Also, if you are moving over from INN 1.X, please note that the directory 
-structure under /var/spool/news has changed.  At a minimum, you will need to 
-move the article database subdirectories from /var/spool/news to 
-/var/spool/news/articles.  The set of directories that belong in 
-/var/spool/news for 2.2.2 and later are:
-
-       archive articles incoming innfeed outgoing overview
-
-Anything else is left over from a previous version, and probably should be 
-moved or removed.
-
-It has been pointed out that inn2's use of /etc/cron.d/inn2 instead of 
-separate files in /etc/cron.daily and so forth poses a problem for users of
-anacron on boxes that are not run continuously.  Since the primary target
-for an INN installation is a fully-connected system that might easily need
-a variety of cron entries with different intervals, I don't intend to change
-this default.  However, if you're bothered by this, feel free to change the
-cron configuration to suite your needs.
-
-If you want to use pgpverify (and you do if you're getting a real feed!),
-you can use the /usr/lib/news/bin/buildinnkeyring program to download the
-keys for some hierarchies from ftp.isc.org and add them to the gnupg
-keyring used by pgpverify.
-This package does not support the non-free PGP program anymore.
-
-The program 'compress' is not a part of Debian GNU/Linux due to patent issues
-with the algorithm.  By default, the innshellvars* files will try to call
-'compress' if you try to transport compressed batches over UUCP.  This will
-work if you install the non-free 'ncompress' package.  Since it's non-free, 
-this might be as unacceptable to you as it is to me!  If you know that all of
-your neighbors can handle gzip, a better solution might be to edit the 
-innshellvars* files to use '/bin/gzip -9' for the COMPRESS variable.  I do not
-intend to change this default to differ from the upstream source.
-
-Log files in /var/log/news need to be owned by user 'news' for the news 
-scanlogs tool to be able to rotate them properly.
-
-If you want to use the ckpasswd program you need to install the libgdbm3
-package.
-
-
-SSL
-~~~
-To enable SSL you need to start /usr/lib/news/bin/nnrpd-ssl with the -S
-flag from inetd or the command line.
-See nnrpd(8) and sasl.conf(5) for details.
-
-You need a certificate authority (CA) certificate in
-/etc/news/nnrpd-ca-cert.pem. You will also need a certificate/key pair,
-named /etc/news/nnrpd-cert.pem and /etc/news/nnrpd-key.pem respectively.
-
-If you do not already have a PKI in place, you can create them with a
-command like:
-
-openssl req -new -x509 -nodes -days 1825 \
-       -keyout /etc/news/nnrpd-key.pem -out /etc/news/nnrpd-cert.pem
-
-The private key must have the correct permissions:
-
-chown root:news /etc/news/nnrpd-key.pem
-chmod 640 /etc/news/nnrpd-key.pem
-
-
-STARTTLS
-~~~~~~~~
-STARTTLS support will not work when nnrpd is started by innd using
-"MODE READER" unless the nnrpd binary is replaced by nnrpd-ssl (e.g.
-by using dpkg-divert(8)).
-The upstream maintainer recommends running nnrpd as a standalone process.
-
-
-Large Files Support
-~~~~~~~~~~~~~~~~~~~
-On 32 bit architectures, the inn2-lfs package is built.
-There is no transition procedure, so if you want to convert an existing
-installation (this may or may not be possible depending on your choice
-of storage and overview formats) then you are on your own.
-When attempting such conversion do not forget that the package will
-delete /var/{spool,lib,log}/news/ when removed so they should be renamed.
-
diff --git a/debian/inn2.cron.d b/debian/inn2.cron.d
deleted file mode 100644 (file)
index 1691131..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-SHELL=/bin/sh
-PATH=/usr/lib/news/bin:/sbin:/bin:/usr/sbin:/usr/bin
-
-# Expire old news and overview entries nightly, generate reports.
-
-15 4   * * *   news    test -x /usr/lib/news/bin/news.daily && news.daily expireover lowmark delayrm
-
-# Refresh the cached IP addresses every day.
-
-2 3    * * *   news    [ -x /usr/sbin/ctlinnd ] && ctlinnd -t 300 -s reload incoming.conf "flush cache"
-
-# Every hour, run an rnews -U. This is not only for UUCP sites, but
-# also to process queud up articles put there by in.nnrpd in case
-# innd wasn't accepting any articles.
-
-10 *   * * *   news    [ -x /usr/bin/rnews ] && rnews -U
-
-# Enable this entry to send posted news back to your upstream provider.
-# Also edit /etc/news/nntpsend.ctl !
-# Not if you use innfeed, of course.
-
-#*/15 *        * * *   news    nntpsend
-
-
-# Enable this if you want to send news by uucp to your provider.
-# Also edit /etc/news/send-uucp.cf !
-
-#22 *  * * *   news    send-uucp.pl
-
-# NINPATHS ###################################################################
-# To enable ninpaths please add this line to /etc/news/newsfeeds:
-#   inpaths!:*:Tc,WP:/usr/lib/news/bin/ginpaths2
-#
-#6 6   * * *   news    ctlinnd -s -t 60 flush inpaths!
-#8 6   1 * *   news    sendinpaths
-# NINPATHS ###################################################################
-
diff --git a/debian/inn2.docs b/debian/inn2.docs
deleted file mode 100644 (file)
index 8307807..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-CONTRIBUTORS
-INSTALL
-NEWS
-README
-doc/checklist
-doc/external-auth
-doc/history
-doc/hook-perl
-doc/IPv6-info
-doc/compliance-nntp
diff --git a/debian/inn2.examples b/debian/inn2.examples
deleted file mode 100644 (file)
index 58759cf..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-extra/active
-extra/newsgroups
diff --git a/debian/inn2.init b/debian/inn2.init
deleted file mode 100644 (file)
index ae5b687..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh -e
-### BEGIN INIT INFO
-# Provides:          inn2
-# Required-Start:    $local_fs $remote_fs $syslog
-# Required-Stop:     $local_fs $remote_fs $syslog
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: INN news server
-# Description:       The InterNetNews news server.
-### END INIT INFO
-#
-# Start/stop the news server.
-#
-
-test -f /usr/lib/news/bin/rc.news || exit 0
-
-start () {
-    if [ ! -d /var/run/news ]; then
-       mkdir -p /var/run/news
-       chown news:news /var/run/news
-       chmod 775 /var/run/news
-    fi
-    su news -c /usr/lib/news/bin/rc.news > /var/log/news/rc.news 2>&1
-    # su news -c '/usr/lib/news/bin/nnrpd -D -c /etc/news/readers-ssl.conf -p 563 -S'
-}
-
-stop () {
-    su news -c '/usr/lib/news/bin/rc.news stop' >> /var/log/news/rc.news 2>&1
-    # start-stop-daemon --stop --name nnrpd --quiet --oknodo
-}
-
-case "$1" in
-    start)
-       echo -n "Starting news server: "
-       start
-       echo "done."
-       ;;
-    stop)
-       echo -n "Stopping news server: "
-       stop
-       echo "done."
-       ;;
-    reload|force-reload)
-       echo -n "Reloading most INN configuration files: "
-       ctlinnd -t 20 reload '' /etc/init.d/inn2
-       ;;
-    restart)
-       echo -n "Restarting innd: "
-       if [ -f /var/run/news/innd.pid ]; then
-           ctlinnd -t 20 throttle "init script" > /dev/null || true
-           ctlinnd -t 20 xexec inndstart > /dev/null || start
-       else
-           start
-       fi
-       echo "done."
-       ;;
-    *)
-       echo "Usage: /etc/init.d/inn start|stop|restart|reload">&2
-       exit 1
-       ;;
-esac
-
-exit 0
diff --git a/debian/inn2.links b/debian/inn2.links
deleted file mode 100644 (file)
index e55863e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/lib/news/bin/ctlinnd usr/sbin/ctlinnd
-usr/lib/news/bin/innstat usr/sbin/innstat
-usr/lib/news/bin/send-uucp usr/lib/news/bin/send-uucp.pl
-usr/share/man/man3/uwildmat.3 usr/share/man/man3/wildmat.3
-usr/share/man/man8/send-uucp.8 usr/share/man/man8/send-ihave.8
-usr/share/man/man8/send-uucp.8 usr/share/man/man8/send-nntp.8
diff --git a/debian/inn2.logcheck.ignore.server b/debian/inn2.logcheck.ignore.server
deleted file mode 100644 (file)
index 25d80ea..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-\w{3} [ :0-9]{11} [._[:alnum:]-]+ (rnews|innd|batcher): Reading config from /etc/news/inn\.conf$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ (expire|expireover|ctlinnd|nnrpd)\[[0-9]+\]: Reading config from /etc/news/inn\.conf$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: offered <[^[:space:]]+> [._[:alnum:]-]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: localhost connected [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]:$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]:[-[:alnum:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]:Expiring process [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]:Flushing log and syslog files$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [[:alpha:]]:/var/log/news/expire\.lowmark$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+ flush$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+ opened [^[:space:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+ closed$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+:[0-9]+ readclose$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+:[0-9]+ inactive [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+:[0-9]+ NCmode \"mode stream\" received$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [._[:alnum:]-]+ connected [0-9]+ streaming allowed$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: ME HISstats [0-9]+ hitpos [0-9]+ hitneg [0-9]+ missed [0-9]+ dne$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: ME time [0-9]+ hishave [0-9]+\([0-9]+\) hiswrite [0-9]+\([0-9]+\) hissync [0-9]+\([0-9]+\) idle [0-9]+\([0-9]+\) artclean [0-9]+\([0-9]+\) artwrite [0-9]+\([0-9]+\) artcncl [0-9]+\([0-9]+\) hishave/artcncl [0-9]+\([0-9]+\) his(grep|write)/artcncl [0-9]+\([0-9]+\) artlog/artcncl [0-9]+\([0-9]+\) his(write|grep)/artcncl [0-9]+\([0-9]+\) sitesend [0-9]+\([0-9]+\) overv [0-9]+\([0-9]+\) perl [0-9]+\([0-9]+\) nntpread [0-9]+\([0-9]+\) artparse [0-9]+\([0-9]+\)( artlog/artparse [0-9]+\([0-9]+\))? artlog [0-9]+\([0-9]+\) datamove [0-9]+\([0-9]+\)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: SERVER (servermode|flushlogs) (running|paused)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: SERVER paused Flushing log and syslog files$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: SERVER running$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: SERVER paused Expiring process [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ batcher\[[0-9]+\]: batcher [[:alnum:]]+ times user [.0-9]+ system [.0-9]+ elapsed [.0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ batcher\[[0-9]+\]: batcher [[:alnum:]]+ stats batches [0-9]+ articles [0-9]+ bytes [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: Reading access from /etc/news/readers\.conf$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: SERVER perl filtering enabled$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ \([.0-9]+\) connect$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ timeout$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ group [.[:alnum:]+-]+ [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: Auth strategy '[[:alnum:]]+' does not match client\.  Removing\.$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ (no_)?match_user [<>_[:alnum:]-]+(@[._[:alnum:]-]+)? [<>,_,\*,\![:alnum:][:punct:]-]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ res <[_[:alnum:]-]+>(@[._[:alnum:]-]+)?$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ time [0-9]+ (hisgrep [0-9]+\([0-9]+\) )?idle [0-9]+\([0-9]+\) (readart [0-9]+\([0-9]+\) )?nntpwrite [0-9]+\([0-9]+\)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ times user [.0-9]+ system [.0-9]+ idle [.0-9]+ elapsed [.0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ exit articles [0-9]+ groups [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ artstats get [0-9]+ time [0-9]+ size [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ post ok <[[:graph:]]+@[._[:alnum:]-]+>$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ \(unknown\) posttrack ok [[:graph:]]+<[[:graph:]]+@[._[:alnum:]-]+>$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ user [[:alnum:][:punct:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ Tracking Disabled \(unknown\)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ auth authenticator successful, user [[:alnum:][:punct:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ auth starting authenticator [[:alnum:][:space:][:punct:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [._[:alnum:]-]+ no_access_realm$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ cnfsstat\[[0-9]+\]: Class [[:alnum:]]+ for groups matching \"[^[:space:]]+\" Buffer [[:alnum:]]+, len: [0-9]+  Mbytes, used: [0-9]+\.[0-9]+ Mbytes \([0-9 ]+\.[0-9]%\) [ 0-9]+ cycles$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ send-uucp\[[0-9]+\]: checking site [^[:space:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ send-uucp\[[0-9]+\]: no articles for [^[:space:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ send-uucp\[[0-9]+\]: Flushing [^[:space:]]+ for site [^[:space:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ send-uucp\[[0-9]+\]: batched articles for [^[:space:]]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: ME time [0-9]+ idle [0-9]+\([0-9]+\) blstats [0-9]+\([0-9]+\) stsfile [0-9]+\([0-9]+\) newart [0-9]+\([0-9]+\) readart [0-9]+\([0-9]+\) prepart [0-9]+\([0-9]+\) read [0-9]+\([0-9]+\) write [0-9]+\([0-9]+\) cb [0-9]+\([0-9]+\)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+ spooling no active connections$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+:[0-9]+ connected$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+ remote MODE STREAM$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+ (final|checkpoint) seconds [0-9]+ spooled [0-9]+ on_close [0-9]+ sleeping [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+ hostChkCxns - maxConnections was [0-9]+ now [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: ME articles (active|total) [0-9]+ bytes [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+:[0-9]+ cxnsleep connect: Connection refused$
diff --git a/debian/inn2.logcheck.violations.ignore b/debian/inn2.logcheck.violations.ignore
deleted file mode 100644 (file)
index 4dc7ef7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: [-[:alnum:].]+:[0-9]+ (closed|checkpoint) seconds [0-9]+ accepted [0-9]+ refused [0-9]+ rejected [0-9]+ duplicate [0-9]+ accepted size [0-9]+ duplicate size [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innd: rejecting\[perl\] <[[:alnum:][:punct:]]+@[.[:alnum:]-]+> [0-9]+ [[:alnum:] ]+( \([._[:alnum:]-]+\))?$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: rejected [0-9]+ Unwanted (newsgroup|distribution) "[._,[:alnum:]-]+"$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: rejected [0-9]+ Too old -- "\w{3}, [0-9 ]+ \w{3} [0-9]{4} [0-9:]{8} (\+|-)[0-9]{4}"$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: rejected [0-9]+ Too old -- "[0-9]+ \w{3} [0-9]{4} [0-9:]{8} ([[:upper:]]+|(\+|-)[0-9]{4})"$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: rejected [0-9]+ No colon-space in "("|x-no-archive:yes)" header$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ rnews: offered <[^[:space:]]+> [._[:alnum:]-]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: [^[:space:]]+ posts received [0-9]+ rejected [0-9]+$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nnrpd\[[0-9]+\]: \? reverse lookup for [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} failed: Unknown host -- using IP address for access$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ innfeed\[[0-9]+\]: [._[:alnum:]-]+(:[0-9]+)? (final|global|checkpoint) seconds [0-9]+ offered [0-9]+ accepted [0-9]+ refused [0-9]+ rejected [0-9]+ (missing [0-9]+ )?accsize [0-9]+ rejsize [0-9]+( spooled [0-9]+ (on_close [0-9]+ )?unspooled [0-9]+)?( deferred [0-9]+/[0-9.]+ requeued [0-9]+ queue [0-9.]+/[0-9\:\,]+)?$
diff --git a/debian/inn2.postinst b/debian/inn2.postinst
deleted file mode 100644 (file)
index 40214d0..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-#!/bin/sh -e
-
-init_inn_files() {
-    PATHDB=$(/usr/lib/news/bin/innconfval pathdb)
-    if [ -z "$PATHDB" ]; then
-       echo "Cannot determine the database path, aborting."
-       exit 1
-    fi
-    cd $PATHDB
-
-    local package='inn2'
-    if [ -e /usr/share/doc/inn2-lfs/ ]; then
-      package='inn2-lfs'
-    fi
-      
-    for file in active newsgroups; do
-       if [ ! -f $file ]; then
-           echo "Installing initial content for $PATHDB/$file"
-           install -m 644 -o news -g news \
-               /usr/share/doc/$package/examples/$file .
-       fi
-    done
-
-    if [ ! -f history.dir ]; then
-      echo -n "Building history database in $PATHDB... "
-      if ! /usr/lib/news/bin/makehistory; then
-        echo "failed!"
-        return
-      fi
-      if ! /usr/lib/news/bin/makedbz -i -o -s 300000; then
-        echo "failed!"
-        return
-      fi
-      chown news:news history*
-      chmod 664 history*
-      echo "done."
-    fi
-
-    if [ ! -f active.times ]; then
-       touch active.times
-       chown news:news active.times
-       chmod 644 active.times
-    fi
-
-    # squelch initial noise in email if this isn't present
-    if [ ! -f .news.daily ]; then
-       touch .news.daily
-       chown news:news .news.daily
-    fi
-
-    # make sure typical log files exist, and can be rotated
-    if [ ! -d /var/log/news ]; then
-       install -d -m 775 -o news -g news /var/log/news
-    fi
-    cd /var/log/news
-    [ -f news.notice ] || touch news.crit news.err news.notice
-    chown news:news . OLD path news.crit news.err news.notice
-
-    if [ -x /etc/init.d/inn2 ]; then
-       update-rc.d inn2 defaults > /dev/null
-    fi
-}
-
-check_usenet_alias() {
-    # must have an alias for user usenet, point it to root by default
-    if [ -f /etc/aliases ] && ! grep -q '^usenet:' /etc/aliases \
-           && ! getent passwd usenet; then
-       echo "Adding alias for pseudo-user usenet to /etc/aliases."
-       echo "usenet: root" >> /etc/aliases
-       [ -x /usr/bin/newaliases ] && /usr/bin/newaliases
-    fi
-}
-
-upgrade_inn_conf() {
-    cd /etc/news
-    if [ "$2" ] && dpkg --compare-versions "$2" lt "2.3.999+20030125-1"; then
-       /usr/lib/news/bin/innupgrade -f inn.conf
-    fi
-}
-
-rebuild_history_index() {
-    [ -f /var/lib/news/must-rebuild-history-index ] || return 0
-
-    cd /var/lib/news
-    HLINES=$(tail -1 history.dir | awk '{ print $1 }')
-    [ "$HLINES" ] || HLINES=1000000
-    echo "Rebuilding the history index for $HLINES lines, please wait..."
-    rm history.hash history.index history.dir
-    su news -c "/usr/lib/news/bin/makedbz -s $HLINES -f history"
-
-    rm /var/lib/news/must-rebuild-history-index
-}
-
-rebuild_overview() {
-    [ -f /var/lib/news/must-rebuild-overview ] || return 0
-
-    OVENABLED=$(/usr/lib/news/bin/innconfval enableoverview)
-    if [ -z "$OVENABLED" ]; then
-       echo "Cannot determine the overview method used, stopping."
-       exit 1
-    fi
-    if [ $OVENABLED = no -o $OVENABLED = false ]; then
-       return 0
-    fi
-
-    OVMETHOD=$(/usr/lib/news/bin/innconfval ovmethod)
-    if [ -z "$OVMETHOD" ]; then
-       echo "Cannot determine the overview method used, stopping."
-       exit 1
-    elif [ $OVMETHOD = tradindexed -o $OVMETHOD = ovdb ]; then
-       OVPATH=$(/usr/lib/news/bin/innconfval pathoverview)
-       if [ -z "$OVPATH" ]; then
-           echo "Cannot determine the overview path, aborting."
-           exit 1
-       fi
-       echo "Deleting the old overview database, please wait..."
-       find $OVPATH -type f -not -name DB_CONFIG -print0 | xargs -0 -r rm -f
-    elif [ $OVMETHOD = buffindexed ]; then
-       echo "Deleting the old overview database, please wait..."
-       awk -F : '/^[0-9]/ { print $2 }' < /etc/news/buffindexed.conf | \
-           while read name size; do
-               dd if=/dev/zero of="$name" bs=1024 count="$size"
-           done
-    else
-       echo "Unknown overview method '$OVMETHOD', aborting."
-       exit 1
-    fi
-
-    echo "Rebuilding the overview database, please wait..."
-    su news -c "/usr/lib/news/bin/makehistory -F -O -x"
-
-    rm /var/lib/news/must-rebuild-overview
-}
-
-start_innd() {
-# make sure we can determine the FQDN, since innd won't launch if we can't
-if hostname --fqdn > /dev/null 2>&1; then
-    invoke-rc.d inn2 start || echo "Could not start INN!"
-else
-cat <<END
-
-
-Not starting innd.  The daemon needs to be able to determine the name of
-this machine, and your /etc/hosts and/or DNS config is apparently not
-allowing this to happen.  After you have fixed things so that 'hostname
---fqdn' returns a reasonable value, you can start the daemon by running
-'/etc/init.d/inn2 start'.
-
-
-END
-fi
-}
-
-case "$1" in
-    configure)
-    init_inn_files
-    check_usenet_alias
-    upgrade_inn_conf "$@"
-    rebuild_history_index
-    rebuild_overview
-    if [ -z "$2" -o ! -e /var/run/news/innd.pid ]; then # first install
-       start_innd
-    else
-       ctlinnd -t 20 throttle "upgrade" > /dev/null || true
-       ctlinnd -t 20 xexec inndstart > /dev/null \
-           || echo "Could not restart INN!"
-    fi
-    ;;
-
-    abort-upgrade|abort-remove|abort-deconfigure)
-    ;;
-
-    *)
-    echo "postinst called with unknown argument '$1'" >&2
-    ;;
-esac
-
-#DEBHELPER#
-
-exit 0
-
diff --git a/debian/inn2.postrm b/debian/inn2.postrm
deleted file mode 100644 (file)
index 53101ec..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh -e
-
-if [ "$1" = "purge" ]; then
-  update-rc.d inn2 remove >/dev/null
-  if [ -e /var/lib/news/ ]; then
-    rm -f /var/lib/news/.news.daily /var/lib/news/active* \
-      /var/lib/news/newsgroups /var/lib/news/history*
-    rmdir --ignore-fail-on-non-empty /var/lib/news/
-  fi
-fi
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/inn2.preinst b/debian/inn2.preinst
deleted file mode 100644 (file)
index 70a1001..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh -e
-
-if [ "$2" ] && dpkg --compare-versions $2 gt 2.0.0 \
-       && dpkg --compare-versions $2 lt 2.3.0; then
-  echo "Some configuration files have changed in INN 2.4 and will need to"
-  echo "be adjusted, most notably nnrp.access has mutated into readers.conf."
-  echo "Also, note that you may need to rebuild the history database."
-  echo "For more information, read the /usr/share/doc/inn2/NEWS.gz file."
-fi
-
-if [ "$2" ] && dpkg --compare-versions $2 eq 2.3.0-1; then
-  echo 'Upgrade from 2.3.0-1 to >= 2.3.999+20030125-4 is not supported.'
-  echo 'Aborting inn upgrade.'
-  exit 1
-fi
-
-if [ "$2" ] && dpkg --compare-versions $2 lt 2.3.1-2; then
-  # remove any remaining symlinks under /usr/lib/news/bin/filter, then remove
-  # the directory if it's empty
-  if [ -d /usr/lib/news/bin/filter ]; then
-    find /usr/lib/news/bin/filter -type l -exec rm {} \;
-    rmdir /usr/lib/news/bin/filter 2> /dev/null || true
-  fi
-fi
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/inn2.prerm b/debian/inn2.prerm
deleted file mode 100644 (file)
index b111c76..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh -e
-
-kill_innd() {
-    if [ -x /etc/init.d/inn2 ]; then
-       invoke-rc.d inn2 stop
-    fi
-}
-
-case "$1" in
-    remove|deconfigure|failed-upgrade)
-       kill_innd
-    ;;
-
-    upgrade)
-    ;;
-
-    *)
-    echo "$0 called with unknown argument '$1'" >&2
-    exit 1
-    ;;
-esac
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/patches/debian-paths b/debian/patches/debian-paths
deleted file mode 100644 (file)
index 38327a5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- 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/debian/patches/fix_ad_flag b/debian/patches/fix_ad_flag
deleted file mode 100644 (file)
index a2e4862..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-honour the Ad flag in newsfeeds
-
-http://inn.eyrie.org/viewcvs/branches/2.4/innd/art.c?r1=7748&r2=7936&pathrev=7936&view=patch
-
---- 2.4/innd/art.c     2008/04/06 13:49:56     7748
-+++ 2.4/innd/art.c     2008/07/20 10:20:41     7936
-@@ -1725,7 +1725,7 @@
-       !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/debian/patches/fix_body_regexps b/debian/patches/fix_body_regexps
deleted file mode 100644 (file)
index 9a0aedd..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-Fix the correct handling of bodies (Perl regexps were sometimes
-not properly working on SV * bodies).  We now use a shared string.
-For Perl < 5.7.1, fall back to a copy of such bodies.  At least,
-that method is reliable, even though it were 17% slower.
-
-http://inn.eyrie.org/viewcvs/branches/2.4/include/ppport.h?r1=7237&r2=7951&pathrev=7951&view=patch
-http://inn.eyrie.org/viewcvs/branches/2.4/innd/perl.c?r1=7815&r2=7951&pathrev=7951&view=patch
-
---- 2.4/innd/perl.c    2008/05/05 08:43:58     7815
-+++ 2.4/innd/perl.c    2008/08/05 19:41:17     7951
-@@ -69,7 +69,6 @@
-     CV *        filter;
-     int         i, rc;
-     char *      p;
--    static SV * body = NULL;
-     static char buf[256];
-     if (!PerlFilterActive) return NULL;
-@@ -87,23 +86,19 @@
-     }
-     /* 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);
---- 2.4/include/ppport.h       2005/06/05 21:57:50     7237
-+++ 2.4/include/ppport.h       2008/08/05 19:41:17     7951
-@@ -150,6 +150,7 @@
- #     endif
- #endif
- #ifndef PERL_VERSION
-+#       define PERL_REVISION (5)
- #       ifdef PERL_PATCHLEVEL
- #               define PERL_VERSION    PERL_PATCHLEVEL
- #       else
-@@ -162,7 +163,7 @@
- #     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 @@
- #     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/debian/patches/no-makedbz-on-install b/debian/patches/no-makedbz-on-install
deleted file mode 100644 (file)
index 63b3f65..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/site/Makefile
-+++ b/site/Makefile
-@@ -116,7 +116,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)
diff --git a/debian/patches/nocem-gpg-import b/debian/patches/nocem-gpg-import
deleted file mode 100644 (file)
index 0c15727..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/control/perl-nocem.in
-+++ b/control/perl-nocem.in
-@@ -521,7 +521,9 @@ Processing NoCeM notices is easy to set 
- Import the keys of the NoCeM issuers you trust in order to check
- the authenticity of their notices.  You can do:
--    gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg --import <key-file>
-+    gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg \
-+        --no-options --allow-non-selfsigned-uid --no-permission-warning \
-+        --batch --import <key-file>
- where <pathetc> is the value of the I<pathetc> parameter set in F<inn.conf>
- and <key-file> the file containing the key(s) to import.  The keyring
---- a/doc/man/perl-nocem.8
-+++ b/doc/man/perl-nocem.8
-@@ -157,8 +157,10 @@ Processing NoCeM notices is easy to set 
- Import the keys of the NoCeM issuers you trust in order to check
- the authenticity of their notices.  You can do:
- .Sp
--.Vb 1
--\&    gpg \-\-no\-default\-keyring \-\-primary\-keyring <pathetc>/pgp/ncmring.gpg \-\-import <key\-file>
-+.Vb 3
-+\&    gpg \-\-no\-default\-keyring \-\-primary\-keyring=/etc/news/pgp/ncmring.gpg \e
-+\&        \-\-no\-options \-\-allow\-non\-selfsigned\-uid \-\-no\-permission\-warning \e
-+\&        \-\-batch \-\-import <key\-file>
- .Ve
- .Sp
- where <pathetc> is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644 (file)
index 9263031..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# backported fixes
-fix_ad_flag
-fix_body_regexps
-
-# waiting to be merged upstream
-
-# debian-specific
-nocem-gpg-import
-debian-paths
-
-# packaging-related
-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/debian/patches/typo_inn_conf_man b/debian/patches/typo_inn_conf_man
deleted file mode 100644 (file)
index 39c2a91..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/doc/man/inn.conf.5
-+++ b/doc/man/inn.conf.5
-@@ -480,7 +480,7 @@ this parameter must be set if \fIenableo
- .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/debian/patches/u_innreport_misc b/debian/patches/u_innreport_misc
deleted file mode 100644 (file)
index 0b4e7d2..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-Bug-fixes for innreport:
- - Test for the existence of 'img_dir' instead of 'html_dir' in innreport;
- - Trailing comma after %innfeed_spooled with "Outgoing feeds (innfeed)
-   by Articles";
- - Column "Total" of "Outgoing feeds (innfeed) by Volume" tries to add
-   two hashes which evaluates to a constant 0;
- - Gracefully handle undefined hash elements in "NNRP readership statistics
-   (by domain)";
- - Also added two error messages generated by perl-nocem.
-
-http://inn.eyrie.org/viewcvs/branches/2.4/scripts/innreport.in?r1=8142&r2=8141&pathrev=8142&view=patch
-http://inn.eyrie.org/viewcvs/branches/2.4/samples/innreport.conf.in?r1=7945&r2=7944&pathrev=7945&view=patch
-http://inn.eyrie.org/viewcvs/branches/2.4/scripts/innreport_inn.pm?r1=7945&r2=7944&pathrev=7945&view=patch
-
---- 2.4/scripts/innreport.in   2008/10/05 23:47:25     8141
-+++ 2.4/scripts/innreport.in   2008/10/07 17:08:32     8142
-@@ -212,7 +212,7 @@
- $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'} ||
---- 2.4/samples/innreport.conf.in      2008/08/03 07:30:03     7944
-+++ 2.4/samples/innreport.conf.in      2008/08/03 07:47:10     7945
-@@ -1267,7 +1267,7 @@
-               data {
-                         name    "Spooled";
-                         color   "#AF00FF";
--                        value   "%innfeed_spooled,";
-+                        value   "%innfeed_spooled";
-                 };
-       };
- };
-@@ -1347,12 +1347,6 @@
-                       color   "#FFAF00";
-                       value   "%innfeed_rejected_size";
-               };
--              data {
--                      name    "Total";
--                      color   "#00FF00";
--                      value   "%innfeed_accepted_size +
--                                 %innfeed_rejected_size";
--              };
-       };
- };
-@@ -2116,8 +2110,8 @@
-                 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 @@
-                 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)";
-         };
---- 2.4/scripts/innreport_inn.pm       2008/08/03 07:30:03     7944
-+++ 2.4/scripts/innreport_inn.pm       2008/08/03 07:47:10     7945
-@@ -440,8 +440,8 @@
-     # 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 @@
-     # 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 @@
-     # 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 @@
-       $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/debian/patches/u_right_length b/debian/patches/u_right_length
deleted file mode 100644 (file)
index b8cc72e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Bug-fix for TLS: return 1 when length is right.
-
-http://inn.eyrie.org/viewcvs/branches/2.4/nnrpd/tls.c?r1=8058&r2=8057&pathrev=8058&view=patch
-
---- 2.4/nnrpd/tls.c    2008/09/26 23:11:47     8057
-+++ 2.4/nnrpd/tls.c    2008/09/26 23:12:49     8058
-@@ -257,7 +257,7 @@
-            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/debian/patches/u_status_init_ip b/debian/patches/u_status_init_ip
deleted file mode 100644 (file)
index e91b1e3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Fix a bug in the IP address displayed for localhost in innd's status file.
-It was not correctly initialized (it is a local connection which does not
-use any IP address).
-
-http://inn.eyrie.org/viewcvs/branches/2.4/innd/status.c?r1=7947&r2=7946&pathrev=7947&view=patch
-
---- 2.4/innd/status.c  2008/08/03 07:50:03     7946
-+++ 2.4/innd/status.c  2008/08/03 07:55:20     7947
-@@ -153,9 +153,14 @@
-       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/debian/patches/u_tls_duplicate_reply b/debian/patches/u_tls_duplicate_reply
deleted file mode 100644 (file)
index 1b6c01e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Do not send 580 when negotiation fails (382 has already been sent).
-
-http://inn.eyrie.org/viewcvs/branches/2.4/nnrpd/misc.c?r1=8057&r2=8056&pathrev=8057&view=patch
-
---- 2.4/nnrpd/misc.c   2008/09/26 23:02:08     8056
-+++ 2.4/nnrpd/misc.c   2008/09/26 23:11:47     8057
-@@ -544,7 +544,7 @@
-   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/debian/patches/u_xhdr_permissions b/debian/patches/u_xhdr_permissions
deleted file mode 100644 (file)
index 8e876af..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-XHDR and XPAT were not checking the permissions the user has to read
-articles when using a message-ID. Now fixed, as well as calls to ARTclose().
-
-http://inn.eyrie.org/viewcvs/branches/2.4/nnrpd/article.c?r1=8004&r2=8003&pathrev=8004&view=patch
-
---- 2.4/nnrpd/article.c        2008/09/05 19:13:28     8003
-+++ 2.4/nnrpd/article.c        2008/09/06 08:49:55     8004
-@@ -688,6 +688,7 @@
-     if (ac > 1)
-       ARTnumber = tart;
-     if ((msgid = GetHeader("Message-ID")) == NULL) {
-+        ARTclose();
-         Reply("%s\r\n", ARTnoartingroup);
-       return;
-     }
-@@ -745,9 +746,9 @@
-         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);
- }
-@@ -1008,6 +1009,12 @@
-               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
-@@ -1047,8 +1054,8 @@
-                   SendIOb(buff, strlen(buff));
-                   SendIOb(p, strlen(p));
-                   SendIOb("\r\n", 2);
--                  ARTclose();
-               }
-+                ARTclose();
-           }
-           SendIOb(".\r\n", 3);
-           PushIOb();
diff --git a/debian/patches/u_xover_duplicate_reply b/debian/patches/u_xover_duplicate_reply
deleted file mode 100644 (file)
index 88a53b5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-Fix a bug in the replies of XOVER/XHDR/XPAT when the group is empty.
-Two initial replies were sent.
-
-http://inn.eyrie.org/viewcvs/branches/2.4/nnrpd/article.c?r1=8000&r2=7999&pathrev=8000&view=patch
-
---- 2.4/nnrpd/article.c        2008/09/03 05:41:27     7999
-+++ 2.4/nnrpd/article.c        2008/09/04 17:06:51     8000
-@@ -854,9 +854,7 @@
-     /* 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;
-       }
-     }
-@@ -1028,10 +1026,7 @@
-       /* 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;
-           }
-       }
diff --git a/debian/rules b/debian/rules
deleted file mode 100755 (executable)
index 91d2e12..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/make -f
-SHELL+= -e
-
-QUILT_STAMPFN := .stamp-patched
-include /usr/share/quilt/quilt.make
-
-D-std := $(CURDIR)/debian/inn2
-D-lfs := $(CURDIR)/debian/inn2-lfs
-D = $(D-$*)
-B = $(CURDIR)/build-$*
-
-##############################################################################
-# this code deals with building a second inn2-lfs package from the same
-# source, but only on 32 bit architectures
-# Ideally new future 32 bit architectures should not bother with inn2-lfs
-# and just enable LFS by default.
-
-DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
-ifeq ($(DEB_HOST_ARCH),$(filter $(DEB_HOST_ARCH),amd64 ia64 ppc64 s390x))
-# 64 bit std package
-FLAVORS := std
-else ifeq ($(DEB_HOST_ARCH),$(filter $(DEB_HOST_ARCH),armel))
-# 32 bit LFS std package
-FLAVORS := std
-std_configure_flags = --enable-largefiles
-else
-# 32 bit std package and 32 bit LFS lfs package
-FLAVORS := std lfs
-lfs_configure_flags = --enable-largefiles
-endif
-
-std_dh_clean_opts = -pinn2 -pinn2-inews -p inn2-dev
-lfs_dh_clean_opts = -pinn2-lfs
-std_dh_movefiles_opts = -pinn2 -pinn2-inews -p inn2-dev
-lfs_dh_movefiles_opts = -pinn2-lfs -pinn2-lfs-inews -p inn2-lfs-dev
-
-ifeq ($(FLAVORS),std)
-no_package := --no-package=inn2-lfs
-endif
-
-# the upstream source needs to be copied in the flavor-specific build dirs
-src_files := $(shell find . -maxdepth 1 \
-       -not -name . -and -not -name debian -and -not -name .pc \
-       -and -not -name 'build-*' -and -not -name '.stamp-*')
-
-##############################################################################
-DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
-  configure_flags += --build $(DEB_HOST_GNU_TYPE)
-else
-  configure_flags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
-endif
-
-clean: unpatch
-       rm -rf .stamp-* build-*
-       [ ! -f Makefile.global ] || $(MAKE) distclean
-       # delete packages which are not in control but are built anyway
-       rm -rf debian/inn2-lfs-dev/ debian/inn2-lfs-inews/
-       # delete the cloned debhelper configuration and logs
-       find debian -maxdepth 1 -name 'inn2-lfs*' -not -type d -print0 \
-               | xargs --no-run-if-empty -0 rm
-       dh_clean
-
-configure: $(addprefix .stamp-configure-, $(FLAVORS))
-.stamp-configure-%: $(QUILT_STAMPFN)
-       dh_testdir
-       mkdir -p $B
-       for dir in $(src_files); do cp -ldpR $$dir $B; done
-       cd $B && \
-       _PATH_PERL=/usr/bin/perl \
-       ac_cv_path__PATH_AWK=awk \
-       ac_cv_path__PATH_EGREP=egrep \
-       ac_cv_path__PATH_SED=sed \
-       ac_cv_path__PATH_SORT=sort \
-       ac_cv_path__PATH_UUX=uux \
-       ac_cv_path_PATH_GPGV=/usr/bin/gpgv \
-       ac_cv_path_GETFTP=wget \
-       ac_cv_search_dbm_open=-ldb \
-       LDFLAGS="-Wl,--as-needed $(LDFLAGS)" \
-       ./configure \
-               --with-perl \
-               --enable-ipv6 \
-               --prefix=/usr/lib/news \
-               --mandir=/usr/share/man \
-               --includedir=/usr/include/inn \
-               --with-db-dir=/var/lib/news \
-               --with-etc-dir=/etc/news \
-               --with-filter-dir=/etc/news/filter \
-               --with-lib-dir=/usr/lib/news \
-               --with-log-dir=/var/log/news \
-               --with-run-dir=/var/run/news \
-               --with-spool-dir=/var/spool/news \
-               --with-tmp-dir=/var/spool/news/incoming/tmp \
-               --with-berkeleydb=/usr \
-               --with-kerberos=/usr \
-               --with-sendmail=/usr/sbin/sendmail \
-               $($*_configure_flags) $(configure_flags)
-       cd $B && \
-       mkdir ssl/ ssl/nnrpd/ && \
-       cd ssl/ && \
-       ln -s ../Makefile.global ../include ../storage ../history . && \
-       cd nnrpd/ && ln -s ../../nnrpd/* .
-       touch $@
-
-build: $(addprefix .stamp-build-, $(FLAVORS))
-.stamp-build-%: .stamp-configure-%
-       dh_testdir
-       cd $B && $(MAKE)
-       cd $B/ssl/nnrpd/ && $(MAKE) \
-               SSLLIB='-L/usr/lib -lssl -lcrypto -ldl' SSLINC='-DHAVE_SSL=1'
-       touch $@
-
-install1-%: .stamp-build-%
-       dh_testdir
-       dh_testroot
-       dh_clean -k $($*_dh_clean_opts)
-
-       cd $B && $(MAKE) install DESTDIR=$D
-       sh -e extra/dh_cloneconf inn2 inn2-lfs
-
-       dh_movefiles $($*_dh_movefiles_opts) --sourcedir=$(subst $(CURDIR)/,,$D)
-
-#      move back this one
-       mv $D-dev/usr/share/man/man3/uwildmat.3 $D/usr/share/man/man3/
-
-#      remove assorted crap and
-#      make sure we don't ship active, active.times, newsgroups in place!
-       cd $D/etc/news/filter && rm -f *.py *.tcl
-       rm -rf $D/usr/lib/news/bin/simpleftp $D/usr/share/man/man1/simpleftp.1\
-               $D/usr/lib/news/doc/ $D/var/lib/news/* \
-               $D/usr/include/
-
-       mv $D/usr/share/man/man1/startinnfeed.1 \
-          $D/usr/share/man/man8/startinnfeed.8
-
-       cp $B/ssl/nnrpd/nnrpd $D/usr/lib/news/bin/nnrpd-ssl
-       install -m 755 extra/buildinnkeyring extra/ginpaths2 \
-               $D/usr/lib/news/bin/
-       install -m 755 contrib/showtoken.in $D/usr/lib/news/bin/showtoken
-       install -m 755 extra/bunbatch $D-inews/usr/lib/news/bin/rnews.libexec/
-
-       install -m 644 extra/send-uucp.cf extra/sasl.conf $D/etc/news/
-
-       mkdir $D/var/log/news/path
-
-install2: $(addprefix install1-, $(FLAVORS))
-       dh_link
-       dh_installchangelogs NEWS
-       dh_installdocs
-       dh_installexamples
-       dh_installinit --noscripts --init-script=inn2
-       dh_installcron
-       dh_installlogcheck
-       dh_compress
-       dh_fixperms \
-           -Xusr/lib/news/bin/inndstart -Xusr/lib/news/bin/startinnfeed
-       # some files are not writeable when installed by make install
-       dh_strip
-
-install3-%: install2
-       chown root:news $D-inews/etc/news/passwd.nntp
-       chmod 640 $D-inews/etc/news/passwd.nntp
-
-       chmod -x $D/usr/lib/news/bin/control/*.pl
-       chmod +rw \
-               $D/usr/lib/news/bin/inndstart \
-               $D/usr/lib/news/bin/startinnfeed
-
-       chown news:uucp $D-inews/usr/lib/news/bin/rnews
-       chmod 4755 $D-inews/usr/lib/news/bin/rnews
-
-       chown -R news:news $D/var/spool/news/ $D/var/lib/news/ \
-               $D/var/run/news/ $D/var/log/news/
-       chmod -R g+w $D/var/spool/news/ $D/var/lib/news/ \
-               $D/var/run/news/ $D/var/log/news/
-
-install4-std: install3-std
-
-# lfs-specific: rename some files installed by debhelper
-install4-lfs: install3-lfs
-       for file in /etc/logcheck/ignore.d.server/inn2 /etc/logcheck/violations.ignore.d/inn2 /etc/cron.d/inn2; do \
-               mv $(D-lfs)$$file-lfs $(D-lfs)$$file; \
-       done
-
-install5: $(addprefix install4-, $(FLAVORS))
-       dh_installdeb
-       dh_md5sums
-       dh_shlibdeps
-       dh_gencontrol $(no_package) -- \
-           -VPERLAPI=$$(perl -MConfig -e 'print "perlapi-$$Config{version}"')
-       dh_builddeb $(no_package)
-
-binary-arch: install5
-
-binary: binary-arch
-
-.PHONY: clean configure build binary-arch binary install%
diff --git a/debian/watch b/debian/watch
deleted file mode 100644 (file)
index 39ffdf8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-version=3
-opts=dversionmangle=s/r$// \
-ftp://ftp.isc.org/isc/inn/inn-([\d\.]+)\.tar\.gz
diff --git a/doc/GPL b/doc/GPL
deleted file mode 100644 (file)
index 264509e..0000000
--- a/doc/GPL
+++ /dev/null
@@ -1,347 +0,0 @@
-[ Please note that the only portions of INN covered by this license are
-  those files explicitly noted as being under the GPL in LICENSE.  It is
-  a requirement of the GPL, however, that a copy of it be distributed
-  with software licensed under it, and some stand-alone programs that
-  are distributed with INN are covered under the GPL. ]
-
-
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                           NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/doc/IPv6-info b/doc/IPv6-info
deleted file mode 100644 (file)
index 4d5c02a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-Notes about IPv6 support in INN:
-
-   This is $Revision: 5416 $, dated $Date: 2002-04-14 07:05:36 -0700 (Sun, 14 Apr 2002) $.
-
-   This document contains some notes about the status of IPv6 support in
-   INN (see also the parts of the code marked FIXME):
-
-
-Things that will break if you compile with --enable-ipv6:
-
-    * innd can only be started via inndstart
-    * IP_OPTIONS are not cleared for any incoming connections to innd even
-      over IPv4
-  
-
-
-Some comments as of the completion of the original patch:
-
-    Date: Wed, 13 Feb 2002 00:10:59 -0500 (EST)
-    From: Nathan Lutchansky <lutchann@litech.org>
-    To: Jeffrey M. Vinocur <jeff@litech.org>
-    Subject: IPv6 patch notes
-
-    The IPv6 patch is based directly on Marco d'Itri's IPv6 patch of
-    2001-03-01 that was posted last year to the inn-workers list.  The
-    patch applied fairly cleanly to a working copy from 2002-02-04, and
-    the resulting tree was used as the basis for my work.
-
-    Modifications by Marco and myself were made so that if IPv6 support is
-    not explicitly enabled with the --enable-ipv6 flag to the configure
-    script, the old networking code will be used.  Hopefully, nobody will
-    notice any problems with the default configuration, although some
-    changes have been made to data structures even when IPv6 is disabled.
-
-    The original patch added IPv6 support to innd and inndstart, and the
-    auth_pass program.  I have added support to nnrpd, innfeed, and the
-    ident auth program.  There is no IPv6 support for imapfeed and other
-    auxiliary programs like the radius auth backend.
-
-    Marco's patch made use of several preprocessor defines for
-    configuration but the defines were hand-coded, so I added the
-    corresponding tests the the configuration script.  I make no
-    guarantees that the configure script will catch all possible
-    non-portable behavior; the IPv6 API standardization process has left
-    quite a wake of incompatible API implementations over the years.
-    -Nathan
-
diff --git a/doc/checklist b/doc/checklist
deleted file mode 100644 (file)
index 144c0ee..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-Introduction
-
-    $Id: checklist 5912 2002-12-03 05:31:11Z vinocur $
-
-    This is an installation checklist written by Rebecca Ore, intended to be
-    the beginning of a different presentation of the information in INSTALL,
-    since getting started with installing INN can be complex.  Further
-    clarifications, updates, and expansion are welcome.
-
-Setup
-
-    *   Make sure there is a "news" user (and a "news" group)
-
-    *   Create a home directory for news (perhaps /usr/local/news/) and make
-        sure it (and subdirectories) are owned by "news", group "news".
-
-        You want to be careful that things in that directory stay owned by
-        "news" -- but you can't just "chown -R news.news" after the install,
-        because you may have binaries that are SUID root.  You can do the
-        build as any user, because "make install" will set the permissions
-        correctly.  After that point, though, you may want to "su news" to
-        avoid creating any files as root.  (For routine maintenance once INN
-        is working, you can generally be root.)
-
-    *   If necessary, add ~news/bin to the news user's path and ~news/man to
-        the news user's manpath in your shell config files.  (You may want
-        to do this, especially the second part, on your regular account; the
-        manpages are very useful.)
-
-        You can do this now or later, but you will certainly want the
-        manpages to help with configuring INN.
-
-        For bash, try:
-
-            PATH=~news/bin:$PATH
-            export PATH
-            MANPATH=~news/man:$MANPATH
-            export MANPATH
-
-        or csh:
-
-            setenv PATH ~news/bin:$PATH
-            setenv MANPATH ~news/man:$MANPATH
-
-        although if you don't already have MANPATH set, the above may give
-        an error or override your defaults (making it so you can only read
-        the news manpages); if "echo $MANPATH" does not give some reasonable
-        path, you'll need to look up what the default is for your system
-        (such as /usr/man or /usr/share/man).
-
-Compile
-
-    *   Download the INN tarball and unpack.
-
-    *   Work out configure options ("./configure --help" for a list).  If
-        you aren't working out of /usr/local/news, or want to put some files
-        on a different partition, you can set the directories now (or later
-        in inn.conf if you change your mind).
-
-        You probably want "--with-perl".  If you're not using NetBSD with
-        cycbuffs or OpenBSD, perhaps "--with-tagged-hash".  You might want
-        to compile in SSL and Berkeley DB, if your system supports them.
-
-            ./configure --with-perl ...
-            make
-
-            su
-            make install
-
-        (If you do the last step as root, all of the ownerships and
-        permissions will be correct.)
-
-Configure
-
-    *   Find INSTALL and open a separate window for it.  A printout is
-        probably a good idea -- it's long but very helpful.  Any time the
-        instructions below ask you to make a decision, you can probably find
-        help in INSTALL.
-
-    *   Now it's time to work on the files in ~news/etc/.  Start with
-        inn.conf; you must fill in the default moderators address, your
-        fully qualified domain names and path.  Fill in all the blanks. 
-        Change the file descriptor limits to something like 500.
-
-    *   If using cycbuffs (the CNFS storage method), open cycbuff.conf in
-        one window and a shell in another to create the cycbuff as described
-        in INSTALL.  As you create them, record in cycbuff.conf the paths
-        and sizes.  Save paths and sizes in a separate text file on another
-        machine in case you ever blow away the wrong file.
-
-        Name the metacycbuff, then configure storage.conf.
-
-    *   In storage.conf, be sure that all sizes of articles can be
-        accomodated.  If you want to throw away large articles, do it
-        explicitly by using the "trash" storage method.
-
-    *   The default options in expire.ctl work fine if you have cycbuffs, if
-        not, configure to suit.
-
-    *   Check over moderators and control.ctl.
-
-    *   Run ~news/bin/inncheck and fix anything noted.
-
-        Inncheck gives a rough check on the appropriateness of the
-        configuration files as you go.  (It's the equivalent of "perl -cw
-        yourfile.pl" for perl scripts.)
-
-        Note that inncheck is very conservative about permissions; there's
-        no reason most of the config files can't be world-readable if you
-        prefer that.
-
-    *   Import an active file (~news/db/active) and run inncheck again. 
-        Change where noted (there's a gotcha in the ISC's active list 000000
-        000000 (whatever number of zeros) should be 0000000 00000001).
-
-    *   Create empty initial db files.  Be sure these end up owned by news.
-
-            cd ~news/db
-
-            touch newsgroups
-            touch active.times
-
-            touch history
-            ~news/bin/makedbz -i
-            mv history.n.hash  history.hash
-            mv history.n.index history.index
-            mv history.n.dir   history.dir
-
-            chmod 644 *
-
-    *   Create the cron jobs and make the changes to your system's
-        syslog.conf as noted in INSTALL.  Also create the cron job for
-        nntpsend if you've chosen that over innfeed.
-
-        Create the log files.
-
-    *   For the time being, we can see if everything initially works without
-        worrying about feeds or reader access.
-
-Run
-
-    *   Start inn by running ~news/bin/rc.news *as the news user*.
-
-        Check ~news/log/news.notice to see if everything went well, also use
-        "ps" to see if innd is running.
-
-        "telnet localhost 119" and you should see either a welcome banner or
-        a "no permission to talk" message.  If not, investigate.
-
-    *   "man ctlinnd" now; you'll use "ctlinnd reload" as you complete your
-        configuration.
-
-Feeds
-
-    All of this can be done while INN is running.
-
-    *   To get your incoming feeds working, edit incoming.conf.  When done,
-        "ctlinnd reload incoming.conf reason" (where "reason" is some text
-        that will show up in the logs, anything will do).
-
-    *   To get your outgoing feeds working, decide whether to use innfeed or
-        nntpsend.  Edit newsfeeds and either innfeed.conf or nntpsend.ctl.
-
-        In newsfeeds, if using innfeed, use the option which doens't require
-        you to do a separate innfeed configuration unless you know more than
-        I do.
-
-        Then "ctlinnd reload newsfeeds reason".
-
-    *   In readers.conf, remember that auth and access can be separated.
-
-        Begin with auth.  Your auth for password users could look like this:
-
-            auth "foreignokay" {
-                auth: "ckpasswd -d ~news/db/newsusers"
-                default: "<unauthenticated>"
-            }
-
-        There is a perl script in the ckpasswd man page if you want to do
-        authentications by password and have the appropriate libraries. 
-        Copy it to ~news/bin, name the file something like makepasswd.pl and
-        change the internal paths to whatever you're using and wherever
-        you're putting the newsusers database.  The standard Apache
-        "htpasswd" tool also works just fine to create INN password files.
-
-        Follow with the access stanzas.  Something for people with
-        passwords:
-
-            access "generalpeople" {
-                users: "*"
-                newsgroups: "*,!junk,!control,!control.*"
-            }
-
-        And then something like one of the following two, depending on
-        whether unauthenticated users get any access:
-
-            access "restrictive" {
-                users: "<unauthenticated>"
-                newsgroups: "!*"
-            }
-
-            access "readonly" {
-                users: "<unauthenticated>"
-                read: "local.*"
-                post: "!*"
-            }
-    
-        You don't need to reload anything after modifying readers.conf;
-        every time an nnrpd launches it reads its configuration from disk.
-
diff --git a/doc/compliance-nntp b/doc/compliance-nntp
deleted file mode 100644 (file)
index 403e104..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-$Id: compliance-nntp 6817 2004-05-18 09:25:55Z rra $
-
-The following are outstanding issues regarding INN's compliance with the
-NNTP standard.  The reference documents used in this analysis are the
-current NNTP IETF Working Group draft (draft-ietf-nntpext-base-15.txt at
-the time of the last check of this audit) or RFC 2980, not RFC 977 (which
-is woefully out of date).
-
-This file documents only compliance issues with the latest version of the
-standard NNTP protocol.  It does not cover INN's private extensions or
-INN's implementation of widely available extensions not documented in the
-NNTP standard.  Specifically, it does not cover the extensions listed in
-RFC 2980.
-
-------------------------------
-
-  Summary: innd doesn't require whitespace between commands and arguments
- Standard: draft-ietf-nntpext-base-15.txt, section 4
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c NCproc() and command handlers
- Severity: Accepts invalid input
-
-The standard states:
-
-    Keywords and arguments MUST be each separated by one or more US-ASCII
-    SPACE or US-ASCII TAB characters.
-
-This is not checked in NCproc or in the individual command handlers in
-innd.  Commands followed immediately by their argument will be accepted by
-innd.  For example:
-
-    stat<9k6vjk.hg0@example.com> 
-    223 0 @0301543531000000000000079AAE0000006A@
-
-Impact:  Should one command be a prefix of another, innd could dispatch
-the handling of the command to the wrong handler, treating the remainder
-of the command verb as an argument.  This laxness also encourages sloppy
-client code.  Internally, the lack of argument parsing in NCproc also
-results in code duplication in all of the command handlers.
-
-Suggested fix:  Lift the argument parsing code into a function called from
-NCproc, breaking the command line into a vector of command and arguments.
-This will work for all commands implemented by innd and will simplify the
-implementation of command handlers, as well as fixing this problem.  This
-is what nnrpd already does.
-
-Impact of fix:  It's possible that some serving code is relying on this
-behavior and not sending spaces after commands.  Fixing this problem would
-break interoperability with that code.
-
-------------------------------
-
-  Summary: INN doesn't check argument length
- Standard: draft-ietf-nntpext-base-15.txt, section 4
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c and nnrpd/nnrpd.c
- Severity: Accepts invalid input
-
-The standard says:
-
-    Arguments MUST NOT exceed 497 octets.
-
-This is not checked by either innd or nnrpd, although both do check that
-the command itself does not exceed 512 octets.
-
-Impact:  Small.  May accept invalid commands in extremely rare edge cases.
-
-Suggested fix:  Probably not worth fixing separately, although if standard
-command parsing code is written to handle both innd and nnrpd, it wouldn't
-hurt to check this along with everything else.
-
-------------------------------
-
-  Summary: Reply codes other than x9x used for private extensions
- Standard: draft-ietf-nntpext-base-15.txt, section 4.1
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: include/nntp.h
- Severity: Violates SHOULD
-
-The standard says:
-
-    Response codes not specified in this standard MAY be used for any
-    installation-specific additional commands also not specified.  These
-    SHOULD be chosen to fit the pattern of x9x specified above.
-
-INN uses quite a few response codes that do not fit this pattern for
-various extensions.  Some of these will likely later be standardized with
-the response codes that INN uses (the streaming commands, the
-authentication reply codes, and possibly the STARTTLS reply codes), but
-the rest (XGTITLE, MODE CANCEL, and XBATCH) should have used response
-codes in the x9x range.
-
-Impact:  Additional ambiguity over the meaning of reply codes, as those
-reply codes could later be standardized as the reply codes for other
-commands.
-
-Suggested fix:  For XGTITLE and probably XBATCH, there is no way to fix
-this now.  Changing the reply codes would break all existing
-implementations.  It may still be possible to change the reply codes for
-MODE CANCEL (which should probably be MODE XCANCEL), but it may not be
-worth the effort.
-
-------------------------------
-
-  Summary: innd may return 480 instead of 500 for unrecognized commands
- Standard: draft-ietf-nntpext-base-15.txt, section 4.1.1
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c NCauthinfo()
- Severity: Violates MUST
-
-The standard says:
-
-    If the command is not recognized, or it is an optional command or
-    extension that is not implemented by the server, the response code 500
-    MUST be returned.
-
-In innd, if the connection is determined to need authentication, all
-incoming commands other than MODE are handed off to NCauthinfo() rather
-than their normal command handlers.  NCauthinfo() responds with a 480
-reply code to anything other than AUTHINFO USER, AUTHINFO PASS, or QUIT.
-
-Impact:  Unlikely to cause problems in practice, but may confuse clients
-that don't understand the rarely used innd-level authentication
-mechanisms.
-
-Suggested fix:  Restructure the command table so that each command also
-has a flag indicating whether it requires authentication for peers that
-are required to authenticate.  (Some commands, like HELP and MODE READER,
-should be allowed without authentication.)  Then eliminate the special
-casing of the state CSgetauth (it may be better to store whether the peer
-has authenticated in the channel rather than in the channel state) and the
-special handling in NCauthinfo.  This should also simplify the code.
-
-------------------------------
-
-  Summary: innd always sends 200 for an accepted connection
- Standard: draft-ietf-nntpext-base-15.txt, section 7.1
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c NCsetup() and rc.c RCreader()
- Severity: Violates MUST
-
-The standard says:
-
-    If the server will accept further commands from the client including
-    POST, the server MUST present a 200 greeting code.  If the server will
-    accept further commands from the client, but it is not authorized to
-    post articles using the POST command, the server MUST present a 201
-    greeting code.
-
-The implication is that the greeting code from innd (which doesn't
-implement POST and therefore is never going to allow it) should always be
-201, at least for the case where innd never spawns nnrpd.  In the case
-where innd spawns nnrpd, it's unclear what the greeting code should be.
-
-The current implementation nevers send 201 unless one knows for certain
-that the connection will never be allowed to issue a POST command, which
-means that innd always sends 200.
-
-It's unknown whether there is any transit news software that would have
-difficulties with a 201 greeting.  Both innxmit and innfeed handle it
-correctly in CURRENT 2001-07-04 and NNTPconnect() handles it correctly in
-INN 1.0, so it seems likely that if any such software exists, it's rare.
-
-Impact:  It's almost certain that the current innd behavior isn't hurting
-anything.  Even a confused client that thought 200 meant that it could
-send a POST command would then try and be rejected with no damage done.
-
-Suggested fix:  The purpose of this return code is to give a hint to a
-reading client indicating whether it should even attempt POST, since
-attempting it may involve a lot of work by the user only to have the post
-rejected.  It's only relevant to reading connections, not to transit
-connections.
-
-It's known that some clients, upon seeing a 201 response, will never
-attempt POST, even if MODE READER then returns 200.  Therefore innd, when
-handing off connections to nnrpd, must return 200 to not confuse a client
-that will later send MODE READER.  For connections where innd won't do
-that handoff, it makes sense to always send 201 if all transit feeds can
-handle that and won't interpret it as unwillingness to accept IHAVE or
-streaming feeds.
-
-RCreader() should therefore be modified to send 201 if noreader is set,
-and otherwise send 200.
-
-Impact of fix:  Any feeding software that didn't consider 201 to be a
-valid greeting would be unable to feed a fixed innd unless that innd also
-allowed reading connections.
-
-------------------------------
-
-  Summary: innd doesn't support LIST EXTENSIONS
- Standard: draft-ietf-nntpext-base-15.txt, section 8.1
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c NClist()
- Severity: Not a violation
-
-Support for LIST EXTENSIONS is optional, and innd's current behavior
-(returning a 500 response) is permitted by the standard, but it means that
-innd cannot advertise any of the extensions that it supports.  Since this
-will eventually include streaming, support should be added.
-
-Suggested fix:  Add support for LIST EXTENSIONS to NClist() as soon as
-innd supports a registered extension or as soon as there is documentation
-for INN's extensions that specify an extension name (beginning with X).
-
-------------------------------
-
-  Summary: nnrpd doesn't return 423 errors when there is no overview info
- Standard: draft-ietf-nntpext-base-17.txt, section 10.5.1.2
-  Version: 1.4 to CURRENT 2003-05-04
-Reference: nnrpd/article.c CMDxover()
- Severity: Violates a MUST
-
-The standard says:
-
-   If there are no articles in the range specified, a 423 response MUST be
-   returned.
-
-nnrpd (from the beginning of the XOVER command) has always returned a 224
-response with an empty multiline response instead.  INN doesn't support
-OVER yet so this isn't actually a bug in INN, but eventually the XOVER
-implementation will also be used for OVER.
-
-Impact:  Less information is communicated to the client about why there
-are no overview records returned.  An error response indicating there are
-no valid articles in that range is possibly more informative.
-
-Suggested fix:  Don't print out the initial 224 message until at least one
-overview entry has been found, so that CMDxover() can print a 420 response
-instead if no overview records are found.
-
-Impact of fix:  May confuse some clients that don't expect to get 420
-errors back from overview queries.  It may be necessary to do something
-different for OVER (where clients should expect this behavior since OVER
-is a new command) than for XOVER (where clients may be relying on the
-existing behavior.
-
-------------------------------
-
-  Summary: HDR can return message IDs rather than article numbers
- Standard: draft-ietf-nntpext-base-17.txt, section 10.6.1.2
-  Version: 1.0 to CURRENT 2003-05-04
-Reference: nnrpd/article.c CMDpat()
- Severity: Violates a protocol description
-
-The standard says:
-
-   The line consists of the article number, a US-ASCII space, and then the
-   contents of the header (without the header name or the colon and space
-   that follow it) or metadata item.  If the article is specified by
-   message-id rather than by article range, the article number is given as
-   "0".
-
-nnrpd instead returns the message ID as the first word of the line when
-HDR is given a message ID argument.
-
-Impact:  A client may not be able to parse the output of HDR correctly,
-since the first word is not a number.
-
-Suggested fix:  Change the code to return 0 as the first word instead of
-the message ID, per the standard.
-
-Impact of fix:  Clients that are expecting the message ID may be
-confused.
-
-------------------------------
-
-  Summary: innd improperly caches DNS returns
- Standard: draft-ietf-nntpext-base-15.txt, section 14.4
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/rc.c RCreadfile() and elsewhere
- Severity: Violates a MUST
-
-The standard says:
-
-    If NNTP clients or servers cache the results of host name lookups in
-    order to achieve a performance improvement, they MUST observe the TTL
-    information reported by DNS.
-
-innd caches DNS lookups when reading incoming.conf and doesn't refresh its
-knowledge of DNS except when incoming.conf is reloaded.
-
-Impact:  An explicit reload is required whenever the IP address of any
-peer changes, and in the presence of network renumbering innd is
-vulnerable to spoofing if DNS is the only authentication mechanism used.
-
-Suggested fix:  This is hard to fix without unacceptable performance
-impact.  The only good fix is to either fork a separate helper process to
-do DNS lookups (since gethostbyname may block for essentially an
-arbitrarily long period) or to use the direct resolver library so that one
-can get access to a file descriptor and throw it into the select loop.
-Either way, this requires keeping a DNS file descriptor in the main select
-loop and updating knowledge of DNS periodically, which is a substantial
-amount of additional complexity.
-
-------------------------------
-
-  Summary: innd doesn't diagnose repeated AUTHINFO USER commands
- Standard: RFC 2980, section 3.1.1
-  Version: 1.0 to CURRENT 2002-12-26
-Reference: innd/nc.c NCauthinfo()
- Severity: Violates a protocol description
-
-RFC 2980 says:
-
-    The 482 code will also be returned when the AUTHINFO commands are not
-    entered in the correct sequence (like two AUTHINFO USERs in a row, or
-    AUTHINFO PASS preceding AUTHINFO USER).
-
-innd ignores AUTHINFO USER and just always returns a 381 response, however,
-since it doesn't care about the username.
-
-Impact:  Probably none.
-
-Suggested fix:  A long-term solution would be to add real authentication
-to innd, in which case it would start caring about the authenticated
-identity (and perhaps use that identity to map to an incoming.conf entry).
-It's unclear if this would be worthwhile.  Failing that, innd would need
-to keep internal state to know whether AUTHINFO USER had already been
-sent.
diff --git a/doc/config-design b/doc/config-design
deleted file mode 100644 (file)
index eda5bf3..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-$Id: config-design 4805 2001-06-21 10:52:27Z rra $
-
-This file is documentation of the design principles that went into INN's
-configuration file syntax, and some rationale for why those principles
-were chosen.
-
- 1.  All configuration files used by INN should have the same syntax.
-     This was the root reason why the project was taken on in the first
-     place; INN developed a proliferation of configuration files, all of
-     which had a slightly (or greatly) different syntax, forcing the
-     administrator to learn several different syntaxes and resulting in a
-     proliferation of parsers, all with their own little quirks.
-
- 2.  Adding a new configuration file or a new set of configuration options
-     should not require writing a single line of code for syntax parsing.
-     Code that analyzes the semantics of the configuration will of course
-     be necessary, but absolutely no additional code to read files, parse
-     files, build configuration trees, or the like should be required.
-     Ideally, INN should have a single configuration parser that
-     everything uses.
-
- 3.  The syntax should look basically like the syntax of readers.conf,
-     incoming.conf, and innfeed.conf in INN 2.3.  After extensive
-     discussion on the inn-workers mailing list, this seemed to be the
-     most generally popular syntax of the ones already used in INN, and
-     inventing a completely new syntax didn't appear likely to have gains
-     outweighing the effort involved.  This syntax seemed sufficiently
-     general to represent all of the configuration information that INN
-     needed.
-
- 4.  The parsing layer should *not* attempt to do semantic analysis of the
-     configuration; it should concern itself solely with syntax (or very
-     low-level semantics that are standard across all conceivable INN
-     configuration files).  In particular, the parsing layer should not
-     know what parameters are valid, what groups are permitted, what types
-     the values for parameters should have, or what default values
-     parameters have.
-
-     This principle requires some additional explanation, since it is very
-     tempting to not do things this way.  However, the more semantic
-     information the parser is aware of, the less general the parser is,
-     and it's very easy to paint oneself into a corner.  In particular,
-     it's *not* a valid assumption that all clients of the parsing code
-     will want to reduce the configuration to a bunch of structs; this
-     happens to be true for most clients of inn.conf, for example, but
-     inndstart doesn't want the code needed to reduce everything to a
-     struct and set default values to necessarily be executed in a
-     security-critical context.
-
-     Additionally, making the parser know more semantic information either
-     complicates (significantly) the parser interface or means that the
-     parser has to be modified when the semantics change.  The latter is
-     not acceptable, and the parser interface should be as straightforward
-     as possible (to encourage all parts of INN to use it).
-
- 5.  The result of a parse of the configuration file may be represented as
-     a tree of dictionaries, where each dictionary corresponds to a group
-     and each key corresponds to a parameter setting.  (Note that this does
-     not assume that the underlying data structure is a hash table, just
-     that it has dictionary semantics, namely a collection of key/value
-     pairs with the keys presumed unique.)
-
- 6.  Parameter values inherit via group nesting.  In other words, if a
-     group is nested inside another group, all parameters defined in the
-     enclosing group are inherited by the nested group unless they're
-     explicitly overriden within the nested group.  (This point and point
-     5 are to some degree just corollaries of point 3.)
-
- 7.  The parsing library must permit writing as well as reading.  It must
-     be possible for a program to read in a configuration file, modify
-     parameters, add and delete groups, and otherwise change the
-     configuration, and then write back out to disk a configuration file
-     that preserves those changes and still remains as faithful to the
-     original (possibly human-written) configuration file as possible.
-     (Ideally, this would extend to preserving comments, but that may be
-     too difficult to do and therefore isn't required.)
-
- 8.  The parser must not limit the configuration arbitrarily.  In
-     particular, unlimited length strings (within available memory) must
-     be supported for string values, and if allowable line length is
-     limited, line continuation must be supported everywhere that there's
-     any reasonable expectation that it might be necessary.  One common
-     configuration parameter is a list of hosts or host wildmats that can
-     be almost arbitrarily long, and the syntax and parser must support
-     that.
-
- 9.  The parser should be reasonably efficient, enough so as to not cause
-     an annoying wait for command-line tools like sm and grephistory to
-     start.  In general, though, efficiency in either time or memory is
-     not as high of a priority as readable, straightforward code; it's
-     safe to assume that configuration parsing is only done on startup and
-     at rare intervals and is not on any critical speed paths.
-
-10.  Error reporting is a must.  It must be possible to clearly report
-     errors in the configuration files, including at minimum the file name
-     and line number where the error occurred.
-
-11.  The configuration parser should not trust its input, syntax-wise.  It
-     must not segfault, infinitely loop, or otherwise explode on malformed
-     or broken input.  And, as a related point, it's better to be
-     aggressively picky about syntax than to be lax and attempt to accept
-     minor violations.  The intended configuration syntax is simple and
-     unambiguous, so it should be unnecessary to accept violations.
-
-12.  It must be possible to do comprehensive semantic checks of a
-     configuration file, including verifying that all provided parameters
-     are known ones, all parameter values have the correct type, group
-     types that are not expected to be repeated are not, and only expected
-     group types are used.  This must *not* be done by the parser, but the
-     parser must provide sufficient hooks that the client program can do
-     this if it chooses.
-
-13.  The parser must be re-entrant and thread-safe.
-
-14.  The grammar shouldn't require any lookahead to parse.  This is in
-     order to keep the parser extremely simple and therefore maintainable.
-     (It's worth noting that this design principle leads to the
-     requirement that parameter keys end in a colon; the presence of the
-     colon allows parameter keys to be distinguished from other syntactic
-     elements allowed in the same scope, like the beginning of a nested
-     group.)
diff --git a/doc/config-semantics b/doc/config-semantics
deleted file mode 100644 (file)
index 49d601e..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-$Id: config-semantics 4792 2001-06-21 08:59:39Z rra $
-
-Groups in a configuration file have a well-defined order, namely the order
-in which the groups would be encountered in a depth-first traversal of the
-parse tree.
-
-The supported operations on a configuration file parse tree for reading
-are:
-
- * Search.  Find the first group of a given type in a given tree.  This is
-   done via depth-first search.
-
- * Next.  Find the next group of a given type, starting from some group.
-   This is done via depth-first search.
-
- * Query.  Look up the value of a given parameter in a given group (with
-   inheritance).  Note that the expected type of the parameter value must
-   be provided by the caller; the parsing library doesn't know the types
-   of parameters.
-
- * Prune.  Limit one's view of the configuration file to only a given set
-   of group types and everything underneath them; any other group types
-   encountered won't be parsed (and therefore everything under them, even
-   groups of the wanted type, won't be seen).
-
-Therefore, the *only* significance of nested group structure is parameter
-inheritence and pruning.  In the absence of pruning, it would always be
-possible, by duplicating parameter settings that were inherited and laying
-out the groups in depth-first traversal order, to transform any
-configuration file into an entirely equivalent one that contains no nested
-groups.  This isn't true in the presence of pruning, but pruning is
-intended to be used primarily for performance (ignoring the parts of the
-configuration that don't apply to a given parsing library client).
-
-The expected way for clients to use the parsing library is to follow one
-of these two access patterns:
-
- * Search for a particular configuration group and then query it for a set
-   of parameters (either one by one as they're used, or all at once to
-   collapse the parameters into a struct for faster access later).  This
-   is expected to be the common pattern for finding and looking up
-   settings for a particular program.  There will generally only be a
-   single group per group type for groups of this sort; it doesn't make
-   sense to have multiple groups setting general configuration options for
-   a program and have to iterate through them and merge them in some
-   fashion.
-
- * Iterate through all groups of a given type, building a list of them (or
-   of the data they contain).  This is the model used by, for example,
-   storage classes; each storage class has a set of parameters, and the
-   storage subsystem needs to know about the full list of classes.
-
-Note that neither of these operations directly reveal the tree structure;
-the tree structure is intended for the convenience of the user in setting
-defaults for various parameters so that they don't have to be repeated in
-each group, and to allow some top-level pruning.  It's not intended to be
-semantically significant other than that.
-
-Here are some suggested general conventions:
-
- * General options for a particular program should be separated out into a
-   their own group.  For example, a group innwatch in inn.conf to set the
-   various options only used by innwatch.  Note that pruning is inclusive
-   rather than exclusive, so programs should ideally only need to care
-   about a short list of groups.
-
- * Groups used only for grouping and setting default parameters, ones that
-   won't be searched for explicitly by any program, should use the type
-   "group".  This can be used uniformly in all configuration files so that
-   whenever a user sees a group of type "group", they know that it's just
-   syntactic convenience to avoid having to repeat a bunch of parameter
-   settings and isn't otherwise significant.
-
- * Groups that are searched for or iterated through shouldn't be nested;
-   for example, if a configuration file defines a list of access groups,
-   nesting one access group inside another is discouraged (in favor of
-   putting both groups inside an enclosing group of type "group" that sets
-   the parameters they have in common).  This is to cut down on user
-   confusion, since otherwise the nesting appears to be significant.
diff --git a/doc/config-syntax b/doc/config-syntax
deleted file mode 100644 (file)
index 4863d5d..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-$Id: config-syntax 5843 2002-11-19 00:08:18Z rra $
-
-This file documents the standardized syntax for INN configuration files.
-This is the syntax that the parsing code in libinn will understand and the
-syntax towards which all configuration files should move.
-
-The basic structure of a configuration file is a tree of groups.  Each
-group has a type and an optional tag, and may contain zero or more
-parameter settings, an association of a name with a value.  All parameter
-names and group types are simple case-sensitive strings composed of
-printable ASCII characters and not containing whitespace or any of the
-characters "\:;{}[]<>" or the double-quote.  A group may contain another
-group (and in fact the top level of the file can be thought of as a
-top-level group that isn't allowed to contain parameter settings).
-
-Supported parameter values are booleans, integers, real numbers, strings,
-and lists of strings.
-
-The basic syntax looks like:
-
-    group-type tag {
-        parameter: value
-        parameter: [ string string ... ]
-        # ...
-
-        group-type tag {
-            # ...
-        }
-    }
-
-Tags are strings, with the same syntax as a string value for a parameter;
-they are optional and may be omitted.  A tag can be thought of as the name
-of a particular group, whereas the <group-type> says what that group is
-intended to specify and there may be many groups with the same type.
-
-The second parameter example above has as its value a list.  The square
-brackets are part of the syntax of the configuration file; lists are
-enclosed in square brackets and the elements are space-separated.
-
-As seen above, groups may be nested.
-
-Multiple occurances of the same parameter in the parameter section of a
-group is an error.  In practice, the second parameter will take precedent,
-but an error will be reported when such a configuration file is parsed.
-
-Parameter values inherit.  In other words, the structure:
-
-    first {
-        first-parameter: 1
-        second {
-            second-parameter: 1
-            third { third-parameter: 1 }
-        }
-
-        another "tag" { }
-    }
-
-is parsed into a tree that looks like:
-
-    +-------+   +--------+   +-------+
-    | first |-+-| second |---| third |
-    +-------+ | +--------+   +-------+
-              |
-              | +---------+
-              +-| another |
-                +---------+
-
-where each box is a group.  The type of the group is given in the box;
-none of these groups have tags except for the only group of type
-"another", which has the tag "tag".  The group of type "third" has three
-parameters set, namely "third-parameter" (set in the group itself),
-"second-parameter" (inherited from the group of type "second"), and
-"first-parameter" (inherited from "first" by "second" and then from
-"second" by "third").
-
-The practical meaning of this is that enclosing groups can be used to set
-default values for a set of subgroups.  For example, consider the
-following configuration that defines three peers of a news server and
-newsgroups they're allowed to send:
-
-    peer news1.example.com { newsgroups: * }
-    peer news2.example.com { newsgroups: * }
-    peer news3.example.com { newsgroups: * }
-
-This could instead be written as:
-
-    group {
-        newsgroups: *
-
-        peer news1.example.com { }
-        peer news2.example.com { }
-        peer news3.example.com { }
-    }
-
-or as:
-
-    peer news1.example.com {
-        newsgroups: *
-
-        peer news2.example.com { }
-        peer news3.example.com { }
-    }
-
-and for a client program that only cares about the defined list of peers,
-these three structures would be entirely equivalent; all questions about
-what parameters are defined in the peer groups would have identical
-answers either way this configuration was written.
-
-Note that the second form above is preferred as a matter of style to the
-third, since otherwise it's tempting to derive some significance from the
-nesting structure of the peer groups.  Also note that in the second
-example above, the enclosing group *must* have a type other than "peer";
-to see why, consider the program that asks the configuration parser for a
-list of all defined peer groups and uses the resulting list to build some
-internal data structures.  If the enclosing group in the second example
-above had been of type peer, there would be four peer groups instead of
-three and one of them wouldn't have a tag, probably provoking an error
-message.
-
-Boolean values may be given as yes, true, or on, or as no, false, or off.
-Integers must be between -2,147,483,648 and +2,147,483,647 inclusive (the
-same as the minimums for a C99 signed long).  Floating point numbers must
-be between 0 and 1e37 in absolute magnitude (the same as the minimums for
-a C99 double) and can safely expect eight digits of precision.
-
-Strings are optionally enclosed in double quotes, and must be quoted if
-they contain any whitespace, double-quote, or any characters in the set
-"\:;[]{}<>".  Escape sequences in strings (sequences beginning with \) are
-parsed the same as they are in C.  Strings can be continued on multiple
-lines by ending each line in a backslash, and the newline is not
-considered part of such a continued string (to embed a literal newline in
-a string, use \n).
-
-Lists of strings are delimited by [] and consist of whitespace-separated
-strings, which must follow the same quoting rules as all other strings.
-Group tags are also strings and follow the same quoting rules.
-
-There are two more bits of syntax.  Normally, parameters must be separated
-by newlines, but for convenience it's possible to put multiple parameters
-on the same line separated by semicolons:
-
-    parameter: value; parameter: value
-
-Finally, the body of a group may be defined in a separate file.  To do
-this, rather than writing the body of the group enclosed in {}, instead
-give the file name in <>:
-
-    group tag <filename>
-
-(The filename is also a string and may be double-quoted if necessary, but
-since file names rarely contain any of the excluded characters it's rarely
-necessary.)
-
-Here is the (almost) complete ABNF for the configuration file syntax.
-The syntax is per RFC 2234.
-
-First the basic syntax elements and possible parameter values:
-
-    newline             = %d13 / %d10 / %d13.10
-                                ; Any of CR, LF, or CRLF are interpreted
-                                ; as a newline.
-
-    comment             = *WSP "#" *(WSP / VCHAR / %x8A-FF) newline
-
-    WHITE               = WSP / newline [comment]
-
-    boolean             = "yes" / "on" / "true" / "no" / "off" / "false"
-
-    integer             = ["-"] 1*DIGIT
-
-    real-number         = ["-"] 1*DIGIT "." 1*DIGIT [ "e" ["-"] 1*DIGIT ]
-
-    non-special         = %x21 / %x23-39 / %x3D / %x3F-5A / %x5E-7A
-                               / %x7C / %x7E / %x8A-FF
-                                ; All VCHAR except "\:;<>[]{}
-
-    quoted-string       = DQUOTE 1*(WSP / VCHAR / %x8A-FF) DQUOTE
-                                ; DQUOTE within the quoted string must be
-                                ; written as 0x5C.22 (\"), and backslash
-                                ; sequences are interpreted as in C
-                                ; strings.
-
-    string              = 1*non-special / quoted-string
-
-    list-body           = string *( 1*WHITE string )
-
-    list                = "[" *WHITE [ list-body ] *WHITE "]"
-
-Now the general structure:
-
-    parameter-name      = 1*non-special
-
-    parameter-value     = boolean / integer / real-number / string / list
-
-    parameter           = parameter-name ":" 1*WSP parameter-value
-
-    parameter-list      = parameter [ *WHITE (";" / newline) *WHITE parameter ]
-
-    group-list          = group *( *WHITE group )
-
-    group-body          = parameter-list [ *WHITE newline *WHITE group-list ]
-                        / group-list
-
-    group-file          = string
-
-    group-contents      = "{" *WHITE [ group-body ] *WHITE "}"
-                        / "<" group-file ">"
-
-    group-type          = 1*non-special
-
-    group-tag           = string
-
-    group-name          = group-type [ 1*WHITE group-tag ]
-
-    group               = group-name 1*WHITE group-contents
-
-    file                = *WHITE *( group *WHITE )
-
-One implication of this grammar is that any line outside a quoted string
-that begins with "#", optionally preceded by whitespace, is regarded as a
-comment and discarded.  The line must begin with "#" (and optional
-whitespace); comments at the end of lines aren't permitted.  "#" has no
-special significance in quoted strings, even if it's at the beginning of a
-line.  Note that comments cannot be continued to the next line in any way;
-each comment line must begin with "#".
-
-It's unclear the best thing to do with high-bit characters (both literal
-characters with value > 0x7F in a configuration file and characters with
-such values created in quoted strings with \<octal>, \x, \u, or \U).  In
-the long term, INN should move towards assuming UTF-8 everywhere, as this
-is the direction that all of the news standards are heading, but in the
-interim various non-Unicode character sets are in widespread use and there
-must be some way of encoding those values in INN configuration files (so
-that things like the default Organization header value can be set
-appropriately).
-
-As a compromise, the configuration parser will pass unaltered any literal
-characters with value > 0x7F to the calling application, and \<octal> and
-\x escapes will generate eight-bit characters in the strings (and
-therefore cannot be used to generate UTF-8 strings containing code points
-greater than U+007F).  \u and \U, in contrast, will generate characters
-encoded in UTF-8.
diff --git a/doc/external-auth b/doc/external-auth
deleted file mode 100644 (file)
index 28fc847..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-NNRPD External Authentication Support
-
-    This is $Revision: 7880 $ dated $Date: 2005-03-17 12:42:46 +0100 (Thu,
-    17 Mar 2005) $.
-
-    A fundamental part of the readers.conf(5)-based authorization mechanism
-    is the interface to external authenticator and resolver programs.  This
-    interface is documented below.
-
-    INN ships with a number of such programs (all written in C, although any
-    language can be used).  Code for them can be found in authprogs/ of the
-    source tree; the authenticators are installed to *pathbin*/auth/passwd,
-    and the resolvers are installed to *pathbin*/auth/resolv.
-
-Reading information from nnrpd
-
-    When nnrpd spawns an external auth program, it passes information on
-    standard input as a sequence of "key: value" lines.  Each line ends with
-    CRLF, and a line consisting of only "." indicates the end of the input. 
-    The order of the fields is not significant.  Additional fields not
-    mentioned below may be included; this should not be cause for alarm.
-
-    (For robustness as well as ease of debugging, it is probably wise to
-    accept line endings consisting only of LF, and to treat EOF as
-    indicating the end of the input even if "." has not been received.)
-
-    Code which reads information in the format discussed below and parses it
-    into convenient structures is available authenticators and resolvers
-    written in C; see libauth(3) for details.  Use of the libauth library
-    will make these programs substantially easier to write and more robust.
-
-  For authenticators
-
-    When nnrpd calls an authenticator, the lines it passes are
-
-        ClientAuthname: user\r\n
-        ClientPassword: pass\r\n
-
-    where *user* and *pass* are the username and password provided by the
-    client (e.g. using AUTHINFO).  In addition, nnrpd generally also passes
-    the fields mentioned as intended for resolvers; it rare instances this
-    data may be useful for authenticators.
-
-  For resolvers
-
-    When nnrpd calls a resolver, the lines it passes are
-
-        ClientHost: hostname\r\n
-        ClientIP: IP-address\r\n
-        ClientPort: port\r\n
-        LocalIP: IP-address\r\n
-        LocalPort: port\r\n
-        .\r\n
-
-    where *hostname* indicates a string representing the hostname if
-    available, *IP-address* is a numeric IP address (dotted-quad for IPv4,
-    equivalent for IPv6 if appropriate), and *port* is a numeric port
-    number.  (The *LocalIP* paramter may be useful for determining which
-    interface was used for the incoming connection.)
-
-    If information is not available, nnrpd will omit the corresponding
-    fields.  In particular, this applies to the unusual situation of nnrpd
-    not being connected to a socket; TCP-related information is not
-    available for standard input.
-
-Returning information to nnrpd
-
-  Exit status and signals
-
-    The external auth program must exit with a status of 0 to indicate
-    success; any other exit status indicates failure.  (The non-zero exit
-    value will be logged.)
-
-    If the program dies due to catching a signal (for example, a
-    segmentation fault occurs), this will be logged and treated as a
-    failure.
-
-  Returning a username and domain
-
-    If the program succeeds, it must return a username string (optionally
-    with a domain appended) by writing to standard output.  The line it
-    should write is exactly:
-
-        user:username\r\n
-
-    where *username* is the string that nnrpd should use in matching
-    readers.conf access blocks.
-
-    There should be no extra spaces in lines sent from the hook to nnrpd;
-    "user:aidan" is read by nnrpd as a different username than "user:
-    aidan".
-
-Error messages
-
-    As mentioned above, errors can be indicated by a non-zero exit value, or
-    termination due to an unhandled signal; both cases are logged by nnrpd. 
-    However, external auth programs may wish to log error messages
-    separately.
-
-    Although nnrpd will syslog() anything an external auth program writes to
-    standard error, it is generally better to use the messages.h functions,
-    such as warn() and die().
-
-    Please use the ckpasswd.c program as an example for any authenticators
-    you write, and ident.c as an example for any resolvers.
-
-HISTORY
-
-    Written by Aidan Cully for InterNetNews.  This documentation rewritten
-    in POD by Jeffrey M. Vinocur <jeff@litech.org>.
-
diff --git a/doc/history b/doc/history
deleted file mode 100644 (file)
index b5d4cc1..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-$Revision: 4165 $
-This file contains a few messages of historical interest.  Some of the
-information in these messages is out of date (e.g., you don't need any
-other software, ihave/sendme is suported, etc); see the README and
-installation manual.
-
-The first is a mail message I sent as soon as I got the idea.
-
-Six months later I had something to beta, and I posted the second message
-to Usenet.  My ship date was optimistic.
-
-The third message is the application that I required all beta sites to
-fill out.
-
-The fourth is a copy of the release notice.
-\f
-From: Rich Salz <rsalz@bbn.com>
-Date: Sat, 8 Dec 90 15:23:20 EST
-Message-Id: <9012082023.AA13441@litchi.bbn.com>
-To: newsgurus@ucsd.edu, nntp-managers@ucbarpa.Berkeley.EDU
-Subject: Speed idea.
-
-Suppose inews, nntp, "rnews -U", newsunbatch, etc., all just fed their
-articles to a single daemon?
-
-An idea I started kicking around yesterday.  This is intended only for
-sites supporting BSD networking.  I believe that anyone else who needs
-this kind of speed would find Cnews good enough.
-
-A multi-threaded server that used non-blocking IO to read all incoming
-articles on several sockets (don't forker a server, select on the
-connection socket will return READOK when a connection request comes in).
-All articles are read into memory, then written out to the filesystem
-using a single writev call (easy way to splice the path).
-
-Hash the active file and compile the sys file so as soon as an article was
-accepted we can write out the batchfile entries.  As one special case,
-write entries to another socket for articles that should be fed out via
-NNTPLINK or something.
-
-Put the socket inside a group-access-only directory, so that only trusted
-front-ends like inews "rnews -U" etc can connect to it.
-
-Oh yeah, for things like nntp use sendmsg/recvmesg to hand off the
-feeding site to the demon once it's authenticated the incoming call and
-recognized it as an "xfer no" site.
-
-I've a few pages of notes and code fragments to type in.
-
-No locks of any kind.  active file is mmap'd or periodically flushed.
-Keep it all in core and blat it out with a single write.
-
-When you want to expire, or add a group, you send a special message
-on a control port, or perhaps a sighup/sigusr1 to force it to resynch.
-
-Any feedback?
-       /r$
-\f
-Path: papaya.bbn.com!rsalz
-From: rsalz@bbn.com (Rich Salz)
-Newsgroups: news.software.nntp,news.admin,comp.org.usenix
-Subject: Seeking beta-testers for a new NNTP transfer system
-Message-ID: <3632@litchi.bbn.com>
-Date: 18 Jun 91 15:47:21 GMT
-Followup-To: poster
-Organization: Bolt, Beranek and Newman, Inc.
-Lines: 72
-Xref: papaya.bbn.com news.software.nntp:1550 news.admin:15565 comp.org.usenix:418
-
-InterNetNews, or INN, is a news transport system.  The core part of the
-package is a single long-running daemon that handles all incoming NNTP
-connections.  It files the articles and arranges for them to be forwarded
-to downstream sites.  Because it is long-running, it can be directed to
-spawn other long-running processes, telling them exactly when an article
-should be sent to a feed.  This can replace the "watch the logfile" mode
-of nntplink, for example, with a much cleaner mechanism:  read the
-batchfile on standard input.
-
-InterNetNews assumes that memory is cheap and fast while disks are slow.
-No temporary files are used while incoming articles are being received,
-and once processed the entire article is written out using a single
-writev(2) call (this includes updating the Path and Xref headers).  The
-active file is kept in memory (a compile-time option can be set to use
-mmap(2)), and the newsfeeds file is parsed once to build a complete matrix
-of which sites receive which newsgroups.
-
-InterNetNews uses many features of standard BSD sockets including
-non-blocking I/O and Unix-domain stream and datagram sockets.  It is
-highly doubtful that the official version will ever provide support for
-TLI, DECNET, or other facilities.
-
-INN is fast.  Not many hard numbers are available (that is one requirement
-of being a beta-site), but some preliminary tests show it to be at least
-twice as fast as the current standard NNTP/C News combination.  For
-example, Jim Thompson at Sun has had 20 nntpxmits feeding into a 4/490,
-and was getting over 14 articles per second, with the CPU 11% utilized.  I
-was getting 10 articles/second feeding into a DECstations 3100, with the
-program (running profiled!) 50% idle and the load average under .7.  (It
-is a scary thing to see several articles filed with the same timestamp.)
-
-The sys file format is somewhat different, and has been renamed.  The
-arcane "foo.all" syntax is gone, replaced with a set of order-dependant
-shell patterns.  For example, instead of "comp,comp.sys.sun,!comp.sys" you
-would write "comp.*,!comp.sys.*,comp.sys.sun"; to not get any groups
-related to binaries or pictures, you write "!*pictures*,!*binaries*".
-
-There are other incompatibilities as well.  For example, ihave/sendme
-control messages are not supported.  Also the philosophy is that that
-invalid articles are dropped, rather than filed into "junk."  (A log
-message is written with the reason, and also sent back to the upstream
-feed as part of the NNTP reject reply.)  The active file is taken to be
-the definitive list of groups that an article wants to recieve, and if
-none of an article's newsgroups are mentioned in the active file, then the
-article is invalid, logged, and dropped.
-
-The history and log files are intended to be compatible with those created
-by C News.  I want to thank Henry and Geoff for their kind permission to
-use DBZ and SUBST.  You will need to be running C News expire or a B2.11
-expire that has been modified to use DBZ.
-
-The InterNetNews daemon does not implement all NNTP commands.  If sites
-within your campus are going to post or read news via NNTP, you will need
-the standard NNTP distribution.  The daemon will spawn the standard nntpd
-if any site not mentioned in its "hosts.nntp" file connects to the TCP
-port.  InterNetNews includes a replacement for the "mini-inews" that comes
-with the standard NNTP distribution.  This can be used on any machine that
-posts news and connects to an NNTP server somewhere; its use is not
-limited to INN.  At some point I hope to have a replacement nntpd
-optimized for newsreaders, and an NNTP transmission program.  These will
-remove the need for any external software beyond the C News expire program.
-
-If you would like to beta-test this version, please FTP the file
-pub/usenet/INN.BETA from cronus.bbn.com for directions.  It will be a
-fairly tightly-screened beta:  DO NOT ASK ME FOR COPIES!  Once the system
-is stable, it will be freely redistributable.  I hope to have the official
-release by August 7, so that schools can bring the system up before the
-semester starts.
-       /rich $alz
--- 
-Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
-Use a domain-based address or give alternate paths, or you may lose out.
-\f
-Thanks for your interest in InterNetNews.  I want to run a fairly
-tightly-controlled beta test of the software before I make it generally
-available.  This means that I'm going to screen the sites which will be
-able to participate in the test.  Please don't be offended or upset by
-this whole procedure.  I want to make the final package as stable as soon
-as possible so that the entire net can benefit (it will be freely
-redistributable).  I've set up this mechanism because I think it's the
-best way for me to get the best test results as quickly as possible.
-
-I would therefore appreciate your answers to the following questions.
-If you think the answers to some of them will be obvious to me (e.g.,
-"Describe your organization" --> "UUNET" :-) then feel free to leave it
-blank.  If you have any other feedback or comments, please add them.
-
-Email your results to <rsalz@bbn.com>
-       /r$
-
-What software (transport, batching, readers, etc.) do you currently run?
-
-How much experience do you have with Usenet and NNTP?
-
-Describe your organization.
-
-How do you plan on testing InterNetNews?  Be specific, describing the
-machine hardware, any test servers, etc.  [The answers to this one
-won't be obvious to me -- you gotta write something.]
-
-What are the rough counts of the upstream and downstream feeds, and how do
-they break down by category (UUCP, NNTP, etc.)?
-
-What special news functions does your server perform (gatewaying,
-archiving, etc.)?
-
-Do you understand that by participating in the beta-test you agree not to
-redistribute the software outside of your administrative domain, and that
-you promise to upgrade to the official release in a timely manner?
-\f
-From: Rich Salz <rsalz@uunet.uu.net>
-Message-Id: <inn-announce@uunet.uu.net>
-Newsgroups: news.software.b,news.protocols.nntp
-Subject: Announcing the release of InterNetNews
-
-I am pleased to announce the official release of InterNetNews.
-
-InterNetNews, or INN, is a news transport system.  The core part of the
-package is a single long-running daemon that handles all incoming NNTP
-connections.  It files the articles and arranges for them to be forwarded
-to downstream sites.  Because it is long-running, it can be directed to
-spawn other long-running processes, telling them exactly when an article
-should be sent to a feed.
-
-INN is a complete Usenet system.  It provides article expiration and
-archiving, NNTP transport, and UUCP support.  Nntplink works fine.
-
-INN does not include a newsreader.  It does provide a version of the NNTP
-reference implementation "clientlib" routines so that rrn and other
-newsreaders compile with little trouble.  The next release of xrn will
-include INN support.
-
-The spool directory is unchanged while the history database is
-upwardly-compatible with that of C News and the log file is very similar.
-All system configuration files are different.
-
-INN assumes that memory is cheap and fast while disks are slow.  No
-temporary files are used while incoming articles are being received, and
-once processed the entire article is written out using a single system
-call (this includes updating the Path and Xref headers).  The active file
-is kept in memory, and the newsfeeds file is parsed at start-up to build a
-complete matrix of which sites receive which newsgroups.  A paper
-describing the implementation was presented at the June 1992 Usenix
-conference.
-
-INN uses many features of standard BSD sockets including non-blocking
-I/O.  It is highly doubtful that the official version will ever provide
-support for TLI, DECNET, or other facilities.  Among others, INN beta
-sites include ATT Unix System V Release 4, Apple A/UX, BSDI BSD/386 0.3.3,
-DEC Ultrix 3.x and 4.x, HP-UX s800 8.0, IBM AIX 3.1 and 3.2, Next NeXT-OS
-2.1, Pyramid OSx 5.1, SCO Xenix 2.3.4, SGI Irix 4.0, Sequent Dynix 3.0.4
-and 3.0.12, and Sun SunOS 3.5 and 4.x.
-
-Almost all of the beta-testers have reported faster performance and less
-load once they installed INN.  Many people find it easy to maintain.
-
-A number of sites have graciously agreed to provide FTP access to this
-release.  The machine names and directories are listed below.  Within
-those directories you will find one or more of the following files:
-       README                  Intro and unpacking instructions;
-        -or-                   a copy appears at the end of this
-       README.INN              article.
-       inn1.0.tar.Z            The full distribution
-       inn.usenix.ps.Z         The Usenix paper on INN
-
-The sites providing access are:
-       cs.utexas.edu           /pub/inn
-       ftp.cs.widener.edu      /pub/inn.tar.Z (or wherever).
-       ftp.germany.eu.net      /pub/news/inn
-       ftp.ira.uka.de          pub/network/news
-       ftp.msen.com            /pub/packages/inn
-       ftp.uu.net              /pub/news/nntp/inn
-       gatekeeper.dec.com      /pub/news/inn
-       grasp1.univ-lyon1.fr    /pub/unix/news/inn
-       munnari.oz.au           /pub/news/inn
-       sparky.Sterling.COM     /news/inn
-       src.doc.ic.ac.uk        /computing/usenet/software/transport
-       stasys.sta.sub.org      /pub/src/inn
-           (Stasys also has anonymous UUCP; contact <fkk@sta.sub.org>.
-       ucsd.edu                /INN
-       usc.edu                 /pub/inn
-
-Discussion about INN should be posted to news.software.b and
-news.software.nntp.  Email should be sent to <rsalz@uunet.uu.net>.  Please
-do NOT send it to <rsalz@osf.org> -- it will only just delay your response
-since I will have to forward it to UUNET.
-
-The README follows after the formfeed.
-       /r$
diff --git a/doc/hook-perl b/doc/hook-perl
deleted file mode 100644 (file)
index b2e33d8..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-INN Perl Filtering and Authentication Support
-
-    This is $Revision: 7880 $ dated $Date: 2008-06-07 14:46:49 +0200 (Sat,
-    07 Jun 2008) $.
-
-    This file documents INN's built-in support for Perl filtering and reader
-    authentication.  The code is based very heavily on work by Christophe
-    Wolfhugel <wolf@pasteur.fr>, and his work was in turn inspired by the
-    existing TCL support.  Please send any bug reports to inn-bugs@isc.org,
-    not to Christophe, as the code has been modified heavily since he
-    originally wrote it.
-
-    The Perl filtering support is described in more detail below. 
-    Basically, it allows you to supply a Perl function that is invoked on
-    every article received by innd from a peer (the innd filter) or by nnrpd
-    from a reader (the nnrpd filter).  This function can decide whether to
-    accept or reject the article, and can optionally do other, more
-    complicated processing (such as add history entries, cancel articles,
-    spool local posts into a holding area, or even modify the headers of
-    locally submitted posts).  The Perl authentication hooks allow you to
-    replace or supplement the readers.conf mechanism used by nnrpd.
-
-    For Perl filtering support, you need to have Perl version 5.004 or
-    newer.  Earlier versions of Perl will fail with a link error at
-    compilation time.  http://language.perl.com/info/software.html should
-    have the latest Perl version.
-
-    To enable Perl support, you have to specify --with-perl when you run
-    configure.  See INSTALL for more information.
-
-The innd Perl Filter
-
-    When innd starts, it first loads the file _PATH_PERL_STARTUP_INND
-    (defined in include/paths.h, by default startup_innd.pl) and then loads
-    the file _PATH_PERL_FILTER_INND (also defined in include/paths.h, by
-    default filter_innd.pl).  Both of these files must be located in the
-    directory specified by pathfilter in inn.conf
-    (/usr/local/news/bin/filter by default).  The default directory for
-    filter code can be specified at configure time by giving the flag
-    --with-filter-dir to configure.
-
-    INN doesn't care what Perl functions you define in which files.  The
-    only thing that's different about the two files is when they're loaded. 
-    startup_innd.pl is loaded only once, when innd first starts, and is
-    never reloaded as long as innd is running.  Any modifications to that
-    file won't be noticed by innd; only stopping and restarting innd can
-    cause it to be reloaded.
-
-    filter_innd.pl, on the other hand, can be reloaded on command (with
-    "ctlinnd reload filter.perl 'reason'").  Whenever filter_innd.pl is
-    loaded, including the first time at innd startup, the Perl function
-    filter_before_reload() is called before it's reloaded and the function
-    filter_after_reload() is called after it's reloaded (if the functions
-    exist).  Additionally, any code in either startup_innd.pl or
-    filter_innd.pl at the top level (in other words, not inside a sub { })
-    is automatically executed by Perl when the files are loaded.
-
-    This allows one to do things like write out filter statistics whenever
-    the filter is reloaded, load a cache into memory, flush cached data to
-    disk, or other similar operations that should only happen at particular
-    times or with manual intervention.  Remember, any code not inside
-    functions in startup_innd.pl is executed when that file is loaded, and
-    it's loaded only once when innd first starts.  That makes it the ideal
-    place to put initialization code that should only run once, or code to
-    load data that was preserved on disk across a stop and restart of innd
-    (perhaps using filter_mode() -- see below).
-
-    As mentioned above, "ctlinnd reload filter.perl 'reason'" (or "ctlinnd
-    reload all 'reason'") will cause filter_innd.pl to be reloaded.  If the
-    function filter_art() is defined after the file has been reloaded,
-    filtering is turned on.  Otherwise, filtering is turned off.  (Note that
-    due to the way Perl stores functions, once you've defined filter_art(),
-    you can't undefine it just by deleting it from the file and reloading
-    the filter.  You'll need to replace it with an empty sub.)
-
-    The Perl function filter_art() is the heart of a Perl filter.  Whenever
-    an article is received from a peer, via either IHAVE or TAKETHIS,
-    filter_art() is called if Perl filtering is turned on.  It receives no
-    arguments, and should return a single scalar value.  That value should
-    be the empty string to indicate that INN should accept the article, or
-    some rejection message to indicate that the article should be rejected.
-
-    filter_art() has access to a global hash named %hdr, which contains all
-    of the standard headers present in the article and their values.  The
-    standard headers are:
-
-        Also-Control, Approved, Bytes, Cancel-Key, Cancel-Lock,
-        Content-Base, Content-Disposition, Content-Transfer-Encoding,
-        Content-Type, Control, Date, Date-Received, Distribution, Expires,
-        Face, Followup-To, From, In-Reply-To, Injection-Date, Injection-Info,
-        Keywords, Lines, List-ID, Message-ID, MIME-Version, Newsgroups,
-        NNTP-Posting-Date, NNTP-Posting-Host, Organization, Originator,
-        Path, Posted, Posting-Version, Received, References, Relay-Version,
-        Reply-To, Sender, Subject, Supersedes, User-Agent,
-        X-Auth, X-Canceled-By, X-Cancelled-By, X-Complaints-To, X-Face,
-        X-HTTP-UserAgent, X-HTTP-Via, X-Mailer, X-Modbot, X-Modtrace,
-        X-Newsposter, X-Newsreader, X-No-Archive, X-Original-Message-ID,
-        X-Original-Trace, X-Originating-IP, X-PGP-Key, X-PGP-Sig,
-        X-Poster-Trace, X-Postfilter, X-Proxy-User, X-Submissions-To,
-        X-Trace, X-Usenet-Provider, Xref.
-
-    Note that all the above headers are as they arrived, not modified by
-    your INN (especially, the Xref: header, if present, is the one of the
-    remote site which sent you the article, and not yours).
-
-    For example, the Newsgroups: header of the article is accessible inside
-    the Perl filter as $hdr{'Newsgroups'}.  In addition, $hdr{'__BODY__'}
-    will contain the full body of the article and $hdr{'__LINES__'} will
-    contain the number of lines in the body of the article.
-
-    The contents of the %hdr hash for a typical article may therefore look
-    something like this:
-
-        %hdr = (Subject      => 'MAKE MONEY FAST!!', 
-            From         => 'Joe Spamer <him@example.com>',
-            Date         => '10 Sep 1996 15:32:28 UTC',
-            Newsgroups   => 'alt.test',
-            Path         => 'news.example.com!not-for-mail',
-            Organization => 'Spammers Anonymous',
-            Lines        => '5',
-            Distribution => 'usa',
-            'Message-ID' => '<6.20232.842369548@example.com>',
-            __BODY__     => 'Send five dollars to the ISC, c/o ...',
-            __LINES__    => 5
-        );
-
-    Note that the value of $hdr{Lines} is the contents of the Lines: header
-    of the article and may bear no resemblence to the actual length of the
-    article.  $hdr{__LINES__} is the line count calculated by INN, and is
-    guaranteed to be accurate.
-
-    The %hdr hash should not be modified inside filter_art().  Instead, if
-    any of the contents need to be modified temporarily during filtering
-    (smashing case, for example), copy them into a seperate variable first
-    and perform the modifications on the copy.  Currently, $hdr{__BODY__} is
-    the only data that will cause your filter to die if you modify it, but
-    in the future other keys may also contain live data.  Modifying live INN
-    data in Perl will hopefully only cause a fatal exception in your Perl
-    code that disables Perl filtering until you fix it, but it's possible
-    for it to cause article munging or even core dumps in INN.  So always,
-    always make a copy first.
-
-    As mentioned above, if filter_art() returns the empty string (''), the
-    article is accepted.  Note that this must be the empty string, not 0 or
-    undef.  Otherwise, the article is rejected, and whatever scalar
-    filter_art() returns (typically a string) will be taken as the reason
-    why the article was rejected.  This reason will be returned to the
-    remote peer as well as logged to the news logs.  (innreport, in its
-    nightly report, will summarize the number of articles rejected by the
-    Perl filter and include a count of how many articles were rejected with
-    each reason string.)
-
-    One other type of filtering is also supported.  If Perl filtering is
-    turned on and the Perl function filter_messageid() is defined, that
-    function will be called for each message ID received from a peer (via
-    either CHECK or IHAVE).  The function receives a single argument, the
-    message ID, and like filter_art() should return an empty string to
-    accept the article or an error string to refuse the article.  This
-    function is called before any history lookups and for every article
-    offered to innd with CHECK or IHAVE (before the actual article is sent).
-    Accordingly, the message ID is the only information it has about the
-    article (the %hdr hash will be empty).  This code would sit in a
-    performance-critical hot path in a typical server, and therefore should
-    be as fast as possible, but it can do things like refuse articles from
-    certain hosts or cancels for already rejected articles (if they follow
-    the $alz convention) without having to take the network bandwidth hit of
-    accepting the entire article first.
-
-    Note that you cannot rely on filter_messageid() being called for every
-    incoming article; articles sent via TAKETHIS without an earlier CHECK
-    will never pass through filter_messageid() and will only go through
-    filter_art().
-
-    Finally, whenever ctlinnd throttle, ctlinnd pause, or ctlinnd go is run,
-    the Perl function filter_mode() is called if it exists.  It receives no
-    arguments and returns no value, but it has access to a global hash %mode
-    that contains three values:
-
-        Mode       The current server mode (throttled, paused, or running)
-        NewMode    The new mode the server is going to
-        reason     The reason that was given to ctlinnd
-
-    One possible use for this function is to save filter state across a
-    restart of innd.  There isn't any Perl function which is called when INN
-    shuts down, but using filter_mode() the Perl filter can dump it's state
-    to disk whenever INN is throttled.  Then, if the news administrator
-    follows the strongly recommended shutdown procedure of throttling the
-    server before shutting it down, the filter state will be safely saved to
-    disk and can be reloaded when innd restarts (possibly by
-    startup_innd.pl).
-
-    The state of the Perl interpretor in which all of these Perl functions
-    run is preserved over the lifetime of innd.  In other words, it's
-    permissible for the Perl code to create its own global Perl variables,
-    data structures, saved state, and the like, and all of that will be
-    available to filter_art() and filter_messageid() each time they're
-    called.  The only variable INN fiddles with (or pays any attention to at
-    all) is %hdr, which is cleared after each call to filter_art().
-
-    Perl filtering can be turned off with "ctlinnd perl n" and back on again
-    with "ctlinnd perl y".  Perl filtering is turned off automatically if
-    loading of the filter fails or if the filter code returns any sort of a
-    fatal error (either due to Perl itself or due to a "die" in the Perl
-    code).
-
-Supported innd Callbacks
-
-    innd makes seven functions available to any of its embedded Perl code. 
-    Those are:
-
-    INN::addhist(*messageid*, *arrival*, *articledate*, *expire*, *paths*)
-        Adds *messageid* to the history database.  All of the arguments
-        except the first one are optional; the times default to the current
-        time and the paths field defaults to the empty string.  (For those
-        unfamiliar with the fields of a history(5) database entry, the
-        *arrival* is normally the time at which the server accepts the
-        article, the *articledate* is from the Date header of the article,
-        the *expire* is from the Expires header of the article, and the
-        *paths* field is the storage API token.  All three times as measured
-        as a time_t since the epoch.)  Returns true on success, false
-        otherwise.
-
-    INN::article(*messageid*)
-        Returns the full article (as a simple string) identified by
-        *messageid*, or undef if it isn't found.  Each line will end with a
-        simple \n, but leading periods may still be doubled if the article
-        is stored in wire format.
-
-    INN::cancel(*messageid*)
-        Cancels *messageid*.  (This is equivalent to "ctlinnd cancel"; it
-        cancels the message on the local server, but doesn't post a cancel
-        message or do anything else that affects anything other than the
-        local server.) Returns true on success, false otherwise.
-
-    INN::filesfor(*messageid*)
-        Returns the *paths* field of the history entry for the given
-        *messageid*.  This will be the storage API token for the message. 
-        If *messageid* isn't found in the history database, returns undef.
-
-    INN::havehist(*messageid*)
-        Looks up *messageid* in the history database and returns true if
-        it's found, false otherwise.
-
-    INN::head(*messageid*)
-        Returns the header (as a simple string) of the article identified by
-        *messageid*, or undef if it isn't found.  Each line will end with a
-        simple \n (in other words, regardless of the format of article
-        storage, the returned string won't be in wire format).
-
-    INN::newsgroup(*newsgroup*)
-        Returns the status of *newsgroup* (the last field of the active file
-        entry for that newsgroup).  See active(5) for a description of the
-        possible values and their meanings (the most common are "y" for an
-        unmoderated group and "m" for a moderated group).  If *newsgroup*
-        isn't in the active file, returns undef.
-
-    These functions can only be used from inside the innd Perl filter;
-    they're not available in the nnrpd filter.
-
-Common Callbacks
-
-    The following additional function is available from inside filters
-    embedded in innd, and is also available from filters embedded in nnrpd
-    (see below):
-
-    INN::syslog(level, message)
-        Logs a message via syslog(2).  This is quite a bit more reliable and
-        portable than trying to use Sys::Syslog from inside the Perl filter.
-        Only the first character of the level argument matters; the valid
-        letters are the first letters of ALERT, CRIT, ERR, WARNING, NOTICE,
-        INFO, and DEBUG (case-insensitive) and specify the priority at which
-        the message is logged.  If a level that doesn't match any of those
-        levels is given, the default priority level is LOG_NOTICE.  The
-        second argument is the message to log; it will be prefixed by
-        "filter: " and logged to syslog with facility LOG_NEWS.
-
-The nnrpd Posting Filter
-
-    Whenever Perl support is needed in nnrpd, it first loads the file
-    _PATH_PERL_FILTER_NNRPD (defined in include/paths.h, by default
-    filter_nnrpd.pl).  This file must be located in the directory specified
-    by pathfilter in inn.conf (/usr/local/news/bin/filter by default).  The
-    default directory for filter code can be specified at configure time by
-    giving the flag --with-filter-dir to configure.
-
-    If filter_nnrpd.pl loads successfully and defines the Perl function
-    filter_post(), Perl filtering is turned on.  Otherwise, it's turned off.
-    If filter_post() ever returns a fatal error (either from Perl or from a
-    "die" in the Perl code), Perl filtering is turned off for the life of
-    that nnrpd process and any further posts made during that session won't
-    go through the filter.
-
-    While Perl filtering is on, every article received by nnrpd via the POST
-    command is passed to the filter_post() Perl function before it is passed
-    to INN (or mailed to the moderator of a moderated newsgroup).  If
-    filter_post() returns an empty string (''), the article is accepted and
-    normal processing of it continues.  Otherwise, the article is rejected
-    and the string returned by filter_post() is returned to the client as
-    the error message (with some exceptions; see below).
-
-    filter_post() has access to a global hash %hdr, which contains all of
-    the headers of the article.  (Unlike the innd Perl filter, %hdr for the
-    nnrpd Perl filter contains *all* of the headers, not just the standard
-    ones.  If any of the headers are duplicated, though, %hdr will contain
-    only the value of the last occurance of the header.  nnrpd will reject
-    the article before the filter runs if any of the standard headers are
-    duplicated.)  It also has access to the full body of the article in the
-    variable $body, and if the poster authenticated via AUTHINFO (or if
-    either Perl authentication or a readers.conf authentication method is
-    used and produces user information), it has access to the authenticated
-    username of the poster in the variable $user.
-
-    Unlike the innd Perl filter, the nnrpd Perl filter can modify the %hdr
-    hash.  In fact, if the Perl variable $modify_headers is set to true
-    after filter_post() returns, the contents of the %hdr hash will be
-    written back to the article replacing the original headers. 
-    filter_post() can therefore make any modifications it wishes to the
-    headers and those modifications will be reflected in the article as it's
-    finally posted.  The article body cannot be modified in this way; any
-    changes to $body will just be ignored.
-
-    Be careful when using the ability to modify headers.  filter_post() runs
-    after all the normal consistency checks on the headers and after server
-    supplied headers (like Message-ID: and Date:) are filled in.  Deleting
-    required headers or modifying headers that need to follow a strict
-    format can result in nnrpd trying to post nonsense articles (which will
-    probably then be rejected by innd).  If $modify_headers is set,
-    *everything* in the %hdr hash is taken to be article headers and added
-    to the article.
-
-    If filter_post() returns something other than the empty string, this
-    message is normally returned to the client as an error.  There are two
-    exceptions:  If the string returned begins with "DROP", the post will be
-    silently discarded and success returned to the client.  If the string
-    begins with "SPOOL", success is returned to the client, but the post is
-    saved in a directory named "spam" under the directory specified by
-    pathincoming in inn.conf (in a directory named "spam/mod" if the post is
-    to a moderated group).  This is intended to allow manual inspection of
-    the suspect messages; if they should be posted, they can be manually
-    moved out of the subdirectory to the directory specified by pathincoming
-    in inn.conf, where they can be posted by running "rnews -U".  If you use
-    this functionality, make sure those directories exist.
-
-Changes to Perl Authentication Support for nnrpd
-
-    The old authentication functionality has been combined with the new
-    readers.conf mechanism by Erik Klavon <erik@eriq.org>; bug reports
-    should however go to inn-bugs@isc.org, not Erik.
-
-    The remainder of this section is an introduction to the new mechanism
-    (which uses the perl_auth: and perl_access: readers.conf parameters)
-    with porting/migration suggestions for people familiar with the old
-    mechanism (identifiable by the nnrpperlauth: parameter in inn.conf).
-
-    Other people should skip this section.
-
-    The perl_auth parameter allows the use of Perl to authenticate a user. 
-    Scripts (like those from the old mechanism) are listed in readers.conf
-    using perl_auth in the same manner other authenticators are using auth:
-
-        perl_auth: "/path/to/script/auth1.pl"
-
-    The file given as argument to perl_auth should contain the same
-    procedures as before. The global hash %attributes remains the same,
-    except for the removal of the "type" entry which is no longer needed in
-    this modification and the addition of several new entries (port,
-    intipaddr, intport) described below. The return array now only contains
-    either two or three elements, the first of which is the NNTP return
-    code. The second is an error string which is passed to the client if the
-    error code indicates that the authentication attempt has failed. This
-    allows a specific error message to be generated by the perl script in
-    place of "Authentication failed". An optional third return element if
-    present will be used to match the connection with the users: parameter
-    in access groups and will also be the username logged. If this element
-    is absent, the username supplied by the client during authentication
-    will be used as was the previous behavior.
-
-    The perl_access parameter (described below) is also new; it allows the
-    dynamic generation of an access group for an incoming connection using a
-    Perl script.  If a connection matches an auth group which has a
-    perl_access parameter, all access groups in readers.conf are ignored;
-    instead the procedure described below is used to generate an access
-    group.  This concept is due to Jeffrey M. Vinocur.
-
-    The new functionality should provide all of the existing capabilities of
-    the Perl hook, in combination with the flexibility of readers.conf and
-    the use of other authentication and resolving programs.  To use Perl
-    authentication code that predates the readers.conf mechanism, you would
-    need to modify the code slightly (see below for the new specification)
-    and supply a simple readers.conf file.  If you don't want to modify your
-    code, the samples directory has nnrpd_auth_wrapper.pl and
-    nnrpd_access_wrapper.pl which should allow you to use your old code
-    without needing to change it.
-
-    However, before trying to use your old Perl code, you may want to
-    consider replacing it entirely with non-Perl authentication.  (With
-    readers.conf and the regular authenticator and resolver programs, much
-    of what once required Perl can be done directly.)  Even if the
-    functionality is not available directly, you may wish to write a new
-    authenticator or resolver (which can be done in whatever language you
-    prefer to work in).
-
-Perl Authentication Support for nnrpd
-
-    Support for authentication via Perl is provided in nnrpd by the
-    inclusion of a perl_auth: parameter in a readers.conf auth group.
-    perl_auth: works exactly like the auth: parameter in readers.conf,
-    except that it calls the script given as argument using the Perl hook
-    rather then treating it as an external program.
-
-    If the processing of readers.conf requires that a perl_auth: statement
-    be used for authentication, Perl is loaded (if it has yet to be) and the
-    file given as argument to the perl_auth: parameter is loaded as well. If
-    a Perl function auth_init() is defined by that file, it is called
-    immediately after the file is loaded.  It takes no arguments and returns
-    nothing.
-
-    Provided the file loads without errors, auth_init() (if present) runs
-    without fatal errors, and a Perl function authenticate() is defined,
-    authenticate() will then be called. authenticate() takes no arguments,
-    but it has access to a global hash %attributes which contains
-    information about the connection as follows: $attributes{hostname} will
-    contain the hostname (or the IP address if it doesn't resolve) of the
-    client machine, $attributes{ipaddress} will contain its IP address (as a
-    string), $attributes{port} will contain the client port (as an integer),
-    $attributes{interface} contains the hostname of the interface the client
-    connected on, $attributes{intipaddr} contains the IP address (as a
-    string) of the interface the client connected on, $attributes{intport}
-    contains the port (as an integer) on the interface the client connected
-    on, $attributes{username} will contain the provided username and
-    $attributes{password} the password.
-
-    authenticate() should return a two or three element array.  The first
-    element is the NNTP response code to return to the client, the second
-    element is an error string which is passed to the client if the response
-    code indicates that the authentication attempt has failed. An optional
-    third return element if present will be used to match the connection
-    with the users: parameter in access groups and will also be the username
-    logged. If this element is absent, the username supplied by the client
-    during authentication will be used for matching and logging.
-
-    The NNTP response code should probably be either 281 (authentication
-    successful) or 502 (authentication unsuccessful).  If the code returned
-    is anything other than 281, nnrpd will print an authentication error
-    message and drop the connection and exit.
-
-    If authenticate() dies (either due to a Perl error or due to calling
-    die), or if it returns anything other than the two or three element
-    array described above, an internal error will be reported to the client,
-    the exact error will be logged to syslog, and nnrpd will drop the
-    connection and exit.
-
-Dynamic Generation of Access Groups
-
-    A Perl script may be used to dynamically generate an access group which
-    is then used to determine the access rights of the client. This occurs
-    whenever the perl_access: is specified in an auth group which has
-    successfully matched the client. Only one perl_access: statement is
-    allowed in an auth group. This parameter should not be mixed with a
-    python_access: statement in the same auth group.
-
-    When a perl_access: parameter is encountered, Perl is loaded (if it has
-    yet to be) and the file given as argument is loaded as well. Provided
-    the file loads without errors, and a Perl function access() is defined,
-    access() will then be called. access() takes no arguments, but it has
-    access to a global hash %attributes which contains information about the
-    connection as follows: $attributes{hostname} will contain the hostname
-    (or the IP address if it doesn't resolve) of the client machine,
-    $attributes{ipaddress} will contain its IP address (as a string),
-    $attributes{port} will contain the client port (as an integer),
-    $attributes{interface} contains the hostname of the interface the client
-    connected on, $attributes{intipaddr} contains the IP address (as a
-    string) of the interface the client connected on, $attributes{intport}
-    contains the port (as an integer) on the interface the client connected
-    on, $attributes{username} will contain the provided username and domain
-    (in username@domain form).
-
-    access() returns a hash, containing the desired access parameters and
-    values.  Here is an untested example showing how to dynamically generate
-    a list of newsgroups based on the client's username and domain.
-
-         my %hosts = ( "example.com" => "example.*", "isc.org" => "isc.*" );
-
-         sub access {
-            %return_hash = (
-               "max_rate" => "10000",
-               "addnntppostinghost" => "true",
-         #     ...
-            );
-            if( defined $attributes{username} &&
-                $attributes{username} =~ /.*@(.*)/ )
-            {
-               $return_hash{"virtualhost"} = "true";
-               $return_hash{"path"} = $1;
-               $return_hash{"newsgroups"} = $hosts{$1};
-            } else {
-               $return_hash{"read"} = "*";
-               $return_hash{"post"} = "local.*"
-            }
-            return %return_hash;
-         }
-
-    Note that both the keys and values are quoted strings. These values are
-    to be returned to a C program and must be quoted strings. For values
-    containing one or more spaces, it is not necessary to include extra
-    quotes inside the string.
-
-    While you may include the users: parameter in a dynamically generated
-    access group, some care should be taken (unless your pattern is just *
-    which is equivalent to leaving the parameter out). The group created
-    with the values returned from the Perl script is the only one considered
-    when nnrpd attempts to find an access group matching the connection. If
-    a users: parameter is included and it doesn't match the connection, then
-    the client will be denied access since there are no other access groups
-    which could match the connection.
-
-    If access() dies (either due to a Perl error or due to calling die), or
-    if it returns anything other than a hash as described above, an internal
-    error will be reported to the client, the exact error will be logged to
-    syslog, and nnrpd will drop the connection and exit.
-
-Notes on Writing Embedded Perl
-
-    All Perl evaluation is done inside an implicit eval block, so calling
-    die in Perl code will not kill the innd or nnrpd process.  Neither will
-    Perl errors (such as syntax errors).  However, such errors will have
-    negative effects (fatal errors in the innd or nnrpd filter will cause
-    filtering to be disabled, and fatal errors in the nnrpd authentication
-    code will cause the client connection to be terminated).
-
-    Calling exit directly, however, *will* kill the innd or nnrpd process,
-    so don't do that.  Similarly, you probably don't want to call fork (or
-    any other function that results in a fork such as system,
-    IPC::Open3::open3(), or any use of backticks) since there are possibly
-    unflushed buffers that could get flushed twice, lots of open state that
-    may not get closed properly, and innumerable other potential problems. 
-    In general, be aware that all Perl code is running inside a large and
-    complicated C program, and Perl code that impacts the process as a whole
-    is best avoided.
-
-    You can use print and warn inside Perl code to send output to STDOUT or
-    STDERR, but you probably shouldn't.  Instead, open a log file and print
-    to it instead (or, in the innd filter, use INN::syslog() to write
-    messages via syslog like the rest of INN).  If you write to STDOUT or
-    STDERR, where that data will go depends on where the filter is running;
-    inside innd, it will go to the news log or the errlog, and inside nnrpd
-    it will probably go nowhere but could go to the client.  The nnrpd
-    filter takes some steps to try to keep output from going across the
-    network connection to the client (which would probably result in a very
-    confused client), but best not to take the chance.
-
-    For similar reasons, try to make your Perl code -w clean, since Perl
-    warnings are written to STDERR.  (INN won't run your code under -w, but
-    better safe than sorry, and some versions of Perl have some mandatory
-    warnings you can't turn off.)
-
-    You *can* use modules in your Perl code, just like you would in an
-    ordinary Perl script.  You can even use modules that dynamically load C
-    code.  Just make sure that none of the modules you use go off behind
-    your back to do any of the things above that are best avoided.
-
-    Whenever you make any modifications to the Perl code, and particularly
-    before starting INN or reloading filter.perl with new code, you should
-    run perl -wc on the file.  This will at least make sure you don't have
-    any glaring syntax errors.  Remember, if there are errors in your code,
-    filtering will be disabled, which could mean that posts you really
-    wanted to reject will leak through and authentication of readers may be
-    totally broken.
-
-    The samples directory has example startup_innd.pl, filter_innd.pl,
-    filter_nnrpd.pl, and nnrpd_auth.pl files that contain some simplistic
-    examples.  Look them over as a starting point when writing your own.
-
-Available Packages
-
-    This is an unofficial list of known filtering packages at the time of
-    publication.  This is not an endorsement of these filters by the ISC or
-    the INN developers, but is included as assistance in locating packages
-    which make use of this filter mechanism.
-
-      CleanFeed               Jeremy Nixon <jeremy@exit109.com>
-      <URL:http://www.exit109.com/~jeremy/news/cleanfeed.html>
-            A spam filter catching excessive multi-posting and a host of
-            other things.  Uses filter_innd.pl exclusively, requires the MD5
-            Perl module.  Probably the most popular and widely-used Perl
-            filter around.
-
-      Usenet II Filter        Edward S. Marshall <emarshal@xnet.com>
-      <URL:http://www.xnet.com/~emarshal/inn/filter_nnrpd.pl>
-            Checks for "soundness" according to Usenet II guidelines in the
-            net.* hierarchy.  Designed to use filter_nnrpd.pl.
-
-      News Gizmo              Aidan Cully <aidan@panix.com>
-      <URL:http://www.panix.com/gizmo/>
-            A posting filter for helping a site enforce Usenet-II soundness,
-            and for quotaing the number of messages any user can post to
-            Usenet daily.
diff --git a/doc/hook-python b/doc/hook-python
deleted file mode 100644 (file)
index f6ef5c0..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-INN Python Filtering and Authentication Support
-
-    This file documents INN's built-in optional support for Python article
-    filtering.  It is patterned after the Perl and (now obsolete) TCL hooks
-    previously added by Bob Heiney and Christophe Wolfhugel.
-
-    For this filter to work successfully, you will need to have at least
-    Python 1.5.2 installed.  You can obtain it from
-    <http://www.python.org/>.
-
-    The innd Python interface and the original Python filtering
-    documentation were written by Greg Andruk (nee Fluffy)
-    <gerglery@usa.net>.  The Python authentication and authorization support
-    for nnrpd as well as the original documentation for it were written by
-    Ilya Etingof <ilya@glas.net> in December 1999.
-
-Installation
-
-    Once you have built and installed Python, you can cause INN to use it by
-    adding the --with-python switch to your "configure" command.  You will
-    need to have all the headers and libraries required for embedding Python
-    into INN; they can be found in Python development packages, which
-    include header files and static libraries.
-
-    You will then be able to use Python authentication, dynamic access group
-    generation and dynamic access control support in nnrpd along with
-    filtering support in innd.
-
-    See the ctlinnd(8) manual page to learn how to enable, disable and
-    reload Python filters on a running server (especially "ctlinnd mode",
-    "ctlinnd python y|n" and "ctlinnd reload filter.python 'reason'").
-
-    Also, see the filter_innd.py, nnrpd_auth.py, nnrpd_access.py and
-    nnrpd_dynamic.py samples in your filters directory for a demonstration
-    of how to get all this working.
-
-Writing an innd Filter
-
-  Introduction
-
-    You need to create a filter_innd.py module in INN's filter directory
-    (see the *pathfilter* setting in inn.conf).  A heavily-commented sample
-    is provided; you can use it as a template for your own filter.  There is
-    also an INN.py module there which is not actually used by INN; it is
-    there so you can test your module interactively.
-
-    First, define a class containing the methods you want to provide to
-    innd.  Methods innd will use if present are:
-
-    __init__(*self*)
-        Not explicitly called by innd, but will run whenever the filter
-        module is (re)loaded.  This is a good place to initialize constants
-        or pick up where "filter_before_reload" or "filter_close" left off.
-
-    filter_before_reload(*self*)
-        This will execute any time a "ctlinnd reload all 'reason'" or
-        "ctlinnd reload filter.python 'reason'" command is issued.  You can
-        use it to save statistics or reports for use after reloading.
-
-    filter_close(*self*)
-        This will run when a "ctlinnd shutdown 'reason'" command is
-        received.
-
-    filter_art(*self*, *art*)
-        *art* is a dictionary containing an article's headers and body. 
-        This method is called every time innd receives an article.  The
-        following can be defined:
-
-            Also-Control, Approved, Bytes, Cancel-Key, Cancel-Lock,
-            Content-Base, Content-Disposition, Content-Transfer-Encoding,
-            Content-Type, Control, Date, Date-Received, Distribution, Expires,
-            Face, Followup-To, From, In-Reply-To, Injection-Date, Injection-Info,
-            Keywords, Lines, List-ID, Message-ID, MIME-Version, Newsgroups,
-            NNTP-Posting-Date, NNTP-Posting-Host, Organization, Originator,
-            Path, Posted, Posting-Version, Received, References, Relay-Version,
-            Reply-To, Sender, Subject, Supersedes, User-Agent,
-            X-Auth, X-Canceled-By, X-Cancelled-By, X-Complaints-To, X-Face,
-            X-HTTP-UserAgent, X-HTTP-Via, X-Mailer, X-Modbot, X-Modtrace,
-            X-Newsposter, X-Newsreader, X-No-Archive, X-Original-Message-ID,
-            X-Original-Trace, X-Originating-IP, X-PGP-Key, X-PGP-Sig,
-            X-Poster-Trace, X-Postfilter, X-Proxy-User, X-Submissions-To,
-            X-Trace, X-Usenet-Provider, Xref, __BODY__, __LINES__.
-
-        Note that all the above values are as they arrived, not modified by
-        your INN (especially, the Xref: header, if present, is the one of
-        the remote site which sent you the article, and not yours).
-
-        These values will be buffer objects holding the contents of the same
-        named article headers, except for the special "__BODY__" and
-        "__LINES__" items.  Items not present in the article will contain
-        "None".
-
-        "art('__BODY__')" is a buffer object containing the article's entire
-        body, and "art('__LINES__')" is an int holding innd's reckoning of
-        the number of lines in the article.  All the other elements will be
-        buffers with the contents of the same-named article headers.
-
-        The Newsgroups: header of the article is accessible inside the
-        Python filter as "art['Newsgroups']".
-
-        If you want to accept an article, return "None" or an empty string. 
-        To reject, return a non-empty string.  The rejection strings will be
-        shown to local clients and your peers, so keep that in mind when
-        phrasing your rejection responses.
-
-    filter_messageid(*self*, *msgid*)
-        *msgid* is a buffer object containing the ID of an article being
-        offered by IHAVE or CHECK.  Like with "filter_art", the message will
-        be refused if you return a non-empty string.  If you use this
-        feature, keep it light because it is called at a rather busy place
-        in innd's main loop.  Also, do not rely on this function alone to
-        reject by ID; you should repeat the tests in "filter_art" to catch
-        articles sent with TAKETHIS but no CHECK.
-
-    filter_mode(*self*, *oldmode*, *newmode*, *reason*)
-        When the operator issues a ctlinnd "pause", "throttle", "go",
-        "shutdown" or "xexec" command, this function can be used to do
-        something sensible in accordance with the state change.  Stamp a log
-        file, save your state on throttle, etc.  *oldmode* and *newmode*
-        will be strings containing one of the values in ("running",
-        "throttled", "paused", "shutdown", "unknown").  *oldmode* is the
-        state innd was in before ctlinnd was run, *newmode* is the state
-        innd will be in after the command finishes.  *reason* is the comment
-        string provided on the ctlinnd command line.
-
-  How to Use these Methods with innd
-
-    To register your methods with innd, you need to create an instance of
-    your class, import the built-in INN module, and pass the instance to
-    "INN.set_filter_hook".  For example:
-
-        class Filter:
-            def filter_art(self, art):
-                ...
-                blah blah
-                ...
-
-            def filter_messageid(self, id):
-                ...
-                yadda yadda
-                ...
-
-        import INN
-        myfilter = Filter()
-        INN.set_filter_hook(myfilter)
-
-    When writing and testing your Python filter, don't be afraid to make use
-    of "try:"/"except:" and the provided "INN.syslog" function.  stdout and
-    stderr will be disabled, so your filter will die silently otherwise.
-
-    Also, remember to try importing your module interactively before loading
-    it, to ensure there are no obvious errors.  One typo can ruin your whole
-    filter.  A dummy INN.py module is provided to facilitate testing outside
-    the server.  To test, change into your filter directory and use a
-    command like:
-
-        python -ic 'import INN, filter_innd'
-
-    You can define as many or few of the methods listed above as you want in
-    your filter class (it is fine to define more methods for your own use;
-    innd will not be using them but your filter can).  If you *do* define
-    the above methods, GET THE PARAMETER COUNTS RIGHT.  There are checks in
-    innd to see whether the methods exist and are callable, but if you
-    define one and get the parameter counts wrong, innd WILL DIE.  You have
-    been warned.  Be careful with your return values, too.  The "filter_art"
-    and "filter_messageid" methods have to return strings, or "None".  If
-    you return something like an int, innd will *not* be happy.
-
-  A Note regarding Buffer Objects
-
-    Buffer objects are cousins of strings, new in Python 1.5.2.  Using
-    buffer objects may take some getting used to, but we can create buffers
-    much faster and with less memory than strings.
-
-    For most of the operations you will perform in filters (like
-    "re.search", "string.find", "md5.digest") you can treat buffers just
-    like strings, but there are a few important differences you should know
-    about:
-
-        # Make a string and two buffers.
-        s = "abc"
-        b = buffer("def")
-        bs = buffer("abc")
-
-        s == bs          # - This is false because the types differ...
-        buffer(s) == bs  # - ...but this is true, the types now agree.
-        s == str(bs)     # - This is also true, but buffer() is faster.
-        s[:2] == bs[:2]  # - True.  Buffer slices are strings.
-
-        # While most string methods will take either a buffer or a string,
-        # string.join (in the string module) insists on using only strings.
-        import string
-        string.join([str(b), s], '.')  # Returns 'def.abc'.
-        '.'.join([str(b), s])          # Returns 'def.abc' too.
-        '.'.join([b, s])               # This raises a TypeError.
-
-        e = s + b                      # This raises a TypeError, but...
-
-        # ...these two both return the string 'abcdef'.  The first one
-        # is faster -- choose buffer() over str() whenever you can.
-        e = buffer(s) + b
-        f = s + str(b)
-
-        g = b + '>'                    # This is legal, returns the string 'def>'.
-
-  Functions Supplied by the Built-in innd Module
-
-    Besides "INN.set_filter_hook" which is used to register your methods
-    with innd as it has already been explained above, the following
-    functions are available from Python scripts:
-
-    addhist(*message-id*)
-    article(*message-id*)
-    cancel(*message-id*)
-    havehist(*message-id*)
-    hashstring(*string*)
-    head(*message-id*)
-    newsgroup(*groupname*)
-    syslog(*level*, *message*)
-
-    Therefore, not only can innd use Python, but your filter can use some of
-    innd's features too.  Here is some sample Python code to show what you
-    get with the previously listed functions.
-
-        import INN
-
-        # Python's native syslog module isn't compiled in by default,
-        # so the INN module provides a replacement.  The first parameter
-        # tells the Unix syslogger what severity to use; you can
-        # abbreviate down to one letter and it's case insensitive.
-        # Available levels are (in increasing levels of seriousness)
-        # Debug, Info, Notice, Warning, Err, Crit, and Alert.  (If you
-        # provide any other string, it will be defaulted to Notice.)  The
-        # second parameter is the message text.  The syslog entries will
-        # go to the same log files innd itself uses, with a 'python:'
-        # prefix.
-        syslog('warning', 'I will not buy this record.  It is scratched.')
-        animals = 'eels'
-        vehicle = 'hovercraft'
-        syslog('N', 'My %s is full of %s.' % (vehicle, animals))
-
-        # Let's cancel an article!  This only deletes the message on the
-        # local server; it doesn't send out a control message or anything
-        # scary like that.  Returns 1 if successful, else 0.
-        if INN.cancel('<meow$123.456@solvangpastries.edu>'):
-            cancelled = "yup"
-        else:
-            cancelled = "nope"
-
-        # Check if a given message is in history.  This doesn't
-        # necessarily mean the article is on your spool; cancelled and
-        # expired articles hang around in history for a while, and
-        # rejected articles will be in there if you have enabled
-        # remembertrash in inn.conf.  Returns 1 if found, else 0.
-        if INN.havehist('<z456$789.abc@isc.org>'):
-            comment = "*yawn* I've already seen this article."
-        else:
-            comment = 'Mmm, fresh news.'
-
-        # Here we are running a local spam filter, so why eat all those
-        # cancels?  We can add fake entries to history so they'll get
-        # refused.  Returns 1 on success, 0 on failure.
-        cancelled_id = buffer('<meow$123.456@isc.org>')
-        if INN.addhist("<cancel." + cancelled_id[1:]):
-            thought = "Eat my dust, roadkill!"
-        else:
-            thought = "Darn, someone beat me to it."
-
-        # We can look at the header or all of an article already on spool,
-        # too.  Might be useful for long-memory despamming or
-        # authentication things.  Each is returned (if present) as a
-        # string object; otherwise you'll end up with an empty string.
-        artbody = INN.article('<foo$bar.baz@bungmunch.edu>')
-        artheader = INN.head('<foo$bar.baz@bungmunch.edu>')
-
-        # As we can compute a hash digest for a string, we can obtain one
-        # for artbody.  It might be of help to detect spam.
-        digest = INN.hashstring(artbody)
-
-        # Finally, do you want to see if a given newsgroup is moderated or
-        # whatever?  INN.newsgroup returns the last field of a group's
-        # entry in active as a string.
-        froupflag = INN.newsgroup('alt.fan.karl-malden.nose')
-        if froupflag == '':
-            moderated = 'no such newsgroup'
-        elif froupflag == 'y':
-            moderated = "nope"
-        elif froupflag == 'm':
-            moderated = "yep"
-        else:
-            moderated = "something else"
-
-Writing an nnrpd Filter
-
-  Changes to Python Authentication and Access Control Support for nnrpd
-
-    The old authentication and access control functionality has been
-    combined with the new readers.conf mechanism by Erik Klavon
-    <erik@eriq.org>; bug reports should however go to <inn-bugs@isc.org>,
-    not Erik.
-
-    The remainder of this section is an introduction to the new mechanism
-    (which uses the *python_auth*, *python_access*, and *python_dynamic*
-    readers.conf parameters) with porting/migration suggestions for people
-    familiar with the old mechanism (identifiable by the now deprecated
-    *nnrpperlauth* parameter in inn.conf).
-
-    Other people should skip this section.
-
-    The *python_auth* parameter allows the use of Python to authenticate a
-    user.  Authentication scripts (like those from the old mechanism) are
-    listed in readers.conf using *python_auth* in the same manner other
-    authenticators are using *auth*:
-
-        python_auth: "nnrpd_auth"
-
-    It uses the script named nnrpd_auth.py (note that ".py" is not present
-    in the *python_auth* value).
-
-    Scripts should be placed as before in the filter directory (see the
-    *pathfilter* setting in inn.conf).  The new hook method "authen_init"
-    takes no arguments and its return value is ignored; its purpose is to
-    provide a means for authentication specific initialization.  The hook
-    method "authen_close" is the more specific analogue to the old "close"
-    method.  These two method hooks are not required, contrary to
-    "authenticate", the main method.
-
-    The argument dictionary passed to "authenticate" remains the same,
-    except for the removal of the *type* entry which is no longer needed in
-    this modification and the addition of several new entries (*port*,
-    *intipaddr*, *intport*) described below.  The return tuple now only
-    contains either two or three elements, the first of which is the NNTP
-    response code.  The second is an error string which is passed to the
-    client if the response code indicates that the authentication attempt
-    has failed.  This allows a specific error message to be generated by the
-    Python script in place of the generic message "Authentication failed". 
-    An optional third return element, if present, will be used to match the
-    connection with the *user* parameter in access groups and will also be
-    the username logged.  If this element is absent, the username supplied
-    by the client during authentication will be used, as was the previous
-    behaviour.
-
-    The *python_access* parameter (described below) is new; it allows the
-    dynamic generation of an access group of an incoming connection using a
-    Python script.  If a connection matches an auth group which has a
-    *python_access* parameter, all access groups in readers.conf are
-    ignored; instead the procedure described below is used to generate an
-    access group.  This concept is due to Jeffrey M. Vinocur and you can add
-    this line to readers.conf in order to use the nnrpd_access.py Python
-    script in *pathfilter*:
-
-        python_access: "nnrpd_access"
-
-    In the old implementation, the authorization method allowed for access
-    control on a per-group basis.  That functionality is preserved in the
-    new implementation by the inclusion of the *python_dynamic* parameter in
-    readers.conf.  The only change is the corresponding method name of
-    "dynamic" as opposed to "authorize".  Additionally, the associated
-    optional housekeeping methods "dynamic_init" and "dynamic_close" may be
-    implemented if needed.  In order to use nnrpd_dynamic.py in
-    *pathfilter*, you can add this line to readers.conf:
-
-        python_dynamic: "nnrpd_dynamic"
-
-    This new implementation should provide all of the previous capabilities
-    of the Python hooks, in combination with the flexibility of readers.conf
-    and the use of other authentication and resolving programs (including
-    the Perl hooks!).  To use Python code that predates the new mechanism,
-    you would need to modify the code slightly (see below for the new
-    specification) and supply a simple readers.conf file.  If you do not
-    want to modify your code, the sample directory has
-    nnrpd_auth_wrapper.py, nnrpd_access_wrapper.py and
-    nnrpd_dynamic_wrapper.py which should allow you to use your old code
-    without needing to change it.
-
-    However, before trying to use your old Python code, you may want to
-    consider replacing it entirely with non-Python authentication.  (With
-    readers.conf and the regular authenticator and resolver programs, much
-    of what once required Python can be done directly.)  Even if the
-    functionality is not available directly, you may wish to write a new
-    authenticator or resolver (which can be done in whatever language you
-    prefer).
-
-  Python Authentication Support for nnrpd
-
-    Support for authentication via Python is provided in nnrpd by the
-    inclusion of a *python_auth* parameter in a readers.conf auth group. 
-    *python_auth* works exactly like the *auth* parameter in readers.conf,
-    except that it calls the script given as argument using the Python hook
-    rather then treating it as an external program.  Multiple, mixed use of
-    *python_auth* with other *auth* statements including *perl_auth* is
-    permitted.  Each *auth* statement will be tried in the order they appear
-    in the auth group until either one succeeds or all are exhausted.
-
-    If the processing of readers.conf requires that a *python_auth*
-    statement be used for authentication, Python is loaded (if it has yet to
-    be) and the file given as argument to the *python_auth* parameter is
-    loaded as well (do not include the ".py" extension of this file in the
-    value of *python_auth*).  If a Python object with a method "authen_init"
-    is hooked in during the loading of that file, then that method is called
-    immediately after the file is loaded.  If no errors have occurred, the
-    method "authenticate" is called.  Depending on the NNTP response code
-    returned by "authenticate", the authentication hook either succeeds or
-    fails, after which the processing of the auth group continues as usual. 
-    When the connection with the client is closed, the method "authen_close"
-    is called if it exists.
-
-  Dynamic Generation of Access Groups
-
-    A Python script may be used to dynamically generate an access group
-    which is then used to determine the access rights of the client.  This
-    occurs whenever the *python_access* parameter is specified in an auth
-    group which has successfully matched the client.  Only one
-    *python_access* statement is allowed in an auth group.  This parameter
-    should not be mixed with a *perl_access* statement in the same auth
-    group.
-
-    When a *python_access* parameter is encountered, Python is loaded (if it
-    has yet to be) and the file given as argument is loaded as well (do not
-    include the ".py" extension of this file in the value of
-    *python_access*).  If a Python object with a method "access_init" is
-    hooked in during the loading of that file, then that method is called
-    immediately after the file is loaded.  If no errors have occurred, the
-    method "access" is called.  The dictionary returned by "access" is used
-    to generate an access group that is then used to determine the access
-    rights of the client.  When the connection with the client is closed,
-    the method "access_close" is called, if it exists.
-
-    While you may include the *users* parameter in a dynamically generated
-    access group, some care should be taken (unless your pattern is just "*"
-    which is equivalent to leaving the parameter out).  The group created
-    with the values returned from the Python script is the only one
-    considered when nnrpd attempts to find an access group matching the
-    connection.  If a *users* parameter is included and it does not match
-    the connection, then the client will be denied access since there are no
-    other access groups which could match the connection.
-
-  Dynamic Access Control
-
-    If you need to have access control rules applied immediately without
-    having to restart all the nnrpd processes, you may apply access control
-    on a per newsgroup basis using the Python dynamic hooks (as opposed to
-    readers.conf, which does the same on per user basis).  These hooks are
-    activated through the inclusion of the *python_dynamic* parameter in a
-    readers.conf auth group.  Only one *python_dynamic* statement is allowed
-    in an auth group.
-
-    When a *python_dynamic* parameter is encountered, Python is loaded (if
-    it has yet to be) and the file given as argument is loaded as well (do
-    not include the ".py" extension of this file in the value of
-    *python_dynamic*).  If a Python object with a method "dynamic_init" is
-    hooked in during the loading of that file, then that method is called
-    immediately after the file is loaded.  Every time a reader asks nnrpd to
-    read or post an article, the Python method "dynamic" is invoked before
-    proceeding with the requested operation.  Based on the value returned by
-    "dynamic", the operation is either permitted or denied.  When the
-    connection with the client is closed, the method "access_close" is
-    called if it exists.
-
-  Writing a Python nnrpd Authentication Module
-
-    You need to create a nnrpd_auth.py module in INN's filter directory (see
-    the *pathfilter* setting in inn.conf) where you should define a class
-    holding certain methods depending on which hooks you want to use.
-
-    Note that you will have to use different Python scripts for
-    authentication and access:  the values of *python_auth*, *python_access*
-    and *python_dynamic* have to be distinct for your scripts to work.
-
-    The following methods are known to nnrpd:
-
-    __init__(*self*)
-        Not explicitly called by nnrpd, but will run whenever the auth
-        module is loaded.  Use this method to initialize any general
-        variables or open a common database connection.  This method may be
-        omitted.
-
-    authen_init(*self*)
-        Initialization function specific to authentication.  This method may
-        be omitted.
-
-    authenticate(*self*, *attributes*)
-        Called when a *python_auth* statement is reached in the processing
-        of readers.conf.  Connection attributes are passed in the
-        *attributes* dictionary.  Returns a response code, an error string,
-        and an optional string to be used in place of the client-supplied
-        username (both for logging and for matching the connection with an
-        access group).
-
-    authen_close(*self*)
-        This method is invoked on nnrpd termination.  You can use it to save
-        state information or close a database connection.  This method may
-        be omitted.
-
-    access_init(*self*)
-        Initialization function specific to generation of an access group. 
-        This method may be omitted.
-
-    access(*self*, *attributes*)
-        Called when a *python_access* statement is reached in the processing
-        of readers.conf.  Connection attributes are passed in the
-        *attributes* dictionary.  Returns a dictionary of values
-        representing statements to be included in an access group.
-
-    access_close(*self*)
-        This method is invoked on nnrpd termination.  You can use it to save
-        state information or close a database connection.  This method may
-        be omitted.
-
-    dynamic_init(*self*)
-        Initialization function specific to dynamic access control.  This
-        method may be omitted.
-
-    dynamic(*self*, *attributes*)
-        Called when a client requests a newsgroup, an article or attempts to
-        post.  Connection attributes are passed in the *attributes*
-        dictionary.  Returns "None" to grant access, or a non-empty string
-        (which will be reported back to the client) otherwise.
-
-    dynamic_close(*self*)
-        This method is invoked on nnrpd termination.  You can use it to save
-        state information or close a database connection.  This method may
-        be omitted.
-
-  The *attributes* Dictionary
-
-    The keys and associated values of the *attributes* dictionary are
-    described below.
-
-    *type*
-        "read" or "post" values specify the authentication type; only valid
-        for the "dynamic" method.
-
-    *hostname*
-        It is the resolved hostname (or IP address if resolution fails) of
-        the connected reader.
-
-    *ipaddress*
-        The IP address of the connected reader.
-
-    *port*
-        The port of the connected reader.
-
-    *interface*
-        The hostname of the local endpoint of the NNTP connection.
-
-    *intipaddr*
-        The IP address of the local endpoint of the NNTP connection.
-
-    *intport*
-        The port of the local endpoint of the NNTP connection.
-
-    *user*
-        The username as passed with AUTHINFO command, or "None" if not
-        applicable.
-
-    *pass*
-        The password as passed with AUTHINFO command, or "None" if not
-        applicable.
-
-    *newsgroup*
-        The name of the newsgroup to which the reader requests read or post
-        access; only valid for the "dynamic" method.
-
-    All the above values are buffer objects (see the notes above on what
-    buffer objects are).
-
-  How to Use these Methods with nnrpd
-
-    To register your methods with nnrpd, you need to create an instance of
-    your class, import the built-in nnrpd module, and pass the instance to
-    "nnrpd.set_auth_hook".  For example:
-
-        class AUTH:
-            def authen_init(self):
-                ...
-                blah blah
-                ...
-
-            def authenticate(self, attributes):
-                ...
-                yadda yadda
-                ...
-
-        import nnrpd
-        myauth = AUTH()
-        nnrpd.set_auth_hook(myauth)
-
-    When writing and testing your Python filter, don't be afraid to make use
-    of "try:"/"except:" and the provided "nnrpd.syslog" function.  stdout
-    and stderr will be disabled, so your filter will die silently otherwise.
-
-    Also, remember to try importing your module interactively before loading
-    it, to ensure there are no obvious errors.  One typo can ruin your whole
-    filter.  A dummy nnrpd.py module is provided to facilitate testing
-    outside the server.  It is not actually used by nnrpd but provides the
-    same set of functions as built-in nnrpd module. This stub module may be
-    used when debugging your own module.  To test, change into your filter
-    directory and use a command like:
-
-        python -ic 'import nnrpd, nnrpd_auth'
-
-  Functions Supplied by the Built-in nnrpd Module
-
-    Besides "nnrpd.set_auth_hook" used to pass a reference to the instance
-    of authentication and authorization class to nnrpd, the nnrpd built-in
-    module exports the following function:
-
-    syslog(*level*, *message*)
-        It is intended to be a replacement for a Python native syslog.  It
-        works like "INN.syslog", seen above.
-
-    $Id: hook-python 7926 2008-06-29 08:27:41Z iulius $
-
diff --git a/doc/hook-tcl b/doc/hook-tcl
deleted file mode 100644 (file)
index 14c4f00..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-NOTE:  The Tcl support described in this file is disabled.  The code is
-all still there, but you have to define DO_TCL manually while compiling to
-enable it.  Compiling in Tcl filtering was causing random innd segfaults
-even if no Tcl filters were defined, so it's been turned off to prevent
-confusion.
-
-The Tcl code will be removed in the next major release of INN since no one
-appears to be using it and the code is unmaintained and has no champion.
-If you want to resurrect it, it may be better to start from scratch, since
-a lot has changed about INN since the filters were originally written and
-the Perl and Python filters have far more capabilities.
-
-
-Note, you need tcl 7.4. Rumour has it that 7.5 won't work.
----------------------------------------------------------------------------
-Subject: TCL-based Filtering for INN 1.5
-Date: Mon, 07 Feb 94 12:36:47 -0800
-From: Bob Heiney <heiney@pa.dec.com>
-
-
-Several times in the past few months, a site or two has started posting
-the same article over and over again, but with a different message id. 
-Usually this is caused by broken software (e.g. mail <-> news gateways,
-which many have written, but few have written correctly). 
-Occasionally, however, the reposting is intentional.  A recent example
-would be the "Global Alert: Jesus Is Coming" message which was posted
-to over 2200 newsgroups (each copy with its own message id).
-
-I expect this to happen more often as the Internet continues its explosive
-growth.  Although my site (decwrl) usually has enough excess capacity to
-weather these problems, many other sites cannot.  One problem on
-comp.sys.sgi.misc several months ago spewed 40MB of duplicate articles
-before the offending sites were fixed, and this overflowed the spool at
-many sites.  Even for sites with lots of resources, there's still no need
-to propagate erroneous or malicious duplicates.
-
-I wanted a way to protect my site that was highly specific, flexible, and
-quick.
-
-Examination of duplicated articles showed that although the message ids
-were different, it was usually easy for a news admin to come up with a
-few rules based on the headers of the article that could be used to
-differentiate the duplicates from other articles.  (E.g. from
-John.Doe@foo.com to comp.sys.sgi.misc with 'foobar' in the subject".) 
-I concluded that modifying innd to let me say "kill things that look
-like _this_" would solve my problem.
-
-I also wanted to allow enough flexibilty in the design that I could
-later work on automatic detection and elimination of excessive
-duplicates (using a body checksum instead of headers).
-
-Since I needed a fairly powerful language to do all this, and since the
-world doesn't need yet another special language, my solution was to add TCL
-support to INN.  I then modified "ARTpost" to call a TCL procedure which
-could then accept or reject the article.  The TCL code has access to an
-associative array called "Headers", which contains all of the articles
-headers.  The TCL code may also call a 32-bit article-body checksum
-procedure (this is to aid in future automatic detection of duplicates).
-
-Here's what a sample TCL filter procedure looks like:
-
-proc filter_news {} {
-  global o Headers
-  set sum [checksum_article]
-  puts $o "$Headers(Message-ID) $sum"
-  set newsgroups [split $Headers(Newsgroups) ,]
-  foreach i $newsgroups {
-    if {$i=="alt.test" && [string match "*heiney@pa.dec.com*" $Headers(From)]} {
-      return "dont like alt.test from heiney"
-    }
-  }
-  return "accept"
-}
-
-The above TCL code does a few things.  First it computes a 32-bit
-checksum and writes it and the message ID to a file.  It then rejects
-articles from me to alt.test.
-
-The work I've done is totally integrated into the INN build and runtime
-environments.  For example, to turn filtering off, you'd just type
-
-       ctlinnd filter n
-
-To reload the TCL code that does the filtering, you just say
-
-       ctlinnd reload filter.tcl 'your comment here'
-
-(You may specify TCL callbacks to be executed right before and/or right
-after reloading, in case your filter is doing fancy stuff.)  See the
-ctlinnd man page for more info.
-
-Filtering capability that's this powerful can be used for many
-purposes, some benign and useful (excessive duplicate detections,
-on-the-fly statistics), others abusive.  I would ask that news admins
-think carefully about any filtering they do.
-
-/Bob
-
-
diff --git a/doc/man/Makefile b/doc/man/Makefile
deleted file mode 100644 (file)
index 3e1a758..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-##  $Id: Makefile 7458 2005-12-12 00:25:05Z eagle $
-
-include ../../Makefile.global
-
-top    = ../..
-
-##  Edit these if you need to.
-MANFLAGS = -c $(OWNER) -m 0444 -B .OLD
-
-SEC1   = convdate.1 fastrm.1 getlist.1 grephistory.1 inews.1 innconfval.1 \
-       innfeed.1 innmail.1 nntpget.1 pgpverify.1 pullnews.1 rnews.1 \
-       shlock.1 shrinkfile.1 simpleftp.1 sm.1 startinnfeed.1
-
-SEC3   = clientlib.3 dbz.3 inndcomm.3 libauth.3 libinn.3 libinnhist.3 \
-       libstorage.3 list.3 parsedate.3 qio.3 tst.3 uwildmat.3
-
-SEC5   = active.5 active.times.5 buffindexed.conf.5 control.ctl.5 \
-       cycbuff.conf.5 distrib.pats.5 expire.ctl.5 history.5 incoming.conf.5 \
-       inn.conf.5 innfeed.conf.5 innwatch.ctl.5 moderators.5 motd.news.5 \
-       newsfeeds.5 nnrpd.track.5 newslog.5 nntpsend.ctl.5 ovdb.5 \
-       overview.fmt.5 passwd.nntp.5 radius.conf.5 readers.conf.5 sasl.conf.5 \
-       storage.conf.5 subscriptions.5
-
-SEC8   = actsync.8 actsyncd.8 archive.8 auth_smb.8 batcher.8 buffchan.8 \
-       ckpasswd.8 cnfsheadconf.8 cnfsstat.8 controlchan.8 ctlinnd.8 \
-       cvtbatch.8 domain.8 expire.8 expireover.8 expirerm.8 filechan.8 \
-       ident.8 inncheck.8 innd.8 inndf.8 inndstart.8 innreport.8 innstat.8 \
-       innupgrade.8 innwatch.8 innxbatch.8 innxmit.8 mailpost.8 makedbz.8 \
-       makehistory.8 mod-active.8 news.daily.8 news2mail.8 ninpaths.8 \
-       nnrpd.8 nntpsend.8 ovdb_init.8 ovdb_monitor.8 ovdb_server.8 \
-       ovdb_stat.8 overchan.8 perl-nocem.8 prunehistory.8 radius.8 \
-       rc.news.8 scanlogs.8 send-nntp.8 send-uucp.8 sendinpaths.8 \
-       tally.control.8 tdx-util.8 writelog.8
-
-COPY   = $(SHELL) ./putman.sh $(MANPAGESTYLE) "$(MANFLAGS)"
-
-all:
-clobber clean distclean:
-tags ctags:
-profiled:
-
-install: install-man1 install-man3 install-man5 install-man8
-
-install-man1:
-       for M in $(SEC1) ; do \
-           $(COPY) $$M $D$(MAN1)/$$M ; \
-       done
-
-install-man3:
-       for M in $(SEC3) ; do \
-           $(COPY) $$M $D$(MAN3)/$$M ; \
-       done
-
-install-man5:
-       for M in $(SEC5) ; do \
-           $(COPY) $$M $D$(MAN5)/$$M ; \
-       done
-
-# auth_krb5 is conditionally compiled, so handle it specially.
-install-man8:
-       for M in $(SEC8) ; do \
-           $(COPY) $$M $D$(MAN8)/$$M ; \
-       done
-       if [ x"$(KRB5_AUTH)" != x ] ; then \
-           $(COPY) auth_krb5.8 $D$(MAN8)/auth_krb5.8 ; \
-       fi
diff --git a/doc/man/active.5 b/doc/man/active.5
deleted file mode 100644 (file)
index 97a0d62..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-.\" 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 "ACTIVE 5"
-.TH ACTIVE 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-active \- List of newsgroups carried by the server
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpathdb\fR/active lists the newsgroups carried by \s-1INN\s0.  This file
-is generally maintained using \fIctlinnd\fR\|(8) to create and remove groups, or
-by letting \fIcontrolchan\fR\|(8) do so on the basis of received control messages.
-This file should not be edited directly without throttling \fBinnd\fR, and
-must be reloaded using \fBctlinnd\fR before \fBinnd\fR is unthrottled.  Editing
-it directly even with those precautions may make it inconsistent with the
-overview database and won't update \fIactive.times\fR, so \fBctlinnd\fR should
-be used to make modifications whenever possible.
-.PP
-Each newsgroup should be listed only once.  Each line specifies one group.
-The order of groups does not matter.  Within each newsgroup, received
-articles for that group are assigned monotonically increasing numbers as
-unique names.  If an article is posted to newsgroups not mentioned in this
-file, those newsgroups are ignored.
-.PP
-If none of the newsgroups listed in the Newsgroups header of an article
-are present in this file, the article is either rejected (if \fIwanttrash\fR
-is false in \fIinn.conf\fR), or is filed into the newsgroup \f(CW\*(C`junk\*(C'\fR and only
-propagated to sites that receive the \f(CW\*(C`junk\*(C'\fR newsgroup (if \fIwanttrash\fR is
-true).
-.PP
-Each line of this file consists of four fields separated by a space:
-.PP
-.Vb 1
-\&    <name> <high> <low> <flag>
-.Ve
-.PP
-The first field is the name of the newsgroup.  The newsgroup \f(CW\*(C`junk\*(C'\fR is
-special, as mentioned above.  The newsgroup \f(CW\*(C`control\*(C'\fR and any newsgroups
-beginning with \f(CW\*(C`control.\*(C'\fR are also special; control messages are filed
-into a control.* newsgroup named after the type of control message if that
-group exists, and otherwise are filed into the newsgroup \f(CW\*(C`control\*(C'\fR
-(without regard to what newsgroups are listed in the Newsgroups header).
-If \fImergetogroups\fR is set to true in \fIinn.conf\fR, newsgroups that begin
-with \f(CW\*(C`to.\*(C'\fR are also treated specially; see \fIinnd\fR\|(8).
-.PP
-The second field is the highest article number that has been used in that
-newsgroup.  The third field is the lowest article number in the group;
-this number is not guaranteed to be accurate, and should only be taken to
-be a hint.  It is normally updated nightly as part of the expire process;
-see \fInews.daily\fR\|(8) and look for \f(CW\*(C`lowmark\*(C'\fR or \f(CW\*(C`renumber\*(C'\fR for more details.
-Note that because of article cancellations, there may be gaps in the
-numbering sequence.  If the lowest article number is greater then the
-highest article number, then there are no articles in the newsgroup.  In
-order to make it possible to update an entry in-place without rewriting
-the entire file, the second and third fields are padded out with leading
-zeros to make them a fixed width.
-.PP
-The fourth field contains one of the following flags:
-.PP
-.Vb 6
-\&    y         Local postings are allowed.
-\&    m         The group is moderated and all postings must be approved.
-\&    n         No local postings are allowed, only articles from peers.
-\&    j         Articles are filed in the junk group instead.
-\&    x         No local postings and ignored for articles from peers.
-\&    =foo.bar  Articles are filed in the group foo.bar instead.
-.Ve
-.PP
-If a newsgroup has the \f(CW\*(C`j\*(C'\fR flag, no articles will be filed in that
-newsgroup, and local postings to that group will be rejected.  If an
-article for that newsgroup is received from a remote site, and it is not
-crossposted to some other valid group, it will be filed into the \f(CW\*(C`junk\*(C'\fR
-newsgroup instead.  This is different than simply not listing the group,
-since the article will still be accepted and can be propagated to other
-sites, and the \f(CW\*(C`junk\*(C'\fR group can be made available to readers if wished.
-.PP
-If the <flag> field begins with an equal sign, the newsgroup is an alias.
-Articles cannot be posted to that newsgroup, but they can be received from
-other sites.  Any articles received from peers for that newsgroup are
-treated as if they were actually posted to the group named after the equal
-sign.  Note that the Newsgroups header of the articles are not modified.
-(Alias groups are typically used during a transition and are typically
-created manually with \fIctlinnd\fR\|(8).)  An alias should not point to another
-alias.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: active.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive.times\fR\|(5), \fIcontrolchan\fR\|(8), \fIctlinnd\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8),
-\&\fInews.daily\fR\|(8)
diff --git a/doc/man/active.times.5 b/doc/man/active.times.5
deleted file mode 100644 (file)
index 2b95ac5..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-.\" 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 "ACTIVE.TIMES 5"
-.TH ACTIVE.TIMES 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-active.times \- List of local creation times of newsgroups
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpathdb\fR/active.times provides a chronological record of when
-newsgruops were created on the local server.  This file is normally
-updated by \fBinnd\fR whenever a newgroup control message is processed or a
-\&\f(CW\*(C`ctlinnd newgroup\*(C'\fR command is issued, and is used by \fBnnrpd\fR to answer
-\&\s-1NEWGROUPS\s0 requests.
-.PP
-Each line consists of three fields:
-.PP
-.Vb 1
-\&    <name> <time> <creator>
-.Ve
-.PP
-The first field is the name of the newsgroup.  The second field is the
-time it was created, expressed as the number of seconds since the epoch.
-The third field is the e\-mail addrses of the person who created the group,
-as specified in the control message or on the \fBctlinnd\fR command line, or
-the newsmaster specified at configure time if no creator argument was
-given to \fBctlinnd\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>
-.PP
-$Id: active.times.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive\fR\|(5), \fIctlinnd\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInnrpd\fR\|(8)
diff --git a/doc/man/actsync.8 b/doc/man/actsync.8
deleted file mode 100644 (file)
index ea06061..0000000
+++ /dev/null
@@ -1,1123 +0,0 @@
-.\" By: Landon Curt Noll       chongo@toad.com         (chongo was here /\../\)
-.\"
-.\" Copyright (c) Landon Curt Noll, 1993.
-.\" All rights reserved.
-.\"
-.\" Permission to use and modify is hereby granted so long as this
-.\" notice remains.  Use at your own risk.  No warranty is implied.
-.\"
-.\" @(#) $Id: actsync.8 6731 2004-05-16 22:00:46Z rra $
-.\" @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actsync.8,v
-.\"
-.TH ACTSYNC 8
-.SH NAME
-actsync, actsyncd \- synchronize newsgroups
-.SH SYNOPSIS
-.B actsync
-[\fB\-A\fP] [\fB\-b\fP\fI hostid\fP] [\fB\-d\fP\fI hostid\fP] [\fB\-g\fP\fI max\fP]
-.br
-          [\fB\-i\fP\fI ignore_file\fP] [\fB\-I\fP\fI hostid\fP] [\fB\-k\fP] [\fB\-l\fP\fI hostid\fP] [\fB\-m\fP]
-.br
-          [\fB\-n\fP\fI name\fP] [\fB\-o\fP\fI fmt\fP] [\fB\-p\fP\fI min_%_unchg\fP] [\fB\-q\fP\fI hostid\fP]
-.br
-          [\fB\-s\fP\fI size\fP] [\fB\-t\fP\fI hostid\fP] [\fB\-T\fP] [\fB\-v\fP\fI verbosity\fP]
-.br
-          [\fB\-z\fP\fI sec\fP] [\fIhost1\fP] \fIhost2\fP
-.sp 1
-.B actsyncd
-[\fB\-x\fP] \fIactsync.cfg\fP [\fIdebug_level\fP [\fIdebug_outfmt\fP] ]
-.SH DESCRIPTION
-.IR Actsync (8)
-permits one to synchronize, compare, or merge two
-.I active
-files.
-With this utility one may add, change, or remove newsgroups on the
-local news server to make it similar to the list the newsgroups
-found on another system or file.
-The synchronization need not be exact.
-Local differences in newsgroup lists may be maintained and preserved.
-Certain newsgroup errors may be detected and optionally corrected.
-.PP
-There are several reasons to run
-.IR actsync (8)
-(or
-.IR actsyncd (8)),
-on a periodic basis.
-Among the reasons are:
-.in +0.5i
-.sp 1
-A control message to add, change or remove a newsgroup
-may fail to reach your site.
-.sp 1
-Your
-.I control.ctl
-may be out of date or incomplete.
-.sp 1
-News articles for a new newsgroup can arrive ahead (sometimes days ahead)
-of the control message.
-.sp 1
-Control messages may be forged, thus bypassing the restrictions
-found in
-.I control.ctl .
-.sp 1
-Your
-.I active
-file may have been trashed.
-.sp 1
-.in -0.5i
-.PP
-If
-.I host1
-or
-.I host2
-begins with a
-.B ``.''
-or
-.BR ``/'' ,
-then it is assumed to be a name of a file containing information in the
-.IR active (5)
-format.
-The
-.IR getlist (1)
-utility may be used to obtain copy a remote system's active file
-via its NNTP server, or an FTP client program can retrieve such a
-file from an FTP archive (such as
-ftp://ftp.isc.org/pub/usenet/CONFIG/active; see more about this below).
-Newsgroup information from a file
-may be treated as if it was obtained from a host.
-In this man page
-.I host1
-and
-.I host2
-are called hosts, even though they may be file names.
-.PP
-If a host argument does not begin with
-.B ``.''
-or
-.BR ``/'' ,
-is assumed to be a
-hostname or Internet address.
-In this case,
-.IR actsync (8)
-will attempt to use the
-.B NNTP
-protocol to obtain a copy of the the specified system's active file.
-If the host argument contains a
-.B ``:'' ,
-the right side will be considerd the port to connect to on the remote system.
-If no port number is specified,
-.IR actsync (8)
-will connect to port 119.
-.PP
-Regardless how the active file information is obtained,
-the actions of
-.IR actsync (8)
-remain the same.
-.PP
-If only one host is specified, it is assumed to be
-.IR host2 ;
-if
-.IR host1
-is not specified, it assumed to be the default local
-NNTP server as specified by the
-.B NNTPSERVER
-environment variable, or by the
-.B server
-value found in
-.IR inn.conf .
-.PP
-The newsgroup synchronization, by default, involves all newsgroups
-found on both hosts.
-One may also synchronize a subset of newsgroups by directing
-.IR actsync (8)
-to ignore certain newsgroups from both systems.  Only newsgroups with
-valid names will be synchronized.  To be valid, a newsgroup name must
-consist only of alphanumeric characters, ``.'', ``+'', ``-'', and ``_''.
-One may not have two ``.''s in a row.  The first character must be
-alphanumeric, as must any character following a ``.''.  The name may not
-end in a ``.'' character.
-.PP
-The
-.IR actsyncd (8)
-daemon provides a convenient interface to configure and run
-.IR actsync (8).
-If a host is not initially reachable,
-the daemon will retry up to 9 additional times, waiting 6 minutes before
-each retry.
-This daemon runs in the foreground, sending output to standard output
-and standard error.
-.PP
-If the \fB\-x\fP flag is given to
-.IR actsyncd (8),
-then a
-.IR ctlinnd\ xexec
-will be used instead of a
-.IR ctlinnd\ reload
-to load the newly modified active file.
-.PP
-The configuration filename for the daemon is given as a
-commandline argument, usually
-.I <pathetc in inn.conf>/actsync.cfg
-The config file can contain the following options:
-.sp 1
-.in +0.5i
-.nf
-\fBhost=\fP\fIhost2\fP
-\fBftppath=\fP\fI/remote/path/to/active/file\fP
-\fBspool=\fP\fI<normally patharticles in inn.conf>\fP
-\fBignore_file=\fP\fIignore_file\fP
-\fBflags=\fP\fIactsyncd\fP(8) options
-.fi
-.in -0.5i
-.sp 1
-The \fBhost\fP, \fBignore_file\fP, and \fBflags\fP lines are mandatory.
-.sp 1
-The keyword must start at the beginning of the line, and there
-may be no whitespace before the
-.B ``=''
-character.
-Blank lines are ignored.
-Comment lines start with
-.B ``#''
-and are ignored.
-Any other lines may produce undefined results.
-.sp 1
-The \fBhost\fP config file line refers to the \fIhost2\fP parameter to
-.IR actsync (8).
-The \fBftppath\fP directive causes the machine named in the \fBhost\fP
-line to accessed as an ftp server, retrieving the file named.  If
-the filename ends in \fB.gz\fP or \fB.Z\fP, then it will automatically
-be uncompressed after retrieval.
-The \fBspool\fP config file lines determines where the top of the
-news spool tree is to be found.
-The \fBignore_file\fP config file line names the ignore file to be
-used by
-.IR actsync (8).
-The \fBflags\fP config file line contains any flags that you wish to pass to
-.IR actsync (8).
-.sp 1
-Note that the \fB\-i ignore_file\fP option
-and the \fB-o format\fP option
-should not be given
-in the \fBflags=\fP line because they are automatically taken care of by
-.IR actsyncd (8).
-.sp 1
-INN is shipped with default values of \fIftp.isc.org\fP for \fBhost\fP
-and \fI/pub/usenet/CONFIG/active\fP for \fBftppath\fP.  You can read
-about the policies used for maintaining that active file at
-\fIftp://ftp.isc.org/pub/usenet/CONFIG/README\fP.  Consider
-sychronizing from this file on a daily basis by using
-.IR cron (8).
-.SH OPTIONS
-The options to
-.IR actsync (8)
-are as follows:
-.PP
-.TP
-.B \-A
-.IR actsync (8)
-tries to authenticate before issuing LIST command.
-.TP
-.BI \-b " hostid"
-This flag causes
-.IR actsync (8)
-to ignore newsgroups with ``bork.bork.bork'' style names.
-That is, newsgroups whose last 3 components are identical.
-For example, the following newsgroups have bork style names:
-.sp 1
-.in +0.5i
-.nf
-alt.helms.dork.dork.dork
-alt.auto.accident.sue.sue.sue
-alt.election.vote.vote.vote
-.fi
-.in -0.5i
-.sp 1
-The value
-.I hostid
-determines on which hosts this action is performed:
-.sp 1
-.in +0.5i
-.nf
-0      neither host
-1      local default server
-2      remove server
-12     both servers
-21     both servers
-.fi
-.in -0.5i
-.sp 1
-The default is
-.BR "\-b 0" ;
-no newsgroups are ignored because of bork-style names.
-.TP
-.BI \-d " hostid"
-This flag causes
-.IR actsync (8)
-to ignore newsgroups that have all numeric path components.
-The
-.B hostid
-value is interpreted the same as in
-.BR \-b .
-For example, the following newsgroups have numeric path components:
-.sp
-.in +0.5i
-.nf
-alt.prime.chongo.23209
-391581.times.2.to_the.216193.power.-1
-99.bottles.of.treacle.on.the.wall
-linfield.class.envio_bio.101.d
-.fi
-.in -0.5i
-.sp 1
-The newsgroups directory of a newsgroups with a all numeric component
-could conflict with an article from another group if stored using the
-``tradspool'' storage method; see
-.IR storage.conf (5).
-For example, the directory for the first newsgroup listed above
-is the same path as article number 23209 from the newsgroup:
-.sp
-.in +0.5i
-.nf
-alt.prime.chongo
-.fi
-.in -0.5i
-.sp 1
-The default is
-.BR "\-d 0" ;
-all numeric newsgroups from both hosts will be processed.
-.TP
-.BI \-g " max"
-Ignore any newsgroup with more than
-.B max
-levels.  For example,
-.BI \-g " 6"
-would ignore:
-.sp 1
-.in +0.5i
-.nf
-alt.feinstien.votes.to.trash.freedom.of.speech
-alt.senator.exon.enemy.of.the.internet
-alt.crypto.export.laws.dumb.dumb.dumb
-.fi
-.in -0.5i
-.sp 1
-but would not ignore:
-.sp 1
-.in +0.5i
-.nf
-alt.feinstien.acts.like.a.republican
-alt.exon.amendment
-alt.crypto.export.laws
-.fi
-.in -0.5i
-.sp 1
-If
-.B max
-is 0, then the max level feature is disabled.
-.sp 1
-By default,
-the max level feature is disabled.
-.TP
-.BI \-i " ignore_file"
-The
-.I ignore_file ,
-usually
-.I <pathetc in inn.conf>/actsync.ign ,
-allows one to have a fine degree of control over which newsgroups are ignored.
-It contains a set of rules that specifies
-which newsgroups will be checked and which will be ignored.
-.sp 1
-By default, these rules apply to both hosts.
-This can be modified by using the
-.BI \-I " hostid"
-flag.
-.sp 1
-By default, all newsgroups are checked.
-If no
-.I ignore_file
-if specified, or if the ignore file contains no rule lines,
-all newsgroups will be checked.
-.sp 1
-Blank lines and text after a
-.B ``#''
-are considered comments and are ignored.
-.sp 1
-Rule lines consist of tokens separated by whitespace.
-Rule lines may be one of two forms:
-.sp 1
-.in +0.5i
-.nf
-\fBc   newsgroup       [type ...]\fP
-\fBi   newsgroup       [type ...]\fP
-.fi
-.in -0.5i
-.sp 1
-If the rule begins with a
-.B c
-then the rule requests certain newsgroups to be checked.
-If the rule begins with an
-.B i
-then the rule requests certain newsgroups to be ignored.
-The
-.B newsgroup
-field may be a specific newsgroup, or a
-.IR uwildmat (3)
-pattern.
-.sp 1
-If one or more
-.BR type s
-are specified, then the rule applies to the newsgroup only if
-is of the specified type.
-Types refer to the 4th field of the
-.I active
-file; that is, a type may be one of:
-.sp 1
-.in +0.5i
-.nf
-\fBy\fP
-\fBn\fP
-\fBm\fP
-\fBj\fP
-\fBx\fP
-\fB=group.name\fP
-.fi
-.in -0.5i
-.sp 1
-Unlike active files, the
-.B group.name
-in an alias type may be a newsgroup name or a
-.IR uwildmat (3)
-pattern.
-Also,
-.B ``=''
-is equivalent to
-.BR ``=*'' .
-.sp 1
-On each rule line, no pattern type may not be repeated.
-For example, one may not have more than one type that begins with
-.BR ``='' ,
-per line.
-However, one may achieve an effect equivalent to using multiple
-.B ``=''
-types by using multiple rule lines affecting the same newsgroup.
-.sp 1
-By default, all newsgroups are candidates to be checked.
-If an ignore file is used, each newsgroup in turn is checked
-against the ignore file.
-If multiple lines match a given newsgroup, the last line
-in the ignore file is used.
-.sp 1
-For example, consider the following ignore file lines:
-.sp 1
-.in +0.5i
-.nf
-i *.general
-c *.general m
-i nsa.general
-.fi
-.in -0.5i
-.sp 1
-The newsgroups
-.B ba.general
-and
-.B mod.general
-would be synchronized if moderated and ignored if not moderated.
-The newsgroup
-.B nsa.general
-would be ignored regardless of moderation status.
-All newsgroups not matching
-.B *.general
-would be synchronized by default.
-.TP
-.BI \-I " hostid"
-This flag restricts which hosts are affected by the ignore file.
-The
-.B hostid
-value is interpreted the same as in
-.BR \-b
-described above.
-.sp 1
-This flag may be useful in conjunction with the
-.B \-m
-merge flag.
-For example:
-.sp 1
-.in +0.5i
-actsync \-i actsync.ign \-I 2 \-m
-.I host1
-.I host2
-.in -0.5i
-.sp 1
-will keep all newsgroups currently on
-.I host1 .
-It will also will only compare
-.I host1
-groups with non-ignored newsgroups from
-.I host2 .
-.sp 1
-The default is
-.BR "\-I 12" ,
-newsgroups from both hosts to be ignored per the
-.I \-i " actsync.ign"
-file.
-.TP
-.B \-k
-By default, any newsgroup on
-.I host1
-that is in error will be considered for removal.
-This causes
-.IR actsync (8)
-simply ignore such newsgroups.
-This flag, used in combination with
-.I \-m ,
-will prevent any newsgroup from being scheduled for removal.
-.TP
-.BR \-l " hostid"
-This flag causes ``problem newsgroups'' of type
-.B ``=''
-from
-.B host1
-or
-.B host2
-to be considered as errors.
-The
-.B hostid
-value is interpreted the same as in
-.BR \-b .
-Newsgroups of type
-.B ``=''
-are newsgroups active entries that have 4th field
-that begins with
-.BR ``='' ,
-i.e. newsgroups that are equivalent to other newsgroups.  A ``problem''
-newsgroup is one which is:
-.sp 1
-.in +0.5i
-.nf
-*  equivalent to itself
-*  in an equivalence chain that loops around
-   to itself
-*  in an equivalence chain longer than 16 groups
-*  equivalent to a non-existant newsgroup
-*  equivalent to a newsgroup that has an error
-   of some kind
-.fi
-.in -0.5i
-.sp 1
-However, a newsgroup that is equivalent to an ignored newsgroup is
-not a problem.
-.sp 1
-By default, problem newsgroups from both hosts are
-marked as errors.
-.TP
-.B \-m
-Merge newsgroups instead of sync.
-By default, if a newsgroup exists on
-.B host1
-but not
-.BR host2 ,
-it will be scheduled to be removed.
-This flag disables this process, permitting newsgroups unique to
-.B host1
-to be kept.
-.TP
-.B \-n " name"
-The
-.IR ctlinnd (8)
-command is used to create newsgroups as necessary.
-By default, the creator name used is
-.BR "actsync" .
-This flag changes the creator name to
-.BR "name" .
-.TP
-.B \-o " fmt"
-Determine the output / action format of this utility.
-The
-.B "fmt"
-may one of:
-.sp 1
-.in +0.5i
-.nf
-\fBa\fP        output in \fIactive\fP\fR(5)\fP\fR format\fP
-\fBa1\fP       output in \fIactive\fP\fR(5)\fP\fR format,\fP
-       and output host1 non-error ignored groups
-\fBak\fP       output in \fIactive\fP\fR(5)\fP\fR format, but use host2\fP
-       hi & low (2nd & 3rd active fields) values
-       for any newsgroup being created
-\fBaK\fP       output in \fIactive\fP\fR(5)\fP\fR format, but use host2\fP
-       hi & low (2nd & 3rd active fields) values
-       for all newsgroups found in host2
-\fBa1k\fP      output in \fIactive\fP\fR(5)\fP\fR format, but use host2\fP
-       hi & low (2nd & 3rd active fields) values
-       for any newsgroup being created,
-       and output host1 non-error ignored groups
-\fBa1K\fP      output in \fIactive\fP\fR(5)\fP\fR format, but use host2\fP
-       hi & low (2nd & 3rd active fields) values
-       for all newsgroups found in host2,
-       and output host1 non-error ignored groups
-\fBak1\fP      same as \fBa1k\fP
-\fBaK1\fP      same as \fBa1K\fP
-\fBc\fP        output in \fIctlinnd\fP\fR(8)\fP\fR format\fP
-\fBx\fP        no output, directly exec \fIctlinnd\fP\fR(8)\fP\fR commands\fP
-\fBxi\fP       no output, directly exec \fIctlinnd\fP\fR(8)\fP\fR commands,\fP
-       in an interactive mode
-.fi
-.in -0.5i
-.sp 1
-The \fBa\fP, \fBa1\fP, \fBak\fP, \fBaK\fP, \fBa1k\fP,
-\fBa1K\fP, \fBak1\fP and \fBaK1\fP style formats allow one to form
-a new active file instead of producing
-.IR ctlinnd (8)
-commands.
-They use hi & low values of
-.B 0000000000
-and
-.B 0000000001
-respectively for newsgroups that are created.
-The \fBak\fP and \fBaK\fP variants change the the hi & low (2nd & 3rd
-active fields).
-In the case of \fBak\fP, newsgroups created take their hi & low values from
-.BR host2 .
-In the case of \fBaK\fP, all newsgroups found on host2 take their
-hi & low values from
-.BR host2 .
-.sp 1
-The \fBc\fP format produces
-.IR ctlinnd (8)
-commands.
-No actions are taken because
-.IR actsync (8)
-simply prints
-.IR ctlinnd (8)
-commands on standard output.
-The sync (or merge) with
-.B host2
-may be accomplished by piping this output into
-.IR sh (1).
-A paranoid person might prefer to use \fBx\fP or \fBxi\fP
-in case a newsgroup name or type contains bogus characters
-that might be interpreted by
-.IR sh (1).
-Even so, this output format is useful to let you see how
-.B host1
-will be affected by the sync (or merge) with
-.BR host2 .
-.sp 1
-The sync (or merge) may be accomplished directly
-by use of the \fBx\fP format.
-With this format,
-.IR actsync (8)
-uses the
-.IR execl (2)
-system call to directly execute
-.IR ctlinnd (8)
-commands.
-Because of the exec, there is no risk
-of bogus newsgroups containing bogus characters causing
-a shell to do bogus (or dangerous) things.
-The output of such exec calls may be seen if the verbosity level
-is at least
-.BR 2 .
-.sp 1
-The
-.IR actsync (8)
-utility will pause for
-.B 4
-seconds before each command is executed if
-.BI \-o " x"
-is selected.
-See the
-.BR \-z " sec"
-flag below for discussion of this delay and how to customize it.
-.sp 1
-The \fBxi\fP format interactively prompts on standard output
-and reads directives on standard input.
-One may pick and choose changes using this format.
-.sp 1
-Care should be taken when producing
-\fIactive\fP\fR(5)\fP\fR formatted output\fP.
-One should check to be sure that
-.IR actsync (8)
-exited with a zero status prior to using such output.
-Also one should realize that such output will not
-contain lines ignored due to
-.BI \-i " ignore_file"
-even if
-.BI \-p " 100"
-is used.
-.sp 1
-By default,
-.BI \-o " c"
-is assumed.
-.TP
-.BI \-p " min_%_unchg"
-By default, the
-.IR actsync (8)
-utility has safeguards against performing massive changes.
-If fewer than
-.B min_%_unchg
-percent of the non-ignored lines from
-.B host1
-remain unchanged, no actions (output, execution, etc.)
-are performed and
-.IR actsync (8)
-exits with a non-zero exit status.
-The
-.B min_%_unchg
-may be a floating point value such as
-.BR 66.667 .
-.sp 1
-A change is considered a
-.B host1
-line that was removed, added, changed, or found to be in error.
-Changing the 2nd or 3rd active fields via
-.BI \-o "ak"
-or
-.BI \-o " aK"
-are not considered changes by
-.BR \-p .
-.sp 1
-To force
-.IR actsync (8)
-to accept any amount of change, use the
-.BI \-p " 0"
-option.
-To force
-.IR actsync (8)
-to reject any changes, use the
-.BI \-p " 100"
-option.
-.sp 1
-Care should be taken when producing
-\fIactive\fP\fR(5)\fP\fR-formatted output\fP;
-be sure to check that
-.IR actsync (8)
-exited with a zero status prior to using such output.
-Also one should realize that such output will not
-contain lines ignored by the
-.BI \-i " ignore_file"
-process even if
-.BI \-p " 100"
-is used.
-.sp 1
-By default, 96% of the lines not ignored in host1 must
-be unchanged.
-That is, by default,
-.BI \-p " 96"
-is assumed.
-.TP
-.BI \-q " hostid"
-By default, all newsgroup errors are reported on standard error.
-This flag quiets errors from
-.B host1
-or
-.BR host2 .
-The
-.B hostid
-value is interpreted the same as in
-.BR \-b .
-.TP
-.BR \-s " size"
-If
-.BR size\ >\ 0,
-then ignore newsgroups with names longer than
-.BR size ,
-and ignore newsgroups equivalent (by following
-.B ``=''
-chains) to names longer than
-.BR size .
-Length checking is performed on both the local and remote hosts.
-.sp 1
-By default,
-.B size
-is 0 and thus no length checking is performed.
-.TP
-.BR \-t " hostid"
-Ignore improper newsgroups consisting of only a top component
-from
-.B host1
-or
-.BR host2 .
-The
-.B hostid
-value is interpreted the same as in
-.BR \-b .
-The following newsgroups are considered proper newsgroups
-despite top only names and therefore are exempt from this flag:
-.sp 1
-.in +0.5i
-.nf
-control
-general
-junk
-test
-to
-.fi
-.in -0.5i
-.sp 1
-For example, the following newsgroup names are improper because they
-only contain a top level component:
-.sp 1
-.in +0.5i
-.nf
-dole_for_pres
-dos
-microsoft
-windows95
-.fi
-.in -0.5i
-.sp 1
-The default is
-.BR "\-t 2" ,
-that is, all improper top-level-only newsgroups from the remote
-are ignored.
-.TP
-.B \-T
-This flag causes
-.B host2
-newsgroups from new hierarchies to be ignored.
-Normally a newsgroup which only exists on
-.B host2 ,
-for example
-.B chongo.was.here ,
-will be created for
-.BR host1 .
-However, if this flag is given and
-.B host1
-does not have any other newsgroups in the same hierarchy,
-e.g. ``\fBchongo.*\fP'', then the newsgroup in question
-will be ignored and will not be created on
-.BR host1 .
-.TP
-.BI \-v " verbosity"
-By default,
-.IR actsync (8)
-is not verbose.
-This flag controls the verbosity level as follows:
-.sp 1
-.in +0.5i
-.nf
-\fB0\fP        no debug or status reports (default)
-\fB1\fP        print summary,
-       but only if work was needed or done
-\fB2\fP        print actions, exec output, and summary,
-       but only if work was needed or done
-\fB3\fP        print actions, exec output, and summary
-\fB4\fP        full debug output
-.fi
-.TP
-.BI \-z " sec"
-If
-.BI \-o " x"
-is selected,
-.IR actsync (8)
-will pause for
-.B sec
-seconds before each command is executed.
-This helps prevent
-.IR innd (8)
-from being busied-out if a large number of
-.IR ctlinnd (8)
-commands are needed.
-One can entirely disable this sleeping by using
-.BI \-z " 0".
-.sp 1
-By default,
-.IR actsync (8)
-will pause for
-.B 4
-seconds before each command is executed if
-.BI \-o " x"
-is selected.
-.in -0.5i
-.SH EXAMPLES
-Determine the difference (but don't change anything) between your
-newsgroup set and uunet's set:
-.PP
-.in +0.5i
-actsync news.uu.net
-.in -0.5i
-.PP
-Same as above, with full debug and progress reports:
-.PP
-.in +0.5i
-actsync \-v 4 news.uu.net
-.in -0.5o
-.PP
-Force a site to have the same newsgroups some other site:
-.PP
-.in +0.5i
-actsync \-o x master
-.in -0.5i
-.PP
-This may be useful to sync a slave site to its master, or
-to sync internal site to a gateway.
-.PP
-Compare your site with uunet, disregarding local groups and
-certain local differences with uunet.
-Produce a report if
-any differences were encountered:
-.PP
-.in +0.5i
-actsync \-v 2 \-i actsync.ign news.uu.net
-.in -0.5i
-.PP
-where
-.B actsync.ign
-contains:
-.PP
-.in +0.5i
-.nf
-# Don't compare to.* groups as they will differ.
-#
-i      to.*
-
-# These are our local groups that nobody else
-# (should) carry.  So ignore them for the sake
-# of the compare.
-#
-i      nsa.*
-
-# These groups are local favorites, so keep them
-# even if uunet does not carry them.
-#
-i      ca.dump.bob.dorman
-i      ca.keep.bob.dorman
-i      alt.tv.dinosaurs.barney.die.die.die
-i      alt.tv.dinosaurs.barney.love.love.love
-i      alt.sounds.*    =alt.binaries.sounds.*
-.PP
-.fi
-.in -0.5i
-.PP
-To interactively sync against news.uu.net, using the same
-ignore file:
-.PP
-.in +0.5i
-actsync \-o xi \-v 2 \-i actsync.ign news.uu.net
-.in -0.5i
-.PP
-Based on newsgroups that you decided to keep, one could
-make changes to the
-.B actsync.ign
-file:
-.PP
-.in +0.5i
-.nf
-# Don't compare to.* groups as they will differ.
-#
-i      to.*
-
-# These are our local groups that nobody else
-# (should) carry.  So ignore them for the sake
-# of the compare.
-#
-i      nsa.*
-
-# These groups are local favorites, so keep them
-# even if uunet does not carry them.
-#
-i      ca.dump.bob.dorman
-i      alt.tv.dinosaurs.barney.die.die.die
-i      alt.sounds.*    =alt.binaries.sounds.*
-
-# Don't sync test groups, except for ones that are
-# moderated or that are under the gnu hierarchy.
-i      *.test
-c      *.test  m       # check moderated test groups
-c      gnu.*.test
-c      gnu.test        # just in case it ever exists
-.PP
-.fi
-.in -0.5i
-.PP
-Automatic processing may be setup by using the following
-.B actsync.cfg
-file:
-.PP
-.in +0.5i
-.nf
-# host to sync off of (host2)
-host=news.uu.net
-
-# location of the ignore file
-ignore_file=<pathetc in inn.conf>/actsync.ign
-
-# where news articles are kept
-spool=<patharticles in inn.conf>
-
-# actsync(8) flags
-#
-# Automatic execs, report if something was done,
-#      otherwise don't say anything, don't report
-#      uunet active file problems, just ignore
-#      the affected entries.
-flags=\-o x \-v 2 \-q 2
-.fi
-.in -0.5i
-.PP
-and then by running
-.IR actsyncd (8)
-with the path to the config
-file:
-.PP
-.in +0.5i
-actsyncd <pathetc in inn.conf>/actsync.cfg
-.in -0.5i
-.PP
-One may produce a trial
-.IR actsyncd (8)
-run without changing anything
-on the server by supplying the \fBdebug_level\fP arg:
-.sp 1
-.in +0.5i
-actsyncd <pathetc in inn.conf>/actsync.cfg 2
-.in -0.5i
-.PP
-The \fBdebug_level\fP causes
-.IR actsyncd (8)
-to run
-.IR actsync (8)
-with an \fB\-v debug_level\fP (overriding any \fB\-v\fP
-flag on the \fBflags\fP line),
-not make any changes to the
-.I active
-file, write a new active file to \fIstandard output\fP,
-and write debug messages to \fIstandard error\fP.
-.PP
-If the \fBdebug_outfmt\fP arg is also given to
-.IR actsyncd (8)
-then the data written to \fIstandard output\fP will
-be in \fB\-o debug_outfmt\fP instead of in \fB\-o a1\fP format.
-The /bin/sh command
-.sp 1
-.in +0.5i
-.nf
-actsyncd <pathetc in inn.conf>/actsync.cfg 4 \\
-       >cmd.log 2>dbg.log
-.fi
-.in -0.5i
-.PP
-will operate in debug mode,
-not change the
-.I active
-file, write
-.IR ctlinnd (8)
-style commands to \fBcmd.log\fP, and
-write debug statements to \fBdbg.log\fP.
-.PP
-To check only the major hierarchies against news.uu,net, use the following
-.B actsync.ign
-file:
-.PP
-.in +0.5i
-.nf
-# by default, ignore everything
-i *
-
-# check the major groups
-c      comp.*
-c      gnu.*
-c      sci.*
-c      alt.*
-c      misc.*
-c      news.*
-c      rec.*
-c      soc.*
-c      talk.*
-.fi
-.in -0.5i
-.PP
-and the command:
-.PP
-.in +0.5i
-actsync \-i actsync.ign news.uu.net
-.in -0.5i
-.PP
-To determine the differences between your old active and
-your current default server:
-.PP
-.in +0.5i
-actsync <pathetc in inn.conf>/active.old \-
-.in -0.5i
-.PP
-To report but not fix any newsgroup problems with the current active file:
-.PP
-.in +0.5i
-actsync \- \-
-.in -0.5i
-.PP
-To detect any newsgroup errors on your local server, and
-to remove any
-.B *.bork.bork.bork
-style silly newsgroup names:
-.PP
-.in +0.5i
-actsync \-b 2 \- \-
-.in -0.5i
-.PP
-The active file produced by:
-.PP
-.in +0.5i
-actsync ...flags... \-o x erehwon.honey.edu
-.in -0.5i
-.PP
-or by:
-.PP
-.in +0.5i
-actsync ...flags... \-o c erehwon.honey.edu | sh
-.in -0.5i
-.PP
-is effectively the same as the active file produced by:
-.PP
-.nf
-.in +0.5i
-ctlinnd pause 'running actsync'
-rm -f active.new
-actsync ...flags... \-o a1 erehwon.honey.edu > active.new
-rm -f active.old
-ln active active.old
-mv active.new active
-ctlinnd reload active 'running actsync'
-ctlinnd go 'running actsync'
-.in -0.5i
-.fi
-.PP
-It should be noted that the final method above, pausing the server
-and simply replacing the
-.I active
-file, is faster.
-.PP
-.SH CAUTION
-Careless use of this tool may result in the unintended
-addition, change, or removal of newsgroups.
-You should avoid using the \fRx\fP output format until
-you are sure it will do what you want.
-.SH BUGS
-If a newsgroup appears multiple times,
-.IR actsync (8)
-will treat all copies as errors.
-However, if the group is marked for removal, only
-one rmgroup will be issued.
-.PP
-The timeout for
-.IR ctlinnd (8)
-commands is fixed at 30 seconds when
-running in ``\fRx\fP'' or ``\fRxi\fP'' output format.
-Perhaps the timeout value should be controlled via a command line option?
-.SH "SEE ALSO"
-.IR active (5),
-.br
-.IR simpleftp (1),
-.br
-.IR mod-active (8),
-.br
-.IR ctlinnd (8),
-.br
-.IR getlist (8),
-.br
-.IR inn.conf (5).
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> for InterNetNews.
-Updated to support ftp fetching by David Lawrence <tale@isc.org>.
diff --git a/doc/man/actsyncd.8 b/doc/man/actsyncd.8
deleted file mode 100644 (file)
index 69d2a45..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-.TH ACTSYNCD 8
-.SH NAME
-actsyncd \- run actsync to synchronize newsgroups
-.SH SYNOPSIS
-Please see the
-.IR actsync (8)
-manual page.
-.SH "SEE ALSO"
-actsync(8)
diff --git a/doc/man/archive.8 b/doc/man/archive.8
deleted file mode 100644 (file)
index 67b84bf..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-.\" $Revision: 5909 $
-.TH ARCHIVE 8
-.SH NAME
-archive \- Usenet article archiver
-.SH SYNOPSIS
-.B archive
-[
-.BI \-a " archive"
-]
-[
-.B \-c
-]
-[
-.B \-f
-]
-[
-.BI \-i " index"
-]
-[
-.BI \-p " newsgroup-list"
-]
-[
-.B \-r
-]
-[
-.I input
-]
-.SH DESCRIPTION
-.I Archive
-makes copies of files specified on its standard input.
-It is normally run either as a channel feed under
-.IR innd (8),
-or by a script before
-.IR expire (8)
-is run.
-.PP
-.I Archive
-reads the named
-.I input
-file, or standard input if no file is given.
-The input is taken as a sequence of lines;
-blank lines and lines starting with a number sign (``#'') are ignored.
-All other lines should specify the token of an article to archive.
-Every article is retrieved from a token,
-and the Xref: header is used to determine the target file in the
-archive directory.
-You can limit the targets taken from the Xref: header with the ``\-p'' option.
-.PP
-Files are copied to a directory within the archive directory,
-.IR <patharchive\ in\ inn.conf> .
-The default is to create a hierarchy that mimics the input files;
-intermediate directories will be created as needed.
-For example, if the input token represents article 2211 in the newsgroup
-comp.sources.unix,
-.IR archive
-will generate a copy in
-.IR <patharchive\ in\ inn.conf>/comp/sources/unix/2211 .
-.SH OPTIONS
-.TP
-.B \-a\ archive
-If the ``\-a'' flag is used then its argument specifies the directory to
-archive in instead of
-.IR <patharchive\ in\ inn.conf> .
-.TP
-.B \-c
-If the ``\-c'' flag is used, then directory names will be flattened as if
-by the ``\-f'' flag; additionally, all posts will be concatenated into a
-.B single\ file ,
-appending if the file already exists, with the final component of the
-filename being YYYYMM based on the local execution time of
-.IR archive.
-In this case, on December 14, 1998, the file would be copied to
-.IR <patharchive\ in\ inn.conf>/comp.sources.unix/199812 .
-.TP
-.B \-f
-If the ``\-f'' flag is used, then all directory names will be
-flattened out, replacing the slashes with periods.
-In this case, the file would be copied to
-.IR <patharchive\ in\ inn.conf>/comp.sources.unix/2211 .
-.TP
-.B \-i
-If the ``\-i'' flag is used, then
-.I archive
-will append one line to the specified
-.I index
-file for each article that it copies.
-This line will contain the destination name as well as the Message-ID and
-Subject headers.
-.TP 
-.B \-p newsgroup-list
-Limits the targets taken from the Xref: header to the groups specified in
-.I newsgroup-list.
-The
-.I newsgroup-list
-is a comma-separated 
-.IR uwildmat (3)
-list of newsgroups you wish to have
-.IR archive
-handle.
-.TP 
-.B \-r
-By default,
-.I archive
-sets its standard error to
-.IR <pathlog\ in\ inn.conf>/errlog .
-To suppress this redirection, use the ``\-r'' flag.
-.SH EXIT STATUS
-If the input is exhausted,
-.I archive
-will exit with a zero status.
-If an I/O error occures, it will try to spool its input, copying it to a file.
-If there was no input filename, the standard input will be copied to
-.I <pathoutgoing in inn.conf>/archive
-and the program will exit.
-If an input filename was given, a temporary file named
-.IR input .bch
-(if
-.I input
-is an absolute pathname)
-or
-.I <pathoutgoing in inn.conf>/input.bch
-(if the filename does not begin with a slash) is created.
-Once the input is copied,
-.I archive
-will try to rename this temporary file to be the name of the input file,
-and then exit.
-
-.SH EXAMPLES
-A typical
-.IR newsfeeds (5)
-entry to archive most source newsgroups is as follows:
-.PP
-.RS
-.nf
-source-archive\e
-       :!*,*sources*,!*wanted*,!*.d\e
-       :Tc,Wn\e
-       :<pathbin in inn.conf>/archive \-f \-i \e
-           <patharchive in inn.conf>/INDEX
-.fi
-.RE
-
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: archive.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5),
-newsfeeds(5).
diff --git a/doc/man/auth_krb5.8 b/doc/man/auth_krb5.8
deleted file mode 100644 (file)
index aa1d313..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-.\" 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 "AUTH_KRB5 8"
-.TH AUTH_KRB5 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-auth_krb5 \- nnrpd Kerberos v5 authenticator
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBauth_krb5\fR [\fB\-i\fR \fIinstance\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This program does authentication for \fBnnrpd\fR against a Kerberos v5 \s-1KDC\s0.
-This is \s-1NOT\s0 real Kerberos authentication using service tickets; instead, a
-username and password is used to attempt to obtain a Kerberos v5 \s-1TGT\s0 to
-confirm that they are valid.  As such, this authenticator assumes that
-\&\fBnnrpd\fR has been given the user's username and password, and therefore is
-not as secure as real Kerberos authentication.  It generally should only
-be used with \s-1NNTP\s0 over \s-1SSL\s0 to protect the password from sniffing.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-i\fR \fIinstance\fR" 4
-.IX Item "-i instance"
-If this option is given, \fIinstance\fR will be used as the instance of the
-principal received from \fBnnrpd\fR and authentication will be done against
-that principal instead of the base principal.  In other words, a principal
-like \f(CW\*(C`user\*(C'\fR, when passed to \fBauth_krb5\fR invoked with \f(CW\*(C`\-i nntp\*(C'\fR, will be
-transformed into \f(CW\*(C`user/nntp\*(C'\fR before attempting Kerberos authentication.
-.Sp
-Since giving one's password to \fBnnrpd\fR is not as secure as normal
-Kerberos authentication, this option supports a configuration where all
-users are given a separate instance just for news authentication with its
-own password, so their regular account password isn't exposed via \s-1NNTP\s0.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-The following \fIreaders.conf\fR\|(5) fragment tells nnrpd to authenticate users
-by attempting to obtain Kerberos v5 TGTs for them, appending an instance
-of \f(CW\*(C`nntp\*(C'\fR to usernames before doing so:
-.PP
-.Vb 3
-\&    auth kerberos {
-\&        auth: "auth_krb5 \-i nntp"
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access kerberos {
-\&        users: "*/nntp"
-\&        newsgroups: example.*
-\&    }
-.Ve
-.PP
-Access is granted to the example.* groups for all users who successfully
-authenticate.
-.SH "BUGS"
-.IX Header "BUGS"
-Currently, any username containing realm information (containing \f(CW\*(C`@\*(C'\fR) is
-rejected.  This is to prevent someone from passing in a username
-corresponding to a principal in another realm that they have access to and
-gaining access to the news server via it.  However, this is also something
-that people may wish to do under some circumstances, so there should be a
-better way of handling it (such as, perhaps, a list of acceptable realms
-or a \-r flag specifying the realm in which to attempt authentication).
-.PP
-It's not clear the right thing to do when the username passed in contains
-a \f(CW\*(C`/\*(C'\fR and \fB\-i\fR was also given.  Right now, \fBauth_krb5\fR will create a
-malformed Kerberos principal with multiple instances and attempt to
-authenticate against it, which will fail but perhaps not with the best
-error message.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Originally written by Christopher P. Lindsey.  This documentation was
-written by Russ Allbery <rra@stanford.edu> based on Christopher's original
-\&\s-1README\s0 file.
-.PP
-$Id: auth_krb5.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5)
-.PP
-The latest version of Christopher's original \fBnnrpkrb5auth\fR may be found
-on his web site at <http://www.mallorn.com/tools/>.
diff --git a/doc/man/auth_smb.8 b/doc/man/auth_smb.8
deleted file mode 100644 (file)
index 42ac1f4..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-.\" 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 "AUTH_SMB 8"
-.TH AUTH_SMB 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-auth_smb \- nnrpd Samba authenticator
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBauth_smb\fR \fBserver\fR [\fBbackup_server\fR] \fBdomain\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This program does authentication for \fBnnrpd\fR against an \s-1SMB\s0 server.  It
-passes the received username and password to \fBserver\fR for validation in
-the specified \s-1SMB\s0 \fBdomain\fR.  A backup server may optionally be
-supplied; if it is missing, only \fBserver\fR is used.
-.PP
-If authentication is successful, the original username is returned as
-the authentication identity.  Brief errors, including incorrect password
-and failure contacting the server, are logged.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-The following \fIreaders.conf\fR\|(5) fragment grants access to users who can
-authenticate against an \s-1SMB\s0 server:
-.PP
-.Vb 4
-\&    auth windows {
-\&        auth: "auth_smb pdc.example.com bdc.example.com USERS"
-\&        default\-domain: "users.example.com"
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access internal {
-\&        users: "*@users.example.com"
-\&        newsgroups: example.*
-\&    }
-.Ve
-.PP
-Access is granted to the example.* groups after successful
-authentication.
-.SH "BUGS"
-.IX Header "BUGS"
-We should link against an external \s-1SMB\s0 library rather than maintain one
-within the \s-1INN\s0 source tree.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Originally written October 2000 by Krischan Jodies <krischan@jodies.cx>,
-based heavily on pam_smb v1.1.6 by David Airlie <airlied@samba.org>.
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-.PP
-$Id: auth_smb.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5)
diff --git a/doc/man/batcher.8 b/doc/man/batcher.8
deleted file mode 100644 (file)
index 3cd2a90..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-.\" $Revision: 6491 $
-.TH BATCHER 8
-.SH NAME
-batcher \- article-batching backend for InterNetNews
-.SH SYNOPSIS
-.B batcher
-[
-.BI \-a " arts"
-]
-[
-.BI \-A " total_arts"
-]
-[
-.BI \-b " size"
-]
-[
-.BI \-B " total_size"
-]
-[
-.BI \-i " string"
-]
-[
-.BI \-N " num_batches"
-]
-[
-.BI \-p " process"
-]
-[
-.B \-r
-]
-[
-.BI \-s " separator"
-]
-[
-.BI \-S " alt_spool"
-]
-[
-.B \-v
-]
-.I host
-[
-.I input
-]
-.SH DESCRIPTION
-.I Batcher
-reads uses a list of files to prepare news batches for the specified
-.IR host .
-It is normally invoked by a script run out of
-.IR cron (8)
-that uses
-.IR shlock (1)
-to lock the host name, followed by a
-.IR ctlinnd (8)
-command to flush the batchfile.
-.PP
-.I Batcher
-reads the named
-.I input
-file, or standard input if no file is given.
-Relative pathnames are interpreted from the
-.I <pathoutgoing in inn.conf>
-directory.
-The input is taken as a sequence of lines;
-blank lines and lines starting with a number sign (``#'') are ignored.
-All other lines should consist of one or two fields separated by a single space.
-The first field is either the storage token of an article or the
-name of a file holding an article; if it is not an an absolute
-pathname or storage token, it is taken relative to
-.IR <patharticles\ in\ inn.conf> .
-The second field, if present, specifies the size of the article in bytes.
-.SH OPTIONS
-.TP
-.B \-S alt_spool
-The ``\-S'' flag may be used to specify an alternate spool directory to
-use if the article is not found; this would perhaps be an NFS-mounted
-spool directory of a master server with longer expiration times.
-.TP
-.B \-r
-By default, the program reports errors to
-.IR <pathlog\ in\ inn.conf>/errlog .
-To suppress this redirection and report errors to standard error,
-use the ``\-r'' flag.
-.TP
-.B \-v
-Upon exit,
-.I batcher
-reports statistics via
-.IR syslog (3).
-If the ``\-v'' flag is used, they will also be printed on the standard
-output.
-.TP
-.B \-b size
-.I Batcher
-collects the text of the named articles into batches.
-To limit the size of each batch, use the ``\-b'' flag.
-The default size is 60 kilobytes.
-Using ``\-b\ 0'' allows unlimited batch sizes.
-.TP
-.B \-a arts
-To limit the number of articles in each batch, use the ``\-a'' flag.
-The default is no limit.
-A new batch will be started when either the byte count or number of
-articles written exceeds the specified limits.
-.TP
-.B \-B total_size
-To limit the total number of bytes written for all batches, use the ``\-B''
-flag.
-.TP
-.B \-A total_arts
-To limit the total number of articles that can be batched use the ``\-A''
-flag.
-.TP
-.B \-N num_batches
-To limit the total number of batches that should be created use the ``\-N''
-flag.
-.IP
-In all three of the above cases, the default is zero, that is, no limit.
-.TP
-.B \-i string
-A batch starts with an identifying line to specify the unpacking method
-to be used on the receiving end.
-When the ``\-i'' flag is used, the initial string,
-.IR string ,
-followed by a newline, will be output at the start of every batch.
-The default is to have no initial string.
-.TP
-.B \-s separator
-Each article starts with a separator line to indicate the size of the article.
-To specify the separator use the ``\-s'' flag.
-This is a
-.IR sprintf (3)
-format string which can have a single ``%ld'' parameter which will be given
-the size of the article.
-If the separator is not empty, then the string and a newline will be output
-before every article.
-The default separator is ``#!\ rnews\ %ld''.
-.TP
-.B \-p process
-By default, batches are written to standard output, which
-is not useful when more than one output batch is created.
-Use the ``\-p'' flag to specify the shell command that should be
-created (via
-.IR popen (3))
-whenever a new batch is started.
-The process is a
-.IR sprintf (3)
-format string which can have a single ``%s'' parameter which will be given
-the host name.
-A common value is:
-.PP
-.RS
-.nf
-( echo '#! cunbatch' ; exec compress ) | uux \- \-r \-z %s!rnews
-.fi
-.RE
-.SH EXIT STATUS
-.PP
-If the input is exhausted,
-.I batcher
-will exit with a zero status.
-If any of the limits specified with the ``\-B'', ``\-A'', or ``\-N'' flags
-is reached, or if there is an error writing the batch, then
-.I batcher
-will try to spool the remaining input, copying it to a file.
-If there was no input filename, standard input will be copied to
-.I <pathoutgoing in inn.conf>/host
-and the program will exit.
-If an input filename was given, the input will be copied to 
-a temporary file named
-.IR input .bch
-(if
-.I input
-is an absolute pathname)
-or
-.I <pathoutgoing in inn.conf>/input.bch
-(if the filename does not begin with a slash).
-Once the input is copied,
-.I batcher
-will try to rename this temporary file to be the name of the input file,
-and then exit.
-.PP
-Upon receipt of an interrupt or termination signal,
-.I batcher
-will finish sending the current article, close the batch, and then
-rewrite the batchfile according as described in the previous paragraph.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: batcher.8 6491 2003-10-18 05:56:37Z rra $
-.SH "SEE ALSO"
-ctlinnd(8),
-inn.conf(5),
-newsfeeds(5),
-shlock(1).
diff --git a/doc/man/buffchan.8 b/doc/man/buffchan.8
deleted file mode 100644 (file)
index 1fd39c1..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-.\" $Revision: 5909 $
-.TH BUFFCHAN 8
-.SH NAME
-buffchan \- buffered file-writing backend for InterNetNews
-.SH SYNOPSIS
-.B buffchan
-[
-.B \-b
-]
-[
-.BI \-c " lines"
-]
-[
-.BI \-C " seconds"
-]
-[
-.BI \-d " directory"
-]
-[
-.BI \-f " num_fields"
-]
-[
-.BI \-m " map"
-]
-[
-.BI \-p " pidfile"
-]
-[
-.BI \-l " lines"
-]
-[
-.BI \-L " seconds"
-]
-[
-.B \-r
-]
-[
-.BI \-s " filename_format"
-]
-[
-.B \-u
-]
-.SH DESCRIPTION
-.I Buffchan
-reads lines from standard input and copies certain fields in
-each line into files named by other fields within the line.
-.I Buffchan
-is intended to be called by
-.IR innd (8)
-as an exploder feed.
-.SH OPTIONS
-.TP
-.B \-b
-Once
-.I buffchan
-opens a file it keeps it open.
-The input must therefore never specify more files than the
-number of available descriptors can keep open.
-If the ``\fB\-b\fP'' flag is used, the program will allocate a buffer and
-attach it to the file using
-.IR setbuf (3).
-.TP
-.B \-c lines
-If the ``\fB\-c\fP'' flag is used,
-.I buffchan
-will close, and re-open, a file after every
-.I lines
-lines are written to a file.
-.TP
-.B \-C seconds
-Similarly, the ``\fB\-C\fP'' flag may be used to specify that all files should
-be closed and re-opened every
-.I seconds
-seconds.
-.TP
-.B \-d directory
-The ``\fB\-d\fP'' flag may be used to specify a directory the program should
-change to before starting.
-If this flag is used, then the default for the ``\fB\-s\fP'' flag is changed to
-be a simple ``%s''.
-.TP
-.B \-f num_fields
-Buffchan
-input is interpreted as a sequence of lines.
-Each line contains a fixed number of initial fields, followed by a
-variable number of filename fields.
-All fields in a line are separated by whitespace.
-The default number of initial fields is one; the ``\fB\-f\fP''
-flag may be
-used to specify a different number of fields.
-.TP
-.B \-m map
-Map files specify short names as aliases for domain names; see
-.IR filechan (8)
-for details and an example.
-.TP
-.B \-p pidfile
-If the ``\fB\-p\fP'' flag is used, the program will write a line containing
-its process ID (in text) to the specified file.
-.TP
-.B \-l lines
-If the ``\fB\-l\fP'' flag is used,
-.I buffchan
-will call
-.IR fflush (3)
-after every
-.I lines
-lines are written to a file.
-.TP
-.B \-L seconds
-If the ``\fB\-L\fP'' flag is used,
-all files will be flushed every
-.I n
-seconds.
-.TP
-.B \-r
-By default, the program sends its error messages to
-.IR <pathlog\ in\ inn.conf>/errlog .
-To suppress this redirection and send error messages to standard error,
-use the ``\fB\-r\fP'' flag.
-.TP
-.B \-s filename_format
-After the initial fields, each remaining field names a file to
-write.
-The ``\fB\-s\fP'' flag may be used to specify a format string that maps
-the field to a file name.
-This is a
-.IR sprintf (3)
-format string which should have a single ``%s'' parameter which will be given
-the contents of a non-initial field.
-The default value is
-.IR <pathoutgoing\ in\ inn.conf>/%s .
-See the description of this flag in
-.IR filechan (8).
-.TP
-.B \-u
-If the ``\fB\-u\fP'' flag is used, the program will request unbuffered output.
-.PP
-.I Buffchan
-can be invoked as an exploder feed (see
-.IR newsfeeds (5)).
-As such, if a line starts with an exclamation point it will be treated
-as a command.
-There are three commands, described below:
-.TP
-.B flush
-The ``flush'' command closes and re-opens
-all open files; ``flush\ xxx'' which flushes only the specified site.
-These are analogous to the
-.IR ctlinnd (8)
-\&``flush'' command, 
-and can be achieved by doing a ``send\ "flush\ xxx"'' command.
-Applications can tell that the ``flush'' has completed by renaming the
-file before issuing the command;
-.I buffchan
-has completed the command when the original filename re-appears.
-If
-.I <$ac_cv_func_fchmod in config.cache>
-is ``yes'', then 
-.I buffchan
-also changes the access permissions of the file from read-only for
-everyone to read-write for owner and group as it flushes or closes each
-output file.  It will change the modes back to read-only if it re-opens
-the same file.
-.TP
-.B drop
-The ``drop'' command is similar to the ``flush'' command except that no
-files are re-opened.
-If given an argument, then the specified site is dropped, otherwise all
-sites are dropped.
-(Note that the site will be restarted if the input stream mentions the
-site.)
-When a
-.I ctlinnd
-\&``drop site'' command is sent,
-.I innd
-will automatically forward the command to
-.I buffchan
-for sites listed as funnels feeding into this exploder.
-To drop all sites, use the
-.I ctlinnd
-\&``send buffchan-site drop'' command.
-.TP
-.B readmap
-The map file (specified with the ``\-m'' flag) is reloaded.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: buffchan.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-ctlinnd(8),
-filechan(8),
-inn.conf(5),
-innd(8),
-newsfeeds(5).
diff --git a/doc/man/buffindexed.conf.5 b/doc/man/buffindexed.conf.5
deleted file mode 100644 (file)
index 42dea50..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-.\" $Revision: 5909 $
-.TH BUFFINDEXED.CONF 5
-.SH NAME
-buffindexed.conf \- configuration file for buffindexed ovmethod
-.SH DESCRIPTION
-The file
-.I <pathetc in inn.conf>/buffindexed.conf
-is required if buffindexed ovmethod is used.
-.PP
-Buffindexed is one of ovmethod which is specified in
-.IR inn.conf .
-It uses preconfigured buffer files to store overview data and index, and
-never needs more disk space other than those files.  The files are divided
-into 8 KB blocks internally; a given block is allocated for either overview
-index or overview data.  A block is never shared among multiple newsgroups.
-There is a database file:
-.I <pathdb in inn.conf>/group.index
-that includes information about each  newsgroup:  the pointer to the index
-block for the group, high mark, low mark, flag of the group, the number of
-articles, and etc.  This file is created automatically when all buffers
-are initialized and must not be edited manually.  If all buffers are filled up,
-.IR innd (8)
-throttles itself.  Note that the buffer files are never rolled over and
-overwritten the way CNFS does.  You need to append another buffer file in 
-this event.  You can see the buffer usage with
-.IR inndf (8)
-with ``-o'' option.
-.PP
-The file consists of a series of lines;
-blank lines and lines beginning with a number sign (``#'') are ignored.
-There is only one kind of configuration line.
-The order of lines in this file is not important.
-.PP
-.RS
-.nf
-index:file_name:buffer_size
-.fi
-.RE
-.PP
-\&``Index'' is an index of overview buffer.
-\&``Index'' must be between 0 and 65535.
-\&``File_name'' is the path to overview buffer file.
-The length of this path should be not more than 63 characters.
-\&``Buffer_size'' is the length of buffer file in kilobytes
-in decimal (1 KB = 1024 bytes).  If the ``file_name'' is not a special
-device, the actual file size must be buffer_size * 1024 bytes.
-You can NOT use buffers over 2 GB even if you specify
-.IR <\-\-with\-largefiles\ at\ configure> ,
-or buffers will be broken.  It'll be fixed in the future.
-.PP
-When creating new overview buffer, there are two different methods for
-creating the files.
-.TP
-.BR 1. " Create a big file on top of a standard filesystem."
-.sp 1
-Use "dd" to create the overview buffer
-files, such as "dd if=/dev/zero of=/path/to/ovbuff bs=1024 count=N"
-where N is the buffer_size.
-.TP
-.BR 2. " Use block disk devices directly."
-.sp 1
-If your operating system will allow you to
-.I mmap()
-block disk devices (Solaris does, FreeBSD does not), this is the
-recommended method.  But note that Solaris (at least 2.6) seems to
-have a problem in regional locking of block disk devices, and should
-not be used as overview data will be corrupted.
-.sp 1
-Partition the disks to make each partition slightly larger (a few MB larger)
-than the intended size of each overview buffer.
-It is not recommend to use the block device files already located in
-``/dev''; instead, use "mknod" to create a new set of block device files.
-In order to do this, do an "ls -Ll" of the /dev/dsk partition.
-The major and minor device numbers are in the fifth and sixth columns (right
-before the date), respectively.  This information should be fed to "mknod"
-to make a "block-type special file" (b).
-Here is a short script that accomplishes this when fed the name of the
-partition as listed in ``/dev/dsk/'':
-.sp 1
-.nf
-.in +0.5i
-#!/bin/sh
-disk=$1
-major=`ls -l /dev/dsk/$disk | awk '{print $5}' | tr -d ,`
-minor=`ls -l /dev/dsk/$disk | awk '{print $6}`
-mkdir /ovbuff
-mknod /ovbuff/$disk b $major $minor
-.in -0.5i
-.fi
-.sp 1
-The created device files themselves consume very little space.
-.PP
-In either case, make certain that each overview buffer file is owned by
-.IR <USER\ specified\ with\ \-\-with\-news\-user\ at\ configure> ,
-.IR <GROUP\ specified\ with\ \-\-with\-news\-group\ at\ configure> ,
-and has read/write modes for the owner and group (mode ``0664'' or ``0660'').
-.PP
-When you first start
-.IR innd (8)
-and everything is configured properly, you should see messages in
-.I <pathlog in inn.conf>/news.notice
-which look like:
-.sp 1   
-.nf
-.in +0.5i
-Aug 27 00:00:00 kevlar innd: buffindexed: No magic cookie found for buffindexed 0, initializing
-.in -0.5i
-.fi
-.PP
-You MUST entirely recreate overview if you remove or relpace buffers.
-You need not recreate if you just append new buffers.  And whenever you
-recreate the overview data base, you need to clean all the buffers.
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: buffindexed.conf.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5).
diff --git a/doc/man/ckpasswd.8 b/doc/man/ckpasswd.8
deleted file mode 100644 (file)
index 4144211..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-.\" 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 "CKPASSWD 8"
-.TH CKPASSWD 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ckpasswd \- nnrpd password authenticator
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBckpasswd\fR [\fB\-gs\fR] [\fB\-d\fR \fIdatabase\fR] [\fB\-f\fR \fIfilename\fR]
-[\fB\-u\fR \fIusername\fR \fB\-p\fR \fIpassword\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBckpasswd\fR is the basic password authenticator for nnrpd, suitable for
-being run from an auth stanza in \fIreaders.conf\fR.  See \fIreaders.conf\fR\|(5) for
-more information on how to configure an nnrpd authenticator.
-.PP
-\&\fBckpasswd\fR accepts a username and password from nnrpd and tells \fInnrpd\fR\|(8)
-whether that's the correct password for that username.  By default, when
-given no arguments, it tries to check the password using \s-1PAM\s0 if support
-for \s-1PAM\s0 was found when \s-1INN\s0 was built.  Failing that, it tries to check the
-password against the password field returned by \fIgetpwnam\fR\|(3).  Note that
-these days most systems no longer make real passwords available via
-\&\fIgetpwnam\fR\|(3) (some still do if and only if the program calling \fIgetpwnam\fR\|(3)
-is running as root).
-.PP
-When using \s-1PAM\s0, \fBckpasswd\fR identifies itself as \f(CW\*(C`nnrpd\*(C'\fR, not as
-\&\f(CW\*(C`ckpasswd\*(C'\fR, and the \s-1PAM\s0 configuration must be set up accordingly.  The
-details of \s-1PAM\s0 configuration are different on different operating systems
-(and even different Linux distributions); see \s-1EXAMPLES\s0 below for help
-getting started, and look for a \fIpam\fR\|(7) or \fIpam.conf\fR\|(4) manual page on your
-system.
-.PP
-When using any method other than \s-1PAM\s0, \fBckpasswd\fR expects all passwords to
-be stored encrypted by the system \fIcrypt\fR\|(3) function and calls \fIcrypt\fR\|(3) on
-the supplied password before comparing it to the expected password.  \s-1IF\s0
-you're using a different password hash scheme (like \s-1MD5\s0), you must use
-\&\s-1PAM\s0.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-d\fR \fIdatabase\fR" 4
-.IX Item "-d database"
-Read passwords from a database (ndbm or dbm format depending on what your
-system has) rather than by using \fIgetpwnam\fR\|(3).  \fBckpasswd\fR expects
-\&\fIdatabase\fR.dir and \fIdatabase\fR.pag to exist and to be a database keyed by
-username with the encrypted passwords as the values.
-.Sp
-While \s-1INN\s0 doesn't come with a program intended specifically to create such
-databases, on most systems it's fairly easy to write a Perl script to do
-so.  Something like:
-.Sp
-.Vb 16
-\&    #!/usr/bin/perl
-\&    use NDBM_File;
-\&    use Fcntl;
-\&    tie (%db, 'NDBM_File', '/path/to/database', O_RDWR|O_CREAT, 0640)
-\&        or die "Cannot open /path/to/database: $!\en";
-\&    $| = 1;
-\&    print "Username: ";
-\&    my $user = <STDIN>;
-\&    chomp $user;
-\&    print "Password: ";
-\&    my $passwd = <STDIN>;
-\&    chomp $passwd;
-\&    my @alphabet = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
-\&    my $salt = join '', @alphabet[rand 64, rand 64];
-\&    $db{$user} = crypt ($passwd, $salt);
-\&    untie %db;
-.Ve
-.Sp
-Note that this will echo back the password when typed; there are obvious
-improvements that could be made to this, but it should be a reasonable
-start.  Sometimes a program like this will be available with the name
-\&\fBdbmpasswd\fR.
-.Sp
-This option will not be available on systems without dbm or ndbm
-libraries.
-.IP "\fB\-f\fR \fIfilename\fR" 4
-.IX Item "-f filename"
-Read passwords from the given file rather than using \fIgetpwnam\fR\|(3).  The
-file is expected to be formatted like a system password file, at least
-vaguely.  That means each line should look something like:
-.Sp
-.Vb 1
-\&    username:pdIh9NCNslkq6
-.Ve
-.Sp
-(and each line may have an additional colon after the encrypted password
-and additional data; that data will be ignored by \fBckpasswd\fR).  Lines
-starting with a number sign (`#') are ignored.  \s-1INN\s0 does not come with a
-utility to create the encrypted passwords, but \fBhtpasswd\fR (which comes
-with Apache) can do so and it's a quick job with Perl (see the example
-script under \fB\-d\fR).  If using Apache's \fBhtpasswd\fR program, be sure to
-give it the \fB\-d\fR option so that it will use \fIcrypt\fR\|(3).
-.IP "\fB\-g\fR" 4
-.IX Item "-g"
-Attempt to look up system group corresponding to username and return a
-string like \*(L"user@group\*(R" to be matched against in \fIreaders.conf\fR.  This
-option is incompatible with the \fB\-d\fR and \fB\-f\fR options.
-.IP "\fB\-p\fR \fIpassword\fR" 4
-.IX Item "-p password"
-Use \fIpassword\fR as the password for authentication rather than reading a
-password using the nnrpd authenticator protocol.  This option is useful
-only for testing your authentication system (particularly since it
-involves putting a password on the command line), and does not work when
-\&\fBckpasswd\fR is run by \fBnnrpd\fR.  If this option is given, \fB\-u\fR must also
-be given.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-Check passwords against the result of \fIgetspnam\fR\|(3) instead of \fIgetpwnam\fR\|(3).
-This function, on those systems that supports it, reads from /etc/shadow
-or similar more restricted files.  If you want to check passwords supplied
-to \fInnrpd\fR\|(8) against system account passwords, you will probably have to
-use this option on most systems.
-.Sp
-Most systems require special privileges to call \fIgetspnam\fR\|(3), so in order
-to use this option you may need to make \fBckpasswd\fR setgid to some group
-(like group \*(L"shadow\*(R") or even setuid root.  \fBckpasswd\fR has not been
-specifically audited for such uses!  It is, however, a very small program
-that you should be able to check by hand for security.
-.Sp
-This configuration is not recommended if it can be avoided, for serious
-security reasons.  See \*(L"\s-1SECURITY\s0 \s-1CONSIDERATIONS\s0\*(R" in readers.conf\&(5) for
-discussion.
-.IP "\fB\-u\fR \fIusername\fR" 4
-.IX Item "-u username"
-Authenticate as \fIusername\fR.  This option is useful only for testing (so
-that you can test your authentication system easily) and does not work
-when \fBckpasswd\fR is run by \fBnnrpd\fR.  If this option is given, \fB\-p\fR must
-also be given.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-See \fIreaders.conf\fR\|(5) for examples of \fInnrpd\fR\|(8) authentication configuration
-that uses \fBckpasswd\fR to check passwords.
-.PP
-An example \s-1PAM\s0 configuration for \fI/etc/pam.conf\fR that tells \fBckpasswd\fR
-to check usernames and passwords against system accounts is:
-.PP
-.Vb 2
-\&    nnrpd auth    required pam_unix.so
-\&    nnrpd account required pam_unix.so
-.Ve
-.PP
-Your system may want you to instead create a file named \fInnrpd\fR in
-\&\fI/etc/pam.d\fR with lines like:
-.PP
-.Vb 2
-\&    auth    required pam_unix.so
-\&    account required pam_unix.so
-.Ve
-.PP
-This is only the simplest configuration.  You may be able to include
-common shared files, and you may want to stack other modules, either to
-allow different authentication methods or to apply restrictions like lists
-of users who can't authenticate using \fBckpasswd\fR.  The best guide is the
-documentation for your system and the other \s-1PAM\s0 configurations you're
-already using.
-.PP
-To test to make sure that \fBckpasswd\fR is working correctly, you can run it
-manually and then give it the username (prefixed with \f(CW\*(C`ClientAuthname:\*(C'\fR)
-and password (prefixed with \f(CW\*(C`ClientPassword:\*(C'\fR) on standard input.  For
-example:
-.PP
-.Vb 2
-\&    (echo 'ClientAuthname: test' ; echo 'ClientPassword: testing') \e
-\&        | ckpasswd \-f /path/to/passwd/file
-.Ve
-.PP
-will check a username of \f(CW\*(C`test\*(C'\fR and a password of \f(CW\*(C`testing\*(C'\fR against the
-username and passwords stored in \fI/path/to/passwd/file\fR.  On success,
-\&\fBckpasswd\fR will print \f(CW\*(C`User:test\*(C'\fR and exit with status 0.  On failure,
-it will print some sort of error message and exit a non-zero status.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: ckpasswd.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIreaders.conf\fR\|(5), \fInnrpd\fR\|(8)
-.PP
-Linux users who want to use \s-1PAM\s0 should read the Linux-PAM System
-Administrator's Guide at
-<http://www.kernel.org/pub/linux/libs/pam/Linux\-PAM\-html/Linux\-PAM_SAG.html>.
diff --git a/doc/man/clientlib.3 b/doc/man/clientlib.3
deleted file mode 100644 (file)
index 1bbb0a3..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-.\" $Revision: 6312 $
-.TH CLIENTLIB 3
-.SH NAME
-clientlib \- NNTP clientlib part of InterNetNews library
-.SH SYNOPSIS
-.nf
-.ta \w'    unsigned long    'u
-.B "extern FILE        *ser_rd_fp;"
-.B "extern FILE        *ser_wr_fp;"
-.B "extern char        ser_line[];"
-
-.B "char *"
-.B "getserverbyfile(file)"
-.B "    char   *file;"
-
-.B "int"
-.B "server_init(host)"
-.B "    char   *host;"
-
-.B "int"
-.B "handle_server_response(response, host)"
-.B "    int    reponse;"
-.B "    char   *host;"
-
-.B "void"
-.B "put_server(text)"
-.B "    char   *text;"
-
-.B "int"
-.B "get_server(buff, buffsize)"
-.B "    char   *buff;"
-.B "    int    buffsize;"
-
-.B "void"
-.B "close_server()"
-.fi
-.SH DESCRIPTION
-The routines described in this manual page are part of the InterNetNews
-library,
-.IR libinn (3).
-They are replacements for the ``clientlib'' part of the NNTP distribution,
-and are intended to be used in building programs like
-.IR rrn .
-.PP
-.I Getserverbyfile
-calls
-.I GetConfigValue
-to get the name of the local NNTP server.
-It returns a pointer to static space.
-The
-.I file
-parameter is ignored.
-.PP
-.I Server_init
-opens a connect to the NNTP server at the specified
-.IR host .
-It returns the server's response code or \-1 on error.
-If a connection was made, then
-.I ser_rd_fp
-and
-.I ser_wr_fp
-can be used to read from and write to the server, respectively, and
-.I ser_line
-will contain the server's response.
-.I Ser_line
-can also be used in other routines.
-.PP
-.I Handle_server_response
-decodes the
-.IR response ,
-which comes from the server on
-.IR host.
-If the client is authorized, it returns 0.
-A client that is only allowed to read is authorized, but
-.I handle_server_response
-will print a message on the standard output.
-If the client is not authorized to talk to the server, then a message is
-printed and the routine returns \-1.
-.PP
-.I Put_server
-sends the text in
-.I buff
-to the server, adding the necessary NNTP line terminators, and flushing
-the I/O buffer.
-.PP
-.I Get_server
-reads a line of text from the server into
-.IR buff ,
-reading at most
-.I buffsize
-characters.
-Any trailing \er\en terminators are stripped off.
-.I Get_server
-returns \-1 on error.
-.PP
-.I Close_server
-sends a ``quit'' command to the server and closes the connection.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: clientlib.3 6312 2003-05-04 21:40:11Z rra $
-.SH "SEE ALSO"
-libinn(3).
diff --git a/doc/man/cnfsheadconf.8 b/doc/man/cnfsheadconf.8
deleted file mode 100644 (file)
index 8acb5cb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-.\" $Revision: 5909 $
-.TH CNFSHEADCONF 8
-.SH NAME
-cnfsheadconf \- set CNFS header
-.SH SYNOPSIS
-.B cnfsheadconf
-[
-.B \-c CLASS
-]
-[
-.B \-h
-]
-[
-.B \-w
-]
-.SH DESCRIPTION
-.I Cnfsheadconf
-reads
-.I <pathetc in inn.conf>/cycbuff.conf
-and
-.I <pathetc in inn.conf>/storage.conf
-to determine which cycbuffs are available, reads the specified cycbuff, and
-modifies the header as directed by the interactive user.
-.SH OPTIONS
-.TP
-.B \-c CLASS
-.I Cnfsheadconf
-prints status of (and modifies, if appropriate) the specified class.
-.TP
-.B \-h
-.I Cnfsheadconf
-prints usage information.
-.TP
-.B \-w
-.I Cnfsheadconf
-prompts for modifications to make to cycbuff header.
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: cnfsheadconf.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-cycbuff.conf(5),
-inn.conf(5),
-storage.conf(5).
diff --git a/doc/man/cnfsstat.8 b/doc/man/cnfsstat.8
deleted file mode 100644 (file)
index ed074e0..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-.\" $Revision: 5909 $
-.TH CNFSSTAT 8
-.SH NAME
-cnfsstat \- show usage of cycbuffs
-.SH SYNOPSIS
-.B cnfsstat
-[
-.B \-a
-]
-[
-.B \-c CLASS
-]
-[
-.B \-h
-]
-[
-.B \-l
-[
-seconds
-]
-]
-[
-.B \-m BUFFER
-]
-[
-.B \-P
-]
-[
-.B \-p
-]
-[
-.B \-s
-]
-.SH DESCRIPTION
-.I Cnfsstat
-reads
-.I <pathetc in inn.conf>/cycbuff.conf
-and
-.I <pathetc in inn.conf>/storage.conf
-to determine which cycbuffs are available, read the specified cycbuffs, and
-shows their usage status.
-.PP
-.I Cnfsstat
-can be invoked from
-.IR rc.news (8),
-if
-.I <docnfsstat in inn.conf>
-is ``true'', and the result is written to
-.IR syslog (3).
-.SH OPTIONS
-.TP
-.B \-a
-.I Cnfsstat
-prints also the age of the oldest article in the cycbuff.
-.TP
-.B \-c CLASS
-.I Cnfsstat
-prints information only for the specified class.
-.TP
-.B \-h
-.I Cnfsstat
-prints usage information.
-.TP
-.B \-l [ seconds ]
-.I Cnfsstat
-prints a status snapshot every
-.IR seconds ,
-and only exits if there is an error.
-The default interval is 600 seconds.
-.TP
-.B \-m BUFFER
-.I Cnfsstat
-prints information about the specified buffer in a format suitable
-for mrtg.
-.TP
-.B \-P
-.I Cnfsstat
-writes PID into
-.IR <pathrun\ in\ inn.conf>/cnfsstat.pid .
-.TP
-.B \-p
-.I Cnfsstat
-prints an mrtg config file.
-.TP
-.B \-s
-.I Cnfsstat
-writes output to
-.IR syslog (3)
-instead of standard output.
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: cnfsstat.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-cycbuff.conf(5),
-inn.conf(5),
-rc.news(8),
-storage.conf(5).
diff --git a/doc/man/control.ctl.5 b/doc/man/control.ctl.5
deleted file mode 100644 (file)
index fe4f120..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-.\" 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 "CONTROL.CTL 5"
-.TH CONTROL.CTL 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-control.ctl \- Specify handling of Usenet control messages
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fIcontrol.ctl\fR in \fIpathetc\fR is used to determine what action is taken
-when a control message is received.  It is read by \fBcontrolchan\fR, which
-is normally invoked as a channel program by \fBinnd\fR.  When \fIcontrol.ctl\fR
-is modified, \fBcontrolchan\fR notices this automatically and reloads it.
-.PP
-Blank lines and lines beginning with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored.
-All other lines should consist of four fields separated by colons:
-.PP
-.Vb 1
-\&    <type>:<from>:<newsgroups>:<action>
-.Ve
-.PP
-The first field, <type>, is the type of control message for which this
-line is valid.  It should either be the name of a control message or the
-word \f(CW\*(C`all\*(C'\fR to indicate that it applies to all control messages.
-.PP
-The second field, <from>, is a shell-style pattern that matches the e\-mail
-address of the person posting the message (with the address first
-converted to lowercase).  The matching is done with rules equivalent to
-those of the shell's \fIcase\fR statement; see \fIsh\fR\|(1) for more details.
-.PP
-If the control message is a newgroup or rmgroup, the third field,
-<newsgroups>, is a shell-style pattern matching the newsgroup affected by
-the control message.  If the control message is a checkgroups, the third
-field is a shell-style pattern matching the newsgroups that should be
-processed for checking.  If the control message is of any other type, the
-third field is ignored.
-.PP
-The fourth field, <action>, specifies what action to take with control
-messages that match this line.  The following actions are understood:
-.IP "\fBdoit\fR" 4
-.IX Item "doit"
-The action requested by the control message should be performed.  For
-checkgroups messages, this means that the shell commands that should
-be run will be mailed to the news administrator (the argument to
-\&\fB\-\-with\-news\-master\fR given at configure time, \f(CW\*(C`usenet\*(C'\fR by default); for
-other commands, this means that the change will be silently performed.  If
-you always want notification of actions taken, use \f(CW\*(C`doit=mail\*(C'\fR instead (see
-below).
-.IP "\fBdoifarg\fR" 4
-.IX Item "doifarg"
-If the control message has an argument, this is equivalent to \fBdoit\fR.  If
-it does not have an argument, this is equivalent to \fBmail\fR.  This is only
-useful for entries for sendsys control messages, allowing a site to
-request its own \fInewsfeeds\fR entry by posting a \f(CW\*(C`sendsys mysite\*(C'\fR control
-message, but not allowing the entire \fInewsfeeds\fR file to be sent.  This
-was intended to partially counter so-called \*(L"sendsys bombs,\*(R" where forged
-sendsys control messages were used to mailbomb people.
-.Sp
-Processing sendsys control messages is not recommended even with this
-work-around unless they are authenticated in some fashion.  The risk of
-having news servers turned into anonymous mail bombing services is too
-high.
-.IP "\fBdoit\fR=\fIfile\fR" 4
-.IX Item "doit=file"
-The action is performed as in \fBdoit\fR, and additionally a log entry is
-written to the specified log file \fIfile\fR.  If \fIfile\fR is the word
-\&\f(CW\*(C`mail\*(C'\fR, the log entry is mailed to the news administrator instead.  An
-empty string is equivalent to \fI/dev/null\fR and says to log nothing.
-.Sp
-If \fIfile\fR starts with a slash, it is taken as the absolute filename to
-use for the log file.  Otherwise, the filename is formed by prepending
-\&\fIpathlog\fR and a slash and appending \f(CW\*(C`.log\*(C'\fR.  In other words, an action
-of \f(CW\*(C`doit=newgroup\*(C'\fR will log to \fIpathlog\fR/newgroup.log.
-.IP "\fBdrop\fR" 4
-.IX Item "drop"
-No action is taken and the message is ignored.
-.IP "\fBverify\-*\fR" 4
-.IX Item "verify-*"
-If the action starts with the string \f(CW\*(C`verify\-\*(C'\fR, as in:
-.Sp
-.Vb 1
-\&    verify\-news.announce.newgroups
-.Ve
-.Sp
-then \s-1PGP\s0 verification of the control message will be done and the user \s-1ID\s0
-of the key of the authenticated signer will be checked against the
-expected identity defined by the rest of the string
-(\f(CW\*(C`news.announce.newgroups\*(C'\fR in the above example.  This verification is
-done via \fBpgpverify\fR; see \fIpgpverify\fR\|(8) for more details.
-.Sp
-If no logging is specified (with =\fIfile\fR as mentioned below), logging will
-be done the same as with \fBdoit\fR as described above.
-.IP "\fBverify\-*\fR=\fBmail\fR" 4
-.IX Item "verify-*=mail"
-\&\s-1PGP\s0 verification is done as for the \fBverify\-*\fR action described above, and
-notification of successful newgroup and rmgroup control messages and the
-output of checkgroups messages will be mailed to the news administrator.
-(In the case of checkgroups messages, this means that the shell script that
-should be run will be mailed to the administrator.)
-.IP "\fBverify\-*\fR=\fIfile\fR" 4
-.IX Item "verify-*=file"
-\&\s-1PGP\s0 verification is done as for the \fBverify\-*\fR action described above,
-and a log entry is written to the specified file as described in
-\&\fBdoit\fR=\fIfile\fR above.  (In the case of checkgroups messages, this means
-that the shell script output of the checkgroups message will be written to
-that file.)
-.IP "\fBlog\fR" 4
-.IX Item "log"
-A one-line log message is sent to standard error.  \fBinnd\fR normally
-directs this to \fIpathlog\fR/errlog.
-.IP "\fBlog\fR=\fIfile\fR" 4
-.IX Item "log=file"
-A log entry is written to the specified log file, which is interpreted as
-in \fBdoit\fR=\fIfile\fR described above.
-.IP "\fBmail\fR" 4
-.IX Item "mail"
-A mail message is sent to the news administrator without taking any other
-action.
-.PP
-Processing of a checkgroups message will never actually change the
-\&\fIactive\fR file (the list of groups carried by the server).  The difference
-between a \fBdoit\fR or \fBverify\fR action and a \fBmail\fR action for a
-checkgroups control message lies only in what e\-mail is sent; \fBdoit\fR or
-\&\fBverify\fR will mail the news administrator a shell script to create,
-delete, or modify newsgroups to match the checkgroups message, whereas
-\&\fBmail\fR will just mail the entire message.  In either case, the news
-administrator will have to take action to implement the checkgroups
-message, and if that mail is ignored, nothing will be changed.
-.PP
-Lines are matched in order and the last matching line in the file will be
-used.
-.PP
-Use of the \fBverify\fR action for processing newgroup, rmgroup, and
-checkgroups messages is \s-1STRONGLY\s0 recommended.  Abuse of control messages
-is rampant, and authentication via \s-1PGP\s0 signature is currently the only
-reliable way to be sure that a control message comes from who it claims to
-be from.  Most major hierarchies are now issuing PGP-authenticated control
-messages.
-.PP
-In order to use \fBverify\fR actions, the \s-1PGP\s0 key ring of the news user must
-be populated with the \s-1PGP\s0 keys of the hierarchy maintainers whose control
-messages you want to honor.  For more details on PGP-authenticated control
-messages and the \s-1URL\s0 for downloading the \s-1PGP\s0 keys of major hierarchies,
-see \fIpgpverify\fR\|(8).
-.PP
-Control messages of type cancel are handled internally by \fBinnd\fR and
-cannot be affected by any of the mechanisms described here.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-With the following three lines in \fIcontrol.ctl\fR:
-.PP
-.Vb 3
-\&    newgroup:*:*:drop
-\&    newgroup:group\-admin@isc.org:comp.*:verify\-news.announce.newgroups
-\&    newgroup:kre@munnari.oz.au:aus.*:mail
-.Ve
-.PP
-a newgroup coming from \f(CW\*(C`group\-admin@isc.org\*(C'\fR will be honored if it is for
-a newsgroup in the comp.* hierarchy and if it has a valid signature
-corresponding to the \s-1PGP\s0 key with a user \s-1ID\s0 of \f(CW\*(C`news.announce.newgroups\*(C'\fR.
-If any newgroup claiming to be from \f(CW\*(C`kre@munnari.oz.au\*(C'\fR for a newsgroup
-in the aus.* hierarchy is received, it too will be honored.  All other
-newgroup messages will be ignored.
-.SH "WARNINGS"
-.IX Header "WARNINGS"
-The third argument for a line affecting checkgroups does \fBnot\fR affect
-whether the line matches.  It is only used after a matching line is found,
-to filter out which newsgroups listed in the checkgroups will be
-processed.  This means that a line like:
-.PP
-.Vb 1
-\&    checkgroups:*:*binaries*:drop
-.Ve
-.PP
-will cause \fBall\fR checkgroups control messages to be dropped unless they
-match a line after this one in \fIcontrol.ctl\fR, not just ignore newsgroups
-containing \f(CW\*(C`binaries\*(C'\fR in the name.  The general rule is to never use \f(CW\*(C`*\*(C'\fR
-in the second field for a line matching checkgroups messages.  There is
-unfortunately no way to do what the author of a line like the above
-probably intended to do (yet).
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: control.ctl.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIcontrolchan\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInewsfeeds\fR\|(5), \fIpgpverify\fR\|(8), \fIsh\fR\|(1).
diff --git a/doc/man/controlchan.8 b/doc/man/controlchan.8
deleted file mode 100644 (file)
index 44acfdd..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-.\" $Revision: 5909 $
-.TH CONTROLCHAN 8
-.SH NAME
-controlchan \- channel\-fed control message handler
-.SH SYNOPSIS
-.B controlchan
-.SH DESCRIPTION
-.I Controlchan
-removes the responsibility for handling control messages
-(except cancels) from
-.IR innd (8)
-and instead processes them from a channel or file feed.
-To reduce load,
-.I controlchan
-keeps a copy of
-.I control.ctl
-in memory and checks permissions (including any required PGP headers) before any
-scripts are called.  Also, the default (``bad message'') case is handled
-internally.  The ``drop'' case is handled with far less fuss.
-.PP
-Normally,
-.I controlchan
-is invoked by
-.IR innd (8)
-as configured in
-.IR newsfeeds .
-An example entry is below.  Make sure that you've created the newsgroup
-control.cancel so that
-.I controlchan
-doesn't have to scan through cancels, which it won't process anyway.
-.sp 1
-.in +0.5i
-.nf
-controlchan!\\
-   :!*,control,control.*,!control.cancel\\
-   :Tc,Wnsm\\ 
-   :<pathbin in inn.conf>/controlchan
-.fi
-.in -0.5i
-.sp 1
-Note that in the (very, very unlikely) event that you need to process
-ihave/sendme control messages, be sure that
-.I logipaddr
-is set to false in
-.IR inn.conf ,
-because in this case controlchan needs a site name, not an IP address.
-.sp 1
-.I Controlchan
-tries to report all log messages through
-.IR syslog (3),
-unless connected to an interactive terminal.  To enable
-.IR syslog (3)'ing
-for versions of Perl prior to 5.6.0,
-you will need to have run ``h2ph'' on your
-system include files at some point (this is required to
-make ``Sys::Syslog'' work).  If you have not done so, do this:
-.sp 1
-.nf
-.in +0.5i
-cd /usr/include
-h2ph * sys/*
-.in -0.5i
-.fi
-.sp 1
-If you run FreeBSD, you will need to run the following in addition:
-.sp 1
-.nf
-.in +0.5i
-h2ph machine/*
-.in -0.5i
-.fi
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: controlchan.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-control.ctl(5),
-inn.conf(5).
diff --git a/doc/man/convdate.1 b/doc/man/convdate.1
deleted file mode 100644 (file)
index 9ee526e..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-.\" 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 "CONVDATE 1"
-.TH CONVDATE 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-convdate \- Convert time/date strings and numbers
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBconvdate\fR [\fB\-dhl\fR] [\fB\-c\fR | \fB\-n\fR | \fB\-s\fR] [\fIdate\fR ...]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBconvdate\fR translates the date/time strings given on the command line,
-outputting the results one to a line.  The input can either be a date in
-some format that \fIparsedate\fR\|(3) can parse or the number of seconds since
-epoch (if \fB\-c\fR is given).  The output is either \fIctime\fR\|(3) results, the
-number of seconds since epoch, or a Usenet Date: header, depending on the
-options given.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-c\fR" 4
-.IX Item "-c"
-Each argument is taken to be the number of seconds since epoch (a time_t)
-rather than a date.
-.IP "\fB\-d\fR" 4
-.IX Item "-d"
-Output a valid Usenet Date: header instead of the results of \fIctime\fR\|(3) for
-each date given on the command line.  This is useful for testing the
-algorithm used to generate Date: headers for local posts.  Normally, the
-date will be in \s-1UTC\s0, but see the \fB\-l\fR option.
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Print usage information and exit.
-.IP "\fB\-l\fR" 4
-.IX Item "-l"
-Only makes sense in combination with \fB\-d\fR.  If given, Date: headers
-generated will use the local time zone instead of \s-1UTC\s0.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-Rather than outputting the results of \fIctime\fR\|(3) or a Date: header, output
-each date given as the number of seconds since epoch (a time_t).  This
-option doesn't make sense in combination with \fB\-d\fR.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-Pass each given date to \fIparsedate\fR\|(3) and print the results of \fIctime\fR\|(3) (or
-a Date: header if \fB\-d\fR is given).  This is the default behavior.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Note that relative times or times with partial information use the current
-time to fill in the rest of the date, so dates like \*(L"12pm\*(R" are taken to be
-12pm of the day when convdate is run.  This is a property of \fIparsedate\fR\|(3);
-see the man page for more information.  Most of these examples are from
-the original man page dating from 1991 and were run in the \-0400 time
-zone.
-.PP
-.Vb 2
-\&    % convdate 'feb 10 10am'
-\&    Sun Feb 10 10:00:00 1991
-.Ve
-.PP
-.Vb 3
-\&    % convdate 12pm 5/4/90
-\&    Fri Dec 13 00:00:00 1991
-\&    Fri May  4 00:00:00 1990
-.Ve
-.PP
-Note that 12pm and 5/4/90 are two *separate* arguments and therefore
-result in two results.  Note also that a date with no time is taken to be
-at midnight.
-.PP
-.Vb 3
-\&    % convdate \-n 'feb 10 10am' '12pm 5/4/90'
-\&    666198000
-\&    641880000
-.Ve
-.PP
-.Vb 2
-\&    % convdate \-c 666198000
-\&    Sun Feb 10 10:00:00 1991
-.Ve
-.PP
-\&\fIctime\fR\|(3) results are in the local time zone.  Compare to:
-.PP
-.Vb 2
-\&    % convdate \-dc 666198000
-\&    Sun, 10 Feb 1991 15:00:00 +0000 (UTC)
-.Ve
-.PP
-.Vb 2
-\&    % env TZ=PST8PDT convdate \-dlc 666198000
-\&    Sun, 10 Feb 1991 07:00:00 \-0800 (PST)
-.Ve
-.PP
-.Vb 2
-\&    % env TZ=EST5EDT convdate \-dlc 666198000
-\&    Sun, 10 Feb 1991 10:00:00 \-0500 (EST)
-.Ve
-.PP
-The system library functions generally use the environment variable \s-1TZ\s0 to
-determine (or at least override) the local time zone.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net>, rewritten and updated by Russ
-Allbery <rra@stanford.edu> for the \fB\-d\fR and \fB\-l\fR flags.
-.PP
-$Id: convdate.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIparsedate\fR\|(3).
diff --git a/doc/man/ctlinnd.8 b/doc/man/ctlinnd.8
deleted file mode 100644 (file)
index 07bf46f..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-.\" $Revision: 7062 $
-.TH CTLINND 8
-.SH NAME
-ctlinnd \- control the InterNetNews daemon
-.SH SYNOPSIS
-.B ctlinnd
-[
-.B \-h
-]
-[
-.B \-s
-]
-[
-.BI \-t " timeout"
-]
-.I command
-[
-.I argument...
-]
-.SH DESCRIPTION
-.I Ctlinnd
-sends a message to the control channel of
-.IR innd (8),
-the InterNetNews server.
-.PP
-In the normal mode of behavior, the message is sent to the server, which
-then performs the requested action and sends back a reply with a text
-message and the exit code for
-.IR ctlinnd .
-If the server successfully performed the command,
-.I ctlinnd
-will exit with a status of zero and print the reply on standard output.
-If the server could not perform the command (for example, it was told to
-remove a newsgroup that does not exist), it will direct
-.I ctlinnd
-to exit with a status of one.  (Note that
-.I ctlinnd
-need not always exit immediately, see the ``\fB-t\fP'' flag.)
-The ``shutdown'', ``xabort'', and ``xexec'' commands do not generate a
-reply (because once
-.I innd
-has successfully exited, it is too late to send a reply to
-.IR ctlinnd );
-after these commands,
-.I ctlinnd
-will always exit silently with a status of zero.
-.SH OPTIONS
-.TP
-.B \-s
-If the ``\fB\-s\fP'' flag is
-used, then no message will be printed if the command was successful.
-.TP
-.B \-t timeout
-The ``\fB\-t\fP'' flag can be used to specify how long to wait for the reply
-from the server (for commands other than ``shutdown'', ``xabort'', and
-``xexec'').
-The timeout value specifies the number of seconds to wait.
-A value of zero waits forever, and a value less
-than zero indicates that no reply is needed (that is, exit immediately
-with status zero).
-When waiting for a reply,
-.I ctlinnd
-will try every two minutes to see if the server is still running, so it
-is unlikely that ``\fB\-t0\fP'' will hang.
-The default is set as 
-.I <CTLINND_TIMEOUT in include/config.h> 
-(typically 
-.IR 0 ).
-.TP
-.B \-h
-To see a command summary, use the ``\fB\-h\fP'' flag.
-If a command is included when
-.I ctlinnd
-is invoked with the ``\fB\-h\fP'' flag, then only the usage for that command
-will be given.
-.PP
-The complete list of commands follows.
-Note that all commands have a fixed number of arguments.
-If a parameter can be an empty string, then it is necessary to
-specify it as two adjacent quotes, like "".
-.TP
-.BI addhist " <Message-ID> arr exp post token"
-Add an entry to the history database.
-This directs the server to create a history line for
-.IR Message-ID .
-The angle brackets are optional.
-.IR Arr ,
-.IR exp ,
-and
-.I post
-specify when the article arrived, what its expiration date is, and
-when it was posted.
-All three values are numbers indicating the number of seconds since the
-epoch.
-.I Exp
-being zero indicates the article does not have an Expires header.
-.I Token
-is the storage API token indicating where the article is stored.
-If the server is throttled manually, this command causes it to briefly
-open the history database.
-If the server is paused or throttled for any other reason, this command
-is rejected.
-.TP
-.BI allow " reason"
-Remote connections are allowed.
-The
-.I reason
-must be the same text given with an earlier ``reject'' command, or an
-empty string.
-.TP
-.BI begin " site"
-Begin feeding
-.IR site .
-This will cause the server to rescan the
-.I newsfeeds
-file to find the specified site and set up a newsfeed for it.
-If the site already exists, a ``drop'' is done first.
-This command is forwarded; see NOTES below.
-.TP
-.BI cancel " <Message-ID>"
-Remove the article with the specified Message-ID from the local system.
-This does
-.I not
-generate a cancel message.
-The angle brackets are optional.
-If the server is throttled manually, this command causes it to briefly
-open the history database.
-If the server is paused or throttled for any other reason, this command
-is rejected.
-.TP
-.BI changegroup " group rest"
-The newsgroup
-.I group
-is changed so that its fourth field in the
-.I active
-file becomes the value specified by the
-.I rest
-parameter.
-This may be used to make an existing group moderated or unmoderated,
-for example.
-This command can only be used while the server is running (not throttled),
-unlike
-.B newgroup
-or
-.BR rmgroup .
-.TP
-.B checkfile
-Check the syntax of the
-.I newsfeeds
-file, and display a message if any errors are found.
-The details of the errors are reported to
-.IR syslog (3).
-.TP
-.BI drop " site"
-Flush and drop
-.I site
-from the server's list of active feeds.
-This command is forwarded; see NOTES below.
-.TP
-.BI feedinfo " site"
-Print detailed information about the state of the
-feed to
-.I site
-or more brief status of all feeds if
-.I site
-is an empty string.
-.TP
-.BI flush " site"
-Flush the buffer for the specified site.
-The actions taken depend on the type of feed the site receives; see
-.IR newsfeeds (5).
-This is useful when the site is fed by a file and batching is about to start.
-If
-.I site
-is an empty string, then all sites are flushed and the
-.I active
-file and history databases are also written out.
-This command is forwarded; see NOTES below.
-.TP
-.B flushlogs
-Close the log and error log files and rename them to have a
-.I \&.old
-extension.
-The history database and
-.I active
-file are also written out.
-.TP
-.BI go " reason"
-Re-open the history database and start accepting articles after a ``pause''
-or ``throttle'' command.
-The
-.I reason
-must either be an empty string or match the text that was given
-in the earlier ``pause'' or ``throttle'' command.
-If a ``reject'' command was done, this will also do an ``allow'' command
-if the
-.I reason
-matches the text that was given in the ``reject.''
-If a ``reserve'' command was done, this will also clear the reservation if
-the
-.I reason
-matches the text that was given in the ``reserve.''
-Note that if only the history database has changed while the server is
-paused or throttled, it is not necessary to send it a ``reload'' command
-before sending it a ``go'' command.
-If the server throttled itself because it accumulated too many I/O
-errors, this command will reset the error count.
-If the server was not started with the ``\fB\-ny\fP'' flag, then this command also
-does a ``readers'' command with ``yes'' as the flag and
-.I reason
-as the text.
-.TP
-.BI hangup " channel"
-Close the socket on the specified incoming channel.
-This is useful when an incoming connection appears to be hung.
-.TP
-.BI help " [command]"
-Print a command summary for all commands, or just
-.I command
-if specified.
-.TP
-.BI kill " signal site"
-Signal
-.I signal
-is sent to the specified
-.IR site ,
-which must be a channel or exploder feed.
-.I Signal
-can be a numeric signal number or the word ``hup'', ``int'', or ``term'';
-case is not significant.
-.TP
-.BI lowmark " file"
-Reset the lowmarks in the
-.I active
-file based on the contents of the given
-file. Each line in the file must be of the form:
-.IP
-.RS
-.nf
-    group low-value
-.fi
-.RE
-.IP
-for example
-.IP
-.RS
-.nf
-    comp.lang.c++    243
-.fi
-.RE
-.TP
-.BI logmode
-Cause the server to log its current operating mode to
-.IR syslog .
-.TP
-.BI mode
-Print the server's operating mode as a multi-line summary of the parameters
-and operating state.
-.TP
-.BI name " nnn"
-Print the name and relevant information of channel number
-.IR nnn ,
-or of all channels if it is an empty string.  The response is formatted as:
-.sp 1
-.in +0.5i
-.nf
-f1:f2:f3:f4:f5
-.fi
-.in -0.5i
-.sp 1
-Where the meanings of the fields are:
-.sp 1
-.in +0.5i
-.nf
-f1     name of this channel
-f2     channel number
-f3     channel type
-f4     idle time for this channel (nntp type)
-       or process id (process type)
-f5     channel status (nntp type)
-.fi
-.in -0.5i
-.sp 1
-The channel type (f3) is one of following:
-.sp 1
-.in +0.5i
-.nf
-control                control channel which is used
-                       for ctlinnd
-file                   file channel which is used for
-                       file feed
-localconn              local channel which is used for
-                       nnrpd or rnews
-nntp                   nntp channel which is used for
-                       current remote connection
-proc                   process channel which is used
-                       for process feed
-remconn                remote channel which will be
-                       used for nntp
-.fi
-.in -0.5i
-.sp 1
-Channel status indicates whether the channel is paused or not.  Nothing is
-shown unless the channel is paused, in which case ``paused'' is shown.
-A channel is paused if the number of remote connection for that label in
-.I incoming.conf
-is beyond ``max-connections'' within ``hold-time'' seconds of connection.
-.TP
-.BI newgroup " group rest creator"
-Create the specified newsgroup.
-The
-.I rest
-parameter should be the fourth field as described in
-.IR active (5);
-if it is not an equal sign, only the first letter is used.
-The
-.I creator
-should be the identity of the person creating the group as described in
-.IR active (5).
-If the newsgroup already exists, this is equivalent to the ``changegroup''
-command.
-This is the only command that has defaults.
-The
-.I creator
-can be omitted and will default to the newsmaster (as specified at configure
-time, ``usenet'' by default), and the
-.I rest
-parameter can be omitted and will default to ``y''.
-This command can only be done while the server is throttled manually
-or running; it will
-update its internal state when a ``go'' command is sent.
-This command updates the
-.I active.times
-file (see
-.IR active.times (5)).
-This command is forwarded; see NOTES below.
-.TP
-.BI param " letter value"
-Change the command-line parameters of the server.
-The combination of defaults make it possible to use the text of the Control
-header directly.
-.I Letter
-is the
-.I innd
-command-line option to set, and
-.I value
-is the new value.
-For example, ``i 5'' directs the server to allow only five incoming
-connections.
-To enable or disable the action of the ``\fB\-n\fP'' flag, use the letter ``y''
-or ``n'', respectively, for the
-.IR value .
-.TP
-.BI pause " reason"
-Pause the server so that no incoming articles are accepted.
-No existing connections are closed, but the history database is closed.
-This command should be used for short-term locks, such as when replacing
-the history files.
-If the server was not started with the ``\fB\-ny\fP'' flag, then this command also
-does a ``readers'' command with ``no'' as the flag and
-.I reason
-as the text.
-.TP
-.BI perl " flag"
-Enable or disable perl news filtering, if
-.IR <\-\-with\-perl\ is\ specified\ at\ configure> .
-If
-.I flag
-starts with the letter ``y'' then filtering is enabled.  If it starts with
-``n'', then filtering is disabled.
-.TP
-.BI python " flag"
-Enable or disable Python news filtering, if
-.IR <\-\-with\-python\ is\ specified\ at\ configure> .
-If
-.I flag
-starts with the letter ``y'' then filtering is enabled.  If it starts with
-``n'', then filtering is disabled.
-.TP
-.BI readers " flag text"
-Allow or disallow newsreaders.
-If
-.I flag
-starts with the letter ``n'' then newsreading is disallowed, by
-causing the server to pass the
-.I text
-as the value of the
-.IR nnrpd (8)
-\&`\fB`\-r\fP'' flag.
-If
-.I flag
-starts with the letter ``y'' and
-.I text
-is either an empty string, or the same string that was used when newsreading
-was disallowed, then newsreading will be allowed.
-.\".TP
-.\".BI refile " path group"
-.\"The article specified by
-.\".I path
-.\"is refiled as if it were posted to the newsgroup
-.\".IR group .
-.TP
-.BI reject " reason"
-Remote connections (those that would not be handed off to
-.IR nnrpd )
-are rejected, with
-.I reason
-given as the explanation.
-.TP
-.BI reload " what reason"
-The server updates its in-memory copies of various configuration files.
-.I What
-identifies what should be reloaded.
-The
-.I reason
-is reported to
-.IR syslog .
-.sp 1
-There is no way to reload the
-.I inn.conf
-file; use
-.I "ctlinnd xexec innd"
-instead.
-.sp 1
-If
-.I what
-is an empty string or the word ``all'' then everything is reloaded;
-if it is the word ``history'' then the history database is closed and opened,
-if it is the word ``incoming.conf'' then the
-.I incoming.conf
-file is reloaded; if it is the word ``active'' or ``newsfeeds'' then both
-the
-.I active
-and
-.I newsfeeds
-files are reloaded; if it is the word ``overview.fmt'' then the
-.I overview.fmt
-file is reloaded.
-.sp 1
-If
-.I <\-\-with\-perl is specified at configure>
-and it is the word ``filter.perl'' then the
-.IR filter_innd.pl
-file is reloaded.  If a Perl procedure named ``filter_before_reload'' exists,
-it will be called prior to rereading
-.IR filter_innd.pl .
-If a Perl procedure named ``filter_after_reload'' exists, it will be called
-after
-.IR filter_innd.pl .
-has been reloaded.  Reloading the Perl filter does not enable filtering if
-it is disabled; use
-.I perl y
-to do this. The
-.I startup_innd.pl
-file cannot be reloaded.
-.sp 1
-If
-.I <\-\-with\-python is specified at configure>
-and it is the word ``filter.python'' then the
-.I filter_innd.py
-file is reloaded.  If a Python method named ``filter_before_reload'' exists,
-it will be called prior to rereading
-.IR filter_innd.py .
-If a Python method named ``__init__'' exists, it will be called
-after
-.IR filter_innd.py .
-has been reloaded.  Reloading the Python filter does not enable filtering if
-it is disabled; use
-.I python y
-to do this.
-If
-.I <\-\-with\-tcl is specified at configure>
-and it is the word ``filter.tcl'' then the
-.I filter.tcl
-file is reloaded.  If a TCL procedure named ``filter_before_reload'' exists,
-it will be called prior to rereading
-.IR filter.tcl.
-If a TCL procedure named ``filter_after_reload'' exists, it will be called
-after
-.I filter.tcl
-has been reloaded.  Reloading the Tcl filter does not enable filtering if
-it is disabled; use
-.IR filter
-to do this.
-The
-.I startup.tcl
-file cannot be reloaded.
-.TP
-.BI renumber " group"
-Scan overview database for the specified newsgroup and update the
-low-water mark and hi-water mark in the
-.I active
-file.  Regardless of the content of the overview database, the hi-water
-mark will not be decreased (decreasing it may cause duplicate article
-numbers to be assigned after a crash, which can cause serious problems
-with the tradspool storage method).
-If
-.I group
-is an empty string then all newsgroups are scanned.
-Renumber only works if overview data has been created.
-(See the description of ``enableoverview'' in
-.IR inn.conf (5)
-for details about overview creation.)
-.TP
-.BI renumberlow " file"
-This command does same as ``lowmark'' command.
-.TP
-.BI reserve " reason"
-The next ``pause'' or ``throttle'' command must use
-.I reason
-as its reason.
-This ``reservation'' is cleared by giving an empty string for the
-.IR reason .
-This command is used by programs like
-.IR expire (8)
-that want to avoid running into other instances of each other.
-.TP
-.BI rmgroup " group"
-Remove the specified newsgroup.
-This is done by editing the
-.I active
-file.
-The spool directory is not touched, and any articles in the group will
-still be expired using the default expiration parameters.
-Unlike the ``newgroup'' command, this command does not update the
-.I active.times
-file.
-This command can be done while the server is only throttled manually or running.
-This command is forwarded; see NOTES below.
-.TP
-.BI send " feed text..."
-The specified
-.I text
-is sent as a control line to the exploder
-.IR feed .
-.TP
-.BI shutdown " reason"
-The server is shut down, with the specified reason recorded in the log
-and sent to all open connections.
-.sp 1
-It is a good idea to send a ``throttle'' command first.
-.sp 1
-If Perl, Python, or TCL filtering is compiled in and enabled, certain
-functions are called at ``throttle'' or ``shutdown'' (for example, to
-save filter state to disk), consult the embedded filter documentation
-for details.
-.TP
-.BI stathist " off|filename"
-Enable or disable generation of history performance statistics.  If the
-parameter is ``off'', no statistics are gathered.  Otherwise statistics
-are written to the specified file.  The file can be parsed by
-.IR contrib/stathist.pl .
-.TP
-.BI status " off|interval"
-Adjust frequency in seconds at which
-.I innd
-reports status informatoin to syslog.  Status reporting is turned off if
-``off'' or ``0'' is specified.  See ``status'' in
-.IR inn.conf (5)
-for information on how to set the startup default.
-.TP
-.BI tcl " flag"
-Enable or disable Tcl news filtering, if
-.IR <\-\-with\-tcl\ is\ specified\ at\ configure> .
-If
-.I flag
-starts with the letter ``y'' then filtering is enabled.  If it starts with
-``n'', then filtering is disabled.
-.TP
-.BI throttle " reason"
-Input is throttled so that all existing connections are closed and new
-connections are rejected.
-The history database is closed.
-This should be used for long-term locks, such as when
-.I expire
-is being run.
-If the server was not started with the ``\-ny'' flag, then this command also
-does a ``readers'' command with ``no'' as the flag and
-.I reason
-as the text.
-.TP
-.BI timer " off|interval"
-Performance monitoring is turned off if ``off'' or ``0'' is specified,
-otherwise, statistics will be reported every
-.I interval
-seconds to syslog.  See ``timer'' in
-.IR inn.conf (5)
-for information on how to set the startup default.
-.TP
-.BI trace " item flag"
-Tracing is turned on or off for the specified
-.IR item .
-.I Flag
-should start with the letter ``y'' or ``n'' to turn tracing on or off.
-If
-.I item
-starts with a number, then tracing is set for the specified
-.I innd
-channel, which must be for an incoming NNTP feed.
-If it starts with the letter ``i'' then general
-.I innd
-tracing is turned on or off.
-If it starts with the letter ``n'' then future
-.IR nnrpd 's
-will or will not have the ``\-t'' flag enabled, as appropriate.
-The ``n'' flag does not affect
-.IR nnrpd 's
-already running or using ``-D'' (running as a daemon).
-.TP
-.BI xabort " reason"
-The server logs the specified
-.I reason
-and then invokes the
-.IR abort (3)
-routine.
-.TP
-.BI xexec " path"
-The server gets ready to shut itself down, but instead of exiting it
-.IR exec 's
-.I <pathbin in inn.conf>/inndstart
-with all of its original arguments except for ``\fB\-r\fP''.
-.I Path
-can be any of ``innd'', ``inndstart'', or an empty string, although all
-three valid parameters have exactly the same effect.
-Any other value is an error.
-.SH NOTES
-In addition to being acted upon within the server, certain commands can
-be forwarded to the appropriate child process.
-If the site receiving the command is an exploder (such as
-.IR buffchan (8)),
-or it is a funnel that feeds into an exploder, then the
-command can be forwarded.
-In this case, the server will send a command line to the exploder that
-consists of the
-.I ctlinnd
-command name.
-If the site funnels into an exploder that has an asterisk (``*'') in its ``W''
-flag (see
-.IR newsfeeds (5)),
-then the site name will be appended to the command; otherwise no argument
-is appended.
-.SH BUGS
-.I Ctlinnd
-uses the
-.IR inndcomm (3)
-library, and is therefore limited to server replies no larger than 4k.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: ctlinnd.8 7062 2004-12-19 21:41:05Z rra $
-.SH "SEE ALSO"
-active(5),
-active.times(5),
-expire(8),
-innd(8),
-inndcomm(3),
-inn.conf(5),
-newsfeeds(5),
-overview.fmt(5).
diff --git a/doc/man/cvtbatch.8 b/doc/man/cvtbatch.8
deleted file mode 100644 (file)
index 12b9c80..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" $Revision: 5909 $
-.TH CVTBATCH 8
-.SH NAME
-cvtbatch \- convert Usenet batch file to INN format
-.SH SYNOPSIS
-.I cvtbatch
-[
-.BI \-w " items"
-]
-.SH DESCRIPTION
-.I Cvtbatch
-reads standard input as a sequence of lines, converts each line, and
-writes it to standard output.
-It is used to convert simple batchfiles that contain just the article
-name to INN batchfiles that contain additional information about each
-article.
-.PP
-Each line is taken as a storage API token indicating a Usenet article.
-(Only the first word of each line is parsed; anything following
-whitespace is ignored.  Lines not starting with a valid token are also
-silently ignored.)
-.PP
-If the input file consists of a series of Message-ID's, then use
-.IR grephistory (1)
-with the `\fB`\-s\fP'' flag piped into
-.IR cvtbatch .
-.SH OPTIONS
-.TP
-.B \-w
-The `\fB`\-w\fP'' flag specifies how each output line should be written.
-The items for this flag should be chosen from the ``W'' flag items as
-specified in
-.IR newsfeeds (5).
-They may be chosen from the following set:
-.PP
-.RS
-.nf
-       b       Size of article in bytes
-       f       full pathname of article
-       m       article message-id
-       n       relative pathname of article
-.fi
-.RE
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: cvtbatch.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-grephistory(1),
-inn.conf(5),
-newsfeeds(5).
diff --git a/doc/man/cycbuff.conf.5 b/doc/man/cycbuff.conf.5
deleted file mode 100644 (file)
index 19eba35..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-.\" 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 "CYCBUFF.CONF 5"
-.TH CYCBUFF.CONF 5 "2008-06-07" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-cycbuff.conf \- Configuration file for INN CNFS storage method
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This file defines the cyclical buffers that make up the storage pools for
-\&\s-1CNFS\s0 (Cyclic News File System).  Some options controlling the behavior of
-the \s-1CNFS\s0 storage system can also be set here.  \fIcycbuff.conf\fR is required
-if the \s-1CNFS\s0 (Cyclic News File System) storage method is used.  \s-1INN\s0 will
-look for it in \fIpathetc\fR (as set in \fIinn.conf\fR).
-.PP
-For information about how to configure \s-1INN\s0 to use \s-1CNFS\s0, see
-\&\fIstorage.conf\fR\|(5).
-.PP
-Blank lines and lines beginning with a hash sign (\f(CW\*(C`#\*(C'\fR) are ignored.  All
-other lines must be of one of the following forms:
-.PP
-.Vb 4
-\&    cycbuffupdate:<interval>
-\&    refreshinterval:<interval>
-\&    cycbuff:<name>:<file>:<size>
-\&    metacycbuff:<name>:<buffer>[,<buffer>,...][:<mode>]
-.Ve
-.PP
-(where items enclosed in [] are optional).  Order is mostly not
-significant, but all \fIcycbuff\fR lines must occur before all \fImetacycbuff\fR
-lines.  Long lines can be continued on the next line by ending the line
-with a backslash (\f(CW\*(C`\e\*(C'\fR).
-.IP "cycbuffupdate:<interval>" 4
-.IX Item "cycbuffupdate:<interval>"
-Sets the number of articles are written before the cycbuff header is
-written back to disk to <interval>.  Under most operating systems, the
-header doesn't have to be written to disk for the updated data to be
-available to other processes on the same system that are reading articles
-out of \s-1CNFS\s0, but any accesses to the \s-1CNFS\s0 cycbuffs over \s-1NFS\s0 will only see
-the data present at the last write of the header.  After a system crash,
-all updates since the last write of the \s-1CNFS\s0 header may be lost.  The
-default value, if this line is omitted, is 25, meaning that the header is
-written to disk after every 25 articles stored in that cycbuff.
-.IP "refreshinterval:<interval>" 4
-.IX Item "refreshinterval:<interval>"
-Sets the interval (in seconds) between re-reads of the cycbuff header to
-<interval>.  This primarily affects \fBnnrpd\fR and controls the frequency
-with which it updates its knowledge of the current contents of the \s-1CNFS\s0
-cycbuffs.  The default value, if this line is omitted, is 30.
-.IP "cycbuff:<name>:<file>:<size>" 4
-.IX Item "cycbuff:<name>:<file>:<size>"
-Configures a particular \s-1CNFS\s0 cycbuff.  <name> is a symbolic name for the
-buffer, to be used later in a metacycbuff line.  It must be no longer than
-seven characters.  <file> is the full path to the buffer file or block
-device, and must be no longer than 63 characters.  <size> is the length of
-the buffer in kilobytes (1KB is 1024 bytes).  If <file> is not a block
-device, it should be <size> * 1024 bytes long.
-.IP "metacycbuff:<name>:<buffer>[,<buffer>,...][:<mode>]" 4
-.IX Item "metacycbuff:<name>:<buffer>[,<buffer>,...][:<mode>]"
-Specifies a collection of \s-1CNFS\s0 buffers that make up a single logical
-storage location from the perspective of \s-1INN\s0.  Metacycbuffs are referred
-to in \fIstorage.conf\fR as storage locations for articles, so in order to
-actually put articles in a cycbuff, it has to be listed as part of some
-metacycbuff which is then referenced in \fIstorage.conf\fR.
-.Sp
-<name> is the symbolic name of the metacycbuff, referred to in the options
-field of cnfs entries in \fIstorage.conf\fR.  <buffer> is the name of a
-cycbuff (the <name> part of a cycbuff line), and any number of cycbuffs
-may be specified, separated by commas.
-.Sp
-If there is more than one cycbuff in a metacycbuff, there are two ways
-that \s-1INN\s0 can distribute articles between the cycbuffs.  The default mode,
-\&\s-1INTERLEAVE\s0, stores the articles in each cycbuff in a round-robin fashion,
-one article per cycbuff in the order listed.  If the cycbuffs are of
-wildly different sizes, this can cause some of them to roll over much
-faster than others, and it may not give the best performance depending on
-your disk layout.  The other storage mode, \s-1SEQUENTIAL\s0, instead writes to
-each cycbuff in turn until that cycbuff is full and then moves on to the
-next one, returning to the first and starting a new cycle when the last
-one is full.  To specify a mode rather than leaving it at the default, add
-a colon and the mode (\s-1INTERLEAVE\s0 or \s-1SEQUENTIAL\s0) at the end of the
-metacycbuff line.
-.PP
-\&\fBinnd\fR only reads \fIcycbuff.conf\fR on startup, so if you change anything
-in this file and want \fBinnd\fR to pick up the changes, you have to stop and
-restart it.  \f(CW\*(C`ctlinnd reload all ''\*(C'\fR is not sufficient.
-.PP
-When articles are stored, the cycbuff into which they're stored is saved
-as part of the article token.  In order for \s-1INN\s0 to retrieve articles from
-a cycbuff, that cycbuff must be listed in \fIcycbuff.conf\fR.  However, if
-\&\s-1INN\s0 should not write to a cycbuff, it doesn't need to be (and shouldn't
-be) listed in a metacycbuff.
-.PP
-This provides an easy way to retire a cycbuff.  Just remove it from its
-metacycbuff, leaving in the cycbuff line, and restart \fBinnd\fR (with, for
-example, \f(CW\*(C`ctlinnd xexec innd\*(C'\fR).  No new articles will be put into the
-cycbuff, but neither will any articles expire from it.  After you no
-longer need the articles in the cycbuff, just remove it entirely from
-\&\fIcycbuff.conf\fR.  Then all of the articles will appear to have been
-deleted to \s-1INN\s0, and the next nightly expire run will clean up any
-remaining references to them.
-.PP
-Adding a new cycbuff just requires creating it (see below), adding a
-cycbuff line, adding it to a metacycbuff, and then restarting \fBinnd\fR.
-.SH "CREATING CYCBUFFS"
-.IX Header "CREATING CYCBUFFS"
-When creating a new cycbuff, there are two different methods for creating
-the buffers in which the articles will be stored.
-.IP "1." 4
-Create a large file on top of a regular file system.  The easiest way to
-do this is probably with \fIdd\fR\|(1), using a command like:
-.Sp
-.Vb 1
-\&    dd if=/dev/zero of=/path/to/cycbuff bs=1024 count=<size>
-.Ve
-.Sp
-where <size> is the size from the cycbuff line in \fIcycbuff.conf\fR.
-\&\fI\s-1INSTALL\s0\fR contains a script that will generate these commands for you
-from your \fIcycbuff.conf\fR file.
-.Sp
-This is the simplest method, but has the disadvantage that very large
-files on regular file systems can be fairly slow to access, particularly
-at the end of the file, and \s-1INN\s0 incurs unnecessary file system overhead
-when accessing the cycbuff.
-.IP "2." 4
-Use block devices directly.  If your operating system allows you to call
-\&\fImmap()\fR on block devices (Solaris and recent versions of Linux do, FreeBSD
-at last report does not), this is the recommended method since you can
-avoid all of the native file system overhead.  Note, however, that each
-cycbuff cannot be larger than 2GB with this method, so if you need a lot
-of spool space, you may have to go back to disk files.
-.Sp
-Partition the disk to make each partition equal to or smaller than 2GB.
-If you're using Solaris, set up your partitions to avoid the first
-cylinder of the disk (or otherwise the cycbuff header will overwrite the
-disk partition table and render the cycbuffs inaccessible).  Then, create
-device files for each block device you're going to use.
-.Sp
-It's not recommended to use the block device files in \fI/dev\fR, since the
-news system doesn't have permission to write to them and changing the
-permissions of the system device files may affect something else.
-Instead, use \fImknod\fR\|(1) to create a new set of block devices (in somewhere
-like \fIpathspool\fR/cycbuffs that's only writable by the news user).  To do
-this, run \f(CW\*(C`ls \-Ll\*(C'\fR on the devices in \fI/dev\fR that correspond to the block
-devices that you want to use.  The major and minor device numbers are in
-the fifth and sixth columns (right before the date), respectively.  Then
-run mknod like:
-.Sp
-.Vb 1
-\&    mknod <file> b <major> <minor>
-.Ve
-.Sp
-where <file> is the path to the device to create (matching the <file> part
-of the cycbuff line) and <major> and <minor> are the major and minor
-device numbers as discovered above.
-.Sp
-Here's a short script to do this when given the path to the system device
-file as an argument:
-.Sp
-.Vb 8
-\&    #!/bin/sh
-\&    base=`echo "$1" | sed 's%.*/%%'`
-\&    major=`ls \-Ll "$1" | awk '{print $5}' | tr \-d ,`
-\&    minor=`ls \-Ll "$1" | awk '{print $6}`
-\&    mkdir \-p /usr/local/news/spool/cycbuffs
-\&    mknod /usr/local/news/spool/cycbuffs/"$base" b "$major" "$minor"
-\&    chown news:news /usr/local/news/spool/cycbuffs/"$base"
-\&    chmod 644 /usr/local/news/spool/cycbuffs/"$base"
-.Ve
-.Sp
-Make sure that the created files are owned by the news user and news
-group, as specified at configure time (the default being \f(CW\*(C`news\*(C'\fR for
-both).  Also make sure that the permissions on the devices allow the news
-user to read and write, and if you want other users on the system to be
-able to use \fBsm\fR to retrieve articles, make sure they're world\-readable.
-.PP
-Once you have everything configured properly and you start \fBinnd\fR, you
-should see messages in \fInews.notice\fR that look like:
-.PP
-.Vb 1
-\&    innd: CNFS\-sm No magic cookie found for cycbuff ONE, initializing
-.Ve
-.PP
-where \s-1ONE\s0 will be whatever you called your cycbuff.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-Rewritten into \s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: cycbuff.conf.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIctlinnd\fR\|(8), \fIinnd\fR\|(8), \fInnrpd\fR\|(8), \fIsm\fR\|(1), \fIstorage.conf\fR\|(5)
diff --git a/doc/man/dbz.3 b/doc/man/dbz.3
deleted file mode 100644 (file)
index 5029d24..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-.TH DBZ 3 "6 Sep 1997"
-.BY "INN"
-.SH NAME
-dbzinit, dbzfresh, dbzagain, dbzclose, dbzexists, dbzfetch, dbzstore, dbzsync, dbzsize, dbzgetoptions, dbzsetoptions, dbzdebug \- database routines
-.SH SYNOPSIS
-.nf
-.B #include <dbz.h>
-.PP
-.B "bool dbzinit(const char *base)"
-.PP
-.B "bool dbzclose(void)"
-.PP
-.B "bool dbzfresh(const char *base, long size)"
-.PP
-.B "bool dbzagain(const char *base, const char *oldbase)"
-.PP
-.B "bool dbzexists(const HASH key)"
-.PP
-.B "off_t dbzfetch(const HASH key)"
-.B "bool dbzfetch(const HASH key, void *ivalue)"
-.PP
-.B "bool dbzstore(const HASH key, off_t offset)"
-.B "bool dbzstore(const HASH key, void *ivalue)"
-.PP
-.B "bool dbzsync(void)"
-.PP
-.B "long dbzsize(long nentries)"
-.PP
-.B "void dbzgetoptions(dbzoptions *opt)"
-.PP
-.B "void dbzsetoptions(const dbzoptions opt)"
-.PP
-.SH DESCRIPTION
-These functions provide an indexing system for rapid random access to a
-text file (the
-.I base 
-.IR file ).
-.PP
-.I Dbz
-stores offsets into the base text file for rapid retrieval.  All retrievals
-are keyed on a hash value that is generated by the 
-.I HashMessageID()
-function.
-.PP
-.I Dbzinit
-opens a database,
-an index into the base file
-.IR base ,
-consisting of files
-.IB base .dir
-,
-.IB base .index
-, and
-.IB base .hash
-which must already exist.
-(If the database is new, they should be zero-length files.)
-Subsequent accesses go to that database until
-.I dbzclose
-is called to close the database.
-.PP
-.I Dbzfetch
-searches the database for the specified
-.IR key ,
-returning the corresponding
-.I value
-if any, if
-.I <\-\-enable\-tagged\-hash at configure>
-is specified.  If
-.I <\-\-enable\-tagged\-hash at configure>
-is not specified, it returns true and content of
-.I ivalue
-is set.
-.I Dbzstore
-stores the
-.I key - value
-pair in the database, if
-.I <\-\-enable\-tagged\-hash at configure>
-is specified.  If
-.I <\-\-enable\-tagged\-hash at configure>
-is not specified, it stores the content of
-.IR ivalue .
-.I Dbzstore
-will fail unless the database files are writable.
-.I Dbzexists 
-will verify whether or not the given hash exists or not.  Dbz is 
-optimized for this operation and it may be significantly faster than
-.IR dbzfetch() .
-.PP
-.I Dbzfresh
-is a variant of
-.I dbzinit
-for creating a new database with more control over details.
-.PP
-.IR Dbzfresh 's
-.I size
-parameter specifies the size of the first hash table within the database,
-in key-value pairs.
-Performance will be best if the number of key-value pairs stored in the 
-database does not exceed about 2/3 of
-.IR size .
-(The
-.I dbzsize
-function, given the expected number of key-value pairs,
-will suggest a database size that meets these criteria.)
-Assuming that an
-.I fseek
-offset is 4 bytes,
-the
-.B .index
-file will be
-.I 4 * size
-bytes.  The 
-.B .hash
-file will be
-.I DBZ_INTERNAL_HASH_SIZE * size
-bytes
-(the
-.B .dir
-file is tiny and roughly constant in size)
-until
-the number of key-value pairs exceeds about 80% of
-.IR size .
-(Nothing awful will happen if the database grows beyond 100% of
-.IR size ,
-but accesses will slow down quite a bit and the 
-.B .index
-and 
-.B .hash
-files will grow somewhat.)
-.PP
-.I Dbz
-stores up to 
-.SM DBZ_INTERNAL_HASH_SIZE
-bytes of the message-id's hash in the 
-.B .hash
-file to confirm a hit.  This eliminates the need to read the base file to
-handle collisions.  This replaces the tagmask feature in previous dbz 
-releases.
-.PP
-A
-.I size
-of ``0''
-given to
-.I dbzfresh
-is synonymous with the local default;
-the normal default is suitable for tables of 5,000,000
-key-value pairs.
-Calling
-.I dbzinit(name)
-with the empty name is equivalent to calling
-.IR dbzfresh(name,\ 0) .
-.PP
-When databases are regenerated periodically, as in news,
-it is simplest to pick the parameters for a new database based on the old one.
-This also permits some memory of past sizes of the old database, so that
-a new database size can be chosen to cover expected fluctuations.
-.I Dbzagain
-is a variant of
-.I dbzinit
-for creating a new database as a new generation of an old database.
-The database files for
-.I oldbase
-must exist.
-.I Dbzagain
-is equivalent to calling
-.I dbzfresh
-with a
-.I size
-equal to the result of applying
-.I dbzsize
-to the largest number of entries in the
-.I oldbase
-database and its previous 10 generations.
-.PP
-When many accesses are being done by the same program,
-.I dbz
-is massively faster if its first hash table is in memory.
-If the ``pag_incore'' flag is set to INCORE_MEM,
-an attempt is made to read the table in when
-the database is opened, and
-.I dbzclose
-writes it out to disk again (if it was read successfully and
-has been modified).
-.I Dbzsetoptions
-can be used to set the 
-.B pag_incore 
-and 
-.B exists_incore 
-flag to new value which should be ``INCORE_NO'', ``INCORE_MEM'', or
-\&``INCORE_MMAP'' for the
-.B .hash
-and
-.B .index 
-files separately; this does not affect the status of a database that has 
-already been opened.  The default is ``INCORE_NO'' for the 
-.B .index 
-file and ``INCORE_MMAP'' for the 
-.B .hash 
-file.  The attempt to read the table in may fail due to memory shortage;
-in this case
-.I dbz
-fails with an error.
-.IR Store s
-to an in-memory database are not (in general) written out to the file
-until
-.IR dbzclose
-or
-.IR dbzsync ,
-so if robustness in the presence of crashes
-or concurrent accesses is crucial, in-memory databases
-should probably be avoided or the 
-.B writethrough
-option should be set to ``true'';
-.PP
-If the
-.B nonblock
-option is ``true'', then writes to the 
-.B .hash
-and 
-.B .index
-files will be done using non-blocking I/O.  This can be significantly faster if
-your platform supports non-blocking I/O with files.
-.PP
-.I Dbzsync
-causes all buffers etc. to be flushed out to the files.
-It is typically used as a precaution against crashes or concurrent accesses
-when a
-.IR dbz -using
-process will be running for a long time.
-It is a somewhat expensive operation,
-especially
-for an in-memory database.
-.PP
-Concurrent reading of databases is fairly safe,
-but there is no (inter)locking,
-so concurrent updating is not.
-.PP
-An open database occupies three
-.I stdio
-streams and two file descriptors;
-Memory consumption is negligible (except for
-.I stdio
-buffers) except for in-memory databases.
-.SH SEE ALSO
-dbm(3), history(5), libinn(3)
-.SH DIAGNOSTICS
-Functions returning
-.I bool
-values return ``true'' for success, ``false'' for failure.
-Functions returning
-.I off_t
-values return a value with
-.I \-1
-for failure.
-.I Dbzinit
-attempts to have
-.I errno
-set plausibly on return, but otherwise this is not guaranteed.
-An
-.I errno
-of
-.B EDOM
-from
-.I dbzinit
-indicates that the database did not appear to be in
-.I dbz
-format.
-.PP
-If 
-.SM DBZTEST
-is defined at compile-time then a 
-.I main()
-function will be included.  This will do performance tests and integrity test.
-.SH HISTORY
-The original
-.I dbz
-was written by
-Jon Zeeff (zeeff@b-tech.ann-arbor.mi.us).
-Later contributions by David Butler and Mark Moraes.
-Extensive reworking,
-including this documentation,
-by Henry Spencer (henry@zoo.toronto.edu) as
-part of the C News project.
-MD5 code borrowed from RSA.  Extensive reworking to remove backwards
-compatibility and to add hashes into dbz files by Clayton O'Neill (coneill@oneill.net)
-.SH BUGS
-.PP
-Unlike
-.IR dbm ,
-.I dbz
-will refuse 
-to 
-.I dbzstore
-with a key already in the database.
-The user is responsible for avoiding this.
-.PP
-The RFC822 case mapper implements only a first approximation to the
-hideously-complex RFC822 case rules.
-.PP
-.I Dbz
-no longer tries to be call-compatible with
-.I dbm
-in any way.
diff --git a/doc/man/distrib.pats.5 b/doc/man/distrib.pats.5
deleted file mode 100644 (file)
index cf513e3..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-.\" 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 "DISTRIB.PATS 5"
-.TH DISTRIB.PATS 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-distrib.pats \- Default values for the Distribution header
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpathetc\fR/distrib.pats is used by \fBnnrpd\fR to determine the
-default value of the Distribution header.  Blank lines and lines beginning
-with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored.  All other lines consist of three
-fields separated by a colon:
-.PP
-.Vb 1
-\&    <weight>:<pattern>:<value>
-.Ve
-.PP
-The first field is the weight to assign to this match.  If a newsgroup
-matches multiple lines, the line with the highest weight is used.  This
-should be an arbitrary integer greater than zero.  The order of lines in
-the file is only important if groups have equal weight (in which case, the
-first matching line will be used).
-.PP
-The second field is either the name of a newsgroup or a \fIuwildmat\fR\|(3)\-style
-pattern to specify a set of newsgroups.
-.PP
-The third field is the value that should be used for the Distribution
-header of a posted article, if this line was picked as the best match and
-no Distribution header was supplied by the user.  It can be an empty
-string, specifying that no Distribution header should be added.
-.PP
-When a post is received by \fBnnrpd\fR that does not already contain a
-Distribution header, each newsgroup to which an article is posted will be
-checked against this file in turn, and the matching line with the highest
-weight will be used as the value of the Distribution header.  If no lines
-match, or if the matching line has an empty string for its third field, no
-header will be added.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: distrib.pats.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fInnrpd\fR\|(8), \fIuwildmat\fR\|(3)
diff --git a/doc/man/domain.8 b/doc/man/domain.8
deleted file mode 100644 (file)
index 8055b6f..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-.\" 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 "DOMAIN 8"
-.TH DOMAIN 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-domain \- nnrpd domain resolver
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBdomain\fR \fBdomainname\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This program can be used in \fIreaders.conf\fR to grant access based on the
-subdomain part of the remote hostname.  In particular, it only returns
-success if the remote hostname ends in \fBdomainname\fR.  (A leading dot on
-\&\fBdomainname\fR is optional; even without it, the argument must match on
-dot-separated boundaries).  The \*(L"username\*(R" returned is whatever initial
-part of the remote hostname remains after \fBdomainname\fR is removed.  It
-is an error if there is no initial part (that is, if the remote hostname
-is \fIexactly\fR the specified \fBdomainname\fR).
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-The following \fIreaders.conf\fR\|(5) fragment grants access to hosts with
-internal domain names:
-.PP
-.Vb 4
-\&    auth internal {
-\&        res: "domain .internal"
-\&        default\-domain: "example.com"
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access internal {
-\&        users: "*@example.com"
-\&        newsgroups: example.*
-\&    }
-.Ve
-.PP
-Access is granted to the example.* groups for all connections from hosts
-that resolve to hostnames ending in \f(CW\*(C`.internal\*(C'\fR; a connection from
-\&\*(L"foo.internal\*(R" would match access groups as \*(L"foo@example.com\*(R".
-.SH "BUGS"
-.IX Header "BUGS"
-It seems the code does not confirm that the matching part is actually at
-the end of the remote hostname (e.g., \*(L"domain: example.com\*(R" would match
-the remote host \*(L"foo.example.com.org\*(R" by ignoring the trailing \*(L".org\*(R"
-part).
-.PP
-Does this resolver actually provide any useful functionality not
-available by using wildcards in the \fIreaders.conf\fR\|(5) \fIhosts\fR parameter?
-If so, the example above should reflect this functionality.
-.SH "HISTORY"
-.IX Header "HISTORY"
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-.PP
-$Id: domain.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5)
diff --git a/doc/man/expire.8 b/doc/man/expire.8
deleted file mode 100644 (file)
index a677a35..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-.\" $Revision: 5909 $
-.TH EXPIRE 8
-.SH NAME
-expire \- Usenet article and history expiration program
-.SH SYNOPSIS
-.B expire
-[
-.BI \-d " dir"
-]
-[
-.BI \-f " file"
-]
-[
-.BI \-g " file"
-]
-[
-.BI \-h " file"
-]
-[
-.B \-i
-]
-[
-.B \-N
-]
-[
-.B \-n
-]
-[
-.B \-p
-]
-[
-.BI \-r " reason"
-]
-[
-.BI \-s " size"
-]
-[
-.B \-t
-]
-[
-.BI \-v " level"
-]
-[
-.BI \-w " number"
-]
-[
-.B \-x
-]
-[
-.BI \-z " file"
-]
-[
-.I expire.ctl
-]
-.SH DESCRIPTION
-.I Expire
-scans the
-.IR history (5)-format
-text file
-.I <pathdb in inn.conf>/history
-and uses the information recorded in it to purge itself of old news articles.
-Articles stored using a storage method that has self-expire
-functionality are by default not affected by
-.IR expire 's
-primary behavior (but see the ``\fB\-N\fP'' flag to disable this).  In
-this case,
-.I expire.ctl
-is ignored except ``/remember/'' line for that article;
-.I expire
-does still probe to see if the article still exists and purges the
-relevant history and overview entries if appropriate.
-However, if ``groupbaseexpiry'' in
-.I inn.conf
-is true,
-.I expire
-acts on all articles as specified by
-.I expire.ctl
-regardless of whether their storage methods have self-expire
-functionality.  In this case, the ``\fB\-e\fP'', \&``\fB\-k\fP'',
-``\fB\-N\fP'', ``\fB\-p\fP'', ``\fB\-q\fP'', ``\fB\-w\fP'' and
-``\fB\-z\fP'' flags are ignored.
-.PP
-Note that
-.I expire
-never purges articles which do not match any entry in
-.IR expire.ctl .
-.SH OPTIONS
-.TP
-.B \-d dir
-If the ``\fB\-d\fP'' flag is used, then the new history file and database is
-created in the specified directory,
-.IR dir .
-This is useful when the filesystem does not have sufficient space to
-hold both the old and new history files.
-When this flag is used,
-.I expire
-leaves the server paused and creates a zero-length file named after the
-new history file, with an extension of ``.done'' to indicate that
-it has successfully completed the expiration.
-The calling script should install the new history file and un-pause the server.
-The ``\fB\-r\fP'' flag should be used with this flag.
-.TP
-.B \-f file
-To specify an alternate history file, use the ``\fB\-f\fP'' flag.
-This flag is valid when used with the ``\fB\-d\fP'', and the output will
-be written to the specified file.
-The default without ``\fB\-f\fP'' flag is ``history''.
-.TP
-.B \-g file
-If the ``\fB\-g\fP'' flag is given, then a one-line summary equivalent to the
-output of ``\fB\-v\fP 1'', except preceded by the current time, will be
-appended to the specified
-.IR file .
-.TP
-.B \-h file
-To specify an alternate input text history file, use the ``\fB\-h\fP'' flag.
-.I Expire
-uses the old
-.IR dbz (3)
-database to determine the size of the new one.
-(If ``\fB\-d\fP'' flag is not used, the output filename will be the same
-as the input filename with an extension of ``.n''.)
-The default without ``\fB\-h\fP'' flag is
-.IR <pathdb\ in\ inn.conf>/history .
-.TP
-.B \-i
-To ignore the old database, use the ``\fB\-i\fP'' flag.
-.TP
-.B \-N
-The control file is normally ignored for articles in storage methods
-which have self-expire functionality.
-If the ``\fB\-N\fP'' flag is used,
-.I expire
-still uses the control file for these articles.
-.TP
-.B \-n
-If
-.I innd
-is not running, use the ``\fB\-n\fP'' flag and
-.I expire
-will not send the ``pause'' or ``go'' commands.
-(For more details on the commands, see
-.IR ctlinnd (8)).
-Note that
-.I expire
-only needs exclusive access for a very short time \(em long enough to see
-if any new articles arrived since it first hit the end of the file, and to
-rename the new files to the working files.
-.TP
-.B \-p
-.I Expire
-makes its decisions on the time the article arrived, as found in the
-.I history
-file.
-This means articles are often kept a little longer than with other
-expiration programs that base their decisions on the article's posting
-date.
-To use the article's posting date, use the ``\fB\-p\fP'' flag.
-.TP
-.B \-r reason
-.I Expire
-normally sends a ``pause'' command to the local
-.IR innd (8)
-daemon when it needs exclusive access to the history file, using
-the string ``Expiring'' as the reason.
-To give a different reason, use the ``\fB\-r\fP'' flag.
-The process ID will be appended to the reason.
-When
-.I expire
-is finished and the new history file is ready, it sends a ``go'' command.
-See also the ``\fB\-n\fP'' flag.
-.TP
-.B \-s size
-Optimize the new history database for approximately 
-.I size
-pairs (lines in
-.IR history ).
-Accurately specifying the size will create a more efficient database.
-(The size should be the estimated eventual size of the file, typically
-the size of the old file.)
-.TP
-.B \-t
-If the ``\fB\-t\fP'' flag is used, then
-.I expire
-will generate a list of the tokens that should be removed on its
-standard output, and the new history file will be left in
-.IR history.n ,
-.IR history.n.dir ,
-.I history.n.index
-and
-.IR history.n.hash .
-This flag be useful for debugging when used with the ``\fB\-n\fP''
-flags.  Note that if the ``\fB\-f\fP'' flag is used, then the
-name specified with that flag will be used instead of
-.IR history .
-.TP
-.B \-v level
-The ``\fB\-v\fP'' flag is used to increase the verbosity of the program,
-generating messages to standard output.
-The
-.I level
-should be a number, where higher numbers result in more output.
-Level one will print totals of the various actions done (not valid if a
-new history file is not written), level two will print a report on each
-individual file, while level five results in multiple lines of output
-for every history line processed.
-.TP
-.B \-w number
-Use the ``\fB\-w\fP'' flag to ``warp'' time so that
-.I expire
-thinks it is running at some time other then the current time.
-The value should be a signed floating point number indicating the number
-of days to use as the offset.
-.TP
-.B \-x
-If the ``\fB\-x\fP'' flag is used, then
-.I expire
-will not create any new history files.  This is most useful when combined
-with the ``\fB\-n\fP'' and `\fB`\-t\fP'' flags to see how
-different expiration policies would change the amount of disk space used.
-.TP
-.B \-z file
-If the ``\fB\-z\fP'' flag is used, then articles are not removed, but their
-names are appended to the specified
-.IR file .
-See the description of
-.I delayrm
-in
-.IR news.daily (8).
-.PP
-If a filename is specified, it is taken as the control file and parsed
-according to the rules in
-.IR expire.ctl .
-A single dash (``\-'') may be used to read the file from standard input.
-If no file is specified, the file
-.I <pathetc in inn.conf>/expire.ctl
-is read.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: expire.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-ctlinnd(8),
-dbz(3),
-expire.ctl(5),
-history(5),
-inn.conf(5),
-innd(8),
-inndcomm(3).
diff --git a/doc/man/expire.ctl.5 b/doc/man/expire.ctl.5
deleted file mode 100644 (file)
index 601c001..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-.\" 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 "EXPIRE.CTL 5"
-.TH EXPIRE.CTL 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-expire.ctl \- Configuration file for article expiration
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpathetc\fR/expire.ctl is the default configuration file for
-\&\fBexpire\fR and \fBexpireover\fR, which read it at start\-up.  It serves two
-purposes:  it defines how long history entries for expired or rejected
-articles are remembered, and it determines how long articles stored on the
-server are retained.
-.PP
-Normally, if all of the storage methods used by the server are
-self-expiring (such as \s-1CNFS\s0), all lines except the \f(CW\*(C`/remember/\*(C'\fR setting
-(described below) are ignored.  This can be changed with the \fB\-N\fR option
-to \fBexpire\fR or \fBexpireover\fR.
-.PP
-Black lines and lines beginning with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored.
-All other lines should be in one of two formats.  The order of the file is
-significant, and the last matching entry will be used.
-.PP
-The first format specifies how long to keep history entries for articles
-that aren't present in the news spool.  These are articles that have
-either already expired, or articles which the server rejected (when
-\&\fIremembertrash\fR is set to true in \fIinn.conf\fR).  There should be one and
-only one line in this format, which looks like:
-.PP
-.Vb 1
-\&    /remember/:<days>
-.Ve
-.PP
-where <days> is a decimal number that specifies the minimum number of days
-a history record for a given message \s-1ID\s0 is retained, regardless of whether
-the article is present in the spool.  (History entries for articles still
-present in the spool are always retained.)
-.PP
-The primary reason to retain a record of old articles is in case a peer
-offers old articles that were previously accepted but have already
-expired.  Without a history record for such articles, the server would
-accept the article again and readers would see duplicate articles.
-Articles older than a certain number of days won't be accepted by the
-server at all (see \fIartcutoff\fR in \fIinn.conf\fR\|(5) and the \fB\-c\fR flag in
-\&\fIinnd\fR\|(8)), and this setting should probably match that time period (10 days
-by default) to ensure that the server never accepts duplicates.
-.PP
-Most of the lines in this file will be in the second format, which
-consists of either four or five colon-separated fields:
-.PP
-.Vb 1
-\&    <pattern>:<flag>:<min>:<default>:<max>
-.Ve
-.PP
-if \fIgroupbaseexpiry\fR is true in \fIinn.conf\fR (the default), and otherwise:
-.PP
-.Vb 1
-\&    <classnum>:<min>:<default>:<max>
-.Ve
-.PP
-All lines must be in the correct format given the current setting of
-\&\fIgroupbaseexpiry\fR, and therefore the two formats cannot co-exist in the
-same file.
-.PP
-Normally, a rule matches a newsgroup through the combination of the
-<pattern> and <flag> fields.  <pattern> is a \fIuwildmat\fR\|(3)\-style pattern,
-specifying the newsgroups to which the line is applied.  Note that the
-last matching entry will be used, so general patterns (such as defaults
-for all groups where <pattern> is \f(CW\*(C`*\*(C'\fR) should appear at the beginning of
-the file before more specific settings.
-.PP
-The <flag> field can be used to further limit newsgroups to which the line
-applies, and should be chosen from the following set:
-.PP
-.Vb 4
-\&    M   Only moderated groups
-\&    U   Only unmoderated groups
-\&    A   All groups
-\&    X   Remove the article from all groups it appears in
-.Ve
-.PP
-One of M, U, or A must be specified.  X should be used in combination with
-one of the other letters, not by itself.
-.PP
-An expiration policy is applied to every article in a newsgroup it
-matches.  There is no way to set an expiration policy for articles
-crossposted to groups you don't carry that's different than other articles
-in the same group.  Normally, articles are not completely deleted until
-they expire out of every group to which they were posted, but if an
-article is expired following a rule where <flag> contains X, it is deleted
-out of all newsgroups to which it was posted immediately.
-.PP
-If \fIgroupbaseexpiry\fR is instead set to false, there is no <pattern> and
-<flag> field and the above does not apply.  Instead, there is a single
-<classnum> field, which is either a number matching the storage class
-number specified in \fIstorage.conf\fR or \f(CW\*(C`*\*(C'\fR to specify a default for all
-storage classes.  All articles stored in a storage class will be expired
-following the instructions in the line with a matching <classnum>, and
-when articles are expired, they're always removed from all groups to which
-they were posted.
-.PP
-The remaining three fields are the same in either format, and are used to
-determine how long an article should be kept.  Each field should be either
-a decimal number of days (fractions like \f(CW8.5\fR are allowed, but remember
-that articles are only removed when \fBexpire\fR or \fBexpireover\fR is run,
-normally once a day by \fBnews.daily\fR) or the word \f(CW\*(C`never\*(C'\fR.
-.PP
-The middle field, <default>, will be used as the expiration period for
-most articles.  The other two fields, <min> and <max>, only come into
-play if the article requests a particular expiration date with an Expires
-header.  Articles with an Expires header will be expired at the date given
-in that header, subject to the constraints that they will be retained at
-least <min> days and no longer than <max> days.
-.PP
-If <min> is set to \f(CW\*(C`never\*(C'\fR, no article matching that line will ever be
-expired.  If <default> is set to \f(CW\*(C`never\*(C'\fR, no article matching that line
-without an explicit Expires header will ever be expired.  If <max> is
-set to \f(CW\*(C`never\*(C'\fR, Expires headers will be honored no matter how far into
-the future they are.
-.PP
-One should think of the fields as a lower bound, the default, and an upper
-bound.  Since most articles do not have an Expires header, the second
-field is the most important and most commonly applied.
-.PP
-Articles that do not match any expiration rule will not be expired, but
-this is considered an error and will result in a warning.  There should
-always be a default line (a line with a <pattern> of \f(CW\*(C`*\*(C'\fR and <flag> of
-\&\f(CW\*(C`A\*(C'\fR, or a line with a <classnum> of \f(CW\*(C`*\*(C'\fR), which can explicitly state
-that articles should never expire by default if that's the desired
-configuration.  The default line should generally be the first line of the
-file (except for \f(CW\*(C`/remember/\*(C'\fR) so that other expiration rules can
-override it.
-.PP
-It is often useful to honor the Expires header in articles, especially
-those in moderated groups.  To do this, set <min> to zero, <default> to
-whatever normal expiration you wish, and <max> to \f(CW\*(C`never\*(C'\fR or some large
-number, like 365 days for a maximum article life of a year.
-.PP
-To ignore any Expires header, set all three fields to the same value.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-When \fIgroupbaseexpiry\fR is true (the default):
-.PP
-.Vb 2
-\&    # Keep expired article history for 10 days, matching artcutoff.
-\&    /remember/:10
-.Ve
-.PP
-.Vb 2
-\&    # Most articles stay for two weeks, ignoring Expires.
-\&    *:A:14:14:14
-.Ve
-.PP
-.Vb 3
-\&    # Accept Expires headers in moderated groups for up to a year and
-\&    # retain moderated groups for a bit longer.
-\&    *:M:1:30:365
-.Ve
-.PP
-.Vb 3
-\&    # Keep local groups for a long time and local project groups forever.
-\&    example.*:A:90:90:90
-\&    example.project.*:A:never:never:never
-.Ve
-.PP
-When \fIgroupbaseexpiry\fR is false, for class-based expiration:
-.PP
-.Vb 2
-\&    # Keep expired article history for 10 days, matching artcutoff.
-\&    /remember/:10
-.Ve
-.PP
-.Vb 2
-\&    # Set a default expiration of seven days.
-\&    *:7:7:7
-.Ve
-.PP
-.Vb 2
-\&    # Class 0 is retained for two weeks.
-\&    0:14:14:14
-.Ve
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: expire.ctl.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIexpire\fR\|(8), \fIexpireover\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInews.daily\fR\|(8),
-\&\fIstorage.conf\fR\|(5), \fIuwildmat\fR\|(3)
diff --git a/doc/man/expireover.8 b/doc/man/expireover.8
deleted file mode 100644 (file)
index 4103a3f..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-.\" 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 "EXPIREOVER 8"
-.TH EXPIREOVER 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-expireover \- Expire entries from the news overview database
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBexpireover\fR [\fB\-ekNpqs\fR] [\fB\-f\fR \fIfile\fR] [\fB\-w\fR \fIoffset\fR]
-[\fB\-z\fR \fIrmfile\fR] [\fB\-Z\fR \fIlowmarkfile\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBexpireover\fR expires old entries from the news overview database.  It
-reads in a list of newsgroups (by default from \fIpathdb\fR/active, but a
-different file can be specified with the \fB\-f\fR option) and then removes
-from the overview database mentions of any articles that no longer exist
-in the news spool.
-.PP
-If \fIgroupbaseexpiry\fR in \fIinn.conf\fR is true, \fBexpireover\fR also removes
-old articles from the news spool according to the expiration rules in
-\&\fIexpire.ctl\fR.  Otherwise it only removes overview entries for articles
-that have already been removed by some other process, and \fB\-e\fR, \fB\-k\fR,
-\&\fB\-N\fR, \fB\-p\fR, \fB\-q\fR, \fB\-w\fR, and \fB\-z\fR are all ignored.
-.PP
-When \fIgroupbaseexpiry\fR is set, the default behavior of \fBexpireover\fR is
-to remove the article from the spool once it expires out of all of the
-newsgroups to which it was crossposted.  The article is, however, removed
-from the overview database of each newsgroup as soon as it expires out of
-that individual newsgroup.  The effect is that an article crossposted to
-several groups will be removed from the overview database from each group
-one-by-one as its age passes the expiration threshold for that group as
-set in \fIexpire.ctl\fR, and then when it expires out of the last newsgroup,
-it will be deleted from the news spool.
-.PP
-Articles that are stored in self-expiring storage backends such as \s-1CNFS\s0
-are normally treated differently and not expired until they expire out of
-the backend regardless of \fIexpire.ctl\fR.  See \fB\-N\fR, however.
-.PP
-By default, \fBexpireover\fR purges all overview information for newsgroups
-that have been removed from the server; this behavior is suppressed if
-\&\fB\-f\fR is given.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-e\fR" 4
-.IX Item "-e"
-Remove articles from the news spool and all overview databases as soon as
-they expire out of any newsgroup to which they are posted, rather than
-retain them until they expire out of all newsgroups.  \fB\-e\fR and \fB\-k\fR
-cannot be used at the same time.  This flag is ignored if
-\&\fIgroupbaseexpiry\fR is false.
-.IP "\fB\-f\fR \fIfile\fR" 4
-.IX Item "-f file"
-Use \fIfile\fR as the newsgroup list instead of \fIpathdb\fR/active.  \fIfile\fR
-can be \f(CW\*(C`\-\*(C'\fR to indicate standard input.  Using this flag suppresses the
-normal purge of all overview information from newsgroups that have been
-removed from the server.
-.IP "\fB\-k\fR" 4
-.IX Item "-k"
-Retain all overview information for an article, as well as the article
-itself, until it expires out of all newsgroups to which it was posted.
-This can cause articles to stick around in a newsgroup for longer than the
-\&\fIexpire.ctl\fR rules indicate, when they're crossposted.  \fB\-e\fR and \fB\-k\fR
-cannot be used at the same time.  This flag is ignored if
-\&\fIgroupbaseexpiry\fR is false.
-.IP "\fB\-N\fR" 4
-.IX Item "-N"
-Apply \fIexpire.ctl\fR rules to expire articles even from storage methods
-that have self-expire functionality.  This may remove articles from
-self-expiring storage methods before the articles \*(L"naturally\*(R" expire.
-This flag is ignored if \fIgroupbaseexpiry\fR is false.
-.IP "\fB\-p\fR" 4
-.IX Item "-p"
-By default, \fBexpireover\fR bases decisions on whether to remove an article
-on the arrival time on the server.  This means that articles may be kept a
-little longer than if the decision were based on the article's posting
-date.  If this option is given, expiration decisions are based on the
-article posting date instead.  This flag is ignored if \fIgroupbaseexpiry\fR
-is false.
-.IP "\fB\-q\fR" 4
-.IX Item "-q"
-\&\fBexpireover\fR normally prints statistics at the end of the expiration
-process.  \fB\-q\fR suppresses this report.  This flag is ignored if
-\&\fIgroupbaseexpiry\fR is false.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-\&\fBexpireover\fR normally only checks the existence of articles in the news
-spool if querying the storage method for that article to see if it still
-exists is considered \*(L"inexpensive.\*(R"  To always check the existence of all
-articles regardless of how resource-intensive this may be, use the \fB\-s\fR
-flag.  See \fIstorage.conf\fR\|(5) for more information about this metric.
-.IP "\fB\-w\fR \fIoffset\fR" 4
-.IX Item "-w offset"
-\&\*(L"Warps\*(R" time so that \fBexpireover\fR thinks that it's running at some time
-other than the current time.  This is occasionally useful to force groups
-to be expired or not expired without changing \fIexpire.ctl\fR for the expire
-run.  \fIoffset\fR should be a signed floating point number specifying the
-number of days difference from the current time to use as \*(L"now.\*(R"  This
-flag is ignored if \fIgroupbaseexpiry\fR is false.
-.IP "\fB\-z\fR \fIrmfile\fR" 4
-.IX Item "-z rmfile"
-Don't remove articles immediately but instead write the path to the
-article or the token of the article to \fIrmfile\fR, which is suitable input
-for \fIfastrm\fR\|(1).  This can substantially speed up deletion of expired
-articles for those storage methods where each article is a single file
-(such as tradspool and timehash).  See the description of \fIdelayrm\fR in
-\&\fInews.daily\fR\|(8) for more details.  This flag is ignored if
-\&\fIgroupbaseexpiry\fR is false.
-.IP "\fB\-Z\fR \fIlowmarkfile\fR" 4
-.IX Item "-Z lowmarkfile"
-Write the lowest article numbers for each newsgroup as it's expired to the
-specified file.  This file is then suitable for \f(CW\*(C`ctlinnd lowmark\*(C'\fR.  See
-\&\fIctlinnd\fR\|(8) for more information.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Normally \fBexpireover\fR is invoked from \fInews.daily\fR\|(8), which handles such
-things as processing the \fIrmfile\fR and \fIlowmarkfile\fR if necessary.
-Sometimes it's convenient to manually expire a particular newsgroup,
-however.  This can be done with a command like:
-.PP
-.Vb 2
-\&    echo example.test | expireover \-f \- \-Z /usr/local/news/tmp/lowmark
-\&    ctlinnd lowmark /usr/local/news/tmp/lowmark
-.Ve
-.PP
-This can be particularly useful if a lot of articles in a particular group
-have expired but the overview information is still present, causing some
-clients to see a lot of \*(L"this article may have been cancelled\*(R" messages
-when they first enter the newsgroup.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rob Robertson <rob@violet.berkeley.edu> and Rich \f(CW$alz\fR
-<rsalz@uunet.uu.net> (with help from Dave Lawrence <tale@uunet.uu.net>)
-for InterNetNews.
-.PP
-$Id: expireover.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive\fR\|(5), \fIctlinnd\fR\|(8), \fIexpire\fR\|(8), \fIexpire.ctl\fR\|(5), \fIinn.conf\fR\|(5),
-\&\fInews.daily\fR\|(8).
diff --git a/doc/man/expirerm.8 b/doc/man/expirerm.8
deleted file mode 100644 (file)
index 5738e02..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-.TH EXPIRERM 8
-.SH NAME
-expirerm \- remove articles that have been expired.
-.SH SYNOPSIS
-.B expirerm
-.I file
-.SH DESCRIPTION
-.I Expirerm
-is a script that removes a list of files.
-The specified
-.I file
-lists the files.
-It is sorted, and then fed into a pipeline responsible for doing
-the removal, normally
-.IR fastrm (8).
-If there seemed to be a problem removing the files, then mail is sent to
-the news administrator.
-If there were no problems, then
-.I file
-is renamed to
-.I <pathlog in inn.conf>/expire.list
-where it is kept (for safety) until the next time expiration is done.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and
-Rich $alz <rsalz@uunet.uu.net>
-.SH "SEE ALSO"
-expire(8),
-fastrm(8),
-inn.conf(5).
-
diff --git a/doc/man/fastrm.1 b/doc/man/fastrm.1
deleted file mode 100644 (file)
index de7cb5f..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-.\" 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 "FASTRM 1"
-.TH FASTRM 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-fastrm \- Quickly remove a list of files
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBfastrm\fR [\fB\-de\fR] [\fB\-u\fR|\fB\-u\fR\fIN\fR] [\fB\-s\fR|\fB\-s\fR\fIM\fR] [\fB\-c\fR|\fB\-c\fR\fII\fR]
-\&\fIbase-directory\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBfastrm\fR reads a list of either file names or storage \s-1API\s0 tokens, one per
-line, from its standard input and removes them.  Storage \s-1API\s0 tokens are
-removed via the \fISMcancel()\fR interface.  \fBfastrm\fR does not delete files
-safely or with an eye to security, but rather cuts every corner it can to
-delete files as fast as it can.  It should therefore never be run on
-publically writable directories, or in any other environment where a
-hostile party may control the directory structure in which it is working.
-.PP
-If a file name is not an absolute path name, it is considered to be
-relative to \fIbase-directory\fR as given on the command line.  The
-\&\fIbase-directory\fR parameter must be a simple absolute pathname (it must
-not contain multiple consecutive slashes or references to the special
-directories \f(CW\*(C`.\*(C'\fR or \f(CW\*(C`..\*(C'\fR).
-.PP
-\&\fBfastrm\fR is designed to be faster than the typical \f(CW\*(C`| xargs rm\*(C'\fR pipeline
-when given a sorted list of file names as input.  For example, \fBfastrm\fR
-will usually \fIchdir\fR\|(2) into a directory before removing files from it,
-meaning that if its input is sorted, most names passed to \fIunlink\fR\|(2) will
-be simple names.  This can substantially reduce the operating system
-overhead from directory lookups.
-.PP
-\&\fBfastrm\fR assumes that its input is valid and that it is safe to call
-\&\fIunlink\fR\|(2) on every file name it is given.  As a safety measure, however,
-\&\fBfastrm\fR when running as root will check with \fIstat\fR\|(2) that a file name
-doesn't specify a directory before removing it.  (In some operating
-systems, root is allowed to unlink directories, even directories which
-aren't empty, which can cause file system corruption.)
-.PP
-The input to \fBfastrm\fR should always be sorted \*(-- or even better be in the
-order file names are output by \fIfind\fR\|(1) \*(-- if speed is an issue and the
-input isn't solely storage \s-1API\s0 tokens.  (It deals fine with unsorted
-input, but is unlikely to be any faster in that case than a simple \f(CW\*(C`xargs
-rm\*(C'\fR command.)  Sorting may even slightly speed up the removal of storage
-\&\s-1API\s0 tokens due to caching effects, since sorting will tend to keep all of
-the tokens from a particular storage method together.
-.PP
-Various additional optimizations for removing files can be turned on
-and/or tuned with options (see below).  Which options will be most
-effective depends heavily on the underlying structure of the file system,
-the way in which directories are stored and searched, and similar, often
-underdocumented, operating system implementation details.  The more
-sophisticated the underlying operating system and file system, the more
-likely that it will already perform the equivalent of these optimizations
-internally.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-d\fR" 4
-.IX Item "-d"
-Don't remove any files.  Instead, print a list of the files that would be
-removed to standard output.  Each line contains either the current
-directory of \fBfastrm\fR at the time it would do the unlink and the relative
-path name it would pass to \fIunlink\fR\|(2) as two fields separated by whitespace
-and a \f(CW\*(C`/\*(C'\fR, the absolute path name (as a single field) that would be
-passed to \fIunlink\fR\|(2), or the string \f(CW\*(C`Token\*(C'\fR and the storage \s-1API\s0 token that
-would be removed.
-.IP "\fB\-e\fR" 4
-.IX Item "-e"
-Treat an empty input file as an error.  This is most useful when \fBfastrm\fR
-is last in a pipeline after a preceding \fIsort\fR\|(1) command, ensuring that
-\&\fBfastrm\fR will fail if the sort fails.
-.IP "\fB\-c\fR\fII\fR" 4
-.IX Item "-cI"
-Controls when \fBfastrm\fR calls \fIchdir\fR\|(2).  If the number of files to be
-unlinked from a given directory is at least \fII\fR, then \fBfastrm\fR will
-change to that directory before unlinking those files.  Otherwise, it will
-use either the absolute path names or a path name relative to the current
-directory (whichever is likely more efficient).  The \fII\fR parameter is
-optional; if just \fB\-c\fR is given, \fB\-c1\fR is assumed, which will cause
-\&\fBfastrm\fR to always chdir before calling \fIunlink\fR\|(2).  The default is
-\&\fB\-c3\fR.  Use \fB\-c0\fR to prevent \fBfastrm\fR from ever using \fIchdir\fR\|(2).
-.IP "\fB\-s\fR\fIM\fR" 4
-.IX Item "-sM"
-When \fB\-s\fR is given and the number of files to remove in a directory is
-greater than \fIM\fR, rather than remove files in the order given, \fBfastrm\fR
-will open the directory and read it, unlinking files in the order that
-they appear in the directory.  On systems with a per-process directory
-cache or that use a linear search to find files in a directory, this
-should make directory lookups faster.  The \fIM\fR parameter is optional; if
-just \fB\-s\fR is given, \fB\-s5\fR is assumed.
-.Sp
-When this option is in effect, \fBfastrm\fR won't attempt to remove files
-that it doesn't see in the directory, possibly significantly speeding it
-up if most of the files to be removed have already been deleted.  However,
-using this option requires \fBfastrm\fR to do more internal work and it also
-assumes that the order of directory listings is stable in the presence of
-calls to \fIunlink\fR\|(2) between calls to \fIreaddir\fR\|(3).  This may be a dangerous
-assumption with some sophisticated file systems (and in general this
-option is only useful with file systems that use unindexed linear searches
-to find files in directories or when most of the files to be removed have
-already been deleted).
-.Sp
-This optimization is off by default.
-.IP "\fB\-u\fR\fIN\fR" 4
-.IX Item "-uN"
-Specifying this option promises that there are no symbolic links in the
-directory tree from which files are being removed.  This allows \fBfastrm\fR
-to make an additional optimization to its calls to \fIchdir\fR\|(2), constructing
-a relative path using \f(CW\*(C`../..\*(C'\fR and the like to pass to \fIchdir\fR\|(2) rather
-than always using absolute paths.  Since this reduces the number of
-directory lookups needed with deeply nested directory structures (such as
-that typically created by traditional news spool storage), it can be a
-significant optimization, but it breaks horribly in the presence of
-symbolic links to directories.
-.Sp
-When \fB\-u\fR is given, \fBfastrm\fR will use at most \fIN\fR levels of \f(CW\*(C`..\*(C'\fR
-segments to construct paths.  \fIN\fR is optional; if just \fB\-u\fR is given,
-\&\fB\-u1\fR is assumed.
-.Sp
-This optimization is off by default.
-.PP
-\&\fBfastrm\fR also accepts \fB\-a\fR and \fB\-r\fR options, which do nothing at all
-except allow you to say \f(CW\*(C`fastrm \-usa\*(C'\fR, \f(CW\*(C`fastrm \-ussr\*(C'\fR, or \f(CW\*(C`fastrm
-\&\-user\*(C'\fR.  These happen to often be convenient sets of options to use.
-.SH "EXIT STATUS"
-.IX Header "EXIT STATUS"
-\&\fBfastrm\fR exits with a status of zero if there were no problems, and an
-exit status of 1 if something went wrong.  Attempting to remove a file
-that does not exist is not considered a problem.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-\&\fBfastrm\fR is typically invoked by \s-1INN\s0 via \fIexpirerm\fR\|(8) using a command
-like:
-.PP
-.Vb 1
-\&    fastrm \-e /usr/local/news/spool/articles < expire.list
-.Ve
-.PP
-To enable all optimizations and see the affect on the order of removal
-caused by \fB\-s\fR, use:
-.PP
-.Vb 1
-\&    fastrm \-d \-s \-e \-u ~news/spool/articles < expire.list
-.Ve
-.PP
-If your file system has indexed directory lookups, but you have a deeply
-nested directory structure, you may want to use a set of flags like:
-.PP
-.Vb 1
-\&    fastrm \-e \-u3 ~news/spool/articles < expire.list
-.Ve
-.PP
-to strongly prefer relative paths but not to use \fIreaddir\fR\|(2) to order the
-calls to \fIunlink\fR\|(2).
-.PP
-You may want to edit \fIexpirerm\fR\|(8) to change the flags passed to \fBfastrm\fR.
-.SH "WARNINGS"
-.IX Header "WARNINGS"
-\&\fBfastrm\fR cuts corners and does not worry about security, so it does not
-use \fIchdir\fR\|(2) safely and could be tricked into removing files other than
-those that were intended if run on a specially constructed file tree or a
-file tree that is being modified while it is running.  It should therefore
-never be used with world-writable directories or any other directory that
-might be controlled or modified by an attacker.
-.SH "NOTES"
-.IX Header "NOTES"
-\&\fBfastrm\fR defers opening the storage subsystem or attempting to parse any
-\&\s-1INN\s0 configuration files until it encounters a token in the list of files
-to remove.  It's therefore possible to use \fBfastrm\fR outside of \s-1INN\s0 as a
-general fast file removal program.
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBfastrm\fR was originally written by kre@munnari.oz.au.  This manual page
-rewritten in \s-1POD\s0 by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: fastrm.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIexpirerm\fR\|(8)
diff --git a/doc/man/filechan.8 b/doc/man/filechan.8
deleted file mode 100644 (file)
index 0d7a387..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-.\" $Revision: 5909 $
-.TH FILECHAN 8
-.SH NAME
-filechan \- file-writing backend for InterNetNews
-.SH SYNOPSIS
-.B filechan
-[
-.BI \-d " directory"
-]
-[
-.BI \-f " num_fields"
-]
-[
-.BI \-m " mapfile"
-]
-[
-.BI \-p " pidfile"
-]
-.SH DESCRIPTION
-.I Filechan
-reads lines from standard input and copies certain fields in
-each line into files named by other fields within the line.
-.I Filechan
-is intended to be called by
-.IR innd (8)
-as a channel feed.
-(It is not a full exploder and does not accept commands; see
-.IR newsfeeds (5)
-for a description of the difference, and
-.IR buffchan (8)
-for an exploder program.)
-.PP
-.I Filechan
-input is interpreted as a sequence of lines.
-Each line contains a fixed number of initial fields, followed by a
-variable number of filename fields.
-All fields in a line are separated by whitespace.
-The default number of initial fields is one.
-.PP
-For each line of input,
-.I filechan
-writes the initial fields, separated by whitespace and followed by a
-newline, to each of the files named in the filename fields.
-When writing to a file,
-.I filechan
-opens it in append mode and tries to lock it and change the
-ownership to the user and group who owns the directory where the file is
-being written.
-.PP
-Because the time window in which a file is open is very small, complicated
-flushing and locking protocols are not needed; a
-.IR mv (1)
-followed by a
-.IR sleep (1)
-for a couple of seconds is sufficient.
-.SH OPTIONS
-.TP
-.B \-f num_fields
-The ``\fB\-f\fP'' flag may be
-used to specify a different number of initial fields.
-.TP
-.B \-d directory
-By default,
-.I filechan
-writes its output into the directory
-.IR <pathoutgoing\ in\ inn.conf> .
-The ``\fB\-d\fP'' flag may be used to specify a directory the program should
-change to before starting.
-.TP
-.B \-p pidfile
-If the ``\fB\-p\fP'' flag is used, the program will write a line containing
-its process ID (in text) to the specified file.
-.TP
-.B \-m mapfile
-A map file may be specified by using the ``\fB\-m\fP'' flag.
-Blank lines and lines starting with a number sign (``#'') are ignored.
-All other lines should have two host names separated by a colon.
-The first field is the name that may appear in the input stream;
-the second field names the file to be used when the name in the first
-field appears.
-For example, the following map file may be used to map the short
-names used in the example below to the full domain names:
-.PP
-.RS
-.nf
-# This is a comment
-uunet:news.uu.net
-foo:foo.com
-munnari:munnari.oz.au
-.fi
-.RE
-.SH EXAMPLES
-If
-.I filechan
-is invoked with ``\fB\-f 2\fP'' and given the following input:
-.PP
-.RS
-.nf
-news/software/b/132 <1643@munnari.oz.au> foo uunet
-news/software/b/133 <102060@litchi.foo.com> uunet munnari
-comp/sources/unix/2002 <999@news.foo.com> foo uunet munnari
-.fi
-.RE
-.PP
-Then the file
-.I foo
-will have these lines:
-.PP
-.RS
-.nf
-news/software/b/132 <1643@munnari.oz.au>
-comp/sources/unix/2002 <999@news.foo.com>
-.fi
-.RE
-.sp
-the file
-.I munnari
-will have these lines:
-.PP
-.RS
-.nf
-news/software/b/133 <102060@litchi.foo.com>
-comp/sources/unix/2002 <999@news.foo.com>
-.fi
-.RE
-.sp
-and the file
-.I uunet
-will have these lines:
-.PP
-.RS
-.nf
-news/software/b/132 <1643@munnari.oz.au>
-news/software/b/133 <102060@litchi.foo.com>
-comp/sources/unix/2002 <999@news.foo.com>
-.fi
-.RE
-.SH HISTORY
-Written by Robert Elz <kre@munnari.oz.au>, flags added by Rich $alz
-<rsalz@uunet.uu.net>.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: filechan.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-buffchan(8),
-inn.conf(5),
-innd(8),
-newsfeeds(5).
diff --git a/doc/man/getlist.1 b/doc/man/getlist.1
deleted file mode 100644 (file)
index fac7402..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-.\" $Revision: 5909 $
-.TH GETLIST 1
-.SH NAME
-getlist \- get a list from an NNTP server
-.SH SYNOPSIS
-.I getlist
-[
-.B \-A
-]
-[
-.BI \-h " host"
-]
-[
-.I list
-[
-.I pattern
-[
-.I types
-]
-]
-]
-.SH DESCRIPTION
-The
-.I getlist
-program obtains a list from an NNTP server and sends
-it to standard output.
-.PP
-The
-.B list
-may be one of
-.IR active ,
-.IR active.times ,
-.IR distributions ,
-or
-.IR newsgroups .
-These values request the
-.IR active ,
-.IR active.times ,
-.IR <pathetc\ in\ inn.conf>/distributions .
-or
-.I <pathdb in inn.conf>/newsgroups
-files, respectively.
-.SH OPTIONS
-.TP
-.B \-A
-If the ``\fB\-A\fP'' flag is used, then the program tries to authenticate
-as per
-.I passwd.nntp
-before issuing LIST command.
-.TP
-.B \-h
-If the ``\fB\-h\fP'' flag is used, then the program connects to the server
-on the specified host.
-The default is to connect to the server specified in the
-.I inn.conf
-file.
-.PP
-If the
-.I list
-parameter is
-.IR active ,
-then the 
-.I pattern
-and
-.I types
-parameters may be used to limit the output.
-When
-.I pattern
-is used, only active lines with groups that match according to
-.IR uwildmat (3)
-are printed.
-When
-.I types
-is also given, only active lines that have a fourth field starting
-with a character found in
-.I types
-are printed.
-.PP
-For example, the following command will obtain the one-line descriptions
-of all newsgroups found on UUNET:
-.RS
-getlist -h news.uu.net newsgroups
-.RE
-.PP
-The following line lists all groups where local postings are permitted,
-are moderated or aliased:
-.RS
-getlist active '*' ym=
-.RE
-.PP
-Note that the listing files other than the active file is a common
-extension to the NNTP protocol and may not be available on all servers.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.SH "SEE ALSO"
-active(5), active.times(5), inn.conf(5), nnrpd(8), uwildmat(3).
diff --git a/doc/man/grephistory.1 b/doc/man/grephistory.1
deleted file mode 100644 (file)
index b2417b6..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-.\" 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 "GREPHISTORY 1"
-.TH GREPHISTORY 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-grephistory \- Query the INN history database
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBgrephistory\fR [\fB\-eilnqsv\fR] [\fB\-f\fR \fIdb\fR] [\fImessage-id\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBgrephistory\fR queries the \s-1INN\s0 history database for information about the
-specified message \s-1ID\s0.  If no flags are given, the program prints the
-storage \s-1API\s0 token of the corresponding article, or \f(CW\*(C`/dev/null\*(C'\fR if the
-article is listed in the history database but not stored on the server.
-If the message \s-1ID\s0 cannot be found in the database, \fBgrephistory\fR will
-print \f(CW\*(C`grephistory: not found\*(C'\fR and exit with a non-zero status.
-.PP
-Be sure to escape any special characters in the message \s-1ID\s0 from the shell.
-Single quotes are recommended for this purpose since many message IDs
-contain dollar signs.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-e\fR" 4
-.IX Item "-e"
-Only print the storage token if the article is stored on the system.  (In
-other words, suppress the \f(CW\*(C`/dev/null\*(C'\fR or \f(CW\*(C`not found\*(C'\fR output for missing
-or remembered articles.)
-.IP "\fB\-f\fR \fIdb\fR" 4
-.IX Item "-f db"
-Query the history database \fIdb\fR rather than the default history database.
-.IP "\fB\-i\fR" 4
-.IX Item "-i"
-Rather than expecting a message \s-1ID\s0 on the command line, \fBgrephistory\fR
-will read a list of message IDs on standard input, one per line.  Leading
-and trailing whitespace is ignored, as are any malformed lines.  It will
-print out standard output those message IDs which are not found in the
-history database.  This is used when processing \f(CW\*(C`ihave\*(C'\fR control messages.
-.IP "\fB\-l\fR" 4
-.IX Item "-l"
-Display the entire line from the history database, rather than just the
-storage \s-1API\s0 token.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-If the message \s-1ID\s0 is present in the history database but has no storage
-\&\s-1API\s0 token, print \f(CW\*(C`/dev/null\*(C'\fR and exit successfully.  This can happen if
-an article has been cancelled or expired, but history information has
-still been retained.  This is the default behavior.
-.IP "\fB\-q\fR" 4
-.IX Item "-q"
-Don't print any message, but still exit with the appropriate status.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-Rather than expecting a message \s-1ID\s0 on the command line, \fBgrephistory\fR
-will read a list of message IDs on standard input, one per line.  Leading
-and trailing whitespace is ignored, as are any malformed lines.  It will
-print on standard output the storage \s-1API\s0 tokens for any articles that are
-still available, one per line.  This flag is used when processing
-\&\f(CW\*(C`sendme\*(C'\fR control messages.
-.IP "\fB\-v\fR" 4
-.IX Item "-v"
-Print out the hash of the message \s-1ID\s0 for diagnostic purposes, as well as
-any other requested information.  This flag is not useful with \fB\-s\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.Sp
-$Id: grephistory.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIhistory\fR\|(5), \fIinn.conf\fR\|(5)
diff --git a/doc/man/history.5 b/doc/man/history.5
deleted file mode 100644 (file)
index 8f7def2..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-.\" $Revision: 3782 $
-.TH HISTORY 5
-.SH NAME
-history \- record of current and recently expired Usenet articles
-.SH DESCRIPTION
-The file
-.I <pathdb in inn.conf>/history
-keeps a record of all articles currently stored in the news system,
-as well as those that have been received but since expired.
-In a typical production environment, this file will be many megabytes.
-.PP
-The file consists of text lines.
-Each line corresponds to one article.
-The file is normally kept sorted in the order in which articles are
-received, although this is not a requirement.
-.IR Innd (8)
-appends a new line each time it files an article, and
-.IR expire (8)
-builds a new version of the file by removing old articles and purging
-old entries.
-.PP
-Each line consists of two or three fields separated by a tab, shown below
-as
-.IR \et :
-.RS
-.nf
-[Hash]         \et   date
-[Hash]         \et   date   \et   token
-.fi
-.RE
-.PP
-The
-.I Hash
-field is the ASCII representation of the hash of the Message-ID header.  
-This is directly used for the key of the
-.IR dbz (3).
-.PP
-The
-.I date
-field consists of three sub-fields separated by a tilde.
-All sub-fields are the text representation of the number of seconds since
-the epoch \(em
-.IR i.e. ,
-a
-.IR time_t ;
-see
-.IR gettimeofday (2).
-The first sub-field is the article's arrival date.
-If copies of the article are still present then the second sub-field is
-either the value of the article's Expires header, or a hyphen if no
-expiration date was specified.
-If an article has been expired then the second sub-field will be a hyphen.
-The third sub-field is the value of the article's Date header, recording
-when the article was posted.
-.PP
-The
-.I token
-field is a token of the article.
-This field is empty if the article has been expired.
-.PP
-For example, an article whose Message-ID was
-<7q2saq$sal$1@isrv4.pa.vix.com>, posted on 26 Aug 1999 08:02:34 GMT and
-recieved at 26 Aug 1999 08:06:54 GMT, could have a
-history line (broken into three lines for display) like the
-following:
-.RS
-.nf
-[E6184A5BC2898A35A3140B149DE91D5C]  \et
-    935678987~-~935678821  \et
-    @030154574F00000000000007CE3B000004BA@
-.fi
-.RE
-.PP
-In addition to the text file, there is a
-.IR dbz (3)
-database associated with the file that uses the Message-ID field as a key
-to determine the offset in the text file where the associated line begins.
-For historical reasons, the key includes the trailing \e0 byte
-(which is not stored in the text file).
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: history.5 3782 2000-08-17 13:30:18Z kondou $
-.SH "SEE ALSO"
-dbz(3),
-expire(8),
-inn.conf(5),
-innd(8),
-makehistory(8).
diff --git a/doc/man/ident.8 b/doc/man/ident.8
deleted file mode 100644 (file)
index da28b53..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-.\" 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 "IDENT 8"
-.TH IDENT 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ident \- nnrpd ident resolver
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBident\fR [\fB\-p\fR \fIport\fR] [\fB\-t\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This program attempts to resolve usernames for \fBnnrpd\fR by using the
-ident protocol to query the remote host.  It contacts the remote host
-using either IPv4 or IPv6 depending on which protocol was used for the
-incoming \s-1NNTP\s0 connection.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-p\fR \fIport\fR" 4
-.IX Item "-p port"
-If this option is given, attempt to contact identd on the specified
-remote port (which can be a numeric or symbolic specification).
-Non-numeric values will be looked up using \fIgetservbyname\fR\|(3).  The
-default value is the result of \f(CW\*(C`getservbyname("ident")\*(C'\fR if available,
-or port 113 otherwise.
-.IP "\fB\-t\fR" 4
-.IX Item "-t"
-If this option is given, the identity returned will never have a domain
-part.  That is, if the remote server returns a result containing an \f(CW\*(C`@\*(C'\fR
-character, \fBident\fR truncates the response at the \f(CW\*(C`@\*(C'\fR.  This is useful
-to allow the \fIdefault-domain\fR parameter in \fIreaers.conf\fR to override
-the domain supplied by the remote host (particularly if the supplied
-domain part is an unqualified local machine name rather than a full
-domain name).
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-The following \fIreaders.conf\fR\|(5) fragment tells nnrpd to trust ident
-information for hosts on a local network, but to replace the domain
-returned from the ident query:
-.PP
-.Vb 5
-\&    auth LAN {
-\&        hosts: "192.168/16"
-\&        res: "ident \-t"
-\&        default\-domain: "internal.example.com"
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access LAN {
-\&        users: "*@internal.example.com"
-\&        newsgroups: example.*
-\&    }
-.Ve
-.PP
-Access is granted to the example.* groups for all users on the local
-network whose machines respond to ident queries.
-.SH "HISTORY"
-.IX Header "HISTORY"
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-.PP
-$Id: ident.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5)
diff --git a/doc/man/incoming.conf.5 b/doc/man/incoming.conf.5
deleted file mode 100644 (file)
index 67f1e13..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-.\" $Revision: 6992 $
-.TH INCOMING.CONF 5
-.SH NAME
-incoming.conf \- names and addresses that feed us news
-.SH DESCRIPTION
-The file
-.I <pathetc in inn.conf>/incoming.conf
-consists of three types of entries: key/value, peer and group.
-Comments are from the hash character ``#'' to the end of the line.
-Blank lines are ignored.  All key/value entries within each type
-must not be duplicated.
-.PP
-Key/value entries are a keyword immediately followed by a colon, at least
-one blank and a value.  For example:
-.PP
-.RS
-.nf
-       max-connections: 10
-.fi
-.RE
-.PP
-A legal key does not contains blanks, colons, nor ``#''.
-There are 3 different types of values:  integers, booleans, and strings.
-Integers are as to be expected. A boolean value is either ``true'' or
-``false'' (case is significant). A string value is any other sequence of
-characters. If the string needs to contain whitespace, then it must be
-quoted with double quotes.
-.PP
-Peer entries look like:
-.PP
-.RS
-.nf
-        peer <name> {
-             # body
-        }
-.fi
-.RE
-.PP
-The word ``peer'' is required. ``<name>''is a label for this peer.
-The ``<name>'' is any string valid as a key. The body of a peer entry
-contains some number of key/value entries.
-.PP
-Group entries look like:
-.PP
-.RS
-.nf
-        group <name> {
-             # body
-        }
-.fi
-.RE
-.PP
-The word ``group'' is required. The ``<name>'' is any string valid as a
-key. The body of a group entry contains any number of the three types of
-entries. So key/value pairs can be defined inside a group, and peers can
-be nested inside a group, and other groups can be nested inside a group.
-.PP
-Key/value entries that are defined outside of all peer and group entries
-are said to be at ``global scope''. Global key/value entries act as
-defaults for peers. When
-.IR innd (8)
-looks for a specific value in a peer entry
-(for example, the maximum number of connections to allow), if the value
-is not defined in the peer entry, then the enclosing groups are examined
-for the entry (starting at the closest enclosing group). If there are no
-enclosing groups, or the enclosing groups don't define the key/value,
-then the value at global scope is used.
-.PP
-A small example could be:
-.PP
-.RS
-.nf
-# Global value applied to all peers that have
-# no value of their own.
-max-connections: 5
-
-# A peer definition.
-peer uunet {
-     hostname: usenet1.uu.net
-}
-
-peer vixie {
-     hostname: gw.home.vix.com
-     max-connections: 10 # override global value.
-}
-
-# A group of two peers who can open more
-# connections than normal
-group fast-sites {
-     max-connections: 15
-
-     # Another peer. The ``max-connections'' value from the
-     # ``fast-sites'' group scope is used. The ``hostname'' value
-     # defaults to the peer's name.
-     peer data.ramona.vix.com {
-     }
-
-     peer bb.home.vix.com {
-         hostname: bb.home.vix.com
-         max-connections: 20 # he can really cook.
-    }
-}
-.fi
-.RE
-.PP
-Given the above configuration file, the defined peers would have the
-following values for the ``max-connections'' key.
-.PP
-.RS
-.nf
-        uunet                  5
-        vixie                 10
-        data.ramona.vix.com   15
-        bb.home.vix.com       20
-.fi
-.RE
-.PP
-Ten keys are allowed:
-.TP
-.BI hostname:
-This key requires a string value. It is a list of hostnames separated by a
-comma. A hostname is the host's FQDN, or the dotted quad ip-address of the
-peer. If this key is not present in a peer block, the hostname defaults to
-the label of the peer.
-.TP
-.BI streaming:
-This key requires a boolean value. It defines whether streaming commands
-are allowed from this peer. (default=true)
-.TP
-.BI max-connections:
-This key requires a positive integer value. It defines the maximum number
-of connections allowed. A value of zero specifies an unlimited number
-of maximum connections (``unlimited'' or ``none'' can be used as synonym).
-(default=0)
-.TP
-.BI hold-time:
-This key requires a positive integer value. It defines the hold time before
-closing, if the connection is over max-connections. A value of zero
-specifies immediate close. (default=0)
-.TP
-.BI password:
-This key requires a string value. It is used if you wish to require a peer
-to supply a password. (default=no password)
-.TP
-.BI identd:
-This key requires a string value. It is used if you wish to require a peer's
-user name retrieved through identd match the specified string. Note that
-currently
-.IR innd (8)
-does not implement any timeout in identd callbacks, so enabling this
-option may cause innd to hang if the remote peer does not respond to ident
-callbacks in a reasonable timeframe (default=no identd)
-.TP
-.BI patterns:
-This key requires a string value. It is a list of
-.IR newsfeeds (5)-style
-list of newsgroups which are to be accepted from this host. (default="*")
-.TP
-.BI email:
-This key requires a string value. Reserved for future use. (default=empty)
-.TP
-.BI comment:
-This key requires a string value. Reserved for future use. (default=empty)
-.TP
-.BI skip:
-This key requires a boolean value. Setting this entry causes this peer
-to be skipped. (default=false)
-.TP
-.BI noresendid:
-This key requires a boolean value. It defines whether
-.IR innd (8)
-should send
-``431 RESENDID'' responses if a message is offered that is being received
-from another peer. This can be useful for peers that resend messages
-right away, as innfeed does. (default=false)
-.TP
-.BI nolist:
-This key requires a boolean value. It defines whether a peer is allowed to
-issue list command. (default=false)
-.SH HISTORY
-Written by Fabien Tassin <fta@sofaraway.org> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: incoming.conf.5 6992 2004-10-01 05:30:17Z rra $
-.SH "SEE ALSO"
-inn.conf(5),
-innd(8),
-newsfeeds(5),
-uwildmat(3).
diff --git a/doc/man/inews.1 b/doc/man/inews.1
deleted file mode 100644 (file)
index 37c2471..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-.\" 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 "INEWS 1"
-.TH INEWS 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-inews \- Post a Usenet article to the local news server
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinews\fR [\fB\-ADhNORSVW\fR] [\fB\-acdeFfnortwx\fR \fIvalue\fR] [\fB\-p\fR \fIport\fR] [\fIfile\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinews\fR reads a Usenet news article, perhaps with headers, from \fIfile\fR
-or standard input if no file is given.  It adds some headers and performs
-some consistency checks.  If the article does not meet those checks, the
-article is rejected.  If it passes the checks, \fBinews\fR sends the article
-to the local news server as specified in \fIinn.conf\fR.
-.PP
-By default, if a file named \fI.signature\fR exists in the home directory of
-the posting user, it is appended to the post, preceeded by a line that
-contains only \f(CW\*(C`\-\- \*(C'\fR.  Signatures are not allowed to be more than four
-lines long.
-.PP
-Cancel messages can only be posted with \fBinews\fR if the sender of the
-cancel message matches the sender of the original message being
-cancelled.  The same check is also applied to Supersedes.  Sender in this
-case means the contents of the Sender header if present, otherwise the
-From header.
-.PP
-Control messages other than cancel messages are only allowed if \fBinews\fR
-is being run by the news user or by a user in the news group and if the
-control message is recognized.  If the article contains a Distribution
-header with a distribution that matches one of the bad distribution
-patterns in \fIinn/options.h\fR (anything containing a period by default),
-the message will be rejected.  The message will also be rejected if
-\&\fIcheckincludedtext\fR is true in \fIinn.conf\fR, it contains more quoted text
-than original text, and it is over 40 lines long.
-.PP
-If not provided, the Path header of an article is constructed as follows:
-The basic Path header will be \*(L"not\-for\-mail\*(R".  If \fIpathhost\fR is specified
-in \fIinn.conf\fR, it will be added to the beginning Path.  Otherwise, if
-\&\fIserver\fR is specified, the full domain of the local host will be added to
-the beginning of the Path.  Then, if \fB\-x\fR was given, its value will be
-added to the beginning of the Path.
-.PP
-If posting fails, a copy of the failed post will be saved in a file named
-\&\fIdead.article\fR in the home directory of the user running \fBinews\fR.
-\&\fBinews\fR exits with a non-zero status if posting failed or with a zero
-status if posting was successful.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-Most of the options to \fBinews\fR take a single value and set the
-corresponding header in the message that is posted.  If the value is more
-than one word or contains any shell metacharacters, it must be quoted to
-protect it from the shell.  Here are all the options that set header
-fields and the corresponding header:
-.PP
-.Vb 12
-\&    \-a  Approved
-\&    \-c  Control
-\&    \-d  Distribution
-\&    \-e  Expires
-\&    \-F  References
-\&    \-f  From
-\&    \-n  Newsgroups
-\&    \-o  Organization
-\&    \-r  Reply\-To
-\&    \-t  Subject
-\&    \-w  Followup\-To
-\&    \-x  Path prefix
-.Ve
-.PP
-The \fB\-x\fR argument will be added to the beginning of the normal Path
-header; it will not replace it.
-.IP "\fB\-A\fR, \fB\-V\fR, \fB\-W\fR" 4
-.IX Item "-A, -V, -W"
-Accepted for compatibility with C News.  These options have no affect.
-.IP "\fB\-D\fR, \fB\-N\fR" 4
-.IX Item "-D, -N"
-Perform the consistency checks and add headers where appropriate, but then
-print the article to standard output rather than sending it to the server.
-\&\fB\-N\fR is accepted as as synonym for compatibility with C News.
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Normally, this flag should always be given.  It indicates that the article
-consists of headers, a blank line, and then the message body.  If it is
-omitted, the input is taken to be just the body of the message, and any
-desired headers have to be specified with command-line options as
-described above.
-.IP "\fB\-O\fR" 4
-.IX Item "-O"
-By default, an Organization header will be added if none is present in the
-article.  To prevent adding the default (from \fIorganization\fR in
-\&\fIinn.conf\fR), use this flag.
-.IP "\fB\-p\fR \fIport\fR" 4
-.IX Item "-p port"
-Connect to the specified port on the server rather than to the default
-(port 119).
-.IP "\fB\-R\fR" 4
-.IX Item "-R"
-Reject all control messages.
-.IP "\fB\-S\fR" 4
-.IX Item "-S"
-Do not attempt to append \fI~/.signature\fR to the message, even if it
-exists.
-.SH "NOTES"
-.IX Header "NOTES"
-If the \s-1NNTP\s0 server requests authentication, \fBinews\fR will try to read
-\&\fIpasswd.nntp\fR to get the username and password to use and will therefore
-need read access to that file.  This is typically done by making that file
-group-readable and adding all users who should be able to use \fBinews\fR to
-post to that server to the appropriate group.
-.PP
-\&\fBinews\fR used to do even more than it does now, and all of the remaining
-checks that are not dependent on the user running \fBinews\fR should probably
-be removed in favor of letting the news server handle them.
-.PP
-Since \s-1INN\s0's \fBinews\fR uses \fIinn.conf\fR and some other corners of an \s-1INN\s0
-installation, it's not very appropriate as a general stand-alone \fBinews\fR
-program for general use on a system that's not running a news server.
-Other, more suitable versions of \fBinews\fR are available as part of various
-Unix news clients or by themselves.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-\&\s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fIrnews\fR\|(1)
diff --git a/doc/man/inn.conf.5 b/doc/man/inn.conf.5
deleted file mode 100644 (file)
index 77cf8c3..0000000
+++ /dev/null
@@ -1,1220 +0,0 @@
-.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
-.\"
-.\" Standard preamble:
-.\" ========================================================================
-.de Sh \" Subsection heading
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp \" Vertical space (when we can't use .PP)
-.if t .sp .5v
-.if n .sp
-..
-.de Vb \" Begin verbatim text
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve \" End verbatim text
-.ft R
-.fi
-..
-.\" Set up some character translations and predefined strings.  \*(-- will
-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
-.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
-.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
-.\" nothing in troff, for use with C<>.
-.tr \(*W-
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.ie n \{\
-.    ds -- \(*W-
-.    ds PI pi
-.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
-.    ds L" ""
-.    ds R" ""
-.    ds C` ""
-.    ds C' ""
-'br\}
-.el\{\
-.    ds -- \|\(em\|
-.    ds PI \(*p
-.    ds L" ``
-.    ds R" ''
-'br\}
-.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
-.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
-.\" entries marked with X<> in POD.  Of course, you'll have to process the
-.\" output yourself in some meaningful fashion.
-.if \nF \{\
-.    de IX
-.    tm Index:\\$1\t\\n%\t"\\$2"
-..
-.    nr % 0
-.    rr F
-.\}
-.\"
-.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
-.\" way too many mistakes in technical documents.
-.hy 0
-.if n .na
-.\"
-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
-.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
-.    \" fudge factors for nroff and troff
-.if n \{\
-.    ds #H 0
-.    ds #V .8m
-.    ds #F .3m
-.    ds #[ \f1
-.    ds #] \fP
-.\}
-.if t \{\
-.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-.    ds #V .6m
-.    ds #F 0
-.    ds #[ \&
-.    ds #] \&
-.\}
-.    \" simple accents for nroff and troff
-.if n \{\
-.    ds ' \&
-.    ds ` \&
-.    ds ^ \&
-.    ds , \&
-.    ds ~ ~
-.    ds /
-.\}
-.if t \{\
-.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-.\}
-.    \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-.    \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-.    \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-.    ds : e
-.    ds 8 ss
-.    ds o a
-.    ds d- d\h'-1'\(ga
-.    ds D- D\h'-1'\(hy
-.    ds th \o'bp'
-.    ds Th \o'LP'
-.    ds ae ae
-.    ds Ae AE
-.\}
-.rm #[ #] #H #V #F C
-.\" ========================================================================
-.\"
-.IX Title "INN.CONF 5"
-.TH INN.CONF 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-inn.conf \- Configuration data for InterNetNews programs
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fIinn.conf\fR in \fIpathetc\fR is the primary general configuration file for
-all InterNetNews programs.  Settings which control the general operation
-of various programs, as well as the paths to all portions of the news
-installation, are found here.  The \s-1INNCONF\s0 environment variable, if set,
-specifies an alternate path to \fIinn.conf\fR.
-.PP
-This file is intended to be fairly static.  Any changes made to it will
-generally not affect any running programs until they restart.  Unlike
-nearly every other configuration file, \fIinn.conf\fR cannot be reloaded
-dynamically using \fIctlinnd\fR\|(8); \fIinnd\fR\|(8) must be stopped and restarted for
-relevant changes to \fIinn.conf\fR to take effect (\f(CW\*(C`ctlinnd xexec innd\*(C'\fR is
-the fastest way to do this.)
-.PP
-Blank lines and lines starting with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored.  All
-other lines specify parameters, and should be of the following form:
-.PP
-.Vb 1
-\&    <name>: <value>
-.Ve
-.PP
-(Any amount of whitespace can be put after the colon and is optional.)  If
-the value contains embedded whitespace or any of the characers \f(CW\*(C`[]<\*(C'\fR\*(L"\e:>,
-it must be enclosed in double quotes (\*(R"").  A backslash (\f(CW\*(C`\e\*(C'\fR) can be used
-to escape quotes and backslashes inside double quotes.  <name> is
-case\-sensitive; \f(CW\*(C`server\*(C'\fR is not the same as \f(CW\*(C`Server\*(C'\fR or \f(CW\*(C`SERVER\*(C'\fR.
-(\fIinn.conf\fR parameters are generally all in lowercase.)
-.PP
-If <name> occurs more than once in the file, the first value is used.
-Some parameters specified in the file may be overridden by environment
-variables.  Most parameters have default values if not specified in
-\&\fIinn.conf\fR; those defaults are noted in the description of each
-parameter.
-.PP
-Many parameters take a boolean value.  For all such parameters, the value
-may be specified as \f(CW\*(C`true\*(C'\fR, \f(CW\*(C`yes\*(C'\fR, or \f(CW\*(C`on\*(C'\fR to turn it on and may be any
-of \f(CW\*(C`false\*(C'\fR, \f(CW\*(C`no\*(C'\fR, or \f(CW\*(C`off\*(C'\fR to turn it off.  The case of these values is
-significant.
-.PP
-This documentation is extremely long and organized as a reference manual
-rather than as a tutorial.  If this is your first exposure to \s-1INN\s0 and
-these parameters, it would be better to start by reading other man pages
-and referring to this one only when an \fIinn.conf\fR parameter is explicitly
-mentioned.  Those parameters which need to be changed when setting up a
-new server are discussed in \fI\s-1INSTALL\s0\fR.
-.SH "PARAMETERS"
-.IX Header "PARAMETERS"
-.Sh "General Settings"
-.IX Subsection "General Settings"
-These parameters are used by a wide variety of different components of
-\&\s-1INN\s0.
-.IP "\fIdomain\fR" 4
-.IX Item "domain"
-This should be the domain name of the local host.  It should not have a
-leading period, and it should not be a full host address.  It is used only
-if the \fIGetFQDN()\fR routine in \fIlibinn\fR\|(3) cannot get the fully-qualified
-domain name by using either the \fIgethostname\fR\|(3) or \fIgethostbyname\fR\|(3) calls.
-The check is very simple; if either routine returns a name with a period
-in it, then it is assumed to have the full domain name.  As this parameter
-is rarely used, do not use it to affect the righthand side of
-autogenerated Message\-IDs; see instead \fIvirtualhost\fR and \fIdomain\fR in
-readers.conf.  The default value is unset.
-.IP "\fIinnflags\fR" 4
-.IX Item "innflags"
-The flags to pass to innd on startup.  See \fIinnd\fR\|(8) for details on the
-possible flags.  The default value is unset.
-.IP "\fImailcmd\fR" 4
-.IX Item "mailcmd"
-The path to the program to be used for mailing reports and control
-messages.  The default is \fIpathbin\fR/innmail.  This should not normally
-need to be changed.
-.IP "\fImta\fR" 4
-.IX Item "mta"
-The command to use when mailing postings to moderators and for the use of
-\&\fIinnmail\fR\|(1).  The message, with headers and an added To: header, will be
-piped into this program.  The string \f(CW%s\fR, if present, will be replaced
-by the e\-mail address of the moderator.  It's strongly recommended for
-this command to include \f(CW%s\fR on the command line rather than use the
-addresses in the To: and Cc: headers of the message, since the latter
-approach allows the news server to be abused as a mechanism to send mail
-to arbitrary addresses and will result in unexpected behavior.  There is
-no default value for this parameter; it must be set in \fIinn.conf\fR or a
-fatal error message will be logged via syslog.
-.Sp
-For most systems, \f(CW\*(C`/usr/lib/sendmail \-oi \-oem %s\*(C'\fR (adjusted for the
-correct path to sendmail) is a good choice.
-.IP "\fIpathhost\fR" 4
-.IX Item "pathhost"
-What to put into the Path: header to represent the local site.  This is
-added to the Path: header of all articles that pass through the system,
-including locally posted articles, and is also used when processing some
-control messages and when naming the server in status reports.  There is
-no default value; this parameter must be set in \fIinn.conf\fR or \s-1INN\s0 will
-not start.  A good value to use is the fully-qualified hostname of the
-system.
-.IP "\fIserver\fR" 4
-.IX Item "server"
-The name of the default \s-1NNTP\s0 server.  If \fInnrpdposthost\fR is not set and
-\&\s-1UNIX\s0 domain sockets are not supported, \fInnrpd\fR\|(8) tries to hand off
-locally-posted articles through an \s-1INET\s0 domain socket to this server.
-\&\fIactsync\fR\|(8), \fInntpget\fR\|(8), and \fIgetlist\fR\|(8) also use this value as the default
-server to connect to.  In the latter cases, the value of the \s-1NNTPSERVER\s0
-environment variable, if it exists, overrides this.  The default value is
-unset.
-.Sh "Feed Configuration"
-.IX Subsection "Feed Configuration"
-These parameters govern incoming and outgoing feeds:  what size of
-articles are accepted, what filtering and verification is performed on
-them, whether articles in groups not carried by the server are still
-stored and propagated, and other similar settings.
-.IP "\fIartcutoff\fR" 4
-.IX Item "artcutoff"
-Articles older than this number of days are dropped.  This setting should
-probably match the setting on the \f(CW\*(C`/remember/\*(C'\fR line in \fIexpire.ctl\fR.
-The default value is \f(CW10\fR.
-.IP "\fIbindaddress\fR" 4
-.IX Item "bindaddress"
-Which \s-1IP\s0 address \fIinnd\fR\|(8) should bind itself to.  This must be in
-dotted-quad format (nnn.nnn.nnn.nnn).  If set to \f(CW\*(C`all\*(C'\fR or not set, innd
-defaults to listening on all interfaces.  The value of the
-\&\s-1INND_BIND_ADDRESS\s0 environment variable, if set, overrides this setting.
-The default value is unset.
-.IP "\fIbindaddress6\fR" 4
-.IX Item "bindaddress6"
-Like \fIbindaddress\fR but for IPv6 sockets. If only one of the \fIbindaddress\fR
-and \fIbindaddress6\fR parameters is used, then only the socket for the
-corresponding address family is created. If both parameters are used
-then two sockets are created. If neither of them is used, the list of
-sockets to listen on will be determined by the system library
-\&\fI\fIgetaddrinfo\fI\|(3)\fR function.  The value of the \s-1INND_BIND_ADDRESS6\s0, if set,
-overrides this setting.  The default value is unset.
-.Sp
-Note that you will generally need to put double quotes ("") around this
-value if you set it, since IPv6 addresses contain colons.
-.IP "\fIhiscachesize\fR" 4
-.IX Item "hiscachesize"
-If set to a value other than \f(CW0\fR, a hash of recently received message IDs
-is kept in memory to speed history lookups.  The value is the amount of
-memory to devote to the cache in kilobytes.  The cache is only used for
-incoming feeds and a small cache can hold quite a few message IDs, so
-large values aren't necessarily useful unless you have incoming feeds that
-are badly delayed.  A good value for a system with more than one incoming
-feed is \f(CW256\fR; systems with only one incoming feed should probably leave
-this at \f(CW0\fR.  The default value is \f(CW0\fR.
-.IP "\fIignorenewsgroups\fR" 4
-.IX Item "ignorenewsgroups"
-Whether newsgroup creation control messages (newgroup and rmgroup) should
-be fed as if they were posted to the newsgroup they are creating or
-deleting rather than to the newsgroups listed in the Newsgroups: header.
-If this parameter is set, the newsgroup affected by the control message
-will be extracted from the Control: header and the article will be fed as
-if its Newsgroups: header contained solely that newsgroup.  This is useful
-for routing control messages to peers when they are posted to irrelevant
-newsgroups that shouldn't be matched against the peer's desired newsgroups
-in \fInewsfeeds\fR.  This is a boolean value and the default is false.
-.IP "\fIimmediatecancel\fR" 4
-.IX Item "immediatecancel"
-When using the timecaf storage method, article cancels are normally just
-cached to be cancelled, not cancelled immediately.  If this is set to
-true, they will instead by cancelled as soon as the cancel is processed.
-This is a boolean value and the default is false.
-.Sp
-This setting is ignored unless the timecaf storage method is used.
-.IP "\fIlinecountfuzz\fR" 4
-.IX Item "linecountfuzz"
-If set to something other than \f(CW0\fR, the line count of the article is
-checked against the Lines: header of the article (if present) and the
-artice is rejected if the values differ by more than this amount.  A
-reasonable setting is \f(CW5\fR, which is the standard maximum signature length
-plus one (some injection software calculates the Lines: header before
-adding the signature).  The default value is \f(CW0\fR, which tells \s-1INN\s0 not to
-check the Lines: header of incoming articles.
-.IP "\fImaxartsize\fR" 4
-.IX Item "maxartsize"
-The maximum size of article (headers and body) that will be accepted by
-the server, in bytes.  A value of \f(CW0\fR allows any size of article, but
-note that \fBinnd\fR will crash if system memory is exceeded.  The default
-value is \f(CW1000000\fR (approximately 1 \s-1MB\s0).  See also \fIlocalmaxartsize\fR.
-.IP "\fImaxconnections\fR" 4
-.IX Item "maxconnections"
-The maximum number of incoming \s-1NNTP\s0 connections \fIinnd\fR\|(8) will accept.  The
-default value is \f(CW50\fR.
-.IP "\fIpathalias\fR" 4
-.IX Item "pathalias"
-If set, this value is prepended to the Path: header of accepted posts
-(before \fIpathhost\fR) if it doesn't already appear in the Path: header.
-The main purpose of this parameter is to configure all news servers within
-a particular organization to add a common identity string to the
-Path: header.  The default value is unset.
-.IP "\fIpathcluster\fR" 4
-.IX Item "pathcluster"
-If set, this value is appended to the Path: header of accepted posts
-(after \fIpathhost\fR) if it isn't already present as the last element
-of the Path: header.  The main purpose of this parameter is to make
-several news servers appear as one server.  The default value is unset.
-.Sp
-Note that the Path: header reads right to left, so appended means inserted
-at the leftmost side of the Path: header.
-.IP "\fIpgpverify\fR" 4
-.IX Item "pgpverify"
-Whether to enable \s-1PGP\s0 verification of control messages other than cancel.
-This is a boolean value and the default is based on whether configure found
-pgp, pgpv, or gpgv.
-.IP "\fIport\fR" 4
-.IX Item "port"
-What \s-1TCP\s0 port \fIinnd\fR\|(8) should listen on.  The default value is \f(CW119\fR, the
-standard \s-1NNTP\s0 port.
-.IP "\fIrefusecybercancels\fR" 4
-.IX Item "refusecybercancels"
-Whether to refuse all articles whose message IDs start with
-\&\f(CW\*(C`<cancel.\*(C'\fR.  This message \s-1ID\s0 convention is widely followed by spam
-cancellers, so the vast majority of such articles will be cancels of spam.
-This check, if enabled, is done before the history check and the message
-\&\s-1ID\s0 is not written to the history file.  This is a boolean value and the
-default is false.
-.Sp
-This is a somewhat messy, inefficient, and inexact way of refusing spam
-cancels.  A much better way is to ask all of your upstream peers to not
-send to you any articles with \f(CW\*(C`cyberspam\*(C'\fR in the Path: header (usually
-accomplished by having them mark \f(CW\*(C`cyberspam\*(C'\fR as an alias for your machine
-in their feed configuration).  The filtering enabled by this parameter is
-hard\-coded; general filtering of message IDs can be done via the embedded
-filtering support.
-.IP "\fIremembertrash\fR" 4
-.IX Item "remembertrash"
-By default, \fIinnd\fR\|(8) records rejected articles in history so that, if
-offered the same article again, it can be refused before it is sent.  If
-you wish to disable this behavior, set this to false.  This can cause a
-substantial increase in the amount of bandwidth consumed by incoming news
-if you have several peers and reject a lot of articles, so be careful with
-it.  Even if this is set to true, \s-1INN\s0 won't log some rejected articles to
-history if there's reason to believe the article might be accepted if
-offered by a different peer, so there is usually no reason to set this to
-false (although doing so can decrease the size of the history file).  This
-is a boolean value and the default is true.
-.IP "\fIsourceaddress\fR" 4
-.IX Item "sourceaddress"
-Which local \s-1IP\s0 address to bind to for outgoing \s-1NNTP\s0 sockets (used by
-\&\fIinnxmit\fR\|(8) among other programs, but \fInot\fR \fIinnfeed\fR\|(8) \*(-- see
-\&\fIbindaddress\fR in \fIinnfeed.conf\fR\|(5) for that).  This must be in dotted-quad
-format (nnn.nnn.nnn.nnn).  If set to \f(CW\*(C`all\*(C'\fR or not set, the operating
-system will choose the source \s-1IP\s0 address for outgoing connections.  The
-default value is unset.
-.IP "\fIsourceaddress6\fR" 4
-.IX Item "sourceaddress6"
-Like \fIsourceaddress\fR but for IPv6 sockets.
-.IP "\fIverifycancels\fR" 4
-.IX Item "verifycancels"
-Set this to true to enable a simplistic check on all cancel messages,
-attempting to verify (by simple header comparison) that the cancel message
-is from the same person as the original post.  This can't be done if the
-cancel arrives before the article does, and is extremely easy to spoof.
-While this check may once have served a purpose, it's now essentially
-security via obscurity, commonly avoided by abusers, and probably not
-useful.  This is a boolean value, and the default is false.
-.IP "\fIwanttrash\fR" 4
-.IX Item "wanttrash"
-Set this to true if you want to file articles posted to unknown newsgroups
-(newsgroups not in the \fIactive\fR file) into the \f(CW\*(C`junk\*(C'\fR newsgroup rather
-than rejecting them.  This is sometimes useful for a transit news server
-that needs to propagate articles in all newsgroups regardless if they're
-carried locally.  This is a boolean value and the default is false.
-.IP "\fIwipcheck\fR" 4
-.IX Item "wipcheck"
-If \s-1INN\s0 is offered an article by a peer on one channel, it will return
-deferral responses (code 436) to all other offers of that article for this
-many seconds.  (After this long, if the peer that offered the article
-still hasn't sent it, it will be accepted from other channels.)  The
-default value is \f(CW5\fR and probably doesn't need to be changed.
-.IP "\fIwipexpire\fR" 4
-.IX Item "wipexpire"
-How long, in seconds, to keep track of message IDs offered on a channel
-before expiring articles that still haven't been sent.  The default value
-is \f(CW10\fR and probably doesn't need to be changed.
-.IP "\fIdontrejectfiltered\fR" 4
-.IX Item "dontrejectfiltered"
-Normally \fIinnd\fR\|(8) rejects incoming articles when directed to do so by any
-enabled article filters (Perl, Python, and \s-1TCL\s0).  However, this parameter
-causes such articles \fInot\fR to be rejected; instead filtering can be
-applied on outbound articles.  If this parameter is set, all articles will
-be accepted on the local machine, but articles rejected by the filter will
-\&\fInot\fR be fed to any peers specified in \fInewsfeeds\fR with the \f(CW\*(C`Af\*(C'\fR flag.
-.Sh "Article Storage"
-.IX Subsection "Article Storage"
-These parameters affect how articles are stored on disk.
-.IP "\fIcnfscheckfudgesize\fR" 4
-.IX Item "cnfscheckfudgesize"
-If set to a value other than \f(CW0\fR, the claimed size of articles in \s-1CNFS\s0
-cycbuffs is checked against \fImaxartsize\fR plus this value, and if larger,
-the \s-1CNFS\s0 cycbuff is considered corrupt.  This can be useful as a sanity
-check after a system crash, but be careful using this parameter if you
-have changed \fImaxartsize\fR recently.  The default value is \f(CW0\fR.
-.IP "\fIenableoverview\fR" 4
-.IX Item "enableoverview"
-Whether to write out overview data for articles.  If set to false, \s-1INN\s0
-will run much faster, but reading news from the system will be impossible
-(the server will be for news transit only).  If this option is set to
-true, \fIovmethod\fR must also be set.  This is a boolean value and the
-default is true.
-.IP "\fIgroupbaseexpiry\fR" 4
-.IX Item "groupbaseexpiry"
-Whether to enable newsgroup-based expiry.  If set to false, article expiry
-is done based on storage class of storing method.  If set to true (and
-overview information is available), expiry is done by newsgroup name.
-This affects the format of \fIexpire.ctl\fR.  This is a boolean value and the
-default is true.
-.IP "\fImergetogroups\fR" 4
-.IX Item "mergetogroups"
-Whether to file all postings to \f(CW\*(C`to.*\*(C'\fR groups in the pseudonewsgroup
-\&\f(CW\*(C`to\*(C'\fR.  If this is set to true, the newsgroup \f(CW\*(C`to\*(C'\fR must exist in the
-\&\fIactive\fR file or \s-1INN\s0 will not start.  (See the discussion of \f(CW\*(C`to.\*(C'\fR
-groups in \fIinnd\fR\|(8) under \s-1CONTROL\s0 \s-1MESSAGES\s0.)  This is a boolean value and
-the default is false.
-.IP "\fIovercachesize\fR" 4
-.IX Item "overcachesize"
-How many cache slots to reserve for open overview files.  If \s-1INN\s0 is
-writing overview files (see \fIenableoverview\fR), \fIovmethod\fR is set to
-\&\f(CW\*(C`tradindexed\*(C'\fR, and this is set to a value other than \f(CW0\fR, \s-1INN\s0 will keep
-around and open that many recently written-to overview files in case more
-articles come in for those newsgroups.  Every overview cache slot consumes
-two file descriptors, so be careful not to set this value too high.  You
-may be able to use the \f(CW\*(C`limit\*(C'\fR command to see how many open file
-descriptors your operating system allows.  \fIinnd\fR\|(8) also uses an open file
-descriptor for each incoming feed and outgoing channel or batch file, and
-if it runs out of open file descriptors it may throttle and stop accepting
-new news.  The default value is \f(CW15\fR (which is probably way too low if
-you have a large number of file descriptors available).
-.Sp
-This setting is ignored unless \fIovmethod\fR is set to \f(CW\*(C`tradindexed\*(C'\fR.
-.IP "\fIovgrouppat\fR" 4
-.IX Item "ovgrouppat"
-If set, restricts the overview data stored by \s-1INN\s0 to only the newsgroups
-matching this comma-separated list of wildmat expressions.  Newsgroups not
-matching this setting may not be readable, and if \fIgroupbaseexpiry\fR is
-set to true and the storage method for these newsgroups does not have
-self-expire functionality, storing overview data will fail.
-The default is unset.
-.IP "\fIovmethod\fR" 4
-.IX Item "ovmethod"
-Which overview storage method to use.  Currently supported values are
-\&\f(CW\*(C`tradindexed\*(C'\fR, \f(CW\*(C`buffindexed\*(C'\fR, and \f(CW\*(C`ovdb\*(C'\fR.  There is no default value;
-this parameter must be set if \fIenableoverview\fR is true (the default).
-.RS 4
-.ie n .IP """buffindexed""" 4
-.el .IP "\f(CWbuffindexed\fR" 4
-.IX Item "buffindexed"
-Stores overview data and index information into buffers, which are
-preconfigured files defined in \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
-.IX Item "tradindexed"
-Uses two files per newsgroup, one containing the overview data and one
-containing the index.  Fast for readers, but slow to write to.
-.ie n .IP """ovdb""" 4
-.el .IP "\f(CWovdb\fR" 4
-.IX Item "ovdb"
-Stores data into a Berkeley \s-1DB\s0 database.  See the \fIovdb\fR\|(5) man page.
-.RE
-.RS 4
-.RE
-.IP "\fIhismethod\fR" 4
-.IX Item "hismethod"
-Which history storage method to use.  The only currently supported
-value is \f(CW\*(C`hisv6\*(C'\fR.  There is no default value; this parameter must
-be set.
-.RS 4
-.ie n .IP """hisv6""" 4
-.el .IP "\f(CWhisv6\fR" 4
-.IX Item "hisv6"
-Stores history data in the \s-1INN\s0 history v6 format:  \fIhistory\fR\|(5) text
-file and a number of \fIdbz\fR\|(3) database files; this may be in true history
-v6 format, or tagged hash format, depending on the build
-options.  Separation of these two is a project which has not yet been
-undertaken.
-.RE
-.RS 4
-.RE
-.IP "\fIstoreonxref\fR" 4
-.IX Item "storeonxref"
-If set to true, articles will be stored based on the newsgroup names in
-the Xref: header rather than in the Newsgroups: header.  This affects what
-the patterns in \fIstorage.conf\fR apply to.  The primary interesting effect
-of setting this to true is to enable filing of all control messages
-according to what storage class the control pseudogroups are filed in
-rather than according to the newsgroups the control messages are posted
-to.  This is a boolean value and the default is true.
-.IP "\fIuseoverchan\fR" 4
-.IX Item "useoverchan"
-Whether to \fIinnd\fR\|(8) should create overview data internally through
-\&\fIlibstorage\fR\|(3).  If set to false, innd creates overview data by itself.  If
-set to true, innd does not create; instead overview data must be created
-by \fIoverchan\fR\|(8) from an appropriate entry in \fInewsfeeds\fR.  Setting to true
-may be useful, if innd cannot keep up with incoming feed and the
-bottleneck is creation of overview data within innd.  This is a boolean
-value and the default is false.
-.IP "\fIwireformat\fR" 4
-.IX Item "wireformat"
-Only used with the tradspool storage method, this says whether to write
-articles in wire format.  Wire format means storing articles with \f(CW\*(C`\er\en\*(C'\fR at
-the end of each line and with periods at the beginning of lines doubled,
-the article format required by the \s-1NNTP\s0 protocol.  Articles stored in this
-format are suitable for sending directly to a network connection without
-requiring conversion, and therefore setting this to true can make the
-server more efficient.  The primary reason not to set this is if you have
-old existing software that looks around in the spool and doesn't
-understand how to read wire format.  Storage methods other than tradspool
-always store articles in wire format.  This is a boolean value and the
-default is false.
-.IP "\fIxrefslave\fR" 4
-.IX Item "xrefslave"
-Whether to act as the slave of another server.  If set, \s-1INN\s0 attempts to
-duplicate exactly the article numbering of the server feeding it by
-looking at the Xref: header of incoming articles and assigning the same
-article numbers to articles as was noted in the Xref: header from the
-upstream server.  The result is that clients should be able to point at
-either server interchangeably (using some load balancing scheme, for
-example) and see the same internal article numbering.  Servers with this
-parameter set should generally only have one upstream feed, and should
-always have \fInnrpdposthost\fR set to hand locally posted articles off to
-the master server.  The upstream should be careful to always feed articles
-in order (\fIinnfeed\fR\|(8) can have problems with this in the event of a
-backlog).  This is a boolean value and the default is false.
-.IP "\fInfswriter\fR" 4
-.IX Item "nfswriter"
-For servers writing articles, determine whether the article spool is
-on \s-1NFS\s0 storage.  If set, \s-1INN\s0 attempts to flush articles to the spool
-in a more timely manner, rather than relying on the operating system
-to flush things such as the \s-1CNFS\s0 article bitmaps.  You should only set
-this parameter if you are attempting to use a shared \s-1NFS\s0 spool on a
-machine acting as a single writer within a cluster.  This is a boolean
-value and the default is false.
-.IP "\fInfsreader\fR" 4
-.IX Item "nfsreader"
-For servers reading articles, determine whether the article spool is
-on \s-1NFS\s0 storage.  If set, \s-1INN\s0 will attempt to force articles and
-overviews to be read directly from the \s-1NFS\s0 spool rather than from
-cached copies.  You should only set this parameter if you are
-attempting to use a shared \s-1NFS\s0 spool on a machine acting a reader a
-cluster.  This is a boolean value and the default is false.
-.IP "\fInfsreaderdelay\fR" 4
-.IX Item "nfsreaderdelay"
-For servers reading articles, determine whether the article spool is
-on \s-1NFS\s0 storage.  If \fInfsreader\fR is set, \s-1INN\s0 will use the value of
-\&\fInfsreaderdelay\fR to delay the apparent arrival time of articles to
-clients by this amount; this value should be tuned based on the \s-1NFS\s0
-cache timeouts locally.  This default is 60 (1 minute).
-.IP "\fImsgidcachesize\fR" 4
-.IX Item "msgidcachesize"
-How many cache slots to reserve for Message \s-1ID\s0 to storage token
-translations.  When serving overview data to clients (\s-1NEWNEWS\s0, \s-1XOVER\s0
-etc.), \fInnrpd\fR\|(8) can cache the storage token associated with a Message
-\&\s-1ID\s0 and save the cost of looking it up in the history file; for some
-configurations setting this parameter can save more than 90% of the
-wall clock time for a session.  The default value is 10000.
-.IP "\fItradindexedmmap\fR" 4
-.IX Item "tradindexedmmap"
-Whether to attempt to \fImmap()\fR tradindexed overviews articles.  Setting
-this to true will give better performance on most systems, but some
-systems have problems with \fImmap()\fR.  If this is set to false, overviews
-will be read into memory before being sent to readers.  This is a
-boolean value and the default is true.
-.Sh "Reading"
-.IX Subsection "Reading"
-These parameters affect the behavior of \s-1INN\s0 for readers.  Most of them are
-used by \fInnrpd\fR\|(8).  There are some special sets of settings that are broken
-out separately after the initial alphabetized list.
-.IP "\fIallownewnews\fR" 4
-.IX Item "allownewnews"
-Whether to allow use of the \s-1NEWNEWS\s0 command by clients.  This command used
-to put a heavy load on the server in older versions of \s-1INN\s0, but is now
-reasonably efficient, at least if only one newsgroup is specified by the
-client.  This is a boolean value and the default is true.  If you use the
-\&\fIaccess\fR parameter in \fIreaders.conf\fR, be sure to read about the way it
-overrides \fIallownewnews\fR.
-.IP "\fIarticlemmap\fR" 4
-.IX Item "articlemmap"
-Whether to attempt to \fImmap()\fR articles.  Setting this to true will give
-better performance on most systems, but some systems have problems with
-\&\fImmap()\fR.  If this is set to false, articles will be read into memory before
-being sent to readers.  This is a boolean value and the default is false.
-.IP "\fIclienttimeout\fR" 4
-.IX Item "clienttimeout"
-How long (in seconds) a client connection can be idle before it exits.
-When setting this parameter, be aware that some newsreaders use the same
-connection for reading and posting and don't deal well with the connection
-timing out while a post is being composed.  If the system isn't having a
-problem with too many long-lived connections, it may be a good idea to
-increase this value to \f(CW3600\fR (an hour).  The default value is \f(CW600\fR
-(ten minutes).
-.IP "\fIinitialtimeout\fR" 4
-.IX Item "initialtimeout"
-How long (in seconds) \fBnnrpd\fR will wait for the first command from a
-reader connection before dropping the connection.  This is a defensive
-timeout intended to protect the news server from badly behaved reader
-clients that open and abandon a multitude of connections without every
-closing them.  The default value is \f(CW10\fR (ten seconds), which may need to
-be increased if many clients connect via slow network links.
-.IP "\fInnrpdcheckart\fR" 4
-.IX Item "nnrpdcheckart"
-Whether \fBnnrpd\fR should check the existence of an article before listing
-it as present in response to an \s-1NNTP\s0 command.  The primary use of this
-setting is to prevent nnrpd from returning information about articles
-which are no longer present on the server but which still have overview
-data available.  Checking the existence of articles before returning
-overview information slows down the overview commands, but reduces the
-number of \*(L"article is missing\*(R" errors seen by the client.  This is a
-boolean value and the default is true.
-.IP "\fInnrpperlauth\fR" 4
-.IX Item "nnrpperlauth"
-This parameter is now obsolete; see \*(L"Changes to Perl Authentication
-Support for nnrpd\*(R" in \fIdoc/hook\-perl\fR.
-.IP "\fInnrppythonauth\fR" 4
-.IX Item "nnrppythonauth"
-This parameter is now obsolete; see \*(L"Changes to Python Authentication and
-Access Control Support for nnrpd\*(R" in \fIdoc/hook\-python\fR.
-.IP "\fInoreader\fR" 4
-.IX Item "noreader"
-Normally, \fIinnd\fR\|(8) will fork a copy of \fInnrpd\fR\|(8) for all incoming
-connections from hosts not listed in \fIincoming.conf\fR.  If this parameter
-is set to true, those connections will instead be rejected with a 502
-error code.  This should be set to true for a transit-only server that
-doesn't support readers, or if nnrpd is running in daemon mode or being
-started out of inetd.  This is a boolean value and the default is false.
-.IP "\fIreaderswhenstopped\fR" 4
-.IX Item "readerswhenstopped"
-Whether to allow readers to connect even if the server is paused or
-throttled.  This is only applicable if \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8)
-rather than run out of inetd or in daemon mode.  This is a boolean value
-and the default is false.
-.IP "\fIreadertrack\fR" 4
-.IX Item "readertrack"
-Whether to enable the tracking system for client behavior.  Tracked
-information is recorded to \fIpathlog\fR/tracklogs/log\-ID, where \s-1ID\s0 is
-determined by nnrpd's \s-1PID\s0 and launch time.)  Currently the information
-recorded includes initial connection and posting; only information about
-clients listed in \fInnrpd.track\fR is recorded.  This is a boolean value and
-the default is false.
-.IP "\fInnrpdflags\fR" 4
-.IX Item "nnrpdflags"
-When \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8), these flags are passed as
-arguments to the nnrpd process.  This setting does not affect instances
-of nnrpd that are started in daemon mode, or instances that are started
-via another listener process such as \fIinetd\fR\|(8) or \fIxinetd\fR\|(8).  Shell
-quoting and metacharacters are not supported.  This is a string value
-and the default is unset.
-.IP "\fInnrpdloadlimit\fR" 4
-.IX Item "nnrpdloadlimit"
-If set to a value other than \f(CW0\fR, connections to nnrpd will be refused
-if the system load average is higher than this value.  The default value
-is \f(CW16\fR.
-.PP
-\&\s-1INN\s0 has optional support for generating keyword information automatically
-from article body text and putting that information in overview for the
-use of clients that know to look for it.  The following parameters control
-that feature.
-.PP
-This may be too slow if you're taking a substantial feed, and probably
-will not be useful for the average news reader; enabling this is not
-recommended unless you have some specific intention to take advantage of
-it.
-.IP "\fIkeywords\fR" 4
-.IX Item "keywords"
-Whether the keyword generation support should be enabled.  This is a
-boolean value and the default is false.
-.Sp
-\&\s-1FIXME:\s0 Currently, support for keyword generation is configured into \s-1INN\s0
-semi-randomly (based on whether configure found the regex library); it
-should be an option to configure and that option should be mentioned here.
-.IP "\fIkeyartlimit\fR" 4
-.IX Item "keyartlimit"
-Articles larger than this value in bytes will not have keywords generated
-for them (since it would take too long to do so).  The default value is
-\&\f(CW100000\fR (approximately 100 \s-1KB\s0).
-.IP "\fIkeylimit\fR" 4
-.IX Item "keylimit"
-Maximum number of bytes allocated for keyword data.  If there are more
-keywords than will fit into this many bytes when separated by commas, the
-rest are discarded.  The default value is \f(CW512\fR.
-.IP "\fIkeymaxwords\fR" 4
-.IX Item "keymaxwords"
-Maximum number of keywords that will be generated for an article.  (The
-keyword generation code will attempt to discard \*(L"noise\*(R" words, so the
-number of keywords actually writen into the overview will usually be
-smaller than this even if the maximum number of keywords is found.)  The
-default value is \f(CW250\fR.
-.Sh "Posting"
-.IX Subsection "Posting"
-These parameters are only used by \fInnrpd\fR\|(8), \fIinews\fR\|(1), and other programs
-that accept or generate postings.  There are some special sets of settings
-that are broken out separately after the initial alphabetized list.
-.IP "\fIaddnntppostingdate\fR" 4
-.IX Item "addnntppostingdate"
-Whether to add an NNTP\-Posting\-Date: header to all local posts.  This is a
-boolean value and the default is true.  Note that \s-1INN\s0 either does not add
-this header or adds the name or \s-1IP\s0 address of the client.  There is no
-intrinsic support for obfuscating the name of the client.  That has to be
-done with a user-written Perl filter, if desired.
-.IP "\fIaddnntppostinghost\fR" 4
-.IX Item "addnntppostinghost"
-Whether to add an NNTP\-Posting\-Host: header to all local posts giving the
-\&\s-1FQDN\s0 or \s-1IP\s0 address of the system from which the post was received.  This
-is a boolean value and the default is true.
-.IP "\fIcheckincludedtext\fR" 4
-.IX Item "checkincludedtext"
-Whether to check local postings for the ratio of new to quoted text and
-reject them if that ratio is under 50%.  Included text is recognized by
-looking for lines beginning with \f(CW\*(C`>\*(C'\fR, \f(CW\*(C`|\*(C'\fR, or \f(CW\*(C`:\*(C'\fR.  This is a
-boolean value and the default is false.
-.IP "\fIcomplaints\fR" 4
-.IX Item "complaints"
-The value of the X\-Complaints\-To: header added to all local posts.  The
-default is the newsmaster's e\-mail address.  (If the newsmaster, selected
-at configure time and defaulting to \f(CW\*(C`usenet\*(C'\fR, doesn't contain \f(CW\*(C`@\*(C'\fR, the
-address will consist of the newsmaster, a \f(CW\*(C`@\*(C'\fR, and the value of
-\&\fIfromhost\fR.)
-.IP "\fIfromhost\fR" 4
-.IX Item "fromhost"
-Contains a domain used to construct e\-mail addresses.  The address of the
-local news administrator will be given as <user>@\fIfromhost\fR, where <user>
-is the newsmaster user set at compile time (\f(CW\*(C`usenet\*(C'\fR by default).  This
-setting will also be used by \fImailpost\fR\|(8) to fully qualify addresses and by
-\&\fIinews\fR\|(1) to generate the Sender: header (and From: header if missing).
-The value of the \s-1FROMHOST\s0 environment variable, if set, overrides this
-setting.  The default is the fully-qualified domain name of the local
-host.
-.IP "\fIlocalmaxartsize\fR" 4
-.IX Item "localmaxartsize"
-The maximum article size (in bytes) for locally posted articles.  Articles
-larger than this will be rejected.  A value of \f(CW0\fR allows any size of
-article, but note that \fBnnrpd\fR and \fBinnd\fR will crash if system memory is
-exceeded.  See also \fImaxartsize\fR, which applies to all articles including
-those posted locally.  The default value is \f(CW1000000\fR (approximately 1
-\&\s-1MB\s0).
-.IP "\fImoderatormailer\fR" 4
-.IX Item "moderatormailer"
-The address to which to send submissions for moderated groups.  It is only
-used if the \fImoderators\fR file doesn't exist, or if the moderated group to
-which an article is posted is not matched by any entry in that file, and
-takes the same form as an entry in the \fImoderators\fR file.  In most cases,
-\&\f(CW\*(C`%s@moderators.isc.org\*(C'\fR is a good value for this parameter (\f(CW%s\fR is
-expanded into a form of the newsgroup name).  See \fImoderators\fR\|(5) for more
-details about the syntax.  The default is unset.  If this parameter isn't
-set and an article is posted to a moderated group that does not have a
-matching entry in the \fImoderators\fR file, the posting will be rejected
-with an error.
-.IP "\fInnrpdauthsender\fR" 4
-.IX Item "nnrpdauthsender"
-Whether to generate a Sender: header based on reader authentication.  If
-this parameter is set, a Sender: header will be added to local posts
-containing the identity assigned by \fIreaders.conf\fR.  If the assigned
-identity does not include an \f(CW\*(C`@\*(C'\fR, the reader's hostname is used.  If this
-parameter is set but no identity is be assigned, the Sender: header will
-be removed from all posts even if the poster includes one.  This is a
-boolean value and the default is false.
-.IP "\fInnrpdposthost\fR" 4
-.IX Item "nnrpdposthost"
-If set, \fInnrpd\fR\|(8) and \fIrnews\fR\|(1) will pass all locally posted articles to the
-specified host rather than trying to inject them locally.  See also
-\&\fInnrpdpostport\fR.  This should always be set if \fIxrefslave\fR is true.  The
-default value is unset.
-.IP "\fInnrpdpostport\fR" 4
-.IX Item "nnrpdpostport"
-The port on the remote server to connect to to post when \fInnrpdposthost\fR
-is used.  The default value is \f(CW119\fR.
-.IP "\fIorganization\fR" 4
-.IX Item "organization"
-What to put in the Organization: header if it is left blank by the poster.
-The value of the \s-1ORGANIZATION\s0 environment variable, if set, overrides this
-setting.  The default is unset, which tells \s-1INN\s0 not to insert an
-Organization: header.
-.IP "\fIspoolfirst\fR" 4
-.IX Item "spoolfirst"
-If true, \fInnrpd\fR\|(8) will spool new articles rather than attempting to send
-them to \fIinnd\fR\|(8).  If false, nnrpd will spool articles only if it receives
-an error trying to send them to innd.  Setting this to true can be useful
-if nnrpd must respond as fast as possible to the client; however, when
-set, articles will not appear to readers until they are given to innd.
-nnrpd won't do this; \f(CW\*(C`rnews \-U\*(C'\fR must be run periodically to take the
-spooled articles and post them.  This is a boolean value and the default
-is false.
-.IP "\fIstrippostcc\fR" 4
-.IX Item "strippostcc"
-Whether to strip To:, Cc:, and Bcc: headers out of all local posts via
-\&\fInnrpd\fR\|(8).  The primary purpose of this setting is to prevent abuse of the
-news server by posting to a moderated group and including To: or Cc:
-headers in the post so that the news server will send the article to
-arbitrary addresses.  \s-1INN\s0 now protects against this abuse in other ways
-provided \fImta\fR is set to a command that includes \f(CW%s\fR and honors it, so
-this is generally no longer needed.  This is a boolean value and the
-default is false.
-.PP
-\&\fInnrpd\fR\|(8) has support for controlling high-volume posters via an
-exponential backoff algorithm, as configured by the following parameters.
-.PP
-Exponential posting backoff works as follows:  News clients are indexed by
-\&\s-1IP\s0 address (or username, see \fIbackoffauth\fR below).  Each time a post is
-received from an \s-1IP\s0 address, the time of posting is stored (along with the
-previous sleep time, see below).  After a configurable number of posts in
-a configurable period of time, \fInnrpd\fR\|(8) will activate posting backoff and
-begin to sleep for increasing periods of time before actually posting
-anything.  Posts will still be accepted, but at an increasingly reduced
-rate.
-.PP
-After backoff has been activated, the length of time to sleep is computed
-based on the difference in time between the last posting and the current
-posting.  If this difference is less than \fIbackoffpostfast\fR, the new
-sleep time will be 1 + (previous sleep time * \fIbackoffk\fR).  If this
-difference is less than \fIbackoffpostslow\fR but greater than
-\&\fIbackoffpostfast\fR, then the new sleep time will equal the previous sleep
-time.  If this difference is greater than \fIbackoffpostslow\fR, the new
-sleep time is zero and posting backoff is deactivated for this poster.
-.PP
-Exponential posting backoff will not be enabled unless \fIbackoffdb\fR is set
-and \fIbackoffpostfast\fR and \fIbackoffpostslow\fR are set to something other
-than their default values.
-.PP
-Here are the parameters that control exponential posting backoff:
-.IP "\fIbackoffauth\fR" 4
-.IX Item "backoffauth"
-Whether to index posting backoffs by user rather than by source \s-1IP\s0
-address.  You must be using authentication in \fInnrpd\fR\|(8) for a value of true
-to have any meaning.  This is a boolean value and the default is false.
-.IP "\fIbackoffdb\fR" 4
-.IX Item "backoffdb"
-The path to a directory, writeable by the news user, that will contain the
-backoff database.  There is no default for this parameter; you must
-provide a path to a creatable or writeable directory to enable exponential
-backoff.
-.IP "\fIbackoffk\fR" 4
-.IX Item "backoffk"
-The amount to multiply the previous sleep time by if the user is still
-posting too quickly.  A value of \f(CW2\fR will double the sleep time for each
-excessive post.  The default value is \f(CW1\fR.
-.IP "\fIbackoffpostfast\fR" 4
-.IX Item "backoffpostfast"
-Postings from the same identity that arrive in less than this amount of
-time (in seconds) will trigger increasing sleep time in the backoff
-algorithm.  The default value is \f(CW0\fR.
-.IP "\fIbackoffpostslow\fR" 4
-.IX Item "backoffpostslow"
-Postings from the same identity that arrive in greater than this amount of
-time (in seconds) will reset the backoff algorithm.  Another way to look
-at this constant is to realize that posters will be allowed to generate at
-most 86400/\fIbackoffpostslow\fR posts per day.  The default value is \f(CW1\fR.
-.IP "\fIbackofftrigger\fR" 4
-.IX Item "backofftrigger"
-This many postings are allowed before the backoff algorithm is triggered.
-The default value is \f(CW10000\fR.
-.Sh "Monitoring"
-.IX Subsection "Monitoring"
-These parameters control the behavior of \fIinnwatch\fR\|(8), the program that
-monitors \s-1INN\s0 and informs the news administrator if anything goes wrong
-with it.
-.IP "\fIdoinnwatch\fR" 4
-.IX Item "doinnwatch"
-Whether to start \fIinnwatch\fR\|(8) from rc.news.  This is a boolean value, and
-the default is true.
-.IP "\fIinnwatchbatchspace\fR" 4
-.IX Item "innwatchbatchspace"
-Free space in \fIpathoutgoing\fR, in \fIinndf\fR\|(8) output units (normally
-kilobytes), at which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8), assuming a
-default \fIinnwatch.ctl\fR.  The default value is \f(CW800\fR.
-.IP "\fIinnwatchlibspace\fR" 4
-.IX Item "innwatchlibspace"
-Free space in \fIpathdb\fR, in \fIinndf\fR\|(8) output units (normally kilobytes), at
-which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8), assuming a default
-\&\fIinnwatch.ctl\fR.  The default value is \f(CW25000\fR.
-.IP "\fIinnwatchloload\fR" 4
-.IX Item "innwatchloload"
-Load average times 100 at which \fIinnd\fR\|(8) will be restarted by \fIinnwatch\fR\|(8)
-(undoing a previous pause or throttle), assuming a default
-\&\fIinnwatch.ctl\fR.  The default value is \f(CW1000\fR (that is, a load average of
-10.00).
-.IP "\fIinnwatchhiload\fR" 4
-.IX Item "innwatchhiload"
-Load average times 100 at which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8),
-assuming a default \fIinnwatch.ctl\fR.  The default value is \f(CW2000\fR (that
-is, a load average of 20.00).
-.IP "\fIinnwatchpauseload\fR" 4
-.IX Item "innwatchpauseload"
-Load average times 100 at which \fIinnd\fR\|(8) will be paused by \fIinnwatch\fR\|(8),
-assuming a default \fIinnwatch.ctl\fR.  The default value is \f(CW1500\fR (that
-is, a load average of 15.00).
-.IP "\fIinnwatchsleeptime\fR" 4
-.IX Item "innwatchsleeptime"
-How long (in seconds) \fIinnwatch\fR\|(8) will sleep between each check of \s-1INN\s0.
-The default value is \f(CW600\fR.
-.IP "\fIinnwatchspoolnodes\fR" 4
-.IX Item "innwatchspoolnodes"
-Free inodes in \fIpatharticles\fR at which \fIinnd\fR\|(8) will be throttled by
-\&\fIinnwatch\fR\|(8), assuming a default \fIinnwatch.ctl\fR.  The default value is
-\&\f(CW200\fR.
-.IP "\fIinnwatchspoolspace\fR" 4
-.IX Item "innwatchspoolspace"
-Free space in \fIpatharticles\fR and \fIpathoverview\fR, in \fIinndf\fR\|(8) output
-units (normally kilobytes), at which \fIinnd\fR\|(8) will be throttled by
-\&\fIinnwatch\fR\|(8), assuming a default \fIinnwatch.ctl\fR.  The default value is
-\&\f(CW8000\fR.
-.Sh "Logging"
-.IX Subsection "Logging"
-These parameters control what information \s-1INN\s0 logs.
-.IP "\fIdocnfsstat\fR" 4
-.IX Item "docnfsstat"
-Whether to start \fIcnfsstat\fR\|(8) when \fIinnd\fR\|(8) is started.  cnfsstat will log
-the status of all \s-1CNFS\s0 cycbuffs to syslog on a periodic basis (frequency
-is the default for \f(CW\*(C`cnfsstat \-l\*(C'\fR, currently 600 seconds).  This is a
-boolean value and the default is false.
-.IP "\fIlogartsize\fR" 4
-.IX Item "logartsize"
-Whether the size of accepted articles (in bytes) should be written to the
-article log file.  This is useful for flow rate statistics and is
-recommended.  This is a boolean value and the default is true.
-.IP "\fIlogcancelcomm\fR" 4
-.IX Item "logcancelcomm"
-Set this to true to log \f(CW\*(C`ctlinnd cancel\*(C'\fR commands to syslog.  This is a
-boolean value and the default is false.
-.IP "\fIlogcycles\fR" 4
-.IX Item "logcycles"
-How many old logs \fIscanlogs\fR\|(8) keeps.  \fIscanlogs\fR\|(8) is generally run by
-\&\fInews.daily\fR\|(8) and will archive compressed copies of this many days worth
-of old logs.  The default value is \f(CW3\fR.
-.IP "\fIlogipaddr\fR" 4
-.IX Item "logipaddr"
-Whether the verified name of the remote feeding host should be logged to
-the article log for incoming articles rather than the last entry in the
-Path: header.  The only reason to ever set this to false is due to some
-interactions with \fInewsfeeds\fR flags; see \fInewsfeeds\fR\|(5) for more
-information.  This is a boolean value and the default is true.
-.IP "\fIlogsitename\fR" 4
-.IX Item "logsitename"
-Whether the names of the sites to which accepted articles will be sent
-should be put into the article log file.  This is useful for debugging and
-statistics and can be used by \fInewsrequeue\fR\|(8).  This is a boolean value and
-the default is true.
-.IP "\fInnrpdoverstats\fR" 4
-.IX Item "nnrpdoverstats"
-Whether nnrpd overview statistics should be logged via syslog.  This can
-be useful for measuring overview performance.  This is a boolean value and
-the default is false.
-.IP "\fInntpactsync\fR" 4
-.IX Item "nntpactsync"
-How many articles to process on an incoming channel before logging the
-activity.  The default value is \f(CW200\fR.
-.Sp
-\&\s-1FIXME:\s0 This is a rather unintuitive name for this parameter.
-.IP "\fInntplinklog\fR" 4
-.IX Item "nntplinklog"
-Whether to put the storage \s-1API\s0 token for accepted articles (used by
-nntplink) in the article log.  This is a boolean value and the default is
-false.
-.IP "\fIstathist\fR" 4
-.IX Item "stathist"
-Where to write history statistics for analysis with
-\&\fIcontrib/stathist.pl\fR; this can be modified with \fIctlinnd\fR\|(8) while innd is
-running.  Logging does not occur unless a path is given, and there is no
-default value.
-.IP "\fIstatus\fR" 4
-.IX Item "status"
-How frequently (in seconds) \fIinnd\fR\|(8) should write out a status report.  The
-report is written to \fIpathhttp\fR/inn_status.html.  If this is set to \f(CW0\fR or
-\&\f(CW\*(C`false\*(C'\fR, status reporting is disabled.  The default value is \f(CW0\fR.
-.IP "\fItimer\fR" 4
-.IX Item "timer"
-How frequently (in seconds) \fIinnd\fR\|(8) should report performance timings to
-syslog.  If this is set to \f(CW0\fR, performance timing is disabled.  Enabling
-this is highly recommended, and \fIinnreport\fR\|(8) can produce a nice summary of
-the timings.  If set to \f(CW0\fR, performance timings in \fInnrpd\fR\|(8) are also
-disabled, although nnrpd always reports statistics on exit and therefore
-any non-zero value is equivalent for it.  The default value is \f(CW0\fR.
-.Sh "System Tuning"
-.IX Subsection "System Tuning"
-The following parameters can be modified to tune the low-level operation
-of \s-1INN\s0.  In general, you shouldn't need to modify any of them except
-possibly \fIrlimitnofile\fR unless the server is having difficulty.
-.IP "\fIbadiocount\fR" 4
-.IX Item "badiocount"
-How many read or write failures until a channel is put to sleep or
-closed.  The default value is \f(CW5\fR.
-.IP "\fIblockbackoff\fR" 4
-.IX Item "blockbackoff"
-Each time an attempted write returns \s-1EAGAIN\s0 or \s-1EWOULDBLOCK\s0, \fIinnd\fR\|(8) will
-wait for an increasing number of seconds before trying it again.  This is
-the multiplier for the sleep time.  If you're having trouble with channel
-feeds not keeping up, it may be good to change this value to \f(CW2\fR or \f(CW3\fR,
-since then when the channel fills \s-1INN\s0 will try again in a couple of
-seconds rather than waiting two minutes.  The default value is \f(CW120\fR.
-.IP "\fIchaninacttime\fR" 4
-.IX Item "chaninacttime"
-The time (in seconds) to wait between noticing inactive channels.  The
-default value is \f(CW600\fR.
-.IP "\fIchanretrytime\fR" 4
-.IX Item "chanretrytime"
-How many seconds to wait before a channel restarts.  The default value is
-\&\f(CW300\fR.
-.IP "\fIdatamovethreshold\fR" 4
-.IX Item "datamovethreshold"
-The threshold for deciding whether to move already-read data to the top of
-buffer or extend the buffer.  The buffer described here is used for reading
-\&\s-1NNTP\s0 data.  Increasing this value may improve performance, but it should
-not be increased on Systems with insufficient memory.  Permitted values
-are between \f(CW0\fR and \f(CW1048576\fR (out of range values are treated as
-\&\f(CW1048576\fR) and the default value is \f(CW8192\fR.  
-.IP "\fIicdsynccount\fR" 4
-.IX Item "icdsynccount"
-How many article writes between updating the active and history files.
-The default value is \f(CW10\fR.
-.IP "\fIkeepmmappedthreshold\fR" 4
-.IX Item "keepmmappedthreshold"
-When using buffindexed, retrieving overview data (that is, responding to
-\&\s-1XOVER\s0 or running expireover) causes mmapping of all overview data blocks
-which include requested overview data for newsgroup.  But for high volume
-newsgroups like control.cancel, this may cause too much mmapping at once
-leading to system resource problems.  To avoid this, if the amount to be
-mmapped exceeds \fIkeepmmappedthreshold\fR (in \s-1KB\s0), buffindexed mmap's just
-one overview block (8 \s-1KB\s0).  This parameter is specific to buffindexed
-overview storage method.  The default value is \f(CW1024\fR (1 \s-1MB\s0).
-.IP "\fImaxcmdreadsize\fR" 4
-.IX Item "maxcmdreadsize"
-If set to anything other than \f(CW0\fR, maximum buffer size (in bytes) for
-reading \s-1NNTP\s0 command will have this value.  It should not be large on
-systems which are slow to process and store articles, as that would lead
-to \fIinnd\fR\|(8) spending a long time on each channel and keeping other channels
-waiting.  The default value is \s-1BUFSIZ\s0 defined in stdio.h (\f(CW1024\fR in most
-environments, see \fIsetbuf\fR\|(3)).
-.IP "\fImaxforks\fR" 4
-.IX Item "maxforks"
-How many times to attempt a \fIfork\fR\|(2) before giving up.  The default value
-is \f(CW10\fR.
-.IP "\fInicekids\fR" 4
-.IX Item "nicekids"
-If set to anything other than \f(CW0\fR, all child processes of \fIinnd\fR\|(8) will
-have this \fInice\fR\|(2) value.  This is usually used to give all child processes
-of \fIinnd\fR\|(8) a lower priority (higher nice value) so that \fIinnd\fR\|(8) can get
-the lion's share of the \s-1CPU\s0 when it needs it.  The default value is \f(CW4\fR.
-.IP "\fInicenewnews\fR" 4
-.IX Item "nicenewnews"
-If set to anything greater than \f(CW0\fR, all \fInnrpd\fR\|(8) processes that receive
-and process a \s-1NEWNEWS\s0 command will \fInice\fR\|(2) themselves to this value
-(giving other nnrpd processes a higher priority).  The default value is
-\&\f(CW0\fR.  Note that this value will be ignored if set to a lower value than
-\&\fInicennrpd\fR (or \fInicekids\fR if \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8)).
-.IP "\fInicennrpd\fR" 4
-.IX Item "nicennrpd"
-If set to anything greater than \f(CW0\fR, all \fInnrpd\fR\|(8) processes will \fInice\fR\|(1)
-themselves to this value.  This gives other news processes a higher
-priority and can help \fIoverchan\fR\|(8) keep up with incoming news (if that's
-the object, be sure \fIoverchan\fR\|(8) isn't also set to a lower priority via
-\&\fInicekids\fR).  The default value is \f(CW0\fR, which will cause \fInnrpd\fR\|(8)
-processes spawned from \fIinnd\fR\|(8) to use the value of \fInicekids\fR, while
-\&\fInnrpd\fR\|(8) run as a daemon will use the system default priority.  Note that
-for \fInnrpd\fR\|(8) processes spawned from \fIinnd\fR\|(8), this value will be ignored if
-set to a value lower than \fInicekids\fR.
-.IP "\fIpauseretrytime\fR" 4
-.IX Item "pauseretrytime"
-Wait for this many seconds before noticing inactive channels.
-Wait for this many seconds before innd processes articles when it's paused
-or the number of channel write failures exceeds \fIbadiocount\fR.  The
-default value is \f(CW300\fR.
-.IP "\fIpeertimeout\fR" 4
-.IX Item "peertimeout"
-How long (in seconds) an \fIinnd\fR\|(8) incoming channel may be inactive before
-innd closes it.  The default value is \f(CW3600\fR (an hour).
-.IP "\fIrlimitnofile\fR" 4
-.IX Item "rlimitnofile"
-The maximum number of file descriptors that \fIinnd\fR\|(8) or \fIinnfeed\fR\|(8) can have
-open at once.  If \fIinnd\fR\|(8) or \fIinnfeed\fR\|(8) attempts to open more file
-descriptors than this value, it is possible the program may throttle or
-otherwise suffer reduced functionality.  The number of open file
-descriptors is roughly the maximum number of incoming feeds and outgoing
-batches for \fIinnd\fR\|(8) and the number of outgoing streams for \fIinnfeed\fR\|(8).  If
-this parameter is set to a negative value, the default limit of the
-operating system will be used; this will normally be adequate on systems
-other than Solaris.  Nearly all operating systems have some hard maximum
-limit beyond which this value cannot be raised, usually either 128, 256,
-or 1024.  The default value of this parameter is \f(CW\*(C`\-1\*(C'\fR.  Setting it to
-\&\f(CW256\fR on Solaris systems is highly recommended.
-.Sh "Paths and File Names"
-.IX Subsection "Paths and File Names"
-.IP "\fIpatharchive\fR" 4
-.IX Item "patharchive"
-Where to store archived news.  The default value is \fIpathspool\fR/archive.
-.IP "\fIpatharticles\fR" 4
-.IX Item "patharticles"
-The path to where the news articles are stored (for storage methods other
-than \s-1CNFS\s0).  The default value is \fIpathspool\fR/articles.
-.IP "\fIpathbin\fR" 4
-.IX Item "pathbin"
-The path to the news binaries.  The default value is \fIpathnews\fR/bin.
-.IP "\fIpathcontrol\fR" 4
-.IX Item "pathcontrol"
-The path to the files that handle control messages.  The code for handling
-each separate type of control message is located here.  Be very careful
-what you put in this directory with a name ending in \f(CW\*(C`.pl\*(C'\fR, as it can
-potentially be a severe security risk.  The default value is
-\&\fIpathbin\fR/control.
-.IP "\fIpathdb\fR" 4
-.IX Item "pathdb"
-The path to the database files used and updated by the server (currently,
-\&\fIactive\fR, \fIactive.times\fR, \fIhistory\fR and its indices, and
-\&\fInewsgroups\fR).  The default value is \fIpathnews\fR/db.
-.IP "\fIpathetc\fR" 4
-.IX Item "pathetc"
-The path to the news configuration files.  The default value is
-\&\fIpathnews\fR/etc.
-.IP "\fIpathfilter\fR" 4
-.IX Item "pathfilter"
-The path to the Perl, Tcl, and Python filters.  The default value is
-\&\fIpathbin\fR/filter.
-.IP "\fIpathhttp\fR" 4
-.IX Item "pathhttp"
-Where any \s-1HTML\s0 files (such as periodic status reports) are placed.  If the
-news reports should be available in real-time on the web, the files in
-this directory should be served by a web server.  The default value is
-the value of \fIpathlog\fR.
-.IP "\fIpathincoming\fR" 4
-.IX Item "pathincoming"
-Location where incoming batched news is stored.  The default value is
-\&\fIpathspool\fR/incoming.
-.IP "\fIpathlog\fR" 4
-.IX Item "pathlog"
-Where the news log files are written.  The default value is
-\&\fIpathnews\fR/log.
-.IP "\fIpathnews\fR" 4
-.IX Item "pathnews"
-The home directory of the news user and usually the root of the news
-hierarchy.  There is no default; this parameter must be set in \fIinn.conf\fR
-or \s-1INN\s0 will refuse to start.
-.IP "\fIpathoutgoing\fR" 4
-.IX Item "pathoutgoing"
-Default location for outgoing feed files.  The default value is
-\&\fIpathspool\fR/outgoing.
-.IP "\fIpathoverview\fR" 4
-.IX Item "pathoverview"
-The path to news overview files.  The default value is
-\&\fIpathspool\fR/overview.
-.IP "\fIpathrun\fR" 4
-.IX Item "pathrun"
-The path to files required while the server is running and run-time state
-information.  This includes lock files and the sockets for communicating
-with \fIinnd\fR\|(8).  This directory and the control sockets in it should be
-protected from unprivileged users other than the news user.  The default
-value is \fIpathnews\fR/run.
-.IP "\fIpathspool\fR" 4
-.IX Item "pathspool"
-The root of the news spool hierarchy.  This used mostly to set the
-defaults for other parameters, and to determine the path to the backlog
-directory for \fIinnfeed\fR\|(8).  The default value is \fIpathnews\fR/spool.
-.IP "\fIpathtmp\fR" 4
-.IX Item "pathtmp"
-Where \s-1INN\s0 puts temporary files.  For security reasons, this is not the
-same as the system temporary files directory (\s-1INN\s0 creates a lot of
-temporary files with predictable names and does not go to particularly
-great lengths to protect against symlink attacks and the like; this
-is safe provided that normal users can't write into its temporary
-directory).  The default value is set at configure time and defaults to
-\&\fIpathnews\fR/tmp.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-Here is a very minimalist example that only sets those parameters that are
-required.
-.PP
-.Vb 5
-\&    mta:                /usr/lib/sendmail \-oi \-oem %s
-\&    ovmethod:           tradindexed
-\&    pathhost:           news.example.com
-\&    pathnews:           /usr/local/news
-\&    hismethod:          hisv6
-.Ve
-.PP
-For a more comprehensive example, see the sample \fIinn.conf\fR distributed
-with \s-1INN\s0 and installed as a starting point; it contains all of the default
-values for reference.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews and since
-modified, updated, and reorganized by innumerable other people.
-.PP
-$Id: inn.conf.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinews\fR\|(1), \fIinnd\fR\|(8), \fIinnwatch\fR\|(8), \fInnrpd\fR\|(8), \fIrnews\fR\|(1).
-.PP
-Nearly every program in \s-1INN\s0 uses this file to one degree or another.  The
-above are just the major and most frequently mentioned ones.
diff --git a/doc/man/inncheck.8 b/doc/man/inncheck.8
deleted file mode 100644 (file)
index 4ead1db..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-.TH INNCHECK 8
-.SH NAME
-inncheck \- check inn configuration and database files.
-.SH SYNOPSIS
-.B inncheck
-[ 
-.B \-a 
-]
-[
-.B \-v 
-]
-[
-.B \-pedantic
-]
-[
-.B \-f
-]
-[
-.B \-perm
-]
-[
-.B \-noperm
-]
-[
-.B "file=value | file"
-]
-.SH DESCRIPTION
-.I Inncheck
-examines various configuration files and databases and verifies things
-about them. Things verified depend on the file being checked, but generally
-are things like permissions, ownership, syntax errors in config files, etc.
-.PP
-.I Inncheck
-does not make changes to any files \(em it just reports what it
-thinks may be wrong, and it is up to the operator to fix the problem.
-.PP
-The set of files checked may be restricted by using \fBfile\fP or
-\fBfile=value\fP arguments. For example, putting \fBincoming.conf\fP causes
-only the 
-.I incoming.conf
-file to be checked. Using \fBincoming.conf=/tmp/incoming.conf\fP on the
-command line will cause 
-.I inncheck
-to only verify the incoming.conf file, and it will perform the
-checks on the file
-/tmp/incoming.conf file instead of the default one.
-.PP
-Valid values for 
-.I file
-are:
-.PP
-.RS
-.nf
-    active
-    control.ctl
-    expire.ctl
-    incoming.conf
-    inn.conf
-    moderators
-    newsfeeds
-    overview.fmt
-    nntpsend.ctl
-    passwd.nntp
-    readers.conf
-.fi
-.RE
-.SH OPTIONS
-.TP
-.B \-a 
-If any ``\fBfile\fP'' value or ``\fBfile=value\fP'' pairs (see below) are
-given, then normally only the files they refer to are checked. Use 
-the ``\fB\-a\fP'' flag to specify that
-.I all
-files should be checked regardless. In this case the form \fBfile=value\fP
-will be the more useful.
-.TP
-.B \-v
-Use the ``\fB\-v\fP'' option to get more verbose output.
-.TP
-.B \-pedantic
-Use the ``\fB\-pedantic\fP'' option to get reports on things that are not
-necessarily wrong, but may indicate a bad configuration \(em such as
-\fIinn.conf\fP missing a key.
-.TP
-.B \-f
-Use the ``\fB\-f\fP'' flag to have inncheck print the appropriate
-chown/chgrp/chmod command necessary to fix a problem that it reports.  Any
-other output lines will be prefixed with a ``#'' character to make the
-output be valid input for a shell.  Note that the ``\fB\-perm\fP'' flag
-must be used as well when using this flag.
-.TP
-.B \-perm
-Inncheck checks all files for permission problems.
-If the ``\fB\-perm\fP'' flag is used, then 
-.I only
-the files specified by the \fBfile\fP or \fBfile=value\fP command line
-arguments will be checked for problems other than permission problems.
-.TP
-.B \-noperm
-To avoid doing any checking of file permissions or ownership, use 
-the ``\fB-noperm\fP'' option.
-.SH EXAMPLES
-.PP
-To have
-.I inncheck
-check all files for syntax and permission problems simply:
-.PP
-.RS
-.nf
-inncheck
-.fi
-.RE
-.PP
-To have 
-.I inncheck
-check all files for permission problems and to verify the syntax of the
-active and incoming.conf files do:
-.PP
-.RS
-.nf
-inncheck -perm active incoming.conf
-.fi
-.RE
-.PP
-To fix the permissions problems noted in the output of the above
-command, modify it as follow:
-.PP
-.RS
-.nf
-inncheck -f -perm | sh
-.fi
-.RE
-.PP
-To have
-.I inncheck
-check the test newsfeeds file in /var/tmp/newsfeeds.testing, do:
-.PP
-.RS
-.nf
-inncheck newsfeeds=/var/tmp/newsfeeds.testing
-.fi
-.RE
-.PP
-To have
-.I inncheck
-check all the files as it normally does, but to specify a different
-location for the newsfeeds file, so:
-.PP
-.RS
-.nf
-inncheck -a newsfeeds=/var/tmp/newsfeeds.testing
-.fi
-.RE
-.SH BUGS
-If the ``\fB-f\fP'' and ``\fB-perm\fP'' options are used together, along with
-``\fB\-a\fP'' or some ``\fBfile\fP'' or ``\fBfile=value\fP'' arguments that
-refer to a file with a syntax problem, then the output will no longer be
-valid input for a shell.
-.SH HISTORY
-Written by Brendan Kehoe <brendan@cygnus.com> and 
-Rich Salz <rsalz@uunet.uu.net>
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: inncheck.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-active(5),
-expire.ctl(5),
-history(5),
-incoming.conf(5),
-inn.conf(5),
-newsfeeds(5)
diff --git a/doc/man/innconfval.1 b/doc/man/innconfval.1
deleted file mode 100644 (file)
index 0fe9d77..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-.\" 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 "INNCONFVAL 1"
-.TH INNCONFVAL 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-innconfval \- Get configuration parameters from inn.conf
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinnconfval\fR [\fB\-pstv\fR] [\fB\-i\fR \fIfile\fR] [\fIparameter\fR ...]
-.PP
-\&\fBinnconfval\fR \fB\-C\fR [\fB\-i\fR \fIfile\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinnconfval\fR normally prints the values of the parameters specified on
-the command line.  By default, it just prints the parameter values, but if
-\&\fB\-p\fR, \fB\-s\fR, or \fB\-t\fR are given, it instead prints the parameter and
-value in the form of a variable assignment in Perl, Bourne shell, or Tcl
-respectively.  If no parameters are specifically requested, \fBinnconfval\fR
-prints out all parameter values (this isn't particularly useful unless one
-of \fB\-p\fR, \fB\-s\fR, or \fB\-t\fR were specified).
-.PP
-All parameters are taken from \fIinn.conf\fR except for \fIversion\fR, which is
-always the version string of \s-1INN\s0.
-.PP
-If given the \fB\-C\fR option, \fBinnconfval\fR instead checks \fIinn.conf\fR,
-reporting any problems found to standard error.  \fBinnconfval\fR will exit
-with status 0 if no problems are found and with status 1 otherwise.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-C\fR" 4
-.IX Item "-C"
-Check \fIinn.conf\fR rather than printing out the values of parameters.
-.IP "\fB\-i\fR \fIfile\fR" 4
-.IX Item "-i file"
-Use \fIfile\fR as the source configuration file rather than \fIinn.conf\fR.
-\&\fIfile\fR must be a valid \fIinn.conf\fR file and will be parsed the same as
-\&\fIinn.conf\fR would be.
-.IP "\fB\-p\fR" 4
-.IX Item "-p"
-Print out parameters as Perl assignment statements.  The variable name
-will be the same as the \fIinn.conf\fR parameter, and string values will be
-enclosed in single quotes with appropriate escaping.  Boolean values will
-be mapped to \f(CW\*(C`true\*(C'\fR or \f(CW\*(C`false\*(C'\fR, and string parameters that are set to
-\&\s-1NULL\s0 will be mapped to empty strings.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-Print out parameters as Bourne shell assignment statements.  The variable
-name will be the \fIinn.conf\fR parameter name in all capitals, and all
-variables will be exported.  String values will be enclosed in single
-quotes with appropriate escaping, and boolean values will be mapped to
-\&\f(CW\*(C`true\*(C'\fR or \f(CW\*(C`false\*(C'\fR.  String parameters that are set to \s-1NULL\s0 will be
-mapped to empty strings.
-.IP "\fB\-t\fR" 4
-.IX Item "-t"
-Print out parameters as Tcl assignment statements.  The variable name will
-be the same as the \fIinn.conf\fR parameter name but with \f(CW\*(C`inn_\*(C'\fR prepended,
-and string variables will be escaped appropriately.  Boolean values will
-be mapped to \f(CW\*(C`true\*(C'\fR or \f(CW\*(C`false\*(C'\fR and string parameters that are set to
-\&\s-1NULL\s0 will be mapped to empty strings.
-.IP "\fB\-v\fR" 4
-.IX Item "-v"
-Print \s-1INN\s0's version.  This is equivalent to \f(CW\*(C`innconfval version\*(C'\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.
-.PP
-$Id: innconfval.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5)
diff --git a/doc/man/innd.8 b/doc/man/innd.8
deleted file mode 100644 (file)
index fc07750..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-.\" 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 "INND 8"
-.TH INND 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-innd \- InterNetNews daemon
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinnd\fR [\fB\-aCdfNrsu\fR] [\fB\-c\fR \fIdays\fR] [\fB\-H\fR \fIcount\fR] [\fB\-i\fR \fIcount\fR]
-[\fB\-I\fR \fIaddress\fR] [\fB\-l\fR \fIsize\fR] [\fB\-m\fR \fImode\fR] [\fB\-n\fR \fIflag\fR]
-[\fB\-o\fR \fIcount\fR] [\fB\-p\fR \fIfd\fR] [\fB\-P\fR \fIport\fR] [\fB\-t\fR \fItimeout\fR]
-[\fB\-T\fR \fIcount\fR] [\fB\-X\fR \fIseconds\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinnd\fR, the InterNetNews daemon, handles all incoming \s-1NNTP\s0 feeds,
-coordinates the storage, retransmission, and overview generation for all
-accepted articles, and manages the \fIactive\fR\|(5) and \fIhistory\fR\|(5) databases.  It
-handles incoming connections on the \s-1NNTP\s0 port, and also creates and
-listens to a local Unix-domain stream socket in order to receive articles
-from local processes such as \fInnrpd\fR\|(8) and \fIrnews\fR\|(1).
-.PP
-As the master daemon, \fBinnd\fR should generally be started at boot and be
-always running.  It listens to a Unix-domain datagram socket for commands
-to control its activites, commands that can be sent using \fIctlinnd\fR\|(8).  The
-current status of \fBinnd\fR can be obtained by running \f(CW\*(C`ctlinnd mode\*(C'\fR, or
-for more detailed output, \fIinnstat\fR\|(8).
-.PP
-\&\fBinnd\fR can be in one of three operating modes:  running, paused, or
-throttled.  Running is the normal mode; when the server is throttled, it
-closes connections and rejects new ones.  Paused is like a temporary
-throttle, suspending \fBinnd\fR's activities but not causing the server to
-shut down existing connections.  The mode is normally changed via
-\&\fIctlinnd\fR\|(8), either by various automated processes (such as nightly article
-expiration) or manually by the news administrator, but \fBinnd\fR will also
-throttle itself if it encounters \s-1ENOSPC\s0 errors in writing data or an
-excessive number of I/O errors (among other problems).
-.PP
-\&\fBinnd\fR normally takes care of spawning \fInnrpd\fR\|(8) to handle connections
-from news reading clients, but it can be run on a separate port from
-\&\fInnrpd\fR\|(8) so that feed connections and news reading connections are handled
-separately (this can often be faster).  Normally, \fBinnd\fR listens on port
-119, the assigned port for \s-1NNTP\s0; if it is desireable to run \fBinnd\fR and
-\&\fInnrpd\fR\|(8) on separate ports, it's recommended that \fInnrpd\fR\|(8) be given port
-119 (since many news reading clients connect only to that port) and that
-port 433 be used for \fBinnd\fR.
-.PP
-The primary configuration files that control \fBinnd\fR's activities are
-\&\fIincoming.conf\fR, which specifies what remote sites \fBinnd\fR will accept
-connections from, \fInewsfeeds\fR, which specifies what is to be done with
-incoming articles besides storing them, and \fIinn.conf\fR, which sets a wide
-variety of configuration parameters.  Some parameters in \fIinn.conf\fR\|(5) can
-also be set with command-line flags; for these, the command-line flags
-take precedence if used.
-.PP
-\&\fBinnd\fR should normally not run directly.  It must run as the news user or
-all sorts of file ownership problems may result, and normally the port it
-listens on (119 or 433) is privileged and must be opened by root.
-Instead, \fBinnd\fR should normally be started via \fIinndstart\fR\|(8), a small
-setuid-root program that opens the appropriate port, cleans up the
-environment, changes to the news user, and then runs \fBinnd\fR, passing
-along any command-line arguments.
-.PP
-To use IPv6, \fBinnd\fR must be started by \fBinndstart\fR.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-For the options below that override \fIinn.conf\fR settings, see \fIinn.conf\fR\|(5)
-for the default values if neither the \fIinn.conf\fR setting nor the
-command-line option is given.
-.IP "\fB\-a\fR" 4
-.IX Item "-a"
-By default, if a host connects to \fBinnd\fR but is not listed in
-\&\fIincoming.conf\fR, the connection is handed off to \fBnnrpd\fR (or rejected if
-\&\fInoreader\fR is set in \fIinn.conf\fR).  If \fB\-a\fR is given, \fIincoming.conf\fR
-is ignored and any host can connect and transfer articles.  This flag
-should never be used with an accessible server connected to Usenet; it
-would open the server up for all sorts of abuse.
-.IP "\fB\-c\fR \fIdays\fR" 4
-.IX Item "-c days"
-\&\fBinnd\fR normally rejects any article that is older (in days) than the
-value of \fIartcutoff\fR in \fIinn.conf\fR.  This option, if given, overrides
-the value of that setting.  If \fIdays\fR is 0, this check is suppressed and
-\&\fBinnd\fR will accept articles regardless of how old they are.
-.IP "\fB\-C\fR" 4
-.IX Item "-C"
-This flag tells \fBinnd\fR to accept and propagate but not actually process
-cancel or supersede messages.  This is intended for sites concerned about
-abuse of cancels, or that wish to use another cancel mechanism with
-stronger authentication.
-.IP "\fB\-d\fR, \fB\-f\fR" 4
-.IX Item "-d, -f"
-\&\fBinnd\fR normally puts itself into the background, points its standard
-output and error to log files, and disassociates itself from the
-terminal.  Using \fB\-d\fR prevents all of this, resulting in log messages
-being written to standard output; this is generally useful only for
-debugging.  Using \fB\-f\fR prevents the backgrounding and disassociation but
-still redirects output; it may be useful if you want to monitor \fBinnd\fR
-with a program that would be confused by forks.
-.IP "\fB\-H\fR \fIcount\fR, \fB\-T\fR \fIcount\fR, \fB\-X\fR \fIseconds\fR" 4
-.IX Item "-H count, -T count, -X seconds"
-These flags control the number of connections per minute that are allowed.
-This code is meant to protect your server from newsreader clients that
-make too many connections per minute (and therefore these flags are
-probably only useful when \fBinnd\fR is spawning \fBnnrpd\fR).  You probably
-should not use these options unless you're having problems.  The table
-used for this check is fixed at 128 entries and is used as a ring; the
-size was chosen to make calculating the index easy and to be fairly sure
-that it won't run out of space.  In practice, it is unlikely that even
-half the table will be used at any given moment.
-.Sp
-The \fB\-H\fR flag limits the number of times a host is allowed to connect to
-the server per the time interval given by \fB\-X\fR.  The default is \f(CW2\fR.
-.Sp
-The \fB\-T\fR flag limits the total number of incoming connections per the
-time interval given by \fB\-X\fR.  The maximum value is \f(CW128\fR, and the
-default is \f(CW60\fR.
-.IP "\fB\-i\fR \fIcount\fR" 4
-.IX Item "-i count"
-\&\fBinnd\fR normally allows a maximum number of concurrent \s-1NNTP\s0 connections
-given by the value of \fImaxconnections\fR in \fIinn.conf\fR.  This option, if
-given, overrides the value of that setting.  If \fIcount\fR is \f(CW0\fR, this
-check is suppressed.
-.IP "\fB\-I\fR \fIaddress\fR" 4
-.IX Item "-I address"
-Normally if \fBinnd\fR itself binds to a port, it lets the operating system
-pick the source \s-1IP\s0 address (unless \fIbindaddress\fR is set in \fIinn.conf\fR).
-If this option is given, it specifies the \s-1IP\s0 address that \s-1INN\s0 should bind
-as.  This is only relevant for servers with multiple local \s-1IP\s0 addresses.
-The \s-1IP\s0 address must be in dotted quad (\f(CW\*(C`nnn.nnn.nnn.nnn\*(C'\fR) format.
-.Sp
-This option is rarely useful since \fBinnd\fR should not be binding to a
-port itself.  Instead, use \fIinndstart\fR\|(8) and its analgous \fB\-I\fR option.
-.IP "\fB\-l\fR \fIsize\fR" 4
-.IX Item "-l size"
-\&\fBinnd\fR normally rejects any article larger than the value of
-\&\fImaxartsize\fR in \fIinn.conf\fR.  This option, if given, overrides the value
-of that setting and specifies a maximum article size of \fIsize\fR.  If
-\&\fIsize\fR is \f(CW0\fR, this check is suppressed.
-.IP "\fB\-m\fR \fImode\fR" 4
-.IX Item "-m mode"
-Normally \fBinnd\fR starts in the \f(CW\*(C`running\*(C'\fR mode.  If this option is given,
-it specifies what mode \fBinnd\fR should start in.  \fImode\fR should begin with
-one of \f(CW\*(C`g\*(C'\fR, \f(CW\*(C`p\*(C'\fR, or \f(CW\*(C`t\*(C'\fR, and the starting mode will be set to
-\&\f(CW\*(C`running\*(C'\fR, \f(CW\*(C`paused\*(C'\fR, or \f(CW\*(C`throttled\*(C'\fR, respectively, based on that
-initial letter.  (\f(CW\*(C`g\*(C'\fR is short for \f(CW\*(C`go\*(C'\fR.)
-.IP "\fB\-N\fR" 4
-.IX Item "-N"
-If this option is given, any filters (Perl, Tcl, or Python) are disabled
-before \fBinnd\fR starts (normally, filters default to being enabled).  The
-filters can be enabled after \fBinnd\fR has started with \fIctlinnd\fR\|(8).
-.IP "\fB\-n\fR \fIflag\fR" 4
-.IX Item "-n flag"
-Whether \fBinnd\fR allows (and hands off to \fBnnrpd\fR) reader connections
-while paused or throttled is normally determined by the value of
-\&\fIreaderswhenstopped\fR in \fIinn.conf\fR).  This option, if given, overrides
-that value.  If \fIflag\fR is \f(CW\*(C`n\*(C'\fR, \fBinnd\fR will not allow readers if it is
-paused or throttled.  If \fIflag\fR is \f(CW\*(C`y\*(C'\fR, readers will be allowed
-regardless of \fBinnd\fR's operating mode.
-.IP "\fB\-o\fR \fIcount\fR" 4
-.IX Item "-o count"
-This flag limits the number of file descriptors that are available for
-outgoing file feeds.  The default is the number of available file
-descriptors minus some reserved for internal use (which could potentially
-starve \fBinnd\fR of descriptors to use for accepting new connections).  If
-\&\fBinnd\fR has more file feeds than \fIcount\fR, some of them will be buffered
-and only written out periodically.
-.Sp
-Normally you never need to use this option, since the number of outgoing
-feeds is fixed, being the number of file feeds configured in \fInewsfeeds\fR,
-and is generally small (particularly given that \fIinnfeed\fR\|(8) is now used for
-most outgoing feeds at large sites).
-.IP "\fB\-p\fR \fIfd\fR" 4
-.IX Item "-p fd"
-If this flag is given, \fBinnd\fR expects the file descriptor given by \fIfd\fR
-to already be open and bound to the appropriate local port and to be
-suitable for listening to for incoming connections.  This is how
-\&\fBinndstart\fR tells \fBinnd\fR which open file descriptor is the network
-connection.  If this flag is not given, \fBinnd\fR will attempt to open its
-network socket itself.  \fBinndstart\fR always passes this flag to \fBinnd\fR.
-.IP "\fB\-P\fR \fIport\fR" 4
-.IX Item "-P port"
-The port \fBinnd\fR should listen on is normally given by the value of
-\&\fIport\fR in \fIinn.conf\fR.  This option, if given, overrides that value and
-specifies the port that \fBinnd\fR should bind to.  This option is rarely
-useful since \fBinnd\fR normally does not bind itself; instead the analgous
-\&\fB\-P\fR option to \fIinndstart\fR\|(8) should be used.  Since \fBinnd\fR should never
-be run as root, \fIport\fR has to be a non-privileged port (one larger than
-1024).
-.IP "\fB\-r\fR" 4
-.IX Item "-r"
-Instructs \fBinnd\fR to renumber the \fIactive\fR file after starting, just as
-if a \f(CW\*(C`ctlinnd renumber\*(C'\fR command were sent.
-.IP "\fB\-s\fR" 4
-.IX Item "-s"
-Just check the syntax of the \fInewsfeeds\fR file and exit.  \fBinnd\fR will
-exit with a non-zero status if any errors are found; the actual errors
-will be reported via \fIsyslog\fR\|(3).
-.IP "\fB\-t\fR \fIseconds\fR" 4
-.IX Item "-t seconds"
-Normally, \fBinnd\fR will flush any changes to history and the active file
-after 300 seconds of inactivity.  This option changes that timeout to
-\&\fIseconds\fR.
-.IP "\fB\-u\fR" 4
-.IX Item "-u"
-The news log (the trace information for every article accepted by \fBinnd\fR)
-is normally buffered.  This option changes the log to be unbuffered.
-.SH "CONTROL MESSAGES"
-.IX Header "CONTROL MESSAGES"
-Arriving articles that have a Control: header are called \*(L"control
-messages\*(R".  Except for cancel messages, these messages are handled by
-\&\fIcontrolchan\fR\|(8) via a feed set up in \fInewsfeeds\fR.
-.PP
-(Cancel messages update the history database, so they must be handled
-internally; the cost of syncing, locking, then unlocking would be too high
-given the number of cancel messages that are received.  Note that if an
-article is cancelled before it is received by the news server, it will
-be rejected when it arrives since the history database has been updated;
-it is useful for rejecting spam before it arrives.)
-.PP
-The distribution of control messages is different than that of standard
-articles.  Control messages are normally filed into the pseudo-newsgroup
-named \f(CW\*(C`control\*(C'\fR regardless of which newsgroup they were actually posted
-to.  If, however, a \f(CW\*(C`control.\*(C'\fR\fIcommand\fR newsgroup exists that matches
-the control command, the control message will be filed into that group
-instead.  For example, a newgroup control message will be filed in
-\&\f(CW\*(C`control.newgroup\*(C'\fR if that group exists; otherwise, it will be filed in
-\&\f(CW\*(C`control\*(C'\fR.
-.PP
-If you want to specifically feed all control messages to a given site
-regardless of whether the control messages would affect the newsgroups
-you're feeding that site, you can put the appropriate control newsgroup in
-the subscription list.  For example, to feed all cancel messages to a
-given remote site (normally a bad idea), add \f(CW\*(C`control.cancel\*(C'\fR to its
-subscription list.  Normally it's best to exclude the control newsgroups
-from feeds to keep from sending your peers more control messages than they
-care about.  That's why the \fInewsfeeds\fR pattern \f(CW\*(C`!control,!control.*\*(C'\fR
-is as often as not specified (adding this pattern do not prevent control
-messages which affect the newsgroups fed to a site from being sent to it).
-.PP
-checkgroups, newgroup and rmgroup control messages receive additional special
-treatment.  If one of these control messages is approved and posted to the
-newsgroup being created or removed (or to the admin group to which the
-checkgroups is posted), the message will be sent to all sites
-whose subscription patterns would cause them to receive articles posted to
-that group.  For example, if a newgroup control message for a nonexistent
-newsgroup \f(CW\*(C`news.admin.meow\*(C'\fR is received, it will be sent to any site
-whose subscription pattern would cause it to receive \f(CW\*(C`news.admin.meow\*(C'\fR if
-that newsgroup existed (such as a pattern of \f(CW\*(C`news.admin.*\*(C'\fR).  For this
-reason, it is correct to post newgroup messages to the newsgroup that the
-control message would create.  It is \fInot\fR generally correct to crosspost
-newgroup messages to some \*(L"well\-propagated\*(R" newsgroup; not only will this
-not actually improve their propagation to sites that want such control
-messages, but it will also cause sites that do not want those control
-messages to receive them.  Therefore, assuming that a newgroup control
-message is sent to the group \f(CW\*(C`news.admin.meow\*(C'\fR (specified in the
-Newsgroups: header) in order to create the group \f(CW\*(C`news.admin.meow\*(C'\fR,
-the sites with the following subscription patterns will receive it:
-.PP
-.Vb 4
-\&    *,@news.*
-\&    news.*
-\&    news.*,!control,!control.*
-\&    control,control.*
-.Ve
-.PP
-but the sites with the following subscription patterns will not receive it:
-.PP
-.Vb 2
-\&    *,@news.*,!control,!control.*
-\&    comp.*,@news.*
-.Ve
-.PP
-If a control message is posted to a group whose name ends with the four
-characters \f(CW\*(C`.ctl\*(C'\fR, this suffix is stripped off and the control message is
-propagated as if it were posted to the base group.  For example, a cancel
-message posted to \f(CW\*(C`news.admin.ctl\*(C'\fR will be sent to all sites that
-subscribe to \f(CW\*(C`control.cancel\*(C'\fR (or \f(CW\*(C`control\*(C'\fR if that newsgroup doesn't
-exist) or \f(CW\*(C`news.admin\*(C'\fR.  This behavior is present for historical
-compatibility reasons and should be considered obsolete; support for the
-\&\f(CW\*(C`.ctl\*(C'\fR suffix may be removed in a future version of \s-1INN\s0.
-.PP
-Finally, articles posted to newsgroups beginning with \f(CW\*(C`to.\*(C'\fR are treated
-specially.  Provided that either that newsgroup exists in the \fIactive\fR file
-or \fImergetogroups\fR is set in \fIinn.conf\fR, the remainder of the newsgroup
-is taken to be a site name, as configured in \fInewsfeeds\fR, and the article
-is sent to that site.  If \fImergetogroups\fR is set, the article will be
-filed in the group named \f(CW\*(C`to\*(C'\fR (which must exist in the \fIactive\fR file).  For
-example, with \fImergetogroups\fR set, an article posted to \f(CW\*(C`to.uunet\*(C'\fR will
-be filed in \f(CW\*(C`to\*(C'\fR and sent to the site \f(CW\*(C`uunet\*(C'\fR.
-.SH "PROTOCOL DIFFERENCES"
-.IX Header "PROTOCOL DIFFERENCES"
-\&\fBinnd\fR implements the \s-1NNTP\s0 commands defined in \s-1RFC\s0 977, with the
-following differences:
-.IP "1." 4
-The \s-1LIST\s0 command may be followed by an optional \s-1ACTIVE\s0, \s-1ACTIVE\s0.TIMES, or
-\&\s-1NEWSGROUPS\s0.  There is only basic support for \s-1LIST\s0 in \fBinnd\fR since feeding
-peers normally don't need it; see \fInnrpd\fR\|(8) for full support.
-.IP "2." 4
-The \s-1AUTHINFO\s0 \s-1USER\s0 and \s-1AUTHINFO\s0 \s-1PASS\s0 commands are implemented, although the
-authentication is currently limited to matching a password for a given
-peer specified in \fIincoming.conf\fR.  These are based on the reference Unix
-implementation.
-.IP "3." 4
-A new command, \s-1MODE\s0 \s-1READER\s0, is implemented.  This command will cause the
-server to pass the connection to \fBnnrpd\fR.
-.IP "4." 4
-The streaming extension (\s-1MODE\s0 \s-1STREAM\s0, \s-1CHECK\s0, and \s-1TAKETHIS\s0) is fully
-supported.
-.IP "5." 4
-A batch transfer command, \s-1XBATCH\s0 \fIbyte-count\fR, is provided.  This command
-will read \fIbyte-count\fR bytes and store them for later processing by
-\&\fIrnews\fR\|(1) (which must be run separately, probably from cron).  See
-\&\fIinnxbatch\fR\|(8) and \fIbackends/sendxbatches\fR for more details on this
-extension.
-.IP "6." 4
-\&\fBinnd\fR implements a limited subset of the protocol useful for
-transferring news.  The only other commands implemented are \s-1HEAD\s0, \s-1HELP\s0,
-\&\s-1IHAVE\s0, \s-1STAT\s0, and \s-1QUIT\s0.  The remaining commands are mostly only useful for
-readers and are implemented by \fInnrpd\fR\|(8).
-.SH "HEADER MODIFICATIONS"
-.IX Header "HEADER MODIFICATIONS"
-\&\fBinnd\fR modifies as few article headers as possible, although it could be
-better in this area.
-.PP
-Empty headers and headers that consist of nothing but whitespace are
-dropped.
-.PP
-The local site's name (as set with the \fIpathhost\fR parameter in
-\&\fIinn.conf\fR) and an exclamation point are prepended to the Path: header,
-provided the first site name in the Path: header is different from the
-local one.  In addition, \fIpathalias\fR and \fIpathcluster\fR may be similarly
-respectively prepended and appended to the Path: header; see \fIinn.conf\fR\|(5)
-for the details.
-.PP
-The Xref: header is removed and a new one created.
-.PP
-A Lines: header will be added if the article was missing one.
-.PP
-\&\fBinnd\fR does not rewrite incorrect headers.  For example, it will not
-replace an incorrect Lines header, though it may reject such an article
-depending on the value of \fIlinecountfuzz\fR in \fIinn.conf\fR.
-.SH "CANCEL FEEDS"
-.IX Header "CANCEL FEEDS"
-In order to efficiently apply a large number of local cancels (such as
-from processing NoCeMs or from some other external source), \s-1INN\s0 supports a
-special feed mode available only to connections to the local Unix domain
-socket (not to connections to any network sockets).
-.PP
-To enter this mode, connect to the Unix domain socket (\fIpathrun\fR/nntpin)
-and send the command \s-1MODE\s0 \s-1CANCEL\s0.  The response will have code \f(CW284\fR.
-Every subsequent line sent on that connection should consist of a single
-message \s-1ID\s0.  An attempt will be made to cancel that message \s-1ID\s0, and the
-server will reply \f(CW289\fR for success or \f(CW484\fR for failure.  (Failure can
-occur, for example, if the server is paused or throttled, or the
-Message-ID is corrupt.  Failure does \fInot\fR occur if the article to be
-cancelled does not exist.)
-.SH "LOGGING"
-.IX Header "LOGGING"
-\&\fBinnd\fR reports all incoming articles in its log file (\fIpathlog\fR/news).
-This is a text file with a variable number of space-separated fields in
-one of the following formats:
-.PP
-.Vb 5
-\&    mon dd hh:mm:ss.mmm + feed <message\-id> site ...
-\&    mon dd hh:mm:ss.mmm j feed <message\-id> site ...
-\&    mon dd hh:mm:ss.mmm c feed <message\-id> Cancelling <message\-id>
-\&    mon dd hh:mm:ss.mmm \- feed <message\-id> reason
-\&    mon dd hh:mm:ss.mmm ? feed <message\-id> reason
-.Ve
-.PP
-There may also be hostname and/or size fields after the message \s-1ID\s0
-depending on the settings of \fInntplinklog\fR and \fIlogartsize\fR in
-\&\fIinn.conf\fR.
-.PP
-The first three fields are the date and time to millisecond resolution.
-The fifth field is the site that sent the article (based on the Path
-header) and the sixth field is the article's message \s-1ID\s0; they will be a
-question mark if the information is not available.
-.PP
-The fourth field indicates whether the article was accepted or not.  If it
-is a plus sign, then the article was accepted.  If it is the letter \f(CW\*(C`j\*(C'\fR
-then the article was accepted, but all of the newsgroups to which the
-article was posted were set to mode \f(CW\*(C`j\*(C'\fR in the active file (or not listed
-in the active file and \fIwanttrash\fR was set in \fIinn.conf\fR) so the article
-was filed into the \f(CW\*(C`junk\*(C'\fR newsgroup.  In both of these cases, the article
-has been accepted and the \f(CW\*(C`site ...\*(C'\fR field contains the space-separated
-list of sites to which the article is being sent.
-.PP
-If the fourth field is the letter \f(CW\*(C`c\*(C'\fR, then a cancel message was accepted
-before the original article arrived, and a history entry for the cancelled
-message was created so that \fBinnd\fR will reject that message if it arrives
-later.
-.PP
-If the fourth field is a minus sign, then the article was rejected.  The
-reasons for rejection generated by \fBinnd\fR include:
-.PP
-.Vb 20
-\&    "%s" header too long
-\&    "%s" wants to cancel <%s> by "%s"
-\&    Article exceeds local limit of %s bytes
-\&    Article posted in the future \-\- "%s"
-\&    Bad "%s" header
-\&    Can't write history
-\&    Duplicate
-\&    Duplicate "%s" header
-\&    EOF in headers
-\&    Linecount %s != %s +\- %s
-\&    Missing %s header
-\&    No body
-\&    No colon\-space in "%s" header
-\&    No space
-\&    Space before colon in "%s" header
-\&    Too old \-\- "%s"
-\&    Unapproved for "%s"
-\&    Unwanted newsgroup "%s"
-\&    Unwanted distribution "%s"
-\&    Whitespace in "Newsgroups" header \-\- "%s"
-.Ve
-.PP
-where \f(CW%s\fR, above, is replaced by more specific information.  (The Perl,
-Python, andr Tcl filters, if used, may reject articles with other
-reasons.)
-.PP
-If the fourth field is the letter \f(CW\*(C`?\*(C'\fR, the article contains strange
-strings, such as \s-1CR\s0 without \s-1LF\s0 or \s-1LF\s0 without \s-1CR\s0.  (These characters should
-never occur in isolation, only together as \s-1CRLF\s0 to indicate the end of a
-line.)  This log message is just informational, to give an idea of how
-widespread such articles are; \fBinnd\fR does not reject such articles.
-.PP
-Note that when \fIwanttrash\fR is set to true in \fIinn.conf\fR and an article
-is received that isn't posted to any valid newsgroups, it will be accepted
-and logged with two lines, a \f(CW\*(C`j\*(C'\fR line and a minus sign line.
-.PP
-\&\fBinnd\fR also makes extensive reports through \fIsyslog\fR\|(3).  The first word of
-the log message will be the name of the site if the entry is site-specific
-(such as a \*(L"connected\*(R" message).  The first word will be \f(CW\*(C`SERVER\*(C'\fR if the
-message relates to the server itself, such as when a read error occurs.
-.PP
-If the second word is the four letters \f(CW\*(C`cant\*(C'\fR, then an error is being
-reported.  (The absence of an apostrophe is intentional; it makes it
-easier to grep from the command line and easier to find error messages in
-FAQs using a search engine.)  In this case, the next two words generally
-name the system call or library routine that failed and the object upon
-which the action was being performed.  The rest of the line may contain
-other information.
-.PP
-In other cases, the second word attempts to summarize what change has been
-made, while the rest of the line gives more specific information.  The
-word \f(CW\*(C`internal\*(C'\fR generally indicates an internal logic error.
-.SH "SIGNALS"
-.IX Header "SIGNALS"
-\&\fBinnd\fR will catch \s-1SIGTERM\s0 and \s-1SIGHUP\s0 and shut down.  If \fB\-d\fR is used,
-\&\s-1SIGINT\s0 will also be caught and will result in an orderly shutdown.
-.PP
-\&\fBinnd\fR will catch the \s-1SIGUSR1\s0 signal and recreate the control channel
-used by \fIctlinnd\fR\|(8).
-.SH "BUGS"
-.IX Header "BUGS"
-\&\fBinnd\fR normally attempts to strip \s-1IP\s0 options from incoming connections,
-since it uses IP-based authentication and source routing can confuse that.
-However, this doesn't work on all systems, and it doesn't work at all in
-the presence of IPv6 support (and is disabled in that case).  Hence, if
-using \fBinnd\fR with IPv6 support, make sure that your kernel or router
-disables source routing.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.
-.PP
-$Id: innd.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive\fR\|(5), \fIctlinnd\fR\|(8), \fIdbz\fR\|(3), \fIhistory\fR\|(5), \fIincoming.conf\fR\|(5), \fIinn.conf\fR\|(5),
-\&\fInewsfeeds\fR\|(5), \fInnrpd\fR\|(8), \fIrnews\fR\|(1), \fIsyslog\fR\|(3).
diff --git a/doc/man/inndcomm.3 b/doc/man/inndcomm.3
deleted file mode 100644 (file)
index 0633e97..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-.\" $Revision: 1586 $
-.TH INNDCOMM 3
-.SH NAME
-inndcomm \- INND communication part of InterNetNews library
-.SH SYNOPSIS
-.nf
-.ta \w'    unsigned long    'u
-.B
-#include "inndcomm.h"
-
-.B "int"
-.B "ICCopen()"
-
-.B "int"
-.B "ICCclose()"
-
-.B "void"
-.B "ICCsettimeout(i)"
-.B "    int    i;"
-
-.B "int"
-.B "ICCcommand(cmd, argv, replyp)"
-.B "    char   cmd;"
-.B "    char   *argv[];"
-.B "    char   **replyp;"
-
-.B "int"
-.B "ICCcancel(mesgid)"
-.B "    char   *mesgid;"
-
-.B "int"
-.B "ICCreserve(why)"
-.B "    char   *why;"
-
-.B "int"
-.B "ICCpause(why)"
-.B "    char   *why;"
-
-.B "int"
-.B "ICCgo(why)"
-.B "    char   *why;"
-
-.B "extern char *ICCfailure;"
-.fi
-.SH DESCRIPTION
-The routines described in this manual page are part of the InterNetNews
-library,
-.IR libinn (3).
-They are used to send commands to a running
-.IR innd (8)
-daemon on the local host.
-The letters ``ICC'' stand for
-.IR I nnd
-.IR C ontrol
-.IR C ommand.
-.PP
-.I ICCopen
-creates a
-Unix-domain datagram socket and binds it to the server's control socket, if
-.I <HAVE_UNIX_DOMAIN_SOCKETS in include/config.h>
-is defined.  Otherwise it creates
-a named pipe for communicating with the server.
-It returns \-1 on failure or zero on success.
-This routine must be called before any other routine.
-.PP
-.I ICCclose
-closes any descriptors that have been created by
-.IR ICCopen .
-It returns \-1 on failure or zero on success.
-.PP
-.I ICCsettimeout
-can be called before any of the following routines to determine how long
-the library should wait before giving up on getting the server's reply.
-This is done by setting and catching a SIGALRM
-.IR signal (2).
-If the timeout is less then zero then no reply will be waited for.
-The SC_SHUTDOWN, SC_XABORT, and SC_XEXEC commands do not get a reply either.
-The default, which can be obtained by setting the timeout to zero, is to
-wait until the server replies.
-.PP
-.I ICCcommand
-sends the command
-.I cmd
-with parameters
-.I argv
-to the server.
-It returns \-1 on error.
-If the server replies, and
-.I replyp
-is not NULL, it will be filled in with an allocated buffer that contains
-the full text of the server's reply.
-This buffer is a string in the form of ``<digits><space><text>''
-where ``digits'' is the text value of the recommended exit code;
-zero indicates success.
-Replies longer then 4000 bytes will be truncated.
-The possible values of
-.I cmd
-are defined in the ``inndcomm.h'' header file.
-The parameters for each command are described in
-.IR ctlinnd (8).
-This routine returns \-1 on communication failure, or the exit status
-sent by the server which will never be negative.
-.PP
-.I ICCcancel
-sends a ``cancel'' message to the server.
-.I Mesgid
-is the Message-ID of the article that should be canceled.
-The return value is the same as for
-.IR ICCcommand .
-.PP
-.IR ICCpause ,
-.IR ICCreserve ,
-and
-.I ICCgo
-send a ``pause,'' ``reserve,'' or ``go'' command to the server, respectively.
-If
-.I ICCreserve
-is used, then the
-.I why
-value used in the
-.I ICCpause
-invocation must match; the value used in the
-.I ICCgo
-invocation must always match that the one used in the
-.I ICCpause
-invocation.
-The return value for all three routines is the same as for
-.IR ICCcommand .
-.PP
-If any routine described above fails, the
-.I ICCfailure
-variable will identify the system call that failed.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: inndcomm.3 1586 1998-12-09 15:53:55Z kondou $
-.SH "SEE ALSO"
-ctlinnd(8),
-innd(8),
-libinn(3).
diff --git a/doc/man/inndf.8 b/doc/man/inndf.8
deleted file mode 100644 (file)
index e1272c4..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-.\" 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 "INNDF 8"
-.TH INNDF 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-inndf \- Report free disk, inodes, and overview information
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinndf\fR [\fB\-Fhi\fR] [\fB\-f\fR \fIfilename\fR] \fIdirectory\fR [\fIdirectory\fR ...]
-.PP
-\&\fBinndf\fR \fB\-n\fR
-.PP
-\&\fBinndf\fR \fB\-o\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinndf\fR was originally a replacement for \f(CW\*(C`df | awk\*(C'\fR in \fIinnwatch.ctl\fR\|(5)
-and \fIinnstat\fR\|(8), and now also reports various other usage information about
-\&\s-1INN\s0's storage that \fIdf\fR\|(1) doesn't understand.  \fBinndf\fR doesn't sync, forks
-less, and is generally less complicated than \fIdf\fR\|(1).
-.PP
-Its default behavior is to report free kilobytes (not disk blocks), or
-free inodes if \fB\-i\fR is used, in the file systems holding the directories
-given on the command line.  (A kilobyte in this case is 1024 bytes.)  If
-only one directory is given, the output will be a simple number; if more
-than one directory is given, the output will be formatted for human
-readability.
-.PP
-If \fIenableoverview\fR is set to true in \fIinn.conf\fR, \fBinndf\fR can also be
-used to get information about the overview database.  With the \fB\-n\fR
-option, it reports a count of the total number of overview records stored.
-With \fB\-o\fR, it reports the percentage of space used in the overview
-database (for those overview methods where this is meaningful data).
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-f\fR \fIfilename\fR" 4
-.IX Item "-f filename"
-\&\fIfilename\fR should contain a list of directories to use in addition to
-those given by the arguments, one per line.  Blank lines and anything
-after \f(CW\*(C`#\*(C'\fR on any line are ignored.
-.IP "\fB\-F\fR" 4
-.IX Item "-F"
-Like \fB\-f\fR execpt that the filename is \fIpathetc\fR/filesystems and it is
-not an error if this file doesn't exist.  (This option is used primarily
-by such things as \fIinnstat\fR\|(8), so that the news administrator can add
-additional file systems to check to \fIpathetc\fR/filesystems without having
-to modify the script.)
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Print a usage message and exit.
-.IP "\fB\-i\fR" 4
-.IX Item "-i"
-Report the number of free inodes rather than the amount of free disk
-space.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-Report the total number of records in the overview database.  Note that
-crossposted articles will have one overview record for each newsgroup
-they're posted to.
-.IP "\fB\-o\fR" 4
-.IX Item "-o"
-Report the percentage usage of the overview database space.  This is only
-meaningful for overview methods that pre-allocate a certain amount of
-space rather than grow to accomodate more records.  Currently, this flag
-is only useful for the buffindexed overview method.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Print the free kilobytes in /news/spool as a simple number:
-.PP
-.Vb 1
-\&    inndf /news/spool
-.Ve
-.PP
-Report the free inodes in /usr/local/news and /news/spool in a format
-designed for human readability:
-.PP
-.Vb 1
-\&    inndf \-i /usr/local/news /news/spool
-.Ve
-.PP
-The same, but also add in all file systems in \fIpathetc\fR/filesystems:
-.PP
-.Vb 1
-\&    inndf \-i \-F /usr/local/news /news/spool
-.Ve
-.PP
-Print out the number of overview records and the percentage space used by
-a buffindexed overview database:
-.PP
-.Vb 1
-\&    inndf \-no
-.Ve
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBinndf\fR was written by Ian Dickinson <idickins@fore.com>.  This manual
-page was written by Swa Frantzen <Swa.Frantzen@belgium.eu.net>.  Thanks
-also to the following folks for ports, patches, and comments:
-.PP
-.Vb 7
-\&    Mahesh Ramachandran <rr@eel.ufl.edu>
-\&    Chuck Swiger <chuck@its.com>
-\&    Sang\-yong Suh <sysuh@kigam.re.kr>
-\&    Brad Dickey <bdickey@haverford.edu>
-\&    Taso N. Devetzis <devetzis@snet.net>
-\&    Wei\-Yeh Lee <weiyeh@columbia.edu>
-\&    Jeff Garzik <jeff.garzik@spinne.com>
-.Ve
-.PP
-and to all the other folks I met and worked with during my 10 years as a
-newsadmin.
-.PP
-Katsuhiro Kondou added the \fB\-n\fR and \fB\-o\fR options.  Russ Allbery added
-reporting of percentage free disk space.  Support for \fB\-f\fR and \fB\-F\fR was
-added by Fabien Tassin <fta@sofaraway.org>.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIdf\fR\|(1), \fIinnwatch.ctl\fR\|(5), \fIinnstat\fR\|(8).
diff --git a/doc/man/inndstart.8 b/doc/man/inndstart.8
deleted file mode 100644 (file)
index 3c086ef..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-.\" 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 "INNDSTART 8"
-.TH INNDSTART 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-inndstart \- Start innd
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinndstart\fR [\fB\-P\fR \fIport\fR] [\fB\-I\fR \fIaddress\fR] [\fIinnd-options\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The purpose of \fBinndstart\fR is to raise system file descriptor limits,
-open the privileged news transfer port, and then start \fIinnd\fR\|(8), passing it
-the open file descriptor for the news port.  \fBinndstart\fR is used since
-only privileged programs can perform those two operations and since
-\&\fBinnd\fR should not run with elevated privileges.  It is installed setuid
-root and drops privileges to the news user (as set at configure time)
-before running \fBinnd\fR.
-.PP
-Normally there is no need to run \fBinndstart\fR directly.  Instead, run
-\&\fIrc.news\fR\|(8) as the news user, and it will handle running \fBinndstart\fR
-appropriately for you.
-.PP
-Since \fBinndstart\fR is setuid root, it is extremely restrictive about who
-can run it and what it is willing to do.  See \*(L"\s-1SECURITY\s0\*(R" for the full
-details.
-.PP
-\&\fBinndstart\fR can only be run by the news user; if run by any other user,
-it will abort.  It will also only bind to ports 119, 433, or a port number
-given at configure time with \fB\-\-with\-innd\-port\fR among those ports below
-1024, although it can bind to any port above 1024.  This is to prevent
-various security exploits possible by binding to arbitrary privileged
-ports.
-.PP
-Before running \fBinnd\fR, \fBinndstart\fR cleans out the environment and sets
-only those environment variables listed in \*(L"\s-1ENVIRONMENT\s0\*(R".
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-P\fR \fIport\fR" 4
-.IX Item "-P port"
-Bind to \fIport\fR instead of whatever is specified by \fIport\fR in
-\&\fIinn.conf\fR.  Note that this is subject to the constraints mentioned
-above.
-.IP "\fB\-I\fR \fIaddress\fR" 4
-.IX Item "-I address"
-Bind as \fIaddress\fR instead of whatever is specified by \fIbindaddress\fR in
-\&\fIinn.conf\fR.  The default behavior is to bind to \s-1INADDR_ANY\s0, and that's
-what's desired almost all the time.  This option, and the \fIinn.conf\fR
-parameter, may be useful if the machine has multiple interface cards and
-\&\fBinnd\fR should only be listening on a particular one.
-.PP
-All other options given on the command line are passed verbatim to
-\&\fBinnd\fR.  In addition, \fBinndstart\fR will give the \fB\-p\fR option to \fBinnd\fR,
-specifying the file descriptor of the open network socket.
-.SH "SECURITY"
-.IX Header "SECURITY"
-\&\fBinndstart\fR is setuid root, and therefore an expected point of attack.
-It has therefore been carefully written with security in mind.  In a
-normal \s-1INN\s0 installation, it is installed setuid root and executable only
-by users in the news group.
-.PP
-Ideally, everything about \fBinndstart\fR's operations would be hard-coded so
-that it could not be modified.  Fighting against this desire, however, is
-the ideal that as much of \s-1INN\s0's operation as possible should be
-configurable at run-time using \fIinn.conf\fR, and the news system should be
-able to an alternate inn.conf by setting \s-1INNCONF\s0 to the path to that file
-before starting any programs.  The configuration data therefore can't be
-trusted.
-.PP
-The security model used is:
-.IP "\(bu" 2
-\&\fBinndstart\fR can only be executed by the news user and news group, as
-determined at configure time and compiled into \fBinndstart\fR as constants.
-Similarly, \fBinndstart\fR will always \fIsetuid()\fR and \fIsetgid()\fR to those users
-before running \fBinnd\fR.  This is to prevent a user other than news but in
-the news group from using \fBinndstart\fR to leverage that access into access
-to the news account.
-.IP "\(bu" 2
-As mentioned above, \fBinndstart\fR will only bind to a very limited subset
-of ports below 1024.  There are various attacks that can be performed
-using random low-numbered ports, including exploits of the \fIrsh\fR\|(1) family
-of commands on some systems.
-.IP "\(bu" 2
-\&\fBinndstart\fR does as little as possible as root, dropping privileges
-before performing any operations that do not require elevated privileges.
-.PP
-This program therefore gives the news user the ability to revoke system
-file descriptor limits and bind to the news port, and nothing else.
-.SH "DIAGNOSTICS"
-.IX Header "DIAGNOSTICS"
-\&\fBinndstart\fR may log the following messages to syslog and print them to
-stderr.
-.ie n .IP "can't bind: %s" 4
-.el .IP "can't bind: \f(CW%s\fR" 4
-.IX Item "can't bind: %s"
-(Fatal) Unable to bind to the designated port.  This usually means that
-something else is already running on the news port.  Check with
-\&\fInetstat\fR\|(8) and make sure that \fIinetd\fR\|(8) doesn't think it's running a
-service on the same port you're trying to run \fBinnd\fR on.
-.ie n .IP "can't bind to restricted port %d" 4
-.el .IP "can't bind to restricted port \f(CW%d\fR" 4
-.IX Item "can't bind to restricted port %d"
-(Fatal) \fBinndstart\fR was told to bind to a low numbered port (under 1024)
-other than 119, 433, or a port number given at configure time.  This is
-not allowed for security reasons.  If you're running \fBinnd\fR on a port
-other than 119 or 433, you need to give the \-\-with\-innd\-port flag to
-\&\f(CW\*(C`configure\*(C'\fR when you compile \s-1INN\s0.
-.ie n .IP "can't exec %s:\fR \f(CW%s" 4
-.el .IP "can't exec \f(CW%s:\fR \f(CW%s\fR" 4
-.IX Item "can't exec %s: %s"
-(Fatal) \fBinndstart\fR was unable to execute \fBinnd\fR.  Make sure that
-\&\fIpathbin\fR is set correctly in inn.conf and that \fBinnd\fR is located in
-that directory and is executable by the news user.
-.IP "can't getgrnam(%s)" 4
-.IX Item "can't getgrnam(%s)"
-(Fatal) Unable to determine the \s-1GID\s0 for the compiled-in news group.
-Perhaps the news group is not listed in \fI/etc/group\fR.
-.IP "can't getpwnam(%s)" 4
-.IX Item "can't getpwnam(%s)"
-(Fatal) Unable to determine the \s-1UID\s0 for the compiled-in news user.
-Perhaps the news user is not listed in \fI/etc/passwd\fR.
-.ie n .IP "can't open socket: %s" 4
-.el .IP "can't open socket: \f(CW%s\fR" 4
-.IX Item "can't open socket: %s"
-(Fatal) Something went wrong in creating the network socket.  Chances are
-your system is out of resources of some kind.
-.ie n .IP "can't set file descriptor limit to %d:\fR \f(CW%s" 4
-.el .IP "can't set file descriptor limit to \f(CW%d:\fR \f(CW%s\fR" 4
-.IX Item "can't set file descriptor limit to %d: %s"
-(Warning) Unable to set the system file descriptor limit to the specified
-value; the limit was left unchanged.  Perhaps that value is too high for
-your system.  Try changing \fIrlimitnofile\fR in \fIinn.conf\fR to a smaller
-value.
-.ie n .IP "can't set \s-1SO_REUSEADDR:\s0 %s" 4
-.el .IP "can't set \s-1SO_REUSEADDR:\s0 \f(CW%s\fR" 4
-.IX Item "can't set SO_REUSEADDR: %s"
-(Warning) \fBinndstart\fR attempts to set \s-1SO_REUSEADDR\s0 using \fIsetsockopt\fR\|(2) so
-that if \fBinnd\fR exits, it can be restarted again immediately without
-waiting for the port to time out.  For some reason, this failed, and that
-option was not set on the port.
-.ie n .IP "can't seteuid to %d:\fR \f(CW%s" 4
-.el .IP "can't seteuid to \f(CW%d:\fR \f(CW%s\fR" 4
-.IX Item "can't seteuid to %d: %s"
-(Fatal) Unable to change the effective \s-1UID\s0.  If \fBinndstart\fR has the
-correct permissions (setuid root) and seteuid to root (\s-1UID\s0 0) is failing,
-this may mean that your system has \fIseteuid\fR\|(2) but doesn't have support for
-\&\s-1POSIX\s0 saved UIDs.  If this is the case, please report this to the \s-1INN\s0
-maintainers.
-.ie n .IP "can't setgid to %d:\fR \f(CW%s" 4
-.el .IP "can't setgid to \f(CW%d:\fR \f(CW%s\fR" 4
-.IX Item "can't setgid to %d: %s"
-(Fatal) Dropping privileges to the news group failed for some reason.
-.ie n .IP "can't setgroups (is inndstart setuid root?): %s" 4
-.el .IP "can't setgroups (is inndstart setuid root?): \f(CW%s\fR" 4
-.IX Item "can't setgroups (is inndstart setuid root?): %s"
-(Warning) Dropping all supplemental groups except the news group failed
-for some reason, and the process group membership was left unchanged.
-This almost always indicates that \fBinndstart\fR isn't setuid root as it has
-to be to do what it does.  Make sure that \fBinndstart\fR is setuid root,
-owned by group news, and mode 4710.
-.ie n .IP "can't setuid to %d:\fR \f(CW%s" 4
-.el .IP "can't setuid to \f(CW%d:\fR \f(CW%s\fR" 4
-.IX Item "can't setuid to %d: %s"
-(Fatal) Dropping privileges to the news user failed for some reason.
-.ie n .IP "invalid address %s" 4
-.el .IP "invalid address \f(CW%s\fR" 4
-.IX Item "invalid address %s"
-(Fatal) \fB\-I\fR was specified on the command line, but the argument wasn't a
-valid address.  Addresses must be given as numeric \s-1IP\s0 addresses.
-.IP "invalid bindaddress in inn.conf (%s)" 4
-.IX Item "invalid bindaddress in inn.conf (%s)"
-(Fatal) The \fIbindaddress\fR specified in \fIinn.conf\fR could not be converted
-to an \s-1IP\s0 address.  See \fIinn.conf\fR\|(5) for more information about valid
-values.
-.ie n .IP "invalid port %s (must be a number)" 4
-.el .IP "invalid port \f(CW%s\fR (must be a number)" 4
-.IX Item "invalid port %s (must be a number)"
-(Fatal) \fB\-P\fR was specified on the command line, but the argument wasn't a
-valid port.  Ports must be port numbers; service names are not allowed.
-.IP "missing address after \-I" 4
-.IX Item "missing address after -I"
-(Fatal) \fB\-I\fR was given on the command line, but no address was given
-after the option.
-.IP "missing port after \-P" 4
-.IX Item "missing port after -P"
-(Fatal) \fB\-P\fR was given on the command line, but no port was given after
-the option.
-.ie n .IP "must be run by user %s\fR (%d), not \f(CW%d" 4
-.el .IP "must be run by user \f(CW%s\fR (%d), not \f(CW%d\fR" 4
-.IX Item "must be run by user %s (%d), not %d"
-(Fatal) Someone other than the news user attempted to run \fBinndstart\fR.
-\&\fBinndstart\fR may only be run by the news user for security reasons.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Normally, \fBinndstart\fR is never run directly.  However, a simple way to
-just restart \fBinnd\fR (if it is not running) without running any other
-auxilliary programs or performing any of the other checks done by
-\&\fIrc.news\fR\|(8) is to just run:
-.PP
-.Vb 1
-\&    inndstart
-.Ve
-.PP
-as the news user.
-.PP
-To start \fBinnd\fR on port 433, passing it the \f(CW\*(C`\-c21\*(C'\fR option, use:
-.PP
-.Vb 1
-\&    inndstart \-P433 \-c21
-.Ve
-.SH "ENVIRONMENT"
-.IX Header "ENVIRONMENT"
-One environment variable affects the operation of \fBinndstart\fR itself:
-.IP "\s-1INNCONF\s0" 8
-.IX Item "INNCONF"
-The full path to the \fIinn.conf\fR\|(5) file to read, rather than the default.
-This can be used to run multiple copies of \s-1INN\s0 on the same machine with
-different settings.
-.PP
-When executing \fBinnd\fR, \fBinndstart\fR cleans out the entire environmnent
-and sets only the following variables:
-.IP "\s-1BIND_INADDR\s0" 8
-.IX Item "BIND_INADDR"
-Passed verbatim from \fBinndstart\fR's environment.  This is used by various
-programs to override the \fIbindaddress\fR parameter in \fIinn.conf\fR and
-therefore must be in \fBinnd\fR's environment for programs like \fIinnfeed\fR\|(8).
-.IP "\s-1HOME\s0" 8
-.IX Item "HOME"
-Set to \fIpathnews\fR from \fIinn.conf\fR.
-.IP "\s-1LOGNAME\s0" 8
-.IX Item "LOGNAME"
-Set to the news master, as determined at configure time.
-.IP "\s-1PATH\s0" 8
-.IX Item "PATH"
-Set to \fIpathbin\fR from \fIinn.conf\fR, \fIpathetc\fR from \fIinn.conf\fR, and then
-\&\fI/bin\fR, \fI/usr/bin\fR, and \fI/usr/ucb\fR in that order.
-.IP "\s-1SHELL\s0" 8
-.IX Item "SHELL"
-Set to the path to the system Bourne shell as determined by configure
-(probably \fI/bin/sh\fR).
-.IP "\s-1TMPDIR\s0" 8
-.IX Item "TMPDIR"
-Set to \fIpathtmp\fR from inn.conf.
-.IP "\s-1TZ\s0" 8
-.IX Item "TZ"
-Passed verbatim from \fBinndstart\fR's environment.
-.IP "\s-1USER\s0" 8
-.IX Item "USER"
-Set to the news master, as determined at configure time.
-.SH "FILES"
-.IX Header "FILES"
-.IP "inn.conf" 4
-.IX Item "inn.conf"
-Read for \fIpathnews\fR, \fIpathbin\fR, \fIpathtmp\fR, \fIrlimitnofile\fR,
-\&\fIbindaddress\fR, and \fIport\fR.
-.IP "\fIpathbin\fR/innd" 4
-.IX Item "pathbin/innd"
-The binary that is executed as \fBinnd\fR and passed the open network socket.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: inndstart.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fIinnd\fR\|(8)
diff --git a/doc/man/innfeed.1 b/doc/man/innfeed.1
deleted file mode 100644 (file)
index db58154..0000000
+++ /dev/null
@@ -1,511 +0,0 @@
-.\" -*- nroff -*-
-.\"
-.\" Author:       James A. Brister <brister@vix.com> -- berkeley-unix --
-.\" Start Date:   Sat, 20 Jan 1996 15:50:56 +1100
-.\" Project:      INN -- innfeed
-.\" File:         innfeed.1
-.\" RCSId:        $Id: innfeed.1 7798 2008-04-26 08:47:01Z iulius $
-.\" Description:  Man page for innfeed(1)
-.\"
-.TH INNFEED 1
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH NAME
-innfeed \- multi-host, multi-connection, streaming NNTP feeder.
-.SH SYNOPSIS
-.B innfeed
-[
-.B \-a spool-dir
-]
-[
-.BI \-b " directory"
-]
-[
-.B \-C
-]
-[
-.BI \-c " filename"
-]
-[
-.BI \-d " num"
-]
-[
-.BI \-e " bytes"
-]
-[
-.B \-h
-]
-[
-.BI \-l " filename"
-]
-[
-.B \-m
-]
-[
-.B \-M
-]
-[
-.B \-o bytes
-]
-[
-.B \-p file
-]
-[
-.B \-S file
-]
-[
-.B \-x 
-]
-[
-.B \-y
-]
-[
-.B \-z 
-]
-[
-.B \-v
-]
-[ file ]
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH DESCRIPTION
-.PP
-.I Innfeed
-implements the NNTP protocol for transferring news between computers.  It
-handles the standard IHAVE protocol as well as the CHECK/TAKETHIS
-streaming extension. Innfeed can feed any number of remote hosts at once
-and will open multiple connections to each host if configured to do so. The
-only limitations are the process limits for open file descriptors and memory.
-.PP
-As an alternative to using NNTP, INN may also be fed to an IMAP
-server.  This is done by using an executable called imapfeed, which is
-identical to innfeed except for the delivery process.  The new version
-has two types of connections: an LMTP connection to deliver regular
-messages and an IMAP connection to handle control messages. The
-startinnfeed process can then be told to start imapfeed instead of innfeed.
-(See the INSTALL file for how to do this.)
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH MODES
-.PP
-.I Innfeed
-has three modes of operation: channel, funnel-file and batch.
-.PP
-Channel mode is used when no filename is given on the command line,
-the ``input-file'' keyword is \fInot\fP given in the config file, \fIand\fP
-the ``\fI\-x\fP'' option is \fInot\fP given.
-In channel mode innfeed runs with stdin connected via a pipe to
-innd. Whenever innd closes this pipe (and it has several reasons during
-normal processing to do so), innfeed will exit. It first will try to
-finish sending all articles it was in the middle of transmitting, before
-issuing a QUIT command. This means innfeed may take a while to exit
-depending on how slow your peers are. It never (well, almost never) just
-drops the connection.
-.PP
-The recommended way to restart innfeed when run in channel mode is
-therefore to tell innd to close the pipe and spawn a new innfeed process.
-This can be done with ``ctlinnd flush <feed>'' where <feed> is the name of
-the innfeed channel feed in ``\fInewsfeeds\fP''.
-.PP
-Funnel-file mode is used when a filename is given as an argument
-or the ``input-file'' keyword is given in the config file.
-In funnel file mode it reads the specified file for the same formatted
-information as innd would give in channel mode. It is expected that innd is
-continually writing to this file, so when innfeed reaches the end of the file
-it will check periodically for new information. To prevent the funnel file
-from growing without bounds, you will need to periodically move the file to
-the side (or simply remove it) and have innd flush the file. Then, after
-the file is flushed by innd, you can send innfeed a SIGALRM, and it too
-will close the file and open the new file created by innd. Something like:
-.PP
-.RS
-.nf
-innfeed -p /var/run/news/innfeed.pid my-funnel-file &
-while true; do
-       sleep 43200
-       rm -f my-funnel-file
-       ctlinnd flush funnel-file-site
-       kill -ALRM `cat /var/run/news/innfeed.pid`
-done
-.fi
-.RE
-.PP
-Batch mode is used when the ``\fI\-x\fP'' flag is used.
-In batch mode innfeed will ignore stdin, and will simply process any
-backlog created by a previously running innfeed. This mode is not normally
-needed as innfeed will take care of backlog processing.
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH CONFIGURATION
-Innfeed expects a couple of things to be able to run correctly: a directory
-where it can store backlog files and a configuration file to describe which
-peers it should handle.
-.PP
-The configuration file is described in
-.IR innfeed.conf (5).
-The ``\fI\-c\fP''
-option can be used to specify a different file.
-.PP
-For each peer (say, ``\fIfoo\fP''), innfeed manages up to 4 files in the
-backlog directory: a ``\fIfoo.lock\fP'' file, which prevents other
-instances of innfeed from interfering with this one; a ``\fIfoo.input\fP''
-file which has old article information innfeed is reading for
-re-processing; a ``\fIfoo.output\fP'' file where innfeed is writing
-information on articles that couldn't be processed (normally due to a slow
-or blocked peer); and a ``\fIfoo\fP'' file.
-.PP
-This last file (``\fIfoo\fP'') is never created by innfeed, but if innfeed
-notices it, it will rename it to ``\fIfoo.input\fP'' at the next
-opportunity and will start reading from it. This lets you create a batch
-file and put it in a place where innfeed will find it. You should never
-alter the .input or .output files of a running innfeed.
-.PP
-The format of these last three files is one of the following:
-.PP
-.RS
-.nf
-/path/to/article <message-id>
-@token@ <message-id>
-.fi
-.RE
-.PP
-This is the same as the first two fields of the lines innd feeds to
-innfeed, and the same as the first two fields of the lines of the batch
-file innd will write if innfeed is unavailable for some reason. When
-innfeed processes its own batch files it ignores everything after the first
-two whitespace separated fields, so moving the innd-created batch file to
-the appropriate spot will work, even though the lines have extra fields.
-.PP
-The first field can also be a storage API token.  The two types of lines can
-be intermingled; innfeed will use the storage manager if appropriate and
-otherwise treat the first field as a filename to read directly.
-.PP
-Innfeed writes its current status to the file ``\fIinnfeed.status\fP'' (or
-the file given by the ``\fI-S\fP'' option). This file contains details on
-the process as a whole, and on each peer this instance of innfeed is
-managing.
-.PP
-If innfeed is told to send an article to a host it is not managing, then
-the article information will be put into a file matching the pattern
-``\fIinnfeed-dropped.*\fP'', with part of the file name matching the pid of
-the innfeed process that is writing to it.  Innfeed will not process this
-file except to write to it. If nothing is written to the file then it will
-be removed if innfeed exits normally.
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH SIGNALS
-.PP
-Upon receipt of a SIGALRM innfeed will close the funnel-file specified on
-the command line, and will reopen it (see funnel file description above).
-.PP
-Innfeed with catch SIGINT and will write a large debugging snapshot of the
-state of the running system.
-.PP 
-Innfeed will catch SIGHUP and will reload the config file. 
-See
-.IR innfeed.conf (5)
-for more details.
-.PP
-Innfeed will catch SIGCHLD and will close and reopen all backlog files.
-.PP 
-Innfeed will catch SIGTERM and will do an orderly shutdown.
-.PP
-Upon receipt of a SIGUSR1 innfeed will increment the debugging level by
-one; receipt of a SIGUSR2 will decrement it by one. The debugging level
-starts at zero (unless the ``-d'' option it used), in which case no debugging
-information is emitted. A larger value for the level means more debugging
-information. Numbers up to 5 are currently useful.
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH SYSLOG ENTRIES
-.PP
-There are 3 different categories of syslog entries for statistics: Host,
-Connection and Global.
-.PP
-The Host statistics are generated for a given peer at regular intervals
-after the first connection is made (or, if the remote is unreachable, after
-spooling starts). The Host statistics give totals over all Connections that
-have been active during the given time frame. For example (broken here to
-fit the page, with ``vixie'' being the peer):
-.PP
-.nf
-  May 23 12:49:08 data innfeed[16015]: vixie checkpoint
-               seconds 1381 offered 2744 accepted 1286 
-               refused 1021 rejected 437 missing 0 spooled 990
-               on_close 0 unspooled 240 deferred 10 requeued 25
-               queue 42.1/100:14,35,13,4,24,10
-.fi
-.PP
-These meanings of these fields are:
-.nr XX \w'unspooled '
-.TP \n(XXu
-seconds
-The time since innfeed connected to the host or since the statistics
-were reset by a ``final'' log entry.
-.TP
-offered
-The number of IHAVE commands sent to the host if it is not in streaming mode.
-The sum of the number of TAKETHIS commands sent when no-CHECK mode
-is in effect plus the number CHECK commands sent in streaming mode (when
-no-CHECK mode is not in effect).
-.TP
-accepted
-The number of articles which were sent to the remote host and accepted
-by it.
-.TP
-refused
-The number of articles offered to the host that it it indicated it
-didn't want because it had already seen the Message-ID.  The remote
-host indicates this by sending a 435 response to an IHAVE command or
-a 438 response to a CHECK command.
-.TP
-rejected
-The number of articles transferred to the host that it did not accept
-because it determined either that it already had the article or it did
-not want it because of the article's Newsgroups: or Distribution: headers,
-etc.  The remote host indicates that it is rejecting the article by
-sending a 437 or 439 response after innfeed sent the entire article.
-.TP
-missing
-The number of articles which innfeed was told to offer to the host but
-which were not present in the article spool.  These articles were probably
-cancelled or expired before innfeed was able to offer them to the host.
-.TP
-spooled
-The number of article entries that were written to the .output backlog file
-because the articles could not either be sent to the host or be refused
-by it.  Articles are generally spooled either because new articles are
-arriving more quickly than they can be offered to the host, or because
-innfeed closed all the connections to the host and pushed all the
-articles currently in progress to the .output backlog file.
-.TP
-on_close
-The number of articles that were spooled when innfeed closed all the
-connections to the host.
-.TP
-unspooled
-The number of article entries that were read from the .input backlog
-file.
-.TP
-deferred
-The number of articles that the host told innfeed to retry later by
-sending a 431 or 436 response.  Innfeed immediately puts these articles
-back on the tail of the queue.
-.TP
-requeued
-The number of articles that were in progress on connections when innfeed
-dropped those connections and put the articles back on the queue.  These
-connections may have been broken by a network problem or became unresponsive
-causing innfeed to time them out.
-.TP
-queue
-The first number is the average (mean) queue size during the previous logging
-interval.  The second number is the maximum allowable queue size.
-The third number is the percentage of the time that the queue
-was empty.  The fourth through seventh numbers are the percentages of the
-time that the queue was >0% to 25% full, 25% to 50% full, 50% to 75%
-full, and 75% to <100% full.  The last number is the percentage of the
-time that the queue was totally full.
-.PP
-If the ``\fI\-z\fP'' option is used (see below), then when the peer stats are
-generated, each Connection will log its stats too. For example, for
-connection number zero (from a set of five):
-.PP
-.nf
-  May 23 12:49:08 data innfeed[16015]: vixie:0 checkpoint
-               seconds 1381 offered 596 accepted 274 
-               refused 225 rejected 97
-.fi
-.PP
-If you only open a maximum of one Connection to a remote, then there will
-be a close correlation between Connection numbers and Host numbers, but in
-general you can't tie the two sets of number together in any easy or very
-meaningful way. When a Connection closes it will always log its stats.
-.PP
-If all Connections for a Host get closed together, then the Host logs its
-stats as ``final'' and resets its counters. If the feed is so busy that
-there's always at least one Connection open and running, then after some
-amount of time (set via the config file), the Host stats are logged as
-final and reset. This is to make generating higher level stats from log
-files, by other programs, easier.
-.PP
-There is one log entry that is emitted for a Host just after its last
-Connection closes and innfeed is preparing to exit. This entry contains
-counts over the entire life of the process. The ``seconds'' field is from the
-first time a Connection was successfully built, or the first time spooling
-started. If a Host has been completely idle, it will have no such log entry.
-.PP
-.nf
-  May 23 12:49:08 data innfeed[16015]: decwrl global 
-               seconds 1381 offered 34 accepted 22 
-               refused 3 rejected 7 missing 0
-.fi
-.PP
-The final log entry is emitted immediately before exiting. It contains a
-summary of the statistics over the entire life of the process.
-.PP
-.nf
-  Feb 13 14:43:41 data innfeed-0.9.4[22344]: ME global
-                seconds 15742 offered 273441 accepted 45750
-                refused 222008 rejected 3334 missing 217
-.fi
-.PP
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH OPTIONS
-.TP
-.B \-a
-The ``\fI\-a\fP'' flag is used to specify the top of the article spool
-tree. Innfeed does a chdir(2) to this directory, so it should probably be
-an absolute path. The default is <patharticles\ in\ inn.conf>.
-.TP
-.B \-b
-The ``\fI\-b\fP'' flag may be used to specify a different directory for backlog
-file storage and retrieval. If the path is relative then it is relative
-to <pathspool\ in\ inn.conf>. The default is ``\fIinnfeed\fP''.
-.TP
-.B \-c
-The ``\fI\-c\fP'' flag may be used to specify a different config file from the
-default value. If the path is relative then it is relative to
-<pathetc\ in\ inn.conf>. The default is ``\fIinnfeed.conf\fP''.
-.TP
-.B \-C 
-The ``\fI\-C\fP'' flag is used to have innfeed simply check the config
-file, report on any errors and then exit.
-.TP
-.B \-d 
-The ``\fI\-d\fP'' flag may be used to specify the initial logging level. All
-debugging messages go to stderr (which may not be what you want, see the
-``\fI\-l\fP'' flag below).
-.TP
-.B \-e
-The ``\fI\-e\fP'' flag may be used to specify the size limit (in bytes) for the
-\fI\%.output\fP backlog files innfeed creates. If the output file gets bigger
-than 10% more than the given number, innfeed will replace the output file
-with the tail of the original version. The default value is 0, which means
-there is no limit.
-.TP
-.B \-h
-Use the ``\fI\-h\fP'' flag to print the usage message.
-.TP
-.B \-l
-The  ``\fI\-l\fP'' flag may be used to specify a different log file from
-stderr. As innd starts innfeed with stderr attached to /dev/null, using this
-option can be useful in catching any abnormal error messages, or any
-debugging messages (all ``normal'' errors messages go to syslog).
-.TP
-.B \-M
-If innfeed has been built with mmap support, then the ``\fI\-M\fP'' flag
-turns OFF the use of mmap(); otherwise it has no effect.
-.TP
-.B \-m
-The ``\fI\-m\fP'' flag is used to turn on logging of all missing
-articles. Normally if an article is missing, innfeed keeps a count, but
-logs no further information. When this flag is used, details about
-message-id and expected pathname are logged.
-.TP
-.B \-o
-The ``\fI\-o\fP'' flag sets a value of the maximum number of bytes of article
-data innfeed is supposed to keep in memory. This doesn't work properly yet.
-.TP
-.B \-p 
-The ``\fI\-p\fP'' flag is used to specify the filename to write the pid of the
-process into. A relative path is relative to <pathrun\ in\ inn.conf>. The
-default is ``\fIinnfeed.pid\fP''.
-.TP
-.B \-S
-The ``\fI\-S\fP'' flag specifies the name of the file to write the periodic
-staus to. If the path is relative it is considered relative to
-<pathlog\ in\ inn.conf>. The default is ``\fIinnfeed.status\fP''.
-.TP
-.B \-v
-When the ``\fI\-v\fP'' flag is given, version information is printed to stderr
-and then innfeed exits.
-.TP
-.B \-x
-The ``\fI\-x\fP'' flag is used to tell innfeed not to expect any article
-information from innd but just to process any backlog files that exist and
-then exit.
-.TP
-.B \-y
-The ``\fI\-y\fP'' flag is used to allow dynamic peer binding. If this flag is
-used and article information is received from innd that specifies an
-unknown peer, then the peer name is taken to be the IP name too, and an
-association with it is created. Using this it is possible to only 
-have the global defaults in the
-.I innfeed.conf
-file, provided the peername as used by innd is the same as the ip name.
-Note that
-.I innfeed
-with ``\fI\-y\fP'' and no peer in
-.I innfeed.conf
-would cause a problem that
-.I innfeed
-drops the first article.
-.TP
-.B \-z
-The ``\fI\-z\fP'' flag is used to cause each connection, in a parallel feed
-configuration, to report statistics when the controller for the connections
-prints its statistics.
-.TP
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH BUGS
-.PP
-When using the ``-x'' option, the config file entry's
-``initial-connections'' field will be the total number of connections
-created and used, no matter how many big the batch file, and no
-matter how big the ``max-connectiond'' field specifies. Thus a value
-of 0 for ``initial-connections'' means nothing will happen in ``-x''
-mode.
-.PP
-Innfeed does not automatically grab the file out of out.going--this needs
-to be prepared for it by external means.
-.PP
-Probably too many other bugs to count.
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH FILES
-innfeed.conf   config file.
-.br
-innfeed                directory for backlog files.
-.\"
-.\"
-.\"
-.\"
-.\"
-.SH HISTORY
-Written by James Brister <brister@vix.com> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innfeed.1 7798 2008-04-26 08:47:01Z iulius $
-.SH SEE ALSO
-.IR innfeed.conf(5)
diff --git a/doc/man/innfeed.conf.5 b/doc/man/innfeed.conf.5
deleted file mode 100644 (file)
index 272cb1a..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-.\" -*- nroff -*-
-.\"
-.\" Author:       James A. Brister <brister@vix.com> -- berkeley-unix --
-.\" Start Date:   Sun, 21 Jan 1996 00:47:37 +1100
-.\" Project:      INN -- innfeed
-.\" File:         innfeed.conf.5
-.\" RCSId:        $Id: innfeed.conf.5 7778 2008-04-17 21:27:22Z iulius $
-.\" Description:  Man page for innfeed.conf(5)
-.\" 
-.TH innfeed.conf 5
-.SH NAME
-innfeed.conf \- configuration file for innfeed
-.SH DESCRIPTION
-.PP
-This man page describes the configuration file for version 1.0 of
-innfeed. This format has changed dramatically since version 0.9.3.
-.PP
-The file 
-.B innfeed.conf
-is used to control the innfeed(1) program. It is a fairly free-format file
-that consists of three types of entries: \fIkey/value\fP, \fIpeer\fP and
-\fIgroup\fP.
-Comments are from the hash character ``#'' to the end of the line.
-.PP
-\fIKey/value\fP entries are a keyword and a value separated by a colon
-(which can itself be surrounded by whitespace). For example:
-.PP
-.RS
-.nf
-max-connections: 10
-.fi
-.RE
-.PP
-A legal
-key starts with a letter and contains only letters, digits, and ``_'',
-``-''.
-.LP 
-There are 5 different type of values: integers, floating-point numbers,
-characters, booleans, and strings. Integer and floating point numbers are
-as to be expected except that exponents in floating point numbers are not
-supported. A boolean value is either ``true'' or ``false'' (case is not
-significant). A character value is a single-quoted character as defined by
-the C-language. A string value is any other sequence of characters. If the
-string needs to contain whitespace, then it must be quoted with double
-quotes, and uses the same format for embedding non-printing characters as
-normal C-language string.
-.PP
-Peer entries look like:
-.PP
-.RS
-.nf
-peer <name> {
-        # body ...
-}
-.fi
-.RE
-.PP
-The word ``peer'' is required. The ``<name>'' is the same as the site name
-in INN's newsfeeds file. The body of a peer entry contains some number
-(possibly zero) of key/value entries.
-.PP
-Group entries look like:
-.PP
-.RS
-.nf
-group <name> {
-       # body 
-}
-.fi
-.RE
-.PP 
-The word ``group'' is required. The ``<name>'' is any string valid as a
-key. The body of a group entry contains any number of the three types of
-entries. So key/value pairs can be defined inside a group, and peers can be
-nested inside a group, and other groups can be nested inside a group.
-.PP
-Key/value entries that are defined outside of all peer and group entries
-are said to be at ``global scope''. There are global key/value entries that
-apply to the process as a whole (for example the location of the backlog
-file directory), and there are global key/value entries that act as
-defaults for peers. When innfeed looks for a specific value in a peer entry
-(for example, the maximum number of connections to set up), if the value is
-not defined in the peer entry, then the enclosing groups are examined for
-the entry (starting at the closest enclosing group). If there are no
-enclosing groups, or the enclosing groups don't define the key/value, then
-the value at global scope is used.
-.PP
-A small example could be:
-.PP
-.RS
-.nf
-# Global value applied to all peers that have 
-# no value of their own.
-max-connections: 5
-
-# A peer definition. ``uunet'' is the name used by innd in 
-# the newsfeeds file.
-peer uunet {
-       ip-name: usenet1.uu.net
-}
-
-peer vixie {
-        ip-name: gw.home.vix.com
-        max-connections: 10      # override global value.
-}
-
-# A group of two peers who can handle more connections 
-# than normal
-group fast-sites {
-       max-connections: 15
-
-       # Another peer. The ``max-connections'' value from the
-       # ``fast-sites'' group scope is used. The ``ip-name'' value
-       # defaults to the peer's name.
-       peer data.ramona.vix.com { 
-       }
-
-       peer bb.home.vix.com {
-               max-connections: 20     # he can really cook.
-       }
-}
-.fi
-.RE
-.PP
-Given the above configuration file, the defined peers would have the
-following values for the ``max-connections'' key.
-.PP
-.RS
-.nf
-uunet                  5
-vixie                 10
-data.ramona.vix.com   15
-bb.home.vix.com       20
-.fi
-.RE
-.PP
-Innfeed ignores key/value pairs it is not interested in. Some config file
-values can be set via a command line option, in which case that setting
-overrides the settings in the file.
-.PP
-Config files can be included in other config files via the syntax:
-.sp 1
-.nf
-.RS
-$INCLUDE filename
-.RE
-.fi
-.sp 1
-There is a maximum nesting depth of 10.
-.PP
-For a fuller example config file, see the supplied \fIinnfeed.conf\fP.
-.SH "GLOBAL VALUES"
-.PP
-The following listing show all the keys that apply to the process as
-whole. These are not required (compiled-in defaults are used where needed).
-.TP
-.B news-spool
-This key requires a pathname value. It specifies where the top of the
-article spool is. This corresponds to the ``\fI\-a\fP'' command-line
-option.
-.TP
-.B input-file
-This key requires a pathname value. It specifies the pathname (relative to
-the \fBbacklog-directory\fP) that should be read in funnel-file mode. This
-corresponds to giving a filename as an argument on the command-line (i.e.
-its presence also implies that funnel-file mode should be used).
-.TP
-.B pid-file
-This key requires a pathname value. It specifies the pathname (relative to
-the \fBbacklog-directory\fP) where the pid of the innfeed process should be
-stored. This corresponds to the ``\fI\-p\fP'' command-line option.
-.TP
-.B debug-level
-This key defines the debug level for the process. A non-zero number
-generates a lot of messages to stderr, or to the config-defined ``log-file''.
-This corresponds to the ``\fI\-d\fP'' command-line option.
-.TP
-.B use-mmap
-This key requires a boolean value. It specifies whether mmaping should be
-used if innfeed has been built with mmap support. If article data on disk
-is not in NNTP-ready format (CR/LF at the end of each line), then after
-mmaping the article is read into memory and fixed up, so mmaping has no
-positive effect (and possibly some negative effect depending on your
-system), and so in such a case this value should be \fIfalse\fP. This
-corresponds to the ``\fI\-M\fP'' command-line option.
-.TP
-.B log-file
-This key requires a pathname value. It specifies where any logging messages
-that couldn't be sent via syslog(3) should go (such as those generated when
-a positive value for ``\fBdebug-value\fP'', is used). This corresponds to 
-the ``\fI\-l\fP'' command-line option. A relative pathname is relative to
-the ``\fBbacklog-directory\fP'' value.
-.\" .TP
-.\" .B initial-sleep
-.\" This key requires a positive integer value. It specifies how many seconds
-.\" innfeed should sleep at startup before attempting to take out its locks. On
-.\" fast machines and with innfeed handling many connections, it can take too
-.\" long for innfeed to recognise that its input has been closed, and that it
-.\" should release any locks it holds.
-.\"..................................................
-.TP
-.B backlog-directory
-This key requires a pathname value. It specifies where the current innfeed
-process should store backlog files. This corresponds to the ``\fI\-b\fP''
-command-line option.
-.TP
-.B backlog-highwater
-This key requires a positive integer value. It specifies how many articles
-should be kept on the backlog file queue before starting to write new
-entries to disk.
-.TP
-.B backlog-ckpt-period
-This key requires a positive integer value. It specifies how many seconds
-between checkpoints of the input backlog file. Too small a number will mean
-frequent disk accesses, too large a number will mean after a crash innfeed
-will re-offer more already-processed articles than necessary.
-.TP
-.B backlog-newfile-period
-This key requires a positive integer value. It specifies how many seconds
-before each checks for externally generated backlog files that are to be
-picked up and processed.
-.TP
-.B backlog-rotate-period
-This key requires a positive integer value. It specifies how many seconds
-elapse before
-.B innfeed
-checks for a manually created backlog file and moves the output backlog
-file to the input backlog file.
-.\"..................................................
-.TP
-.B dns-retry
-This key requires a positive integer value. It defines the number of seconds
-between attempts to re-lookup host information that previous failed to be
-resolved.
-.TP
-.B dns-expire
-This key requires a positive integer value. It defines the number of seconds
-between refreshes of name to address DNS translation. This is so long-running
-processes don't get stuck with stale data, should peer ip addresses change.
-.TP
-.B close-period
-This key requires a positive integer value. It is the maximum number of
-seconds a connection should be kept open. Some NNTP servers don't deal well
-with connections being held open for long periods.
-.TP
-.B gen-html
-This key requires a boolean value. It specifies whether the
-\fBstatus-file\fP should be HTML-ified.
-.TP
-.B status-file
-This key requires a pathname value. It specifies the pathname (relative to
-the \fBbacklog-directory\fP) where the periodic status of the innfeed
-process should be stored. This corresponds to the ``\fI\-S\fP''
-command-line option.
-.TP
-.B connection-stats
-This key requires a boolean value. If the value is true, then whenever the
-transmission statistics for a peer are logged, then each active connection
-logs its own statistics. This corresponds to the ``\fI\-z\fP''
-command-line option.
-.TP
-.B host-queue-highwater
-This key requires a positive integer value. It defines how many articles
-will be held internally for a peer before new arrivals cause article
-information to be spooled to the backlog file.
-.TP
-.B stats-period
-This key requires a positive integer value. It defines how many seconds
-innfeed waits between generating statistics on transfer rates.
-.TP
-.B stats-reset
-This key requires a positive integer value. It defines how many seconds
-innfeed waits before resetting all internal transfer counters back to zero
-(after logging one final time). This is so a innfeed-process running more
-than a day will generate ``final'' stats that will be picked up by logfile
-processing scripts.
-.\"..................................................
-.TP
-.B initial-reconnect-time
-This key requires a positive integer value. It defines how many seconds to
-first wait before retrying to reconnect after a connection failure. If the
-next attempt fails too, then the reconnect time is approximately doubled
-until the connection succeeds, or \fBmax-reconnection-time\fP is reached.
-.TP
-.B max-reconnect-time
-This key requires an integer value. It defines the maximum number of
-seconds to wait between attempt to reconnect to a peer. The initial value
-for reconnection attempts is defined by \fBinitial-reconnect-time\fP, and
-it is doubled after each failure, up to this value.
-.TP
-.B stdio-fdmax
-This key requires a non-negative integer value. If the value is greater
-than zero, then whenever a network socket file descriptor is created and
-it has a value \fIless than\fP this, the file descriptor will be dup'ed to
-bring the value up greater than this. This is to leave lower numbered file
-descriptors free for stdio. Certain systems, Sun's in particular, require
-this. SunOS 4.1.x usually requires a value of 128 and Solaris requires a
-value of 256. The default if this is not specified, is 0.
-.\"..................................................
-.SH "GLOBAL PEER DEFAULTS"
-.PP
-All the key/value pairs mentioned in this section must be specified at
-global scope. They may also be specified inside a group or peer
-definition. Note that when peers are added dynamically (i.e. when
-innfeed receives an article for an unspecified peer), it will add
-the peer site using the parameters specified at global scope.
-.TP
-.B article-timeout
-This key requires a non-negative integer value. If no articles need to be
-sent to the peer for this many seconds, then the peer is considered idle
-and all its active connections are torn down.
-.TP
-.B response-timeout
-This key requires a non-negative integer value. It defines the maximum
-amount of time to wait for a response from the peer after issuing a
-command.
-.TP
-.B initial-connections
-This key requires a non-negative integer value. It defines the number of
-connections to be opened immediately when setting up a peer binding. A
-value of 0 means no connections will be created until an article needs to
-be sent.
-.TP
-.B max-connections
-This key requires positive integer value. It defines the maximum number of
-connections to run in parallel to the peer. A value of zero specifies an
-unlimited number of maximum connections. In general use of an unlimited
-number of maximum connections is not recommended. Do not ever set
-\fBmax-connections\fP to zero with \fBdynamic-method\fP 0 set, as this will
-saturate peer hosts with connections. [ Note that in previous versions
-of innfeed, a value of 1 had a special meaning. This is no longer the case,
-1 means a maximum of 1 connection ].
-.TP
-.B dynamic-method
-This key requires an integer value between 0 and 3. It controls how connections
-(up to max-connections) are opened, up to the maximum specified by
-\fBmax-connections\fP. In general (and specifically, with \fBdynamic-method\fP
-0), a new connection is opened when the current number of connections is
-below \fBmax-connections\fP, and an article is to be sent while no current
-connections are idle. Without further restraint (i.e. using
-\fBdynamic-method\fP 0), in practice this means that \fBmax-connections\fP
-connections are established while articles are being sent. Use of other
-\fBdynamic-method\fP settings imposes a further limit on the amount of
-connections opened below that specified by \fBmax-connections\fP. This
-limit is calculated in different ways, depending of the value of
-\fBdynamic-method\fP.
-Users should note that adding additional connections is not always
-productive - just because opening twice as many connections results
-in a small percentage increase of articles accepted by the remote peer,
-this may be at considerable resource cost both locally and at the remote
-site, whereas the remote site might well have received the extra articles
-sent from another peer a fraction of a second later. Opening large
-numbers of connections is considered antisocial.
-The meanings of the various settings are:
-.RS
-.TP
-.B 0 no method
-Increase of connections up to \fBmax-connections\fP is unrestrained.
-.TP
-.B 1 maximize articles per second
-Connections are increased (up to \fBmax-connections\fP) and decreased so as
-to maximize the number of articles per second sent, while using the fewest
-connections to do this.
-.TP
-.B 2 set target queue length
-Connections are increased (up to \fBmax-connections\fP) and decreased so as
-to keep the queue of articles to be sent within the bounds set by
-\fBdynamic-backlog-low\fP and \fBdynamic-backlog-high\fP,
-while using the minimum resources possible.
-As the queue will tend to fill if the site is not keeping up, this method
-ensures that the maximum number of articles are offered to the peer
-while using the minimum number of connections to achieve this.
-.TP
-.B 3 combination
-This method uses a combination of methods 1 and 2 above. For sites
-accepting a large percentage of articles, method 2 will be used to
-ensure these sites are offered as complete a feed as possible. For sites
-accepting a small percentage of articles, method 1 is used, to minimize
-remote resource usage. For intermediate sites, an appropriate combination
-is used.
-.RE
-.TP
-.B dynamic-backlog-low
-This key requires an integer value between 0 and 100.  It represents (as a
-percentage) the low water mark for the host queue. If the host queue falls
-below this level while using \fBdynamic-method\fP 2 or 3, and if 2 or more
-connections are open, innfeed will attempt to drop connections to the host.
-An IIR filter is applied to the value to prevent connection flap (see
-\fBdynamic-filter\fP). A value of 25.0 is recommended. This value
-must be smaller than \fBdynamic-backlog-high\fP.
-.TP
-.B dynamic-backlog-high
-This key requries an integer value between 0 and 100.  It represents (as a
-percentage) the high water mark for the host queue. If the host queue rises
-above this level while using \fBdynamic-method\fP 2 or 3, and if less than
-\fBmax-connections\fP are open to the host, innfeed will attempt
-to open further connections to the host. An IIR filter is applied to the value
-to prevent connection flap (see \fBdynamic-filter\fP). A value of 50.0
-is recommended.  This value must be larger than \fBdynamic-backlog-low\fP.
-.TP
-.B dynamic-backlog-filter
-This key requires a floating-point value between 0 and 1.  It represents the
-filter coefficient used by the IIR filter used to implement
-\fBdynamic-method\fP 2 and 3.
-The recommended value of this filter is 0.7, giving a time
-constant of 1/(1-0.7) articles. Higher values will result in slower
-response to queue fullness changes, lower values in faster response.
-.TP
-.B max-queue-size
-This key requires a positive integer value. It defines the maximum number
-of articles to process at one time when using streaming to transmit to a
-peer. Larger numbers mean more memory consumed as articles usually get
-pulled into memory (see the description of \fBuse-mmap\fP).
-.TP
-.B streaming
-This key requires a boolean value. It defines whether streaming commands
-are used to transmit articles to the peers.
-.TP
-.B no-check-high
-This key requires a floating-point number which must be in the range [0.0,
-100.0]. When running transmitting with the streaming commands, innfeed
-attempts an optimization called ``no-CHECK'' mode. This involves \fInot\fP
-asking the peer if it wants the article, but just sending it. This
-optimization occurs when the percentage of the articles the peer has
-accepted gets larger than this number. If this value is set to 100.0, then
-this effectively turns off no-CHECK mode, as the percentage can never get
-above 100.0. If this value is too small, then the number of articles the
-peer rejects will get bigger (and your bandwidth will be wasted). A value
-of 95.0 usually works pretty well. NOTE: In innfeed 0.9.3 and earlier this
-value was in the range [0.0, 9.0].
-.TP
-.B no-check-low:
-This key requires a floating-point number which must be in the range [0.0,
-100.0), and it must be smaller that the value for \fBno-check-high\fP. When
-running in no-CHECK mode, as described above, if the percentage of articles
-the remote accepts drops below this number, then the no-CHECK optimization
-is turned off until the percentage gets above the \fBno-check-high\fP value
-again. If there is small difference between this and the
-\fBno-check-high\fP value (less than about 5.0), then innfeed may
-frequently go in and out of no-CHECK mode. If the difference is too big,
-then it will make it harder to get out of no-CHECK mode when necessary
-(wasting bandwidth). Keeping this to between 5.0 and 10.0 less than
-\fBno-check-high\fP usually works pretty well.
-.TP
-.B no-check-filter
-This is a floating point value representing the time constant, in articles,
-over which the CHECK / no-CHECK calculations are done. The recommended
-value is 50.0 which will implement an IIR filter of time constant 50. This
-roughly equates to making a decision about the mode over the previous
-50 articles. A higher number will result in a slower response to changing
-percentages of articles accepted; a lower number will result in a faster
-response.
-.TP
-.B bindaddress
-This key requires a string value.  It specifies which outgoing IPv4 address
-innfeed should bind the local end of its connection to.
-Must be an IPv4 address in dotted-quad format (nnn.nnn.nnn.nnn), "any",
-or "none".  If not set or set to "any", innfeed defaults
-to letting the kernel choose this address.
-If set to "none", innfeed will not use IPv4 for outgoing connections
-to peers in this scope (i.e. it forces IPv6).
-The default value is unset.
-.TP
-.B bindaddress6
-This key requires a string value.  It behaves like \fBbindaddress\fP except
-for outgoing IPv6 connections.  Must be in numeric IPv6 format, "any",
-or "none".  If set to "none", innfeed will not use IPv6 for outgoing
-connections to peers in this scope.  A value containing colons must be
-enclosed in double quotes.
-.TP
-.B port-number
-This key requires a positive integer value. It defines the tcp/ip port
-number to use when connecting to the remote.
-.TP
-.B force-ipv4
-This key requires a boolean value. By default it is set to false.
-Setting it to true is the same as setting "bindaddress6: none"
-and removing "bindaddress: none" if it was set.
-.TP
-.B drop-deferred
-This key requires a boolean value. By default it is set to false. When
-set to true, and a peer replies with code 431 or 436 (try again later) just
-drop the article and don't try to re-send it. This is useful for some
-peers that keep on deferring articles for a long time to prevent innfeed
-from trying to offer the same article over and over again.
-.TP
-.B min-queue-connection
-This key requires a boolean value. By default it is set to false. When
-set to true, innfeed will attempt to use a connection with the least queue
-size (or the first empty connection).  If this key is set to true, it is
-recommended that \fBdynamic-method\fP be set to 0. This allows for article
-propagation with the least delay.
-.TP
-.B no-backlog
-This key requires a boolean value. It specifies whether spooling should
-be enabled (false, the default) or disabled (true). Note that when no-backlog
-is set, articles reported as "spooled" are actually silently discarded.
-.TP
-.B backlog-limit
-This key requires a non-negative integer value. If the number is 0 then
-backlog files are allowed to grown without bound when the peer is unable to
-keep up with the article flow. If this number is greater than 0 then it
-specifies the size (in bytes) the backlog file should get truncated to when
-the backlog file reaches a certain limit. The limit depends on whether
-\fBbacklog-factor\fP or \fBbacklog-limit-highwater\fP is used.
-.TP
-.B backlog-factor
-This key requires a floating point value, which must be larger than 1.0. It
-is used in conjunction with the peer key \fBbacklog-limit\fP. If
-\fBbacklog-limit\fP has a value greater than zero, then when the backlog
-file gets larger than the value \fBbacklog-limit * backlog-factor\fP, then
-the backlog file will be truncated to the size \fBbacklog-limit\fP. For
-example if \fBbacklog-limit\fP has a value of 1000000, and
-\fBbacklog-factor\fP has a value of 2.0, then when the backlogfile gets to
-be larger than 2000000 bytes in size, it will be truncated to 1000000 bytes.
-The front
-portion of the file is removed, and the trimming happens on line boundaries,
-so the final size may be a bit less than this number. If
-\fBbacklog-limit-highwater\fP is defined too, then \fBbacklog-factor\fP
-takes precedence.
-.TP
-.B backlog-limit-highwater
-This key requires a positive integer value that must be larger than the
-value for \fBbacklog-limit\fP. If the size of the backlog file gets larger
-than this value (in bytes), then the backlog file will be shrunk down to
-the size of \fBbacklog-limit\fP. If both \fBbacklog-factor\fP and
-\fBbacklog-limit-highwater\fP are defined, then the value of
-\fBbacklog-factor\fP is used.
-.TP
-.B backlog-feed-first
-This key requires a boolean value. By default it is set to false. When set
-to true, the backlog is fed before new files. This is intended to enforce
-in-order delivery, so setting this to true when initial-connections or
-max-connections is more than 1 is inconsistent.
-.TP
-.B username
-This key requires a string value.  If the value is defined, then innfeed
-tries to authenticate by ``AUTHINFO USER'' and this value used for user name.
-\fBpassword\fP must also be defined, if this key is defined.
-.TP
-.B password
-This key requires a string value.  The value is the password
-used for ``AUTHINFO PASS''.
-\fBusername\fP must also be defined, if this key is defined.
-.TP
-.B deliver
-This key is used with imapfeed to authenticate to a remote host.  It is optional.
-There are several parameters that must be included with deliver:
-.RS
-.TP
-.B deliver-authname
-The authname is who you want to authenticate as.
-.TP
-.B deliver-password
-This is the appropriate password for authname.
-.TP
-.B deliver-username
-The username is who you want to "act" as, that is, who is actually
-going to be using the server.
-.TP
-.B deliver-realm
-In this case, the "realm" is the realm in which the specified authname
-is valid.  Currently this is only needed by the DIGEST-MD5 SASL
-mechanism.
-.TP
-.B deliver-rcpt-to
-A printf-style format string for creating the envelope recipient address.
-The pattern MUST include a single string specifier which will be
-replaced with the newgroup (e.g "bb+%s").  The default is "+%s".
-.TP
-.B deliver-to-header
-An optional printf-style format string for creating a To: header to be
-prepended to the article.  The pattern MUST include a single string
-specifier which will be replaced with the newgroup (e.g
-"post+%s@domain").  If not specified, the To: header will not be
-prepended.
-.RE
-.\"..................................................
-.SH "PEER VALUES"
-As previously explained, the peer definitions can contain redefinitions of
-any of the key/value pairs described in the \fBGLOBAL PEER DEFAULTS\fP
-section above. There is one key/value pair that is specific to a peer
-definition.
-.TP
-.B ip-name
-This key requires a word value. The word is the host's FQDN, or the dotted
-quad ip-address. If this value is not specified then the name of the peer
-is taken to also be its ip-name. See the entry for
-data.ramona.vix.com in the example below.
-.\"..................................................
-.SH RELOADING
-.PP
-If innfeed gets a SIGHUP signal, then it will reread the config file. All
-values at global scope except for ``\fBbacklog-directory\fP'' can be
-changed (although note that ``\fBbindaddress\fP'' and
-``\fBbindaddress6\fP'' changes will only affect new connections). Any new
-peers are added and any missing peers have their connections closed.
-.\"..................................................
-.SH EXAMPLE
-.PP
-Below is the sample innfeed.conf file.
-.RS
-.nf
-#
-# innfeed.conf file. See the comment block at the
-# end for a fuller description.
-#
-
-##
-## Global values. Not specific to any peer. These
-## are optional, but if used will override the
-## compiled in values. Command-line options used
-## will override these values.
-##
-
-pid-file:               innfeed.pid
-debug-level:            0
-use-mmap:               false
-log-file:               innfeed.log
-stdio-fdmax:            0
-
-backlog-directory:      innfeed
-backlog-rotate-period:  60
-backlog-ckpt-period:    30
-backlog-newfile-period: 600
-
-dns-retry:              900
-dns-expire:             86400
-close-period:           3600
-gen-html:               false
-status-file:            innfeed.status
-connection-stats:       false
-host-queue-highwater:   200
-stats-period:           600
-stats-reset:            43200
-
-max-reconnect-time:     3600
-initial-reconnect-time: 30
-
-
-##
-## Defaults for all peers. These must all exist at
-## global scope. Any of them can be redefined
-## inside a peer or group definition.
-##
-
-article-timeout:        600
-response-timeout:       300
-initial-connections:    1
-max-connections:        5
-max-queue-size:         25
-streaming:              true
-no-check-high:          95.0
-no-check-low:           90.0
-no-check-filter:        50.0
-port-number:            119
-backlog-limit:          0
-backlog-factor:         1.10
-backlog-limit-highwater:0
-dynamic-method:         3
-dynamic-backlog-filter: 0.7
-dynamic-backlog-low:    25.0
-dynamic-backlog-high:   50.0
-no-backlog:             false
-
-##
-## Peers. 
-##
-peer decwrl {
-        ip-name:                news1.pa.dec.com
-}
-
-peer uunet {
-        ip-name:                news.uunet.uu.net
-        max-connections:        10
-}
-
-peer data.ramona.vix.com {
-        # ip-name defaults to data.ramona.vix.com
-        streaming:              false
-}
-
-peer bb.home.vix.com {
-        ip-name:        192.5.5.33
-}
-
-
-
-# Blank lines are ignored. Everything after a '#'
-# is ignored too.
-#
-# Format is:
-#               key : value
-#
-# See innfeed.conf(5) for a description of
-# necessary & useful keys. Unknown keys and their
-# values are ignored.
-#
-# Values may be a integer, floating-point, c-style
-# single-quoted characters, boolean, and strings.
-#
-# If a string value contains whitespace, or
-# embedded quotes, or the comment character
-# (``#''), then the whole string must be quoted
-# with double quotes.  Inside the quotes, you may
-# use the standard c-escape sequence
-# (\\t,\\n,\\r,\\f,\\v,\\",\\').
-#
-# Examples:
-#       eg-string:      "New\\tConfig\\tfile\\n"
-#       eg-long-string: "A long string that goes
-#                       over multiple lines. The
-#                       newline is kept in the
-#                       string except when quoted 
-#                       with a backslash \\
-#                       as here."
-#       eg-simple-string: A-no-quote-string
-#       eg-integer:     10
-#       eg-boolean:     true
-#       eg-char:        'a'
-#       eg-ctrl-g:      '\\007'
-
-.fi
-.RE
-.SH HISTORY
-Written by James Brister <brister@vix.com> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innfeed.conf.5 7778 2008-04-17 21:27:22Z iulius $
-.SH SEE ALSO
-innfeed(1), newsfeeds(5)
diff --git a/doc/man/innmail.1 b/doc/man/innmail.1
deleted file mode 100644 (file)
index 2b89713..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-.\" 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 "INNMAIL 1"
-.TH INNMAIL 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-innmail \- Simple mail\-sending program
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinnmail\fR [\fB\-h\fR] [\fB\-s\fR \fIsubject\fR] \fIaddress\fR [\fIaddress\fR ...]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinnmail\fR is a Perl script intended to provide the non-interactive
-mail-sending functionality of \fImail\fR\|(1) while avoiding nasty security
-problems.  It takes the body of a mail message on standard input and sends
-it to the specified addresses by invoking the value of \fImta\fR in
-\&\fIinn.conf\fR.
-.PP
-At least one address (formatted for the \s-1MTA\s0 specified in \fIinn.conf\fR, if it
-matters) is required.  \fBinnmail\fR will sanitize the addresses so that they
-contain only alphanumerics and the symbols \f(CW\*(C`@\*(C'\fR, \f(CW\*(C`.\*(C'\fR, \f(CW\*(C`\-\*(C'\fR, \f(CW\*(C`+\*(C'\fR, \f(CW\*(C`_\*(C'\fR,
-and \f(CW\*(C`%\*(C'\fR.
-.PP
-\&\fBinnmail\fR was written to be suitable for the \fImailcmd\fR setting in
-\&\fIinn.conf\fR.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Gives usage information.
-.IP "\fB\-s\fR \fIsubject\fR" 4
-.IX Item "-s subject"
-Sets the Subject: header of the message.  A warning is issued if this
-option is omitted.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-This sends a one-line message to the local user \f(CW\*(C`joe\*(C'\fR:
-.PP
-.Vb 1
-\&    echo "A one\-line message." | innmail \-s "Simple message" joe
-.Ve
-.PP
-\&\fBinnmail\fR by default is used by \s-1INN\s0 for sending nightly reports and
-control message reports.
-.SH "BUGS"
-.IX Header "BUGS"
-\&\fBinnmail\fR fails on addresses that begin with \f(CW\*(C`\-\*(C'\fR, although one might
-hope that the news server will not need to contact any such addresses.
-.PP
-There are many \*(L"correct\*(R" addresses that will be silently modified by the
-sanitization process.  A news administrator should be careful to use
-particularly sane addresses if they may be passed to \fBinnmail\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBinnmail\fR was written by James Brister <brister@vix.com> for
-InterNetNews.  This manual page was originally written by Jeffrey
-M. Vinocur.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fImail\fR\|(1).
diff --git a/doc/man/innreport.8 b/doc/man/innreport.8
deleted file mode 100644 (file)
index 53c0562..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-.TH innreport 8
-.SH NAME
-innreport \- summarize INN log files.
-.SH SYNOPSIS
-innreport -f innreport.conf [ -[no]options ] [ logfiles ]
-.SH DESCRIPTION
-.I Innreport
-is a
-.IR perl (1)
-script that summarizes INN log files. It is normally invoked by
-.IR scanlogs (8).
-Supported programs are
-.IR innd (8), 
-.IR innfeed (1), 
-.IR innxmit (8), 
-.I nntplink, 
-.IR nnrpd (8), 
-.IR batcher (8), 
-.IR rnews (1), 
-.IR crosspost (8)
-and a few others.
-.SH OPTIONS
-There are lots of 'em. Run innreport with ``\-h'' or ``\-help'' to get full
-details.
-.SH HISTORY
-Written by Fabien Tassin <fta@sofaraway.org> for InterNetNews. 
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innreport.8 4320 2001-01-12 16:57:49Z kondou $
-
-.SH "SEE ALSO"
-innd(8),
-innfeed(8),
-innxmit(8),
-news.daily(8),
-newslog(5),
-nnrpd(8),
-scanlogs(8),
-writelog(8).
diff --git a/doc/man/innstat.8 b/doc/man/innstat.8
deleted file mode 100644 (file)
index 194cf78..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-.TH INNSTAT 8
-.SH NAME
-innstat \- print snapshot of INN system
-.SH SYNOPSIS
-.B innstat
-.SH DESCRIPTION
-The
-.I innstat
-script prints a snapshot of the INN system.
-It displays the operating mode of the server,
-as well as disk usage and the status of all log and lock files.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innstat.8 584 1998-04-09 15:16:17Z mibsoft $
-.SH "SEE ALSO"
-innd(8),
-news.daily(8),
-newslog(5),
-nnrpd(8)
diff --git a/doc/man/innupgrade.8 b/doc/man/innupgrade.8
deleted file mode 100644 (file)
index 38cf082..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-.\" 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 "INNUPGRADE 8"
-.TH INNUPGRADE 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-innupgrade \- Upgrade INN configuration files
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBinnupgrade\fR \fIdirectory\fR
-.PP
-\&\fBinnupgrade\fR [\fB\-t\fR \fItype\fR] \fB\-f\fR \fIfile\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBinnupgrade\fR is intended to be run during a major upgrade of \s-1INN\s0 to fix
-the configuration files with any required changes.  If given a directory,
-it will scan that directory for any files that it has updates defined for,
-try to perform those updates, and replace the files with updated versions
-if applying the updates resulted in any changes.  The old versions of the
-files will be saved with a \f(CW\*(C`.OLD\*(C'\fR extension.
-.PP
-If the \fB\-f\fR flag is used, only that file will be updated.  If the file
-name doesn't match the standard file name of an \s-1INN\s0 configuration file,
-the optional \fB\-t\fR flag may be given to specify the type.  See
-\&\*(L"\s-1EXAMPLES\s0\*(R" for an example of this.
-.PP
-Currently, \fBinnupgrade\fR knows how to apply the following updates:
-.IP "\(bu" 2
-\&\fIinn.conf\fR:  Quote values with whitespace and comment out keys with no
-values, required for the change in configuration parsers introduced in \s-1INN\s0
-2.4.  The new format is not backward compatible with the previous parser,
-since the previous parser will include the double-quotes in the value of
-the parameter.
-.PP
-Normally, \fBinnupgrade\fR should be run on the \fIpathetc\fR directory after
-any upgrade of \s-1INN\s0 other than a patch release (any upgrade that changes
-the first or second version numbers).  This may occur automatically during
-the upgrade process.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-f\fR \fIfile\fR" 4
-.IX Item "-f file"
-Only act on \fIfile\fR rather than working on an entire directory.
-.IP "\fB\-t\fR \fItype\fR" 4
-.IX Item "-t type"
-For a file specified with \fB\-f\fR, parse it and upgrade it as if it were
-named \fItype\fR.  Used for upgrading files with the same syntax as normal
-\&\s-1INN\s0 configuration files but with different names.  Only makes sense in
-combination with \fB\-f\fR.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Upgrade any configuration files found in \fI/usr/local/news/etc\fR:
-.PP
-.Vb 1
-\&    innupgrade /usr/local/news/etc
-.Ve
-.PP
-Upgrade only \fI/news/etc/inn.conf\fR:
-.PP
-.Vb 1
-\&    innupgrade \-f /news/etc/inn.conf
-.Ve
-.PP
-Upgrade a file named \fIinn\-special.conf\fR that should have the same syntax
-as \fIinn.conf\fR:
-.PP
-.Vb 1
-\&    innupgrade \-t inn.conf \-f inn\-special.conf
-.Ve
-.PP
-Any upgrade rules that apply to \fIinn.conf\fR will be applied to the
-alternate file.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: innupgrade.8 7880 2008-06-16 20:37:13Z iulius $
diff --git a/doc/man/innwatch.8 b/doc/man/innwatch.8
deleted file mode 100644 (file)
index a45aa1d..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-.TH INNWATCH 8
-.SH NAME
-innwatch \- monitor innd.
-.SH SYNOPSIS
-.B innwatch 
-[ 
-.BI -l " logfile"
-]
-[
-.BI -t " seconds"
-]
-.SH DESCRIPTION
-.I Innwatch
-is normally started by
-.IR rc.news .
-It periodically \(em every
-.I <innwatchsleeptime in inn.conf>
-seconds \(em examines the load average, and the number of free blocks
-and inodes on the spool partition, as described by its
-control file,
-.IR innwatch.ctl .
-.PP
-If the load gets too high, or the disk gets too full, it throttles the server.
-When the condition restores, it unblocks the server.
-In addition, on each pass through the loop it will check the
-logfile
-.I <pathlog in inn.conf>/news.crit
-to see if it has been modified, and send mail to the news administrator
-if so.
-.PP
-Upon receipt of an interrupt signal (SIGINT),
-.IR innwatch
-will report its status in the file
-.IR <pathrun\ in\ inn.conf>/innwatch.status .
-.SH OPTIONS
-.TP
-.B \-l logfile
-To specify a log file to watch, other than the default of 
-.IR news.crit ,
-use the ``\fB\-l\fP'' flag.
-.TP
-.B \-t seconds
-To change the period between checks from the default from
-.I inn.conf ,
-use the ``\fB\-t\fP''
-flag.
-.SH HISTORY
-Written by Mike Cooper <mcooper@usc.edu>, with modifications by
-<kre@munnari.oz.au>,  Steve Groom <stevo@elroy.Jpl.Nasa.Gov> and
-Christophe Wolfhugel <wolf@pasteur.fr>.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innwatch.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-ctlinnd(8), 
-inn.conf(5),
-innwatch.ctl(5),
-shlock(1).
diff --git a/doc/man/innwatch.ctl.5 b/doc/man/innwatch.ctl.5
deleted file mode 100644 (file)
index 72290c6..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-.\" $Revision: 5909 $
-.TH INNWATCH.CTL 5
-.SH NAME
-innwatch.ctl \- control Usenet supervision by innwatch
-.SH DESCRIPTION
-The file
-.I <pathetc in inn.conf>/innwatch.ctl
-is used to determine what actions are taken during the periodic
-supervisions by
-.IR innwatch .
-.PP
-The file consists of a series of lines; blank lines and lines beginning
-with a number sign (``#'') are ignored.
-All other lines consist of seven fields, each preceded by a delimiting
-character, for example:
-.sp 1
-.nf
-.RS
-:label:state:condition:test:limit:command:reason
-.RE
-or
-.RS
-@label@state@condition@test@limit@command@reason
-.RE
-.fi
-.PP
-The delimiter can be any one of several non-alphanumeric characters that does
-not appear elsewhere in the line; there is no way to quote it to
-include it in any of the fields.
-Any of ``!'', ``,'', ``:'', ``@'', ``;'', or ``?'' is a good choice.
-Each line can have a different delimiter; the first character on each line
-is the delimiter for that line.
-White space surrounding delimiters, except before the first, is ignored,
-and does not form part of the fields; white space within fields is
-permitted.
-All delimiters must be present.
-.PP
-The first field is a label for this control line.
-It is used as an internal state indicator and in
-.I ctlinnd
-messages to control the server.
-If this field is empty, the line number is used.
-.PP
-The second field specifies when this control line should be used.
-It consists of a list of labels
-and special indicators,
-separated by whitespace.
-If the current state matches against any of the labels in this field,
-this line will be used as described below.
-The values that may be used are:
-.IP "\-"
-This line matches if the current state is the same as the label on
-this line, or if the current state is ``run'', the initial state.
-This is also the default state if this field is empty.
-.IP "+"
-This line matches if the current state is ``run''.
-.IP "*"
-This line always matches.
-.IP "label"
-This line matches if the current state is the specified ``label''.
-.IP "\-label"
-This line matches if the current state is not the specified ``label''.
-.PP
-The third field specifies a shell command that is invoked if this line matches.
-Do not use any shell filename expansion characters such as ``*'', ``?'',
-or ``['' (even quoted, they're not likely to work as intended).
-If the command succeeds, as indicated by its exit status, it is expected
-to have printed a single integer to standard output.
-This gives the value of this control line, to be used below.
-If the command fails, the line is ignored.
-The command is executed with its current directory set to the news spool
-articles directory,
-.IR <patharticles\ in\ inn.conf> .
-.PP
-The fourth field specifies the operator to use to test the value returned above.
-It should be one of the two letter numeric test operators defined in
-.IR test (1)
-such as ``eq'', ``lt'' and the like.
-The leading dash (``\-'') should not be included.
-.PP
-The fifth field specifies a constant with which to compare the value using
-the operator just defined.
-This is done by invoking the command:
-.sp 1
-.RS
-test value -operator constant
-.RE
-.sp 1
-The line is said to ``succeed'' if it returns true.
-.PP
-The sixth field specifies what should be done if the line succeeds,
-and in some cases if it fails.
-Any of the following words may be used:
-.IP throttle
-Causes
-.I innwatch
-to throttle the server if this line succeeds.
-It also sets the state to the value of the line's label.
-If the line fails, and the state was previously equal to
-the label on this line (that is, this line had previously succeeded),
-then a
-.I go
-command will be sent to the server, and
-.I innwatch
-will return to the ``run'' state.
-The ``throttle'' is only performed if the current state is ``run'' or a
-state other than the label of this line, regardless of whether the command
-succeeds.
-.IP pause
-Is identical to ``throttle'' except that the server is paused.
-.IP shutdown
-Sends a ``shutdown'' command to the server.
-It is for emergency use only.
-.IP flush
-Sends a ``flush'' command to the server.
-.IP go
-Causes
-.I innwatch
-to send a ``go'' command to the server and to set the state to ``run''.
-.IP exit
-Causes
-.I innwatch
-to exit.
-.PP
-.IP skip
-The remainder of the control file is skipped for the current pass.
-.PP
-The last field specifies the reason that is used in those
-.I ctlinnd
-commands that require one.
-More strictly, it is part of the reason \(em
-.I innwatch
-appends some information to it.
-In order to enable other sites to recognize the state of the local
-.I innd
-server, this field should usually be set to one of several standard
-values.
-Use ``No\ space'' if the server is rejecting articles because of a lack
-of filesystem resources.
-Use ``loadav'' if the server is rejecting articles because of a lack
-of CPU resources.
-.PP
-Once
-.I innwatch
-has taken some action as a consequence of its control line, it skips the
-rest of the control file for this pass.
-If the action was to restart the server (that is, issue a ``go'' command),
-then the next pass will commence almost immediately, so that
-.I innwatch
-can discover any other condition that may mean that the server should
-be suspended again.
-.SH EXAMPLES
-.RS
-.nf
-@@@inndf .@lt@10000@throttle@No space
-@@@inndf -i .@lt@1000@throttle@No space (inodes)
-.fi
-.RE
-.PP
-The first line causes the server to be throttled if the free space drops
-below 10000 units
-(using whatever units
-.IR inndf (8)
-uses), and restarted again when free space increases above the threshold.
-.PP
-The second line does the same for inodes.
-.PP
-The next three lines act as a group and should
-appear in the following order.
-It is easier to explain them, however, if they are described from the last up.
-.PP
-.RS
-.nf
-!load!load hiload!loadavg!lt!5!go!
-:hiload:+ load:loadavg:gt:8:throttle:loadav
-/load/+/loadavg/ge/6/pause/loadav
-.fi
-.RE
-.PP
-The final line causes the server to be paused if
-.I innwatch
-is in the ``run'' state and the load average rises to, or above, six.
-The state is set to ``load'' when this happens.
-The previous line causes the server to be throttled when
-.I innwatch
-is in the ``run'' or ``load'' state, and the load average rises above eight.
-The state is set to ``hiload'' when this happens.
-Note that
-.I innwatch
-can switch the server from ``paused'' to ``throttled'' if the load average
-rises from below six to between six and seven, and then to above eight.
-The first line causes the server to be sent a ``go'' command if
-.I innwatch
-is in the ``load'' or ``hiload'' state, and the load average drops below five.
-.PP
-Note that all three lines assume a mythical command
-.I loadavg
-that is assumed to print the current load average as an integer.
-In more practical circumstances, a pipe of
-.I uptime
-into
-.I awk
-is more likely to be useful.
-.SH BUGS
-This file must be tailored for each individual site, the sample supplied
-is truly no more than a sample.
-The file should be ordered so that the more common problems are tested first.
-.PP
-The ``run'' state is not actually identified by the label with that three
-letter name, and using it will not work as expected.
-.PP
-Using an ``unusual'' character for the delimiter such as ``('', ``*'',
-``&'', ``\(ga'', ``\(aa'', and the like, is likely to lead to obscure and
-hard to locate bugs.
-.SH HISTORY
-Written by <kre@munnari.oz.au> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innwatch.ctl.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5),
-innd(8),
-inndf(8),
-ctlinnd(8),
-news.daily(8).
diff --git a/doc/man/innxbatch.8 b/doc/man/innxbatch.8
deleted file mode 100644 (file)
index 784080d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-.TH INNXBATCH 8
-.SH NAME
-innxbatch \- send xbatched Usenet articles to a remote NNTP server
-.SH SYNOPSIS
-.I innxbatch
-[
-.B \-D
-]
-[
-.BI \-t " timeout"
-]
-[
-.BI \-T " timeout"
-]
-[
-.B \-v
-]
-.I host
-.I file ...
-.SH DESCRIPTION
-.I Innxbatch
-connects to the NNTP server at the specified
-.I host
-and sends it the specified xbatch files, using the XBATCH extension to
-the NNTP protocol. It is normally invoked by a script run out of
-.IR cron (8)
-that uses
-.IR shlock (1)
-to lock the host name, followed by a
-.IR ctlinnd (8)
-command to flush the batchfile.
-.PP
-Each file is removed after it has been successfully transferred.
-.PP
-If a communication error such as a
-.IR write (2)
-failure, or an unexpected reply from the remote server occurs,
-.I innxbatch
-will stop sending and leave all remaining files untouched for later retry.
-
-
-.SH OPTIONS
-.TP
-.B \-t seconds
-.I Innxbatch
-normally blocks until the connection is made.
-To specify a timeout on how long to try to make the connection, use
-the ``\-t'' flag.
-.TP
-.B \-T seconds
-To specify the total amount of time that should be allowed for article
-transfers, use the ``\-T'' flag.
-.br
-The default is to wait until an I/O error occurs, or all the articles have
-been transferred. If the ``\-T'' flag is used, the time is checked
-just before each article is started; it will not abort a transfer that
-is in progress.
-.TP
-.B \-v
-Upon exit,
-.I innxbatch
-reports transfer and CPU usage statistics via
-.IR syslog (3).
-If the ``\-v'' flag is used, they will also be printed on the standard
-output.
-.TP
-.B \-D
-Use the ``\-D'' flag to print debugging information on standard error.
-This will show the protocol transactions between
-.I innxbatch
-and the NNTP server on the remote host.
-.SH EXAMPLES
-A sample
-.I newsfeeds(5)
-entry to produce appropriate xbatch files (thanks to Karsten Leipold
-<poldi@dfn.de>):
-.sp 1
-.nf
-  nase\e
-    :*\e
-    :Tc,Wnb\e
-.ds R$ <pathbin in inn.conf>
-    :\*(R$/batcher \e
-.ds R$ <$ac_cv_path_COMPRESS in config.cache>
-.ds P$ <pathoutgoing in inn.conf>
-       -p "(\*(R$ >\e
-       \*(P$/nase.\e$\e$)" \e
-       nase.do.main
-.fi
-.sp 1
-A sample script to invoke
-.I innxbatch(8)
-is:
-.sp 1
-.nf
-  #!/bin/sh
-  ##  SH script to send xbatches for a site, wrapped around innxbatch
-  ##  Invocation:
-  ##     sendxbatches.sh <sitename> <hostname> <xbatch file name> ...
-
-  if [ $# -le 3 ]
-  then
-       echo "usage: $0 <sitename> <hostname> <xbatch file name>"
-       exit 1
-  fi
-
-  . <pathbin in inn.conf>/innshellvars
-
-  site="$1"; host="$2"; shift; shift
-
-  ctlinnd flush "$site" \e
-  && sleep 5 \e
-  && exec $NEWSBIN/innxbatch -v -D "$host" $*
-.fi
-.SH HISTORY
-Written by Stefan Petri <petri@ibr.cs.tu-bs.de>, modelled after
-.IR innxmit (8)
-and the XBATCH patch for the nntp reference implementation.
-.SH "SEE ALSO"
-ctlinnd(8),
-inn.conf(5),
-innd(8),
-innxmit(8),
-newsfeeds(5),
-nntpsend(8),
-shlock(1).
diff --git a/doc/man/innxmit.8 b/doc/man/innxmit.8
deleted file mode 100644 (file)
index a7457b0..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-.\" $Revision: 5909 $
-.TH INNXMIT 8
-.SH NAME
-innxmit \- send Usenet articles to a remote NNTP server
-.SH SYNOPSIS
-.I innxmit
-[
-.B \-a
-]
-[
-.B \-c
-]
-[
-.B \-d
-]
-[
-.B \-H
-]
-[
-.B \-l
-]
-[
-.BI \-P " portnum"
-]
-[
-.B \-p
-]
-[
-.B \-r
-]
-[
-.B \-s
-]
-[
-.BI \-T " timeout"
-]
-[
-.BI \-t " timeout"
-]
-.I host
-.I file
-.SH DESCRIPTION
-.I Innxmit
-connects to the NNTP server at the specified
-.I host
-(validating itself via
-.IR passwd.nntp
-if possible) 
-and sends it the articles specified in the batchfile named
-.IR file .
-It is normally invoked by a script run out of
-.IR cron (8)
-that uses
-.IR shlock (1)
-to lock the host name, followed by a
-.IR ctlinnd (8)
-command to flush the batchfile.
-.PP
-If the
-.I file
-is not an absolute pathname, it is taken relative to the
-.I <pathoutgoing in inn.conf>
-directory.
-It is normally written by specifying the ``Wnm'' flags in the
-.I newsfeeds
-file.
-Each line in the batchfile should be in one of the following formats:
-.PP
-.RS
-.nf
-token Message-ID
-token
-.fi
-.RE
-.PP
-The
-.I token
-field names the article to be sent.
-If the
-.I Message-ID
-field is not specified, it will be obtained by scanning the article.
-The
-.I token
-and
-.I Message-Id
-fields are separated by a space.
-.PP
-If a communication error such as a
-.IR write (2)
-failure occurs,
-.I innxmit
-will stop sending and rewrite the batchfile to contain the current
-article and any other unsent articles.
-.SH OPTIONS
-.TP
-.B \-a
-If all articles were sent successfully,
-.I innxmit
-will remove the batchfile; otherwise it will rewrite it to contain the
-list of unsent articles.
-If no articles were sent or rejected, the file is left untouched.
-This can cause the batchfile to grow excessively large if many articles
-have been expired and there are communication problems.
-To always rewrite the batchfile, use the ``\fB\-a\fP'' flag.
-.TP
-.B \-c
-In streaming mode, a check of each message ID is still made to avoid sending
-articles already on the server.
-The ``\fB\-c\fP'' flag will, if streaming mode is supported,
-result in sending articles without checking.
-This results in slightly greater throughput and may be appropriate when
-it is known that the site could not already have the articles such as in
-the case of a "leaf" site.
-.TP
-.B \-d
-Use the ``\fB\-d\fP'' flag to print debugging information on standard error.
-This will show the protocol transactions between
-.I innxmit
-and the NNTP server on the remote host.
-.TP
-.B \-H
-If the ``\fB\-H\fP'' flag is given, then only headers are sent to
-.I host
-for all articles except control messages.
-And Bytes: header is also included even if it does not exist in the original
-article.  ``\fB\-H\fP'' flag is useful for diablo reader.
-.TP
-.B \-l
-The ``\fB\-l\fP'' flag is used to turn on logging of reasons the remote gives
-for rejecting an article.
-.TP
-.B \-P portnum
-To specify a port number other than the default, use the ``\fB\-P\fP'' flag.
-.TP
-.B \-p
-If the ``\fB\-p\fP'' flag is given, then no connection is made and the batchfile
-is purged of entries that refer to files that no longer exist.
-This implies the ``\fB\-a\fP'' flag.
-.TP
-.B \-r
-If the remote server sends an unexpected reply code,
-.I innxmit
-will requeue the article and proceed.
-Use the ``\fB\-r\fP'' flag if the article should not be requeued.
-.TP
-.B \-s
-.I Innxmit
-will attempt to negotiate a streaming mode extension of the NNTP
-protocol with the server at connect time.
-If successful it will use a slightly different protocol that enhances
-throughput.
-If the server does not recognize the streaming mode negotiation
-.I innxmit
-will revert to normal NNTP transfer mode.
-Use the ``\fB\-s\fP'' flag to disable the attempt to negotiate the streaming
-mode extension.
-.TP
-.B \-T seconds
-To specify the total amount of time that should be allowed for article
-transfers, use the ``\fB\-T\fP'' flag.
-The default is to wait until an I/O error occurs, or all the articles have
-been transferred.
-If the ``\fB\-T\fP'' flag is used, the time is checked just before each
-article is started; it will not abort a transfer that is in progress.
-.TP
-.B \-t seconds
-.I Innxmit
-normally blocks until the connection is made.
-To specify a timeout on how long to try to make the connection, use 
-the ``\fB\-t\fP''
-flag.
-.TP
-.B \-v
-Upon exit,
-.I innxmit
-reports transfer and CPU usage statistics via
-.IR syslog (3).
-If the ``\fB\-v\fP'' flag is used, they will also be printed on the standard
-output.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: innxmit.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-ctlinnd(8),
-inn.conf(5),
-innd(8),
-newsfeeds(5),
-shlock(1).
diff --git a/doc/man/libauth.3 b/doc/man/libauth.3
deleted file mode 100644 (file)
index 8289640..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-.\" 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 "libauth 3"
-.TH libauth 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-libauth \- routines for writing nnrpd resolvers and authenticators
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-.Vb 1
-\&    #include "libauth.h"
-.Ve
-.PP
-.Vb 5
-\&    struct res_info {
-\&        struct sockaddr *client;
-\&        struct sockaddr *local;
-\&        char *clienthostname;
-\&    };
-.Ve
-.PP
-.Vb 4
-\&    struct auth_info {
-\&        char *username;
-\&        char *password;
-\&    };
-.Ve
-.PP
-.Vb 2
-\&    struct auth_info *get_auth_info(FILE *);
-\&    struct res_info  *get_res_info (FILE *);
-.Ve
-.PP
-.Vb 2
-\&    void free_auth_info(struct auth_info*);
-\&    void free_res_info (struct res_info*);
-.Ve
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-These functions provide a convenient C frontend to the nnrpd external
-authentication interface documented in \fIdoc/external\-auth\fR.  Use of
-this library is \fBnot\fR required; in particular, external resolvers and
-authenticators written in languages other than C will need to implement
-the necessary functionality themselves.
-.PP
-The \fIget_auth_info()\fR and \fIget_res_info()\fR functions allocate sufficient
-memory for a \fBstruct auth_info\fR or \fBstruct res_info\fR and any necessary
-fields, and return a pointer to the struct with the fields filled in
-from information supplied by nnrpd (the \fBFILE*\fR parameter generally
-should be \f(CW\*(C`stdin\*(C'\fR).  Both functions return \s-1NULL\s0 on error.  The caller
-is responsible for deallocating the memory by using the functions below.
-.PP
-The string fields of both structs are straightforward.  The \fBclient\fR
-and \fBlocal\fR fields of \fBstruct res_info\fR actually point to instances of
-\&\fBstruct sockaddr_in\fR (or \fBstruct sockaddr_in6\fR if IPv6 support is
-compiled in).
-.PP
-The \fIfree_auth_info()\fR and \fIfree_res_info()\fR functions free the struct
-passed in as argument and all necessary fields.
-.SH "BUGS"
-.IX Header "BUGS"
-In many cases, nnrpd provides more information than is normally useful
-(for example, even when calling an authenticator, the resolver
-information is often provided.)  On the other hand, in certain cases it
-provides less information than might be expected (for example, if nnrpd
-is reading from stdin rather than a socket).  The implementation is
-capable of handling at least the first of these issues, but that
-functionality is not exposed in the interface.
-.PP
-At present, \fIlibauth.h\fR and its implementation are located in
-\&\fIauthprogs/\fR; perhaps they should be moved to \fIinclude/\fR and \fIlib/\fR,
-respectively?
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Jeffrey M. Vinocur <jeff@litech.org> for InterNetNews.
-.PP
-$Id: libauth.3 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5), \fIdoc/external\-auth\fR
diff --git a/doc/man/libinn.3 b/doc/man/libinn.3
deleted file mode 100644 (file)
index e6fd51f..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-.\" $Revision: 6124 $
-.TH LIBINN 3
-.SH NAME
-libinn \- InterNetNews library routines
-.SH SYNOPSIS
-.nf
-.ta \w'    unsigned long    'u
-.B
-#include "libinn.h"
-
-.B "typedef struct _TIMEINFO {"
-.B "    time_t time;"
-.B "    long   usec;"
-.B "    long   tzone;
-.B "} TIMEINFO;"
-
-.B "char *"
-.B "GenerateMessageID(domain)"
-.B "    char    *domain;"
-
-.B "void"
-.B "HeaderCleanFrom(from)"
-.B "    char   *from;"
-
-.B "char *"
-.B "HeaderFind(Article, Header, size)"
-.B "    char   *Article;"
-.B "    char   *Header;"
-.B "    int    size;"
-
-.B "FILE *"
-.B "CAopen(FromServer, ToServer)"
-.B "    FILE   *FromServer;"
-.B "    FILE   *ToServer;"
-
-.B "FILE *"
-.B "CAlistopen(FromServer, ToServer, request)"
-.B "    FILE   *FromServer;"
-.B "    FILE   *ToServer;"
-.B "    char   *request;"
-
-.B "void"
-.B "CAclose()"
-
-.B "struct _DDHANDLE *"
-.B "DDstart(FromServer, ToServer)"
-.B "    FILE   *FromServer;"
-.B "    FILE   *ToServer;"
-
-.B "void"
-.B "DDcheck(h, group)"
-.B "    DDHANDLE       *h;"
-.B "    char   *group;"
-
-.B "char *"
-.B "DDend(h)"
-.B "    DDHANDLE       *h;"
-
-.B "void"
-.B "close_on_exec(fd, flag)"
-.B "    int    fd;"
-.B "    bool   flag;"
-
-.B "int"
-.B "nonblocking(fd, flag)"
-.B "    int    fd;"
-.B "    bool   flag;"
-
-.B "bool"
-.B "inn_lock_file(fd, type, flag)"
-.B "    int    fd;"
-.B "    LOCKTYPE       type;"
-.B "    bool   block;"
-
-.B "char *"
-.B "GetFQDN(domain)"
-.B "    char    *domain;"
-
-.B "char *"
-.B "GetModeratorAddress(FromServer, ToServer, group, moderatormailer)"
-.B "    FILE   *FromServer;"
-.B "    FILE   *ToServer;"
-.B "    char   *group;"
-.B "    char   *moderatormailer;"
-
-.B "int"
-.B "GetResourceUsage(usertime, systime)"
-.B "    double *usertime;"
-.B "    double *systime;"
-
-.B "int"
-.B "GetTimeInfo(now)"
-.B "    TIMEINFO       *now;"
-
-.B "int"
-.B "NNTPlocalopen(FromServerp, ToServerp, errbuff)"
-.B "    FILE   **FromServerp;"
-.B "    FILE   **ToServerp;"
-.B "    char   *errbuff;"
-
-.B "int"
-.B "NNTPremoteopen(port, FromServerp, ToServerp, errbuff)"
-.B "    int    port;"
-.B "    FILE   **FromServerp;"
-.B "    FILE   **ToServerp;"
-.B "    char   *errbuff;"
-
-.B "int"
-.B "NNTPconnect(host, port, FromServerp, ToServerp, errbuff)"
-.B "    char   *host;"
-.B "    int    port;"
-.B "    FILE   **FromServerp;"
-.B "    FILE   **ToServerp;"
-.B "    char   *errbuff;"
-
-.B "int"
-.B "NNTPsendarticle(text, ToServer, Terminate)"
-.B "    char   *text;"
-.B "    FILE   *ToServer;"
-.B "    int    Terminate;"
-
-.B "int"
-.B "NNTPsendpassword(server, FromServer, ToServer)"
-.B "    char   *server;"
-.B "    FILE   *FromServer;"
-.B "    FILE   *ToServer;"
-
-.B "void"
-.B "Radix32(value, p)
-.B "    unsigned long  value;"
-.B "    char   *p;"
-
-.B "char *"
-.B "ReadInFile(name, Sbp)"
-.B "    char   *name;"
-.B "    struct stat    *Sbp;"
-
-.B "char *"
-.B "ReadInDescriptor(fd, Sbp)"
-.B "    int    fd;"
-.B "    struct stat    *Sbp;"
-
-.B "HASH"
-.B "HashMessageID(MessageID)"
-.B "    const char *MessageID;"
-.fi
-.SH DESCRIPTION
-.I Libinn
-is a library of utility routines for manipulating Usenet articles and
-related data.
-It is not necessary to use the header file
-.IR libinn.h ;
-if it is not available, it is only necessary to properly declare the
-.I TIMEINFO
-datatype, as given above.
-.PP
-.I GenerateMessageID
-uses the current time, process-ID, and fully-qualified domain name, which is
-passed as an argument and used if local host can not be resolved or it is
-different from ``domain'' set in
-.IR inn.conf ,
-to create a Message-ID header that is highly likely to be unique.
-The returned value points to static space that is reused on subsequent calls.
-.PP
-.I HeaderCleanFrom
-removes the extraneous information from the value of a ``From'' or ``Reply-To''
-header and leaves just the official mailing address.
-In particular, the following transformations are made to the
-.I from
-parameter:
-.RS
-.nf
-.ta \w'stuff <address>  'u
-address        -->  address
-address (stuff)        -->  address
-stuff <address>        -->  address
-.fi
-.RE
-The transformations are simple, based on RFC\ 1036 which limits the format
-of the header.
-.PP
-.I HeaderFind
-searches through
-.I Article
-looking for the specified
-.IR Header .
-.I Size
-should be the length of the header name.
-It returns a pointer to the value of the header, skipping leading whitespace,
-or NULL if the header cannot be found.
-.I Article
-should be a standard C string containing the text of the article; the end
-of the headers is indicated by a blank line \(em two consecutive \en
-characters.
-.PP
-.I CAopen
-and
-.I CAclose
-provide news clients with access to the active file; the ``CA'' stands for
-.IR C lient
-.IR A ctive.
-.I CAopen
-opens the
-.I active
-file for reading.
-It returns a pointer to an open FILE, or NULL on error.
-If a local or NFS-mounted copy exists,
-.I CAopen
-will use that file.
-The
-.I FromServer
-and
-.I ToServer
-parameters should be FILE's connected to the NNTP server for input and
-output, respectively.
-See
-.I NNTPremoteopen
-or
-.IR NNTPlocalopen ,
-below.
-If either parameter is NULL, then
-.I CAopen
-will just return NULL if the file is not locally available.
-If they are not NULL,
-.I CAopen
-will use them to query the NNTP server using
-the ``list'' command to make a local temporary copy.
-.PP
-The
-.I CAlistopen
-sends a ``list'' command to the server and returns a temporary file
-containing the results.
-The
-.I request
-parameter, if not NULL, will be sent as an argument to the command.
-Unlike
-.IR CAopen ,
-this routine will never use a locally-available copy of the active file.
-.PP
-.I CAclose
-closes the active file and removes any temporary file that might have
-been created by
-.I CAopen
-or
-.IR CAlistopen .
-.PP
-.I CloseOnExec
-can make a descriptor ``close-on-exec'' so that it is not shared
-with any child processes.
-If the flag is non-zero, the file is so marked; if zero, the ``close-on-exec''
-mode is cleared.
-.PP
-.IR DDstart ,
-.IR DDcheck ,
-and
-.I DDend
-are used to set the Distribution header; the ``DD'' stands for
-.IR D efault
-.IR D istribution.
-The
-.I distrib.pats
-file is consulted to determine the proper value for the Distribution
-header after all newsgroups have been checked.
-.I DDstart
-begins the parsing.
-It returns a pointer to an opaque handle that should be used on subsequent
-calls.
-The
-.I FromServer
-and
-.I ToServer
-parameters should be FILE's connected to the NNTP server for input and
-output, respectively.
-If either parameter is NULL, then an empty default will ultimately be returned
-if the file is not locally available.
-.PP
-.I DDcheck
-should be called
-with the handle,
-.IR h ,
-returned by
-.I DDstart
-and a newgroups,
-.IR group ,
-to check.
-It can be called as often as necessary.
-.PP
-.I DDend
-releases any state maintained in the handle and returns an allocated copy
-of the text that should be used for the Distribution header.
-.PP
-.I SetNonBlocking
-enables (if
-.I flag
-is non-zero) or disables (if
-.I flag
-is zero) non-blocking I/O on the indicated descriptor.
-It returns \-1 on failure or zero on success.
-.PP
-.I inn_lock_file
-tries to lock the file descriptor
-.IR fd .
-If
-.I block
-is true it will block until the lock can be made, otherwise
-it will return false if the file cannot be locked.
-.I type
-is one of: INN_LOCK_READ, INN_LOCK_WRITE, or INN_LOCK_UNLOCK.
-It returns false on failure or true on success.
-.PP
-.I GetFQDN
-returns the fully-qualified domain name of the local host.
-.I Domain
-is used if local host can not be resolved.
-The returned value points to static space that is reused on subsequent calls,
-or NULL on error.
-.PP
-.I GetModeratorAddress
-returns the mailing address of the moderator for specified
-.I group
-or NULL on error.
-.I Moderatormailer
-is used as its address, if there is no matched moderator.
-See
-.IR moderators (5)
-for details on how the address is determined.
-.I GetModeratorAddress
-does no checking to see if the specified group is actually moderated.
-The returned value points to static space that is reused on subsequent
-calls.
-The
-.I FromServer
-and
-.I ToServer
-parameters should be FILE's connected to the NNTP server for input and
-output, respectively.  If either of these parameters is NULL, then an
-attempt to get the list from a local copy is made.
-.PP
-.I GetResourceUsage
-fills in the
-.I usertime
-and
-.I systime
-parameters with the total user and system time used by the current
-process and any children it may have spawned.
-If
-.I <HAVE_GETRUSAGE in include/config.h>
-is defined, it gets the values by doing a
-.IR getrusage (2)
-system call; otherwise it calls
-.IR times (2).
-It returns \-1 on failure, or zero on success.
-.PP
-.I GetTimeInfo
-fills in the
-.I now
-parameter with information about the current time and tzone.
-The ``time'' and ``usec'' fields will be filled in by a call to
-.IR gettimeofday (2)
-if
-.I <$ac_cv_func_gettimeofday in config.cache>
-is ``yes''.  Otherwise, the ``time'' field will be filled in by a call to
-.IR time (2),
-and the ``usec'' field will be set to zero.
-The ``tzone'' field will be filled in with the current offset from GMT.
-If
-.I <HAVE_TM_GMTOFF in include/config.h>
-is defined, this is done by calling
-.IR localtime (3)
-and taking the value of the ``tm_gmtoff'' field, negating it, and dividing
-it by 60.
-Otherwise, this is done by calling
-.IR localtime (3)
-and comparing the value with that returned by a call to
-.IR gmtime (3).
-
-For efficiency, the ``tzone'' field is only recalculated if more than an
-hour pass passed since the last time
-.I GetTimeInfo
-has been called.
-This routine returns \-1 on failure, or zero on success.
-.PP
-.I NNTPlocalopen
-opens a connection to the private port of an InterNetNews server running on
-the local host, if
-.I <HAVE_UNIX_DOMAIN_SOCKETS in include/config.h>
-is defined. 
-It returns \-1 on failure, or zero on success.
-.I FromServerp
-and
-.I ToServerp
-will be filled in with FILE's which can be used to communicate
-with the server.
-.I Errbuff
-can either be NULL or a pointer to a buffer at least 512 bytes long.
-If not NULL, and the server refuses the connection, then it will be
-filled in with the text of the server's reply.
-This routine is not for general use.
-If
-.I <HAVE_UNIX_DOMAIN_SOCKETS in include/config.h>
-is not defined, this
-is a stub routine, for compatibility with systems that have Unix-domain
-stream sockets.
-It always returns \-1.
-.PP
-.I NNTPremoteopen
-does the same except that it uses ``innconf->server''
-as the local server, and opens a connection to the
-.IR port .
-Any client program can use this routine.
-It returns \-1 on failure, or zero on success.
-.PP
-.I NNTPconnect
-is the same as
-.I NNTPremoteopen
-except that the desired host is given as the
-.I host
-parameter.
-.PP
-.I NNTPsendarticle
-writes
-.I text
-on
-.I ToServer
-using NNTP conventions for line termination.
-The text should consist of one or more lines ending with a newline.
-If
-.I Terminate
-is non-zero, then the routine will also write the NNTP data-termination
-marker on the stream.
-It returns \-1 on failure, or zero on success.
-.PP
-.I NNTPsendpassword
-sends authentication information to an NNTP server by finding the appropriate
-entry in the
-.I passwd.nntp
-file.
-.I Server
-contains the name of the host; ``innconf->server'' will be used if
-.I server
-is NULL.
-.I FromServer
-and
-.I ToServer
-should be FILE's that are connected to the server.
-No action is taken if the specified host is not listed in the password file.
-.PP
-.I Radix32
-converts the number in
-.I value
-into a radix-32 string into the buffer pointed to by
-.IR p .
-The number is split into five-bit pieces and each pieces is converted
-into a character using the alphabet
-.I "0..9a..v"
-to represent the numbers 0..32.
-Only the lowest 32 bits of
-.I value
-are used, so
-.I p
-need only point to a buffer of eight bytes (seven characters and the
-trailing \e0).
-.PP
-.I ReadInFile
-reads the file named
-.I name
-into allocated memory, appending a terminating \e0 byte.
-It returns a pointer to the space, or NULL on error.
-If
-.I Sbp
-is not NULL, it is taken as the address of a place to store the results
-of a
-.IR stat (2)
-call.
-.PP
-.I ReadInDescriptor
-performs the same function as
-.I ReadInFile
-except that
-.I fd
-refers to an already-open file.
-.PP
-.I HashMessageID
-returns hashed message-id using MD5.
-.SH EXAMPLES
-.RS
-.nf
-char   *p;
-char   *Article;
-char   buff[256], errbuff[256];
-FILE   *F;
-FILE   *ToServer;
-FILE   *FromServer;
-int    port = 119;
-
-if ((p = HeaderFind(Article, "From", 4)) == NULL)
-    Fatal("Can't find From line");
-(void)strcpy(buff, p);
-HeaderCleanFrom(buff);
-
-if ((F = CAopen(FromServer, ToServer)) == NULL)
-    Fatal("Can't open active file");
-
-/* Don't pass the file on to our children. */
-CloseOnExec(fileno(F), 1);
-
-/* Make a local copy. */
-p = ReadInDescriptor(fileno(F), (struct stat *)NULL);
-
-/* Close the file. */
-CAclose();
-
-if (NNTPremoteopen(port, &FromServer, &ToServer, errbuff) < 0)
-    Fatal("Can't connect to server");
-
-if ((p = GetModeratorAddress("comp.sources.unix")) == NULL)
-    Fatal("Can't find moderator's address");
-.fi
-.RE
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: libinn.3 6124 2003-01-14 06:03:29Z rra $
-.SH "SEE ALSO"
-active(5),
-dbz(3z),
-parsedate(3),
-inn.conf(5),
-inndcomm(3),
-moderators(5),
-passwd.nntp(5).
diff --git a/doc/man/libinnhist.3 b/doc/man/libinnhist.3
deleted file mode 100644 (file)
index 3f60759..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-.\" 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 "libinnhist 3"
-.TH libinnhist 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-his \- routines for managing INN history
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fB#include <inn/history.h>\fR
-.PP
-\&\fBstruct history;\fR
-.PP
-\&\fBstruct histstats {\fR
-\&\fB    int hitpos;\fR
-\&\fB    int hitneg;\fR
-\&\fB    int misses;\fR
-\&\fB    int dne;\fR
-\&\fB};\fR
-.PP
-\&\fB#define \s-1HIS_RDONLY\s0 ...\fR
-\&\fB#define \s-1HIS_RDWR\s0 ...\fR
-\&\fB#define \s-1HIS_CREAT\s0 ...\fR
-\&\fB#define \s-1HIS_ONDISK\s0 ...\fR
-\&\fB#define \s-1HIS_INCORE\s0 ...\fR
-\&\fB#define \s-1HIS_MMAP\s0 ...\fR
-.PP
-\&\fBenum {\fR
-\&\fB    \s-1HISCTLG_PATH\s0,\fR
-\&\fB    \s-1HISCTLS_PATH\s0,\fR
-\&\fB    \s-1HISCTLS_SYNCCOUNT\s0,\fR
-\&\fB    \s-1HISCTLS_NPAIRS\s0,\fR
-\&\fB    \s-1HISCTLS_IGNOREOLD\s0,\fR
-\&\fB    \s-1HISCTLS_STATINTERVAL\s0\fR
-\&\fB};\fR
-.PP
-\&\fBstruct history *HISopen(const char *\fR\fIpath\fR\fB, const char *\fR\fImethod\fR\fB, int \fR\fIflags\fR\fB);\fR
-.PP
-\&\fBbool HISclose(struct history *\fR\fIhistory\fR\fB);\fR
-.PP
-\&\fBbool HISsync(struct history *\fR\fIhistory\fR\fB);\fR
-.PP
-\&\fBvoid HISsetcache(struct history *\fR\fIhistory\fR\fB, size_t \fR\fIsize\fR\fB);\fR
-.PP
-\&\fBbool HISlookup(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIkey\fR\fB, time_t *\fR\fIarrived\fR\fB, time_t *\fR\fIposted\fR\fB, time_t *\fR\fIexpires\fR\fB, \s-1TOKEN\s0 *\fR\fItoken\fR\fB);\fR
-.PP
-\&\fBbool HIScheck(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIkey\fR\fB);\fR
-.PP
-\&\fBbool HISwrite(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIkey\fR\fB, time_t \fR\fIarrived\fR\fB, time_t \fR\fIposted\fR\fB, time_t \fR\fIexpires\fR\fB, const \s-1TOKEN\s0 *\fR\fItoken\fR\fB);\fR
-.PP
-\&\fBbool HISremember(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIkey\fR\fB, time_t \fR\fIarrived\fR\fB);\fR
-.PP
-\&\fBbool HISreplace(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIkey\fR\fB, time_t \fR\fIarrived\fR\fB, time_t \fR\fIposted\fR\fB, time_t \fR\fIexpires\fR\fB, const \s-1TOKEN\s0 *\fR\fItoken\fR\fB);\fR
-.PP
-\&\fBbool HISexpire(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIpath\fR\fB, const char *\fR\fIreason\fR\fB, bool \fR\fIwriting\fR\fB, void *\fR\fIcookie\fR\fB, time_t \fR\fIthreshold\fR\fB, bool (*\fR\fIexists\fR\fB)(void *cookie, time_t arrived, time_t posted, time_t expires, const \s-1TOKEN\s0 *token));\fR
-.PP
-\&\fBbool HISwalk(struct history *\fR\fIhistory\fR\fB, const char *\fR\fIreason\fR\fB, void *\fR\fIcookie\fR\fB, bool (*\fR\fIcallback\fR\fB)(void *cookie, time_t arrived, time_t posted, time_t expires, const \s-1TOKEN\s0 *token));\fR
-.PP
-\&\fBstruct histstats HISstats(struct history *\fR\fIhistory\fR\fB);\fR
-.PP
-\&\fBconst char *HISerror(struct history *\fR\fIhistory\fR\fB);\fR
-.PP
-\&\fBbool HISctl(struct history *\fR\fIhistory\fR\fB, int \fR\fIrequest\fR\fB, void *\fR\fIval\fR\fB);\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-These functions provide provide access to the \s-1INN\s0 history
-database. They maintain key/value pairs in an opaque database whilst
-providing for expiry of outdated information.
-.PP
-The history structure is an opaque handle returned from HISopen.
-.PP
-The \fBHISopen\fR function opens the history file designated by \fIpath\fR
-using the mode \fIflags\fR using the specified \fImethod\fR. \fIflags\fR may be
-\&\fB\s-1HIS_RDONLY\s0\fR to indicate that read-only access to the history
-database is desired, or \fB\s-1HIS_RDWR\s0\fR for read/write access. History
-methods are defined at build time; the history method currently
-available is \*(L"hisv6\*(R". On success a newly initialised history handle is
-returned, or \fB\s-1NULL\s0\fR on failure.
-.PP
-\&\fB\s-1HIS_ONDISK\s0\fR, \fB\s-1HIS_INCORE\s0\fR and \fB\s-1HIS_MMAP\s0\fR may be logically ORed
-into \fIflags\fR to provide a hint to the underlying history manager as
-to how it should handle its data files; \fB\s-1HIS_ONDISK\s0\fR indicates that
-the caller would like as much of the data to be kept on disk (and out
-of memory), \fB\s-1HIS_INCORE\s0\fR indicates that the data files should be kept
-in main memory where possible and \fB\s-1HIS_MMAP\s0\fR that the files should be
-\&\fImmap()\fRed into the processes address space. \fB\s-1HIS_INCORE\s0\fR is typically
-used where a mass rebuild of the history database is being performed;
-the underlying history manager may assume that the caller will call
-\&\fBHISsync\fR() to sync the data files to disk.
-.PP
-The \fB\s-1HIS_CREAT\s0\fR flag indicates that the history database should be
-initialised as new; if any options which affect creation of the
-database need to be set an anonymous history handle should be created
-by calling \fBHISopen\fR with \fIpath\fR set to \fB\s-1NULL\s0\fR, any options set
-using \fBHISctl\fR, then the database opened by calling \fBHISctl\fR with
-\&\fB\s-1HISCTLS_PATH\s0\fR.
-.PP
-The \fBHISclose\fR function closes the handle \fIhistory\fR and deallocates
-any resources associated with it. It returns \fBfalse\fR on failure or
-\&\fBtrue\fR on success.
-.PP
-The \fBHISsync\fR function synchronises any outstanding transactions
-associated with \fIhistory\fR to disk.
-.PP
-\&\fBHISsetcache\fR associates a cache used for speeding up HIScheck with
-\&\fIhistory\fR. The cache will occupy approximately \fIsize\fR bytes.
-.PP
-\&\fBHISlookup\fR retrieves a token from \fIhistory\fR based on the passed
-\&\fIkey\fR (normally the Message\-ID). If no entry with an associated token
-can be found, \fBHISlookup\fR will return \fBfalse\fR. If a token is found
-\&\fIarrived\fR, \fIexpires\fR, and \fIposted\fR are filled in with the message
-arrival, expiry, and posting times respectively (or zero, if the time
-component is not available), in addition to \fItoken\fR being set to the
-retrieved token and a function return value of \fBtrue\fR. Any of
-arrived, expires, posted, or token may be \fB\s-1NULL\s0\fR in which case that
-component is not returned to the caller, without affecting the return
-value.
-.PP
-\&\fBHIScheck\fR checks the database \fIhistory\fR for \fIkey\fR (normally the
-Message\-ID); if \fIkey\fR has previously been set via \fBHISwrite\fR,
-\&\fBHIScheck\fR returns \fBtrue\fR, else \fBfalse\fR.
-.PP
-\&\fBHISwrite\fR writes a new entry to the database \fIhistory\fR associated
-with \fIkey\fR. \fIarrived\fR, \fIposted\fR, and \fIexpired\fR specify the arrival,
-posting, and expiry time respectively; \fIposted\fR and \fIexpired\fR may be
-specifed as <= 0 in which case that component shall be treated as
-absent in the database. \fItoken\fR is associated with the specified
-\&\fIkey\fR. \fBHISwrite\fR returns \fBtrue\fR on success, or \fBfalse\fR on
-failure. The behaviour when \fIkey\fR is not unique with respect to the
-existing entries in \fIhistory\fR is unspecified.
-.PP
-\&\fBHISremember\fR writes a new entry to the database \fIhistory\fR
-associated with \fIkey\fR, merely remembering that this \fIkey\fR has been
-seen, together with its arrival time \fIarrived\fR. \fBHISremember\fR
-returns \fBtrue\fR on success, or \fBfalse\fR on failure. The behaviour when
-\&\fIkey\fR is not unique with respect to the existing entries in
-\&\fIhistory\fR is unspecified.
-.PP
-\&\fBHISreplace\fR replaces an existing entry in the database \fIhistory\fR,
-associated with \fIkey\fR. \fIarrived\fR, \fIposted\fR, \fIexpired\fR specify the
-arrival, posting and expiry time respectively; \fIposted\fR and
-\&\fIexpired\fR may be specifed as <= 0 in which case that component shall
-be treated as absent in the database. \fItoken\fR is associated with the
-specified \fIkey\fR; if \fB\s-1NULL\s0\fR then the history database merely
-remembers that this \fIkey\fR has been seen, together with its arrival
-time. \fBHISreplace\fR returns \fBtrue\fR on success, or \fBfalse\fR on
-failure.
-.PP
-\&\fBHISexpire\fR expires the history database associated with \fIhistory\fR,
-creating a new, replacement, database in the same location if \fIpath\fR
-is \fB\s-1NULL\s0\fR, or in \fIpath\fR if not \fB\s-1NULL\s0\fR; if \fIpath\fR is not \fB\s-1NULL\s0\fR
-then the replacement of the old history database with the new one is
-assumed to be performed out of band by the caller. The \fIwriting\fR flag
-is normally passed as \fBtrue\fR, if you wish to inhibit writing of the
-new database (and so merely see the callbacks), \fIwriting\fR may be set
-\&\fBfalse\fR.
-.PP
-If the underlying history mechanism needs to pause the server, the
-\&\fIreason\fR string is used as the argument to the `ctlinnd pause'
-command, and as such the server should be reserved by the caller prior
-to calling \fBHISexpire\fR; if the caller wishes to inhibit pausing of
-the server, passing \fB\s-1NULL\s0\fR will achieve this. If \fIreason\fR is not
-\&\fB\s-1NULL\s0\fR, then on successful return from \fBHISexpire\fR the server will
-be left paused and the caller should unpause it.
-.PP
-The history database is scanned and entries with an associated storage
-token are passed to the discrimination function \fIexists\fR.
-.PP
-If \fIexists\fR() returns \fBfalse\fR it indicates that stored entity
-associated with token is no longer available (or no longer required),
-and therefore the associated history entry may be expired once it
-meets the \fIthreshold\fR constraint. If \fIexists\fR() returns \fBtrue\fR the
-entry is kept as-is in the newly expired history database.
-.PP
-The \fIexists\fR function is passed the arrival, posting and expiry
-times, in addition to the token associated with the entry. Note that
-posting and/or expiry may be zero, but that the token will never be
-\&\fB\s-1NULL\s0\fR (such entries are handled solely via the threshold
-mechanism). The storage token passed to the discrimination function
-may updated if required (for example, as might be needed by a
-hierachical storage management implementation).
-.PP
-Entries in the database with an arrival time less than \fIthreshold\fR
-with no token associated with them are deleted from the database.
-.PP
-The parameter \fIcookie\fR is passed to the discrimination function, and
-may be used for any purpose required by the caller.
-.PP
-If the discrimination function attempts to access the underlying
-database (for read or write) during the callback, the behaviour is
-unspecified.
-.PP
-\&\fBHISwalk\fR provides an iteration function for the specified \fIhistory\fR
-database. For every entry in the history database, \fIcallback\fR is
-invoked, passing the \fIcookie\fR, arrival, posting, and expiry times, in
-addition to the token associated with the entry. If the \fIcallback\fR()
-returns \fBfalse\fR the iteration is aborted and \fBHISwalk\fR returns
-\&\fBfalse\fR to the caller.
-.PP
-To process the entire database in the presence of a running server,
-\&\fIreason\fR may be passed; if this argument is not \fB\s-1NULL\s0\fR, it is used
-as an an argument to the `ctlinnd (reserve|pause|go)' commands. If
-\&\fIreason\fR is \fB\s-1NULL\s0\fR and the server is running, the behaviour of
-\&\fBHISwalk\fR is undefined.
-.PP
-If the callback function attempts to access the underlying database
-during the callback, the behaviour is unspecified.
-.PP
-\&\fBHISstats\fR returns statistics on the history cache mechanism; given a
-handle \fIhistory\fR, the return value is a \fIstruct histstats\fR
-detailing:
-.ie n .IP """hitpos""" 4
-.el .IP "\f(CWhitpos\fR" 4
-.IX Item "hitpos"
-The number of times an item was found directly in the cache and known
-to exist in the underlying history manager.
-.ie n .IP """hitneg""" 4
-.el .IP "\f(CWhitneg\fR" 4
-.IX Item "hitneg"
-The number of times an item was found directly in the cache and known
-not to exist in the underlying history manager.
-.ie n .IP """misses""" 4
-.el .IP "\f(CWmisses\fR" 4
-.IX Item "misses"
-The number of times an item was not found directly in the cache, but
-on retrieval from the underlying history manager was found to exist.
-.ie n .IP """dne""" 4
-.el .IP "\f(CWdne\fR" 4
-.IX Item "dne"
-The number of times an item was not found directly in the cache, but
-on retrieval from the underlying history manager was found not to exist.
-.PP
-Note that the history cache is only checked by \fBHIScheck\fR and only
-affected by \fBHIScheck\fR, \fBHISwrite\fR, \fBHISremember\fR and
-\&\fBHISreplace\fR. Following a call to \fBHISstats\fR the history statistics
-associated with \fIhistory\fR are cleared.
-.PP
-\&\fBHISerror\fR returns a string describing the most recent error
-associated with \fIhistory\fR; the format and content of these strings is
-history manager dependent. Note that on setting an error, the history
-\&\s-1API\s0 will call the \fBwarn\fR function from \fIlibinn\fR\|(3).
-.PP
-\&\fBHISctl\fR provides a control interface to the underlying history
-manager. The \fIrequest\fR argument determines the type of the request
-and the meaning of the \fIval\fR argument. The values for \fIrequest\fR are:
-.ie n .IP """HISCTLG_PATH"" (const char **)" 4
-.el .IP "\f(CWHISCTLG_PATH\fR (const char **)" 4
-.IX Item "HISCTLG_PATH (const char **)"
-Get the base file path which the history handle represents. \fIval\fR
-should be a pointer to a location of type \fBconst char *\fR.  The
-result must not later be passed to \fIfree\fR\|(3).
-.ie n .IP """HISCTLS_PATH"" (const char *)" 4
-.el .IP "\f(CWHISCTLS_PATH\fR (const char *)" 4
-.IX Item "HISCTLS_PATH (const char *)"
-Set the base file path which this history handle should use; typically
-this is used after an anonymous handle has been created using
-\&\fBHISopen(\s-1NULL\s0, ...)\fR. \fIval\fR should be a value of type \fBconst char
-*\fR and will be copied before being stored internally.
-.ie n .IP """HISCTLS_SYNCCOUNT"" (size_t *)" 4
-.el .IP "\f(CWHISCTLS_SYNCCOUNT\fR (size_t *)" 4
-.IX Item "HISCTLS_SYNCCOUNT (size_t *)"
-Set an upper bound on how many history operations may be pending in
-core before being synced to permanent storage; \fB0\fR indicates
-unlimited. \fIval\fR should be a pointer to a value of type \fBsize_t\fR and
-will not be modified by the call.
-.ie n .IP """HISCTLS_NPAIRS"" (size_t *)" 4
-.el .IP "\f(CWHISCTLS_NPAIRS\fR (size_t *)" 4
-.IX Item "HISCTLS_NPAIRS (size_t *)"
-Set a hint to the to the underlying history manager as to how many
-entries there are expected to be in the history database; \fB0\fR
-indicates that an automatic or default sizing should be made. \fIval\fR
-should be a pointer to a value of type \fBsize_t\fR and will not be
-modified by the call.
-.ie n .IP """HISCTLS_IGNOREOLD"" (bool *)" 4
-.el .IP "\f(CWHISCTLS_IGNOREOLD\fR (bool *)" 4
-.IX Item "HISCTLS_IGNOREOLD (bool *)"
-Instruct the underlying history manager to ignore existing database
-when creating new ones; typically this option may be set to \fBtrue\fR if
-the administrator believes that the existing history database is
-corrupt and that ignoring it may help. \fIval\fR should be a pointer to a
-value of type \fBbool\fR and will not be modified by the call.
-.ie n .IP """HISCTLS_STATINTERVAL"" (time_t *)" 4
-.el .IP "\f(CWHISCTLS_STATINTERVAL\fR (time_t *)" 4
-.IX Item "HISCTLS_STATINTERVAL (time_t *)"
-For the history v6 and tagged hash managers, set the interval, in
-seconds, between \fIstat\fR\|(2)s of the history files checking for replaced
-files (as happens during expire); this option is typically used by
-\&\fInnrpd\fR\|(8) like applications. \fIval\fR should be a pointer to a value of
-type \fBtime_t\fR and will not be modified by the call.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Alex Kiernan <alexk@demon.net> for InterNetNews 2.4.0.
-.Sp
-$Id: libinnhist.3 7880 2008-06-16 20:37:13Z iulius $
diff --git a/doc/man/libstorage.3 b/doc/man/libstorage.3
deleted file mode 100644 (file)
index c6f2cfd..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-.\" $Revision: 6124 $
-.TH LIBSTORAGE 3
-.SH NAME
-libstorage \- InterNetNews Storage API library routines
-.SH SYNOPSIS
-.nf
-.ta \w'    unsigned long    'u
-
-#include "storage.h"
-
-.B "bool IsToken(const char *text);"
-
-.B "char *TokenToText(const TOKEN token);"
-
-.B "TOKEN TextToToken(const char *text);"
-
-.B "bool SMsetup(SMSETUP type, void *value);"
-
-.B "bool SMinit(void);"
-
-.B "TOKEN SMstore(const ARTHANDLE article);"
-
-.B "ARTHANDLE *SMretrieve(const TOKEN token, const RETRTYPE amount);"
-
-.B "ARTHANDLE *SMnext(const ARTHANDLE *article, const RETRTYPE amount);"
-
-.B "void SMfreearticle(ARTHANDLE *article);"
-
-.B "bool SMcancel(TOKEN token);"
-
-.B "bool SMprobe(PROBETYPE type, TOKEN *token, void *value);"
-
-.B "void SMprintfiles(FILE *file, TOKEN token, char **xref, int ngroups)"
-
-.B "bool SMflushcacheddata(FLUSHTYPE type);"
-
-.B "void SMshutdown(void);"
-
-.B "int SMerrno;"
-.B "char *SMerrorstr;"
-
-#include "ov.h"
-
-.B "bool OVopen(int mode);"
-
-.B "bool OVctl(OVCTLTYPE type, void *val);"
-
-.B "bool OVgroupstats(char *group, int *lo, int *hi, int *count, int *flag);"
-
-.B "bool OVgroupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag);"
-
-.B "bool OVgroupdel(char *group);"
-
-.B "OVADDRESULT OVadd(TOKEN token, char *data, int len, time_t arrived);"
-
-.B "bool OVcancel(TOKEN token);"
-
-.B "void *OVopensearch(char *group, int low, int high);"
-
-.B "bool OVsearch(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived);"
-
-.B "void OVclosesearch(void *handle);"
-
-.B "bool OVgetartinfo(char *group, ARTNUM artnum, char **data, int *len, TOKEN *token);"
-
-.B "bool OVexpiregroup(char *group, int *lo);"
-
-.B "typedef struct _OVGE {"
-.B "    bool        delayrm;"
-.B "    bool        usepost;"
-.B "    bool        quiet;"
-.B "    bool        keep;"
-.B "    bool        earliest;"
-.B "    bool        ignoreselfexpire;"
-.B "    char        *filename;"
-.B "    time_t      now;"
-.B "    float       timewarp;"
-.B "} OVGE;"
-
-.B "void OVclose(void);"
-
-.fi
-.SH DESCRIPTION
-.I Libstorage
-is a library of common utility (the storage manager) routines for accessing
-Usenet articles and related data independent of particular storage method;
-this is known as the storage API.
-The storage manager's function is to isolate the applications from the
-individual methods and make the policy decisions as to which storage method
-should be called to store an article.
-.PP
-One of the core concepts in the storage API is that articles are not
-manipulated using the message-id or article number, but rather a token that
-uniquely identifies the article to the method that stored it.  This may seem
-to be redundant since the message-id already is a unique identifier for the
-article, however, since the storage method generates the token, it can
-encode all the information it needs to locate the article in the token.
-.PP
-\&``OV'' is a common utility routines for accessing newsgroups and overview
-data independent of particular overview method.
-The ``OV'' function is to isolate the applications from the
-individual methods.
-.PP
-All articles passed through the storage API are assumed to be in wire
-format.  Wire format means ``\\CR\\LF'' at the end of lines, ``.'' at the
-beginning of lines, and ``.\\CR\\LF'' at the end of article on NNTP stream
-are not stripped.  This has a performance win when transferring articles.
-For the ``tradspool'' method, wire format can be disabled.  This is just
-for compatibility which is needed by some old tools written for
-traditional spool.
-.PP
-.I IsToken
-checks to see if the text is formatted as a text token string.
-It returns true if formatted correctly or returns false if not.
-.PP
-.I TokenToText
-converts token into text string for output.
-.PP
-.I TextToToken
-converts text into token.
-.PP
-.I SMsetup
-configures some parameters for use by storage manager.
-.I Type
-is one of following.
-.sp 1
-.in +0.5i
-.nf
-SM_RDWR        allow read/write open for storage
-       files (default is false)
-SM_PREOPEN     open all storage files at startup
-       time and keep them (default is false)
-.fi
-.in -0.5i
-.sp 1
-The
-.I value
-is the pointer which tells each type's value.
-It returns true if setup is successful, or false if not.
-.PP
-.I SMinit
-calls the setup function for all of the configured methods based on
-.IR SMsetup .
-This function should be called prior to all other storage API functions which
-begin with ``SM'' except
-.IR SMsetup .
-It returns true if initialization is successful or returns false if not.
-.I SMinit
-returns true, unless all storage methods fail initialization.
-.PP
-.I SMstore
-stores an article specified with
-.IR article .
-If
-.I arrived
-is specified,
-.I SMstore
-uses its value as article's arrival time; otherwise
-.I SMstore
-uses the current time for it.
-.I SMstore
-returns token type as
-.IR type ,
-or returns
-.I TOKEN_EMPTY
-if article is not stored because some error occurs or simply does not
-match any
-.IR uwildmat (3)
-in
-.IR storage.conf .
-.I SMstore
-fails if
-.I SM_RDWR
-has not been set to true with
-.IR SMsetup .
-.PP
-.I SMretrieve
-retrieves an article specified with
-.IR token .
-.I Amount
-is the one of following which specifies retrieving type.
-.sp 1
-.in +0.5i
-.nf
-RETR_ALL       retrieve whole article
-RETR_HEAD      retrieve headers of article
-RETR_BODY      retrieve body of article
-RETR_STAT      just check to see if article exists
-.fi
-.in -0.5i
-.sp 1
-.PP
-The data area indicated by
-.I ARTHANDLE
-should not be modified.
-.PP
-.I SMnext
-is similar in function to
-.I SMretrieve
-except that it is intended for traversing the method's article store
-sequentially.
-To start a query,
-.I SMnext
-should be called with a NULL pointer
-.IR ARTHANDLE .
-Then
-.I SMnext
-returns
-.I ARTHANDLE
-which should be used for the next query.
-If a NULL pointer
-.I ARTHANDLE
-is returned, no articles are left to be queried.
-If
-.I data
-of
-.I ARTHANDLE
-is NULL pointer or
-.I len
-of
-.I ARTHANDLE
-is 0, it indicates the article may be corrupted and should be cancelled by
-.IR SMcancel .
-The data area indicated by
-.I ARTHANDLE
-should not be modified.
-.PP
-.I SMfreearticle
-frees all allocated memory used by
-.I SMretrieve
-and
-.IR SMnext .
-If
-.I SMnext
-will be called with previously returned
-.IR ARTHANDLE ,
-.I SMfreearticle
-should not be called as
-.I SMnext
-frees allocated memory internally.
-.PP
-.I SMcancel
-removes the article specified with
-.IR token .
-It returns true if cancellation is successful or returns false if not.
-.I SMcancel
-fails if
-.I SM_RDWR
-has not been set to true with
-.IR SMsetup .
-.PP
-.I SMprobe
-checks the token on
-.IR PROBETYPE .
-.I Type
-is one of following.
-.sp 1
-.in +0.5i
-.nf
-SELFEXPIRE     checks to see if the method of the token
-       has self expire functionality
-SMARTNGNUM     gets newsgroup name and article number
-       of the token.
-.fi
-.in -0.5i
-.sp 1
-.PP
-.I SMprintfiles
-shows file name or token usable by
-.IR fastrm (8).
-.PP
-.I SMflushcacheddata
-flushes cached data on each storage method.
-.I Type
-is one of following.
-.sp 1
-.in +0.5i
-.nf
-SM_HEAD        flushes cached header
-SM_CANCELEDART flushes articles which should be canceled
-SM_ALL flushes all cached data
-.fi
-.in -0.5i
-.sp 1
-.PP
-.I SMshutdown
-calls the shutdown for each configured storage method and
-then frees any resources it has allocated for itself.
-.PP
-.I SMerrno
-and
-.I SMerrorstr
-indicate the reason of the last error concerning storage manager.
-.PP
-.I OVopen
-calls the setup function for configured method which is specified as
-\&``ovmethod'' in
-.IR inn.conf .
-.I Mode
-is constructed from following.
-.sp 1
-.in +0.5i
-.nf
-OV_READ        allow read open for overview
-       method
-OV_WRITE       allow write open for overview
-       method
-.fi
-.in -0.5i
-.sp 1
-This function should be called prior to all other OV functions which
-begin with ``OV''.
-.PP
-.I OVctl
-probes or sets some parameters for overview method.
-.I Type
-is one of following.
-.sp 1
-.in +0.5i
-.nf
-OVGROUPBASEDEXPIRE     setup how group-based expiry is
-       done
-OVCUTOFFLOW    do not add overview data, if the
-       data is under lowest article
-OVSORT probe which key is suitable for
-       overview method
-OVSPACE        probe overview space usage
-OVSTATALL      stat all articles when
-       OVexpiregroup is called
-.fi
-.in -0.5i
-.sp 1
-.PP
-.I OVgroupstats
-retrieves specified newsgroup information from overview method.
-.PP
-.I OVgroupadd
-informs overview method that specified newsgroup is being added.
-.PP
-.I OVgroupdel
-informs overview method that specified newsgroup is being removed.
-.PP
-.I OVadd
-stores an overview data.
-.PP
-.I OVcancel
-requests the overview method delete overview data specified with token.
-.PP
-.I OVopensearch
-requests the overview method prepare overview data retrieval.
-The request range is determined by
-.I low
-and
-.IR high .
-.PP
-.I OVsearch
-retrieves information; article number, overview data, or arrival time.
-.I OVsearch
-should be called with NULL handle when it is the first time;
-subsequent
-.I OVsearch
-calls should use the handle returned by the previous call to
-.IR OVsearch .
-.I OVsearch
-returns true, unless it reaches high which is specified by
-.IR OVopensearch .
-Retrieved overview data are sorted by article number, and
-.I len
-is ``0'' if there is no overview data for article.  Note that the
-retrieved data is not neccessarily null-terminated; you should only rely
-on
-.I len
-octets of overview data being present.
-.PP
-.I OVclosesearch
-frees all resources which have been allocated by
-.IR OVopensearch .
-.PP
-.I OVgetartinfo
-retrieves overview data and token specified with
-.IR artnum .
-.PP
-.I OVexpiregroup
-expires overview data for the newsgroup.
-.I OVexpiregroup
-checks the existense of the article and purges overview data if the
-article no longer exists.
-If ``groupbaseexpiry'' in
-.I inn.conf
-is true,
-.I OVexpiregroup
-also expires articles.
-.PP
-.I OVclose
-frees all resources which are used by the overview method.
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: libstorage.3 6124 2003-01-14 06:03:29Z rra $
-.SH "SEE ALSO"
-expire(8),
-inn.conf(5),
-storage.conf(5).
diff --git a/doc/man/list.3 b/doc/man/list.3
deleted file mode 100644 (file)
index 6ea53fc..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-.\" 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 "list 3"
-.TH list 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-list \- list routines
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fB#include <inn/list.h>\fR
-.PP
-struct node {
-    struct node *succ;
-    struct node *pred;
-};
-.PP
-struct list {
-    struct node *head;
-    struct node *tail;
-    struct node *tailpred;
-};
-.PP
-\&\fBvoid list_new(struct list *\fR\fIlist\fR\fB);\fR
-.PP
-\&\fBstruct node *list_addhead(struct list *\fR\fIlist\fR\fB, struct node *\fR\fInode\fR\fB);\fR
-.PP
-\&\fBstruct node *list_addtail(struct list *\fR\fIlist\fR\fB, struct node *\fR\fInode\fR\fB);\fR
-.PP
-\&\fBstruct node *list_head(struct list *\fR\fIlist\fR\fB);\fR
-.PP
-\&\fBstruct node *list_tail(struct list *\fR\fIlist\fR\fB);\fR
-.PP
-\&\fBstruct node *list_succ(struct node *\fR\fInode\fR\fB);\fR
-.PP
-\&\fBstruct node *list_pred(struct node *\fR\fInode\fR\fB);\fR
-.PP
-\&\fBstruct node *list_remhead(struct list *\fR\fIlist\fR\fB);\fR
-.PP
-\&\fBstruct node *list_remtail(struct list *\fR\fIlist\fR\fB);\fR
-.PP
-\&\fBstruct node *list_remove(struct node *\fR\fInode\fR\fB);\fR
-.PP
-\&\fBstruct node *list_insert(struct list *\fR\fIlist\fR\fB, struct node *\fR\fInode\fR\fB, struct node *\fR\fIpred\fR\fB);\fR
-.PP
-\&\fBbool list_isempty(struct list *\fR\fIlist\fR\fB);\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBlist_new\fR initialises the list header \fIlist\fR so as to create an
-empty list.
-.PP
-\&\fBlist_addhead\fR adds \fInode\fR to the head of \fIlist\fR, returning the node
-just added.
-.PP
-\&\fBlist_addtail\fR adds \fInode\fR to the tail of \fIlist\fR, returning the node
-just added.
-.PP
-\&\fBlist_head\fR returns a pointer to the the node at the head of \fIlist\fR
-or \fB\s-1NULL\s0\fR if the list is empty.
-.PP
-\&\fBlist_tail\fR returns a pointer to the the node at the tail of \fIlist\fR
-or \fB\s-1NULL\s0\fR if the list is empty.
-.PP
-\&\fBlist_succ\fR returns the next (successor) node on the list after
-\&\fInode\fR or \fB\s-1NULL\s0\fR if \fInode\fR was the final node.
-.PP
-\&\fBlist_pred\fR returns the previous (predecessor) node on the list before
-\&\fInode\fR or \fB\s-1NULL\s0\fR if \fInode\fR was the first node.
-.PP
-\&\fBlist_remhead\fR removes the first node from \fIlist\fR and returns it to
-the caller. If the list is empty \fB\s-1NULL\s0\fR is returned.
-.PP
-\&\fBlist_remtail\fR removes the last node from \fIlist\fR and returns it to
-the caller. If the list is empty \fB\s-1NULL\s0\fR is returned.
-.PP
-\&\fBlist_remove\fR removes \fInode\fR from the list it is on and returns it
-to the caller.
-.PP
-\&\fBlist_insert\fR inserts \fInode\fR onto \fIlist\fR after the node \fIpred\fR. If
-\&\fIpred\fR is \fB\s-1NULL\s0\fR then \fInode\fR is added to the head of \fIlist\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Alex Kiernan <alex.kiernan@thus.net> for InterNetNews 2.4.0.
-.PP
-$Id: list.3 7880 2008-06-16 20:37:13Z iulius $
diff --git a/doc/man/mailpost.8 b/doc/man/mailpost.8
deleted file mode 100644 (file)
index a477f70..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-.\" 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 "MAILPOST 8"
-.TH MAILPOST 8 "2008-04-26" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-mailpost \- Feed an e\-mail message into a newsgroup
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBmailpost\fR [\fB\-hn\fR] [\fB\-a\fR \fIaddr\fR] [\fB\-b\fR \fIdatabase\fR] [\fB\-c\fR \fIwait-time\fR]
-[\fB\-d\fR \fIdistribution\fR] [\fB\-f\fR \fIaddr\fR] [\fB\-m\fR \fImailing-list\fR]
-[\fB\-o\fR \fIoutput-command\fR] [\fB\-p\fR \fIport\fR] [\fB\-r\fR \fIaddr\fR]
-[\fB\-x\fR \fIheader\fR[\fB:\fR\fIheader\fR...]] \fInewsgroups\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The \fBmailpost\fR program reads a properly formatted e\-mail message from stdin
-and feeds it to \fBinews\fR for posting to a news server.  \fInewsgroups\fR is a
-whitespace-separated list of group names to which to post the article
-(at least one newsgroup must be specified).
-.PP
-Before feeding the article to \fBinews\fR, it checks that the article has not
-been seen before, and it changes some headers (cleans up some address
-headers, removes X\-Trace: and X\-Complaints\-To:, and puts \f(CW\*(C`X\-\*(C'\fR in front
-of unknown headers).
-.PP
-If the article has been seen before (\fBmailpost\fR records the Message-ID of
-each article it handles), then the article will be silently dropped.  Other
-errors will cause the article to be mailed to the newsmaster (selected
-at configure time and defaulting to \f(CW\*(C`usenet\*(C'\fR).
-.PP
-Normally, \fBmailpost\fR is run by \fIsendmail\fR\|(8) via an alias entry:
-.PP
-.Vb 2
-\&    local\-mail\-wreck\-bikes: "|<pathbin in inn.conf>/mailpost
-\&        \-b /var/tmp \-d local local.mail.rec.bicycles.racing"
-.Ve
-.PP
-Instead of \fI/var/tmp\fR, the mail spool directory can be specified,
-or any other directory where the \fBmailpost\fR process has write access.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-a\fR \fIaddr\fR" 4
-.IX Item "-a addr"
-If the \fB\-a\fR flag is used, the value given is added to the article 
-as an Approved: header.
-.IP "\fB\-b\fR \fIdatabase\fR" 4
-.IX Item "-b database"
-If the \fB\-b\fR flag is used, then it defines the location of the database 
-used to store the Message-IDs of articles sent on.  This is to prevent articles
-looping around if a news-to-mail gateway sends them back here.  This option may
-be required if the \fBmailpost\fR process does not have write access to the news
-temporary directory.  The default value is \fIpathtmp\fR as set in \fIinn.conf\fR.
-.IP "\fB\-c\fR \fIwait-time\fR" 4
-.IX Item "-c wait-time"
-The \fB\-c\fR flag indicates a length of time to sleep before posting.  If
-duplicate messages are received in this interval (by any instance of
-\&\fBmailpost\fR using the same database), the article is only posted once, but
-with Newsgroups: header modified to crosspost the article to all indicated
-groups.  The units for \fIwait-time\fR are seconds; a reasonable value may be
-anywhere from tens to hundreds of seconds, or even higher, depending on how
-long mail can be delayed on its way to your system.
-.IP "\fB\-d\fR \fIdistribution\fR" 4
-.IX Item "-d distribution"
-If the \fB\-d\fR flag is used, the value given is added to the article as a
-Distribution: header.
-.IP "\fB\-f\fR \fIaddr\fR" 4
-.IX Item "-f addr"
-The \fB\-f\fR flag is a synonym for the \fB\-r\fR flag.
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Print usage information and exit.
-.IP "\fB\-m\fR \fImailing-list\fR" 4
-.IX Item "-m mailing-list"
-If the \fB\-m\fR flag is used, the value given is added to the article in a 
-Mailing\-List: header, if such a header doesn't already exist.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-If the \fB\-n\fR flag is used, neither an article is posted nor a mail is sent
-in case an error occurs.  Everything is written to the standard output.
-.IP "\fB\-o\fR \fIoutput-command\fR" 4
-.IX Item "-o output-command"
-Specifies the program to which the resulting article processed by \fBmailpost\fR
-should be sent.  For debugging purpose, \f(CW\*(C`\-o cat\*(C'\fR can be used.  The default
-value is \f(CW\*(C`inews \-S \-h\*(C'\fR.
-.IP "\fB\-p\fR \fIport\fR" 4
-.IX Item "-p port"
-Specifies the port on which \fBnnrpd\fR is listening, used for article posting.
-If given, \fB\-p\fR is passed along to \fBinews\fR.
-.IP "\fB\-r\fR \fIaddr\fR" 4
-.IX Item "-r addr"
-A heuristic is used to determine a reasonable value for the Path: header.
-The \fB\-r\fR flag indicates what to use if no other value can be determined.
-.IP "\fB\-x\fR \fIheader\fR[\fB:\fR\fIheader\fR...]" 4
-.IX Item "-x header[:header...]"
-A colon-separated list of additional headers which should be treated as
-known headers; these headers will be passed through to \fBinews\fR without
-having \f(CW\*(C`X\-\*(C'\fR prepended.
-.Sp
-Known headers are:
-.Sp
-.Vb 12
-\&    Approved
-\&    Content\-*
-\&    Date
-\&    Distribution
-\&    From
-\&    Mailing\-List
-\&    Message\-ID
-\&    MIME\-*
-\&    References
-\&    Return\-Path
-\&    Sender
-\&    Subject
-.Ve
-.SH "FILES"
-.IX Header "FILES"
-.IP "\fIpathbin\fR/mailpost" 4
-.IX Item "pathbin/mailpost"
-The Perl script itself used to feed an e\-mail message to a newsgroup.
-.IP "\fIpathtmp\fR/mailpost\-msgid.dir and \fIpathtmp\fR/mailpost\-msgid.pag" 4
-.IX Item "pathtmp/mailpost-msgid.dir and pathtmp/mailpost-msgid.pag"
-The default database files which record previously seen Message\-IDs.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Paul Vixie long ago and then hacked up by James Brister for \s-1INN\s0 
-integration.
-.PP
-$Id: mailpost.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive\fR\|(5), \fIinews\fR\|(1), \fIinn.conf\fR\|(5), \fInnrpd\fR\|(8), \fIuwildmat\fR\|(3).
diff --git a/doc/man/makeactive.8 b/doc/man/makeactive.8
deleted file mode 100644 (file)
index 7bb63e6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-.\" $Revision: 5909 $
-.TH MAKEACTIVE 8
-.SH NAME
-makeactive \- tool to recover Usenet active file.
-.SH SYNOPSIS
-.IR makeactive (8)
-is obsolete.
-.SH "SEE ALSO"
-active(5)
diff --git a/doc/man/makedbz.8 b/doc/man/makedbz.8
deleted file mode 100644 (file)
index 702d2a7..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-.\" $Revision: 5909 $
-.TH MAKEDBZ 8
-.SH NAME
-makedbz \- rebuild dbz files
-.SH SYNOPSIS
-.B makedbz
-[
-.BI \-f " filename"
-]
-[
-.B \-i
-]
-[
-.B \-o
-]
-[
-.BI \-s " size"
-]
-.SH DESCRIPTION
-.PP
-.I Makedbz
-rebuilds
-.IR dbz (3)
-database.
-The default name of the text file is
-.IR <pathdb\ in\ inn.conf>/history ;
-to specify a different name, use the ``\fB\-f\fP'' flag.
-.SH OPTIONS
-.TP
-.B \-f file
-If the ``\fB\-f\fP'' flag is used, then the database files are named
-.IR file.dir ,
-.IR file.index ,
-and
-.IR file.hash .
-If the ``\fB\-f\fP'' flag is not used, then a temporary link to the name
-.I history.n
-is made and the database files are written as
-.I history.n.index
-,
-.I history.n.hash
-and
-.IR history.n.dir .
-.TP
-.B \-i
-To ignore the old database use the ``\fB\-i\fP'' flag.
-Using the ``\fB\-o\fP'' or ``\fB\-s\fP'' flags implies the ``\fB\-i\fP'' flag.
-.TP
-.B \-o
-If the ``\fB\-o\fP'' flag is used, then the link is not made and any existing
-history files are overwritten.
-If the old database exists,
-.I makedbz
-will use it to determine the size of the new database.
-.TP
-.B \-s size
-The program will also ignore any old database if the ``\fB\-s\fP'' flag is used
-to specify the approximate number of entries in the new database.
-Accurately specifying the size is an optimization that will create a more
-efficient database.  Size is measured in key-value pairs (i.e., lines).
-(The size should be the estimated eventual size of the file, typically
-the size of the old file.)
-For more information, see the discussion of
-.I dbzfresh
-and
-.I dbzsize
-in
-.IR dbz (3).
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: makedbz.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-dbz(3),
-history(5),
-inn.conf(5).
diff --git a/doc/man/makehistory.8 b/doc/man/makehistory.8
deleted file mode 100644 (file)
index 5c8582e..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-.\" 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 "MAKEHISTORY 8"
-.TH MAKEHISTORY 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-makehistory \- Initialize or rebuild INN history database
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBmakehistory\fR [\fB\-abeFIOx\fR] [\fB\-f\fR \fIfilename\fR] [\fB\-l\fR \fIcount\fR]
-[\fB\-T\fR \fItmpdir\fR] [\fB\-s\fR \fIsize\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBmakehistory\fR rebuilds the \fIhistory\fR\|(5) text file, which contains a list of
-Message-IDs of articles already seen by the server.  It can also be used
-to rebuild the overview database.  Note that the \fIdbz\fR\|(3) indexes for the
-history file are rebuilt by \fImakedbz\fR\|(8), not by \fBmakehistory\fR as in
-earlier versions of \s-1INN\s0.
-.PP
-The default location of the history text file is \fIpathdb\fR/history; to
-specify an alternate location, use the \fB\-f\fR flag.
-.PP
-By default, \fBmakehistory\fR will scan the entire spool, using the storage
-manager, and write a history line for every article.  To also generate
-overview information, use the \fB\-O\fR flag.
-.PP
-\&\s-1WARNING:\s0 If you're trying to rebuild the overview database, be sure to
-stop \fIinnd\fR\|(8) and delete or zero out the existing database before you start
-for the best results.  An overview rebuild should not be done while the
-server is running.  Unless the existing overview is deleted, you may end
-up with problems like out-of-order overview entries, excessively large
-overview buffers, and the like.
-.PP
-If \fIovmethod\fR in \fIinn.conf\fR is \f(CW\*(C`ovdb\*(C'\fR, you must have the ovdb processes
-running while rebuilding overview.  ovdb needs them available while
-writing overview entries.  You can start them by hand separate from the
-rest of the server by running \fBovdb_init\fR; see \fIovdb_init\fR\|(8) for more
-details.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-a\fR" 4
-.IX Item "-a"
-Append to the history file rather than generating a new one.  If you
-append to the main history file, make sure \fIinnd\fR\|(8) is throttled or not
-running, or you can corrupt the history.
-.IP "\fB\-b\fR" 4
-.IX Item "-b"
-Delete any messages found in the spool that do not have valid Message-ID
-headers in them.
-.IP "\fB\-e\fR" 4
-.IX Item "-e"
-Compute Bytes headers which is used for overview data.  This option is valid
-only if \fB\-O\fR flag is specified and \fIoverview.fmt\fR includes \f(CW\*(C`Bytes:\*(C'\fR.
-.IP "\fB\-f\fR \fIfilename\fR" 4
-.IX Item "-f filename"
-Rather than writing directly to \fIpathdb\fR/history, instead write to
-\&\fIfilename\fR.
-.IP "\fB\-F\fR" 4
-.IX Item "-F"
-Fork a separate process to flush overview data to disk rather than doing
-it directly.  The advantage of this is that it allows \fBmakehistory\fR to
-continue to collect more data from the spool while the first batch of data
-is being written to the overview database.  The disadvantage is that up to
-twice as much temporary disk space will be used for the generated overview
-data.  This option only makes sense in combination with \fB\-O\fR.  With
-\&\f(CW\*(C`buffindexed\*(C'\fR, the \f(CW\*(C`overchan\*(C'\fR program is invoked to write overview.
-.IP "\fB\-I\fR" 4
-.IX Item "-I"
-Don't store overview data for articles numbered lower than the lowest
-article number in \fIactive\fR.  This is useful if there are for whatever
-reason old articles on disk that shouldn't be available to readers or put
-into the overview database.
-.IP "\fB\-l\fR \fIcount\fR" 4
-.IX Item "-l count"
-This option specifies how many articles to process before writing the
-accumulated overview information out to the overview database.  The
-default is \f(CW10000\fR.  Since overview write performance is faster with
-sorted data, each \*(L"batch\*(R" gets sorted.  Increasing the batch size
-with this option may further improve write performance, at the cost
-of longer sort times.  Also, temporary space will be needed to store
-the overview batches.  At a rough estimate, about 300 * \fIcount\fR bytes
-of temporary space will be required (not counting temp files created
-by \fIsort\fR\|(1)).  See the description of the \fB\-T\fR option for how to
-specify the temporary storage location.  This option has no effect
-with \f(CW\*(C`buffindexed\*(C'\fR, because \f(CW\*(C`buffindexed\*(C'\fR does not need sorted
-overview and no batching is done.
-.IP "\fB\-s\fR \fIsize\fR" 4
-.IX Item "-s size"
-Size the history database for approximately \fIsize\fR pairs.  Accurately
-specifying the size is an optimization that will create a more
-efficient database.  (The size should be the estimated eventual size
-of the \fIhistory\fR file, typically the size of the old file, in lines.)
-.IP "\fB\-O\fR" 4
-.IX Item "-O"
-Create the overview database as well as the history file.  Overview
-information is only required if the server supports readers; it is not
-needed for a transit-only server (see \fIenableoverview\fR in \fIinn.conf\fR\|(5)).
-If you are using the \f(CW\*(C`buffindexed\*(C'\fR overview storage method, erase all of
-your overview buffers before running \fBmakehistory\fR with \fB\-O\fR.
-.IP "\fB\-T\fR \fItmpdir\fR" 4
-.IX Item "-T tmpdir"
-If \fB\-O\fR is given, \fBmakehistory\fR needs a location to write temporary
-overview data.  By default, it uses \fIpathtmp\fR, set in \fIinn.conf\fR, but if
-this option is given, the provided \fItmpdir\fR is used instead.  This is
-also used for temporary files created by \fIsort\fR\|(1) (which is invoked in the
-process of writing overview information since sorted overview information
-writes faster).  By default, sort usually uses your system temporary
-directory; see the \fIsort\fR\|(1) man page on your system to be sure.
-.IP "\fB\-x\fR" 4
-.IX Item "-x"
-If this option is given, \fBmakehistory\fR won't write out history file
-entries.  This is useful mostly for building overview without generating
-a new history file.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Here's a typical example of rebuilding the entire history and overview
-database, removing broken articles in the news spool.  This uses the
-default temporary file locations and should be done while innd isn't
-running (or is throttled).
-.PP
-.Vb 1
-\&    makehistory \-b \-f history.n \-O \-l 30000 \-I
-.Ve
-.PP
-This will rebuild the overview (if using \f(CW\*(C`buffindexed\*(C'\fR, erase the
-existing overview buffers before running this command) and leave a new
-history file as \f(CW\*(C`history.n\*(C'\fR in \fIpathdb\fR.  To preserve all of the history
-entries from the old history file that correspond to rejected articles or
-expired articles, follow the above command with:
-.PP
-.Vb 2
-\&    cd /usr/local/news/db
-\&    awk 'NF == 2 { print }' < history >> history.n
-.Ve
-.PP
-(replacing the path with your \fIpathdb\fR, if it isn't the default).  Then
-look over the new history file for problems and run:
-.PP
-.Vb 1
-\&    makedbz \-s `wc \-l < history` \-f history.n
-.Ve
-.PP
-Then rename all of the files matching \f(CW\*(C`history.n.*\*(C'\fR to \f(CW\*(C`history.*\*(C'\fR,
-replacing the current history database and indexes.  After that, it's safe
-to unthrottle innd.
-.PP
-For a simpler example:
-.PP
-.Vb 1
-\&    makehistory \-b \-f history.n \-I \-O
-.Ve
-.PP
-will scan the spool, removing broken articles and generating history and
-overview entries for articles missing from history.
-.PP
-To just rebuild overview:
-.PP
-.Vb 1
-\&    makehistory \-O \-x \-F
-.Ve
-.SH "FILES"
-.IX Header "FILES"
-.IP "inn.conf" 4
-.IX Item "inn.conf"
-Read for \fIpathdb\fR, \fIpathtmp\fR, and other settings.
-.IP "\fIpathdb\fR/history" 4
-.IX Item "pathdb/history"
-This is the default output file for \fBmakehistory\fR.
-.IP "\fIpathtmp\fR" 4
-.IX Item "pathtmp"
-Where temporary files are written unless \fB\-T\fR is given.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Originally written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews and
-updated by various other people since.
-.PP
-$Id: makehistory.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIdbz\fR\|(3), \fIactive\fR\|(5), \fIhistory\fR\|(5), \fIinn.conf\fR\|(5), \fIctlinnd\fR\|(8), \fIinnd\fR\|(8),
-\&\fImakedbz\fR\|(8), \fIovdb_init\fR\|(8), \fIoverview.fmt\fR\|(5).
diff --git a/doc/man/mod-active.8 b/doc/man/mod-active.8
deleted file mode 100644 (file)
index cb224b3..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-.\" $Revision: 5909 $
-.TH MOD-ACTIVE 8
-.SH NAME
-mod-active \- batch processing of ctlinnd newgroup/rmgroup/changegroup
-.SH SYNOPSIS
-.B mod-active
-[
-.I ctlinnd_command_file
-]
-.SH DESCRIPTION
-.B mod-active
-is a
-.B perl
-script that updates the
-.I active
-file based on its input lines of ctlinnd newgroup, rmgroup and
-changegroup commands.  It pauses the server briefly while the existing
-active file is read and rewritten, which not only keeps
-.B innd
-from updating the active file but also locks against other instances
-of
-.BR mod-active .
-.PP
-The input to
-.B mod-active
-can come either from one or more files named on the command line, or
-from the standard input.  Typically its input is the output from the
-.B docheckgroups
-or
-.B actsync
-commands.  Every line which contains the string "ctlinnd newgroup",
-"ctlinnd rmgroup", or "ctlinnd changegroup", optionally preceded by
-whitespace and/or the path to 
-.BR ctlinnd ,
-is noted for the update.  Redundant commands, such as a newgroup
-directive for a group that already exists, are silently ignored.  All
-other lines in the input are also silently ignored.
-.PP
-After the new 
-.I active
-file has been generated, the existing one is renamed to
-.I active.old
-and the new one is moved into place.  The script then displays the
-differences between the two files.
-.PP
-Any groups that were added to the
-.I active
-file are also added to the
-.I active.times
-file with the string "checkgroups-update".
-.SH BUGS
-Though
-.B innd
-is paused while
-.B mod-active
-works, it is not inconceivable that there could be a conflict if
-something else tries to update the active file during the relatively
-short time that mod-active is working.  The two most realistic ways I
-can think of for this to happen are either by an administrator
-concurrently doing a manual ctlinnd command, or by
-.B innd 
-receiving a control message, then
-.B mod-active
-pausing the server, then the control message handler script that
-.B innd
-forked running its own
-.B ctlinnd
-command while
-.B mod-active
-is working.
-I've been using
-.B mod-active
-regularly for several years, though, and never had either problem.
-.SH HISTORY
-Written by David C Lawrence <tale@isc.org>.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.SH "SEE ALSO"
-.IR active (5),
-.IR active.times (5),
-.IR actsync (8),
-.IR ctlinnd (8),
-.IR innd (8).
diff --git a/doc/man/moderators.5 b/doc/man/moderators.5
deleted file mode 100644 (file)
index 35ad6b6..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-.\" $Revision: 5909 $
-.TH MODERATORS 5
-.SH NAME
-moderators \- submission addresses for moderated newsgroups
-.SH DESCRIPTION
-When an unapproved article is posted locally to a moderated newsgroup,
-it is not passed off to
-.IR innd (8)
-for normal handling; instead it's instead sent via e-mail to the submission
-address for that newsgroup.  The file
-.I <pathetc in inn.conf>/moderators
-lists the submission addresses for moderated newsgroups.
-This file is used by
-.IR nnrpd "(8), " inews (1),
-and any other program that uses the GetModeratorAddress() routine (see
-.IR libinn (3)).
-.PP
-The moderators file is a list of associations between
-.IR uwildmat(3)
-patterns matching newsgroups and the submission address for those
-newsgroups.
-Blank lines and lines starting with a number sign (``#'') are ignored.
-All other lines should consist of two fields separated by a colon.
-.PP
-The first field specifies the group or groups to match using
-.IR uwildmat(3).
-The first matching line is used, so more specific patterns should occur
-earlier than general patterns.
-.PP
-The second field, the submission address, may have at most one
-.I %s
-anywhere in it; if present, this will be replaced by the name of the
-newsgroup with periods replaced by dashes.  If there is a literal ``%'' in
-the submission address, it must be written as ``%%'' (even if not followed
-by an ``s'').
-.PP
-Here is a sample file:
-.RS
-.nf
-
-example.important:announce-request@example.com
-example.*:%s@smtp.example.com
-gnu.*:%s@prep.ai.mit.edu
-*:%s@moderators.isc.org
-
-.fi
-.RE
-Using the above file, postings to the moderated newsgroup in the left
-column will be sent to the address shown in the right column:
-.RS
-.nf
-
-.ta \w'example.x.announce   'u
-example.important      announce-request@example.com
-example.x.announce     example-x-announce@smtp.example.com
-gnu.emacs.sources      gnu-emacs-sources@prep.ai.mit.edu
-comp.sources.unix      comp-sources-unix@moderators.isc.org
-
-.fi
-.RE
-Periods are converted to dashes for historical reasons, from back in the
-days when periods in the local part of addresses were not always handled
-correctly.  It's probably no longer necessary, but so much now depends on
-it that it can't be easily changed.
-.PP
-It's intended that the sample moderators file included in the INN
-distribution always be sufficient for all world-wide newsgroups.  The
-hosts behind moderators.isc.org have graciously volunteered to handle
-forwarding tasks for all world-wide newsgroups so that individual sites
-don't have to keep track of the submission addresses for moderated groups.
-The forwarding database used by moderators.isc.org is coordinated by
-moderators-request@isc.org; if you know of a world-wide newsgroup
-hierarchy that is not correctly handled by moderators.isc.org, please send
-the details to that address.
-.PP
-Given that, the only thing you should have to add to the sample file under
-normal circumstances are the forwarding addresses for local or 
-limited-distribution moderated groups.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: moderators.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inews(1), inn.conf(5), libinn(3), uwildmat(3).
diff --git a/doc/man/motd.news.5 b/doc/man/motd.news.5
deleted file mode 100644 (file)
index b59bfac..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-.\" 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 "MOTD.NEWS 5"
-.TH MOTD.NEWS 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-motd.news \- Message of the day information for readers
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This file, found in \fIpathetc\fR/motd.news, contains local information for
-news readers in a free-form format.  The entire file is returned verbatim
-to any client that issues the \s-1LIST\s0 \s-1MOTD\s0 command.  This might be used for
-new information, notification of upcoming downtime, or similar purposes.
-.PP
-Be aware that use of the \s-1LIST\s0 \s-1MOTD\s0 command is not widespread and most news
-clients will never ask for this file.
-.PP
-If this file is missing, it is not an error.  The server will just send
-the client an empty response.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Rewritten in \s-1POD\s0 by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: motd.news.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5)
diff --git a/doc/man/news.daily.8 b/doc/man/news.daily.8
deleted file mode 100644 (file)
index feb0a01..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-.TH NEWS.DAILY 8
-.SH NAME
-news.daily \- do regular Usenet system administration
-.SH SYNOPSIS
-.B news.daily
-[
-.B keyword...
-]
-
-.SH DESCRIPTION
-.I News.daily
-performs a number of important Usenet administrative functions.
-This includes producing a status report, removing old news articles, 
-processing log files, rotating the archived log files, renumbering the
-active file, 
-removing any old socket files found in the
-.I <pathrun in inn.conf>
-directory, and collecting the output.
-.I "This program should be run under the news administrator's id, not as root."
-.PP
-By default, 
-.I news.daily
-performs all of its functions and mails the output to the news administrator,
-.IR <USER\ specified\ with\ \-\-with\-news\-master\ at\ configure> .
-By specifying ``keywords'' on the command line, it is possible to
-modify the functions performed, as well as change the arguments given to
-.IR expire (8)
-and
-.IR expireover (8).
-.PP
-.I News.daily
-should be run once a day, typically out of
-.IR cron (8).
-It may be run more often, but such invocations should at least use the
-\&``norotate'' keyword (or perhaps the \&``notdaily'' keyword) to
-prevent the log files from being processed and rotated too fast.
-.PP
-The
-.IR shlock (1)
-program is used to prevent simultaneous executions.
-.SH "KEYWORDS"
-.PP
-The following keywords may be used:
-.TP
-.I delayrm
-This uses the ``\fB\-z\fP'' flag when invoking
-.I expire
-and
-.IR expireover .
-The names of articles to be removed are written to a temporary file, and
-then renamed after expiration by calling
-.IR expirerm (8).
-.TP
-.IR expctl= path
-Specify the file to use as the
-.IR expire.ctl (5)
-file for
-.IR expire .
-.TP
-.IR expdir= path
-By default,
-.I expire
-builds the new
-.IR history (5)
-file and database in the same directory as the current files.
-Using this keyword specifies a different local to build the new files
-(by passing the ``\fB\-d\fP'' flag to
-.IR expire ),
-which will then be moved to the right location when finished.
-.TP
-.I nostat
-This keyword disables the status report generated by
-.I innstat
-(see
-.IR innstat (8)).
-Without this keyword, the status report is the first function performed,
-just prior to obtaining the
-.I news.daily
-lock.
-.TP
-.I notdaily
-By default 
-.I news.daily
-expects to be run only once a day, and it does
-various things (like rotating logs) that normally should only be done on
-daily basis. Use this keyword any extra times
-.I news.daily
-is run in the
-day and the normal logfile processing (and rotation) will not be done.
-.TP
-.I noexpire
-By default,
-.I expire
-is invoked to remove old news articles.
-Using this keyword disables this function.
-.TP
-.I noexpireover
-By default,
-.I expireover
-is invoked to remove old overview database, if
-.I enableoverview
-is set in
-.IR inn.conf .
-Using this keyword disables this function.
-.TP
-.I noexplog
-.I Expire
-normally appends information to
-.I <pathlog in inn.conf>/expire.log
-(see
-.IR newslog (5)).
-Using this keyword causes the
-.I expire
-output to be handled as part of 
-.IR news.daily 's
-output.
-It has no effect if the ``noexpire'' keyword is used.
-.TP
-.IR flags= "'args\ for\ expire'"
-By default, 
-.I expire
-is invoked with argument ``\-v1''.
-Using this keyword changes the arguments to those specified.
-Be careful to use quotes if multiple arguments are needed.
-This keyword has no effect if the ``noexpire'' keyword is used.
-.TP
-.I nologs
-After expiration,
-.IR scanlogs (8)
-is invoked to process the log files.
-Using this keyword disables all log processing functions.
-.TP
-.I norotate
-By default, log processing includes rotating and cleaning out log files.
-Using this keyword disables the rotating and cleaning aspect of the log
-processing: the logs files are only scanned for information and no contents
-are altered.
-.IP
-This keyword has no effect if the ``nologs'' keyword is used.
-The ``norotate'' keyword is passed on to
-.I scanlogs
-if it is invoked.
-.TP
-.I norenumber
-This keyword disables the
-.IR ctlinnd (8)
-renumber operation.
-Normally, the low-water marks for all newsgroups (see
-.IR active (5))
-are reset.
-.TP
-.I norm
-By default, any socket
-.I ctlinnd
-socket that has not been modified for two days will be removed.
-Using this keyword disables this function.
-.TP
-.I nomail
-.I News.daily
-normally sends a mail message containing the results to the administrator.
-Using this keyword causes this message to be sent to stdout and stderr instead.
-Normally, all utilities invoked by the script have their stdout and stderr
-redirected into a file.
-If the file is empty, no message is sent.
-.TP
-.I expireover
-The
-.I expireover
-program is called after expiration to purge the overview databases.
-If no overview data is created, the ``expireover''
-keyword is not needed.  This is the case that the server runs only for
-feeder(no reader).
-.TP
-.IR expireoverflags= "'args\ for\ expireover'"
-If the ``expireover'' keyword is used, this keyword may be used to specify
-the flags to be passed to
-.IR expireover .
-If the ``delayrm'' keyword is used, then the default value is ``\-z''
-and the list of deleted files; otherwise, the default value is ``\-s''.
-.TP
-.I /full/path
-The program specified by the given path is executed just before any
-expiration is done.
-A typical use is to specify an alternate expiration program and use the
-\&``noexpire'' keyword.
-Multiple programs may be specified; they will be invoked in order.
-.TP
-.IR postexec= "'post executed program'"
-The program specified by the given path is executed just after all
-expiration is done.
-Multiple programs may be specified; they will be invoked in order.
-.TP
-.I lowmark
-If the ``lowmark'' keyword is used, 
-.IR ctlinnd (8)
-lowmark is used for renumbering
-.IR active .
-Normal
-.IR ctlinnd (8)
-renumber operation will take long time.  With ``lowmark'' keyword this will
-take less time.
-If the ``lowmark'' keyword is used,
-\&``norenumber'' keyword is not needed, since
-.I news.daily
-specifies it implicitly.
-.TP
-.IR tmpdir= path
-Sets the environment variable TMPDIR to the specified path.
-Various parts of the expire process, such as sort, will then use this
-path as the directory for temporary files.
-.SH HISTORY
-.I News.daily
-and this manual page written by Landon Curt Noll <chongo@toad.com> and
-Rich $alz <rsalz@uunet.uu.net>.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: news.daily.8 6398 2003-07-12 19:15:50Z rra $
-.SH "SEE ALSO"
-active(5),
-ctlinnd(8), 
-expire(8),
-fastrm(8),
-inn.conf(5),
-newslog(5),
-innwatch.ctl(5),
-shlock(1).
diff --git a/doc/man/news2mail.8 b/doc/man/news2mail.8
deleted file mode 100644 (file)
index 910f1a2..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-.\" -*- nroff -*-
-.\" $Revision: 5909 $
-.TH NEWS2MAIL 8
-.SH NAME
-news2mail \- a channel script to gateway news into email.
-.SH SYNOPSIS
-.I news2mail
-.SH DESCRIPTION
-.I news2mail
-runs as a channel process underneath innd. It is set up as channel feed in
-newsfeeds, with different mailing lists as funnel entries pointing to it (see
-below).
-.PP
-.I news2mail
-uses a config file 
-.PP
-.RS
-.I <pathetc\ in\ inn.conf>/news2mail.cf
-.RE
-.PP
-to map mailing list names to email addresses.
-.PP
-.I news2mail
-causes sendmail to queue the messages for later delivery (to avoid DOS attacks
-by mass postings). You must run 'sendmail -q' periodically to get the queue
-processed.
-.SH CONFIG FILE
-The config file format is simple: comments (start with ``#'') and blank lines
-are ignored. All other lines have two fields on them. The first is the list
-name and is what innd uses (i.e. the site field of the entry in the newsfeeds
-file). The second field is the actual email address to send the article to. In
-the email message, the ``To'' header will have the mailing list name (i.e. the
-first field).
-.PP
-.RS
-.nf
-# list-name             address
-big-red-ants@ucsd.edu   big-red-ants-digest@ucsd.edu           
-news-software@ucsd.edu  news-software-digest@ucsd.edu
-.fi
-.RE
-.PP
-a set of newsfeeds entries for these lists would be:
-.PP
-.RS
-.nf
-.ds R$ <pathbin in inn.conf>
-n2m!:!*:Tc,Ac,Wn*:\*(R$/news2mail
-
-big-red-ants@ucsd.edu:rec.pets.redants.*:Tm:n2m!
-
-news-software@ucsd.edu:news.software.nntp:Tm:n2m!
-.fi
-.RE
-.PP
-.I news2mail
-strips most article headers from the article before mailing. It leaves: From, Subject
-Date, Organization and Message-ID in there. It add a To header with the mailing 
-list name in it.
-.SH HISTORY
-news2mail was written by Brian Kantor. This man page was written by James
-Brister.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: news2mail.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-ctlinnd(8),
-inn.conf(5),
-innd(8),
-newsfeeds(5),
-shlock(1).
-
diff --git a/doc/man/newsfeeds.5 b/doc/man/newsfeeds.5
deleted file mode 100644 (file)
index cc75700..0000000
+++ /dev/null
@@ -1,911 +0,0 @@
-.\" 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 "NEWSFEEDS 5"
-.TH NEWSFEEDS 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-newsfeeds \- Determine where Usenet articles are sent
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpathetc\fR/newsfeeds specifies how incoming articles should be
-distributed to other programs and files on the server.  It is parsed by
-the InterNetNews server \fIinnd\fR\|(8) when it starts up, or when directed to by
-\&\fIctlinnd\fR\|(8).  \fBinnd\fR doesn't send articles to remote sites itself, so
-\&\fInewsfeeds\fR doesn't directly determine which remote news servers articles
-are sent to.  Instead, it specifies what batch files should be created or
-which programs should be run (and what information should be sent to
-them), and then this information is used by programs like \fIinnxmit\fR\|(8) and
-\&\fIinnfeed\fR\|(8) to feed articles to remote sites.
-.PP
-The \fInewsfeeds\fR file isn't used solely to set up feeding accepted
-articles to remote sites but also to pass them (or bits of information
-about them) to any local programs or files that want that data.  For
-example, \fIcontrolchan\fR\|(8), a daemon that processes incoming control
-messages, runs out of \fInewsfeeds\fR, as could a news to mail gateway.
-.PP
-The file is interpreted as a set of lines, parsed according to the
-following rules:  If a line ends with a backslash, the backslash, the
-newline, and any whitespace at the start of the next line is deleted.
-This is repeated until the entire \*(L"logical\*(R" line is collected.  If the
-logical line is blank or starts with a number sign (\f(CW\*(C`#\*(C'\fR), it is ignored.
-.PP
-All other lines are interpreted as feed entries.  An entry should consist
-of four colon-separated fields; two of the fields may have optional
-sub\-fields, marked off by a slash.  Fields or sub-fields that take
-multiple parameters should be separated by a comma.  Extra whitespace can
-cause problems and should be avoided.  Except for the site names, case is
-significant.  The format of an entry is:
-.PP
-.Vb 4
-\&    sitename[/exclude,exclude,...]\e
-\&        :pattern,pattern...[/distribution,distribution...]\e
-\&        :flag,flag...\e
-\&        :parameter
-.Ve
-.PP
-Each field is described below.
-.PP
-The \fIsitename\fR is the name of the site to which a news article can be
-sent.  It is used for writing log entries and for determining if an
-article should be forwarded to a site.  (A \*(L"site\*(R" is the generic term for
-some destination of newsfeed data; it often corresponds to a remote news
-peer, but doesn't have to.  For example, a local archiving program run
-from \fInewsfeeds\fR is also a \*(L"site.\*(R")  If \fIsitename\fR already appears in
-the article's Path: header, then the article will not be sent to the site.
-The name is usually whatever the remote site uses to identify itself in
-the Path: header, but can be almost any word.
-.PP
-Be careful, though, to avoid having the \fIsitename\fR accidentally match a
-Path: header entry unintentionally.  For this reason, special local
-entries (such as archivers or gateways) should probably end with an
-exclamation point to make sure that they do not have the same name as any
-real site.  For example, \f(CW\*(C`gateway\*(C'\fR is an obvious name for the local entry
-that forwards articles out to a mailing list.  If a site with the name
-\&\f(CW\*(C`gateway\*(C'\fR posts an article, when the local site receives the article it
-will see the name in the Path and not send the article to its own
-\&\f(CW\*(C`gateway\*(C'\fR entry.  Since \f(CW\*(C`gateway!\*(C'\fR can't appear as an individual Path:
-entry since \f(CW\*(C`!\*(C'\fR is a delimiter in the Path: header, that would be a
-better thing to use for \fIsitename\fR.
-.PP
-(Another way to avoid this problem is with the \f(CW\*(C`Ap\*(C'\fR flag; see the
-description below.)
-.PP
-If an entry has an exclusion sub\-field, the article will not be sent to
-that site if any of \fIexclude\fR appear in the Path: header.  (It's
-sometimes convenient to have the \fIsitename\fR be an abbreviated form of the
-name of the remote site, since all the \fIsitename\fRs to which an article
-is sent are written to the log and using shorter \fIsitename\fRs can
-therefore improve performance for large servers.  In this case, the Path:
-header entries of those sites should be given as \fIexclude\fR entries and
-the \f(CW\*(C`Ap\*(C'\fR flag used so that the abbreviated \fIsitename\fR doesn't
-accidentally match some other Path: header entry.)
-.PP
-The same \fIsitename\fR can be used more than once and the appropriate action
-will be taken for each entry that should receive the article, but this is
-recommended only for program feeds to avoid confusion.  Case is not
-significant in site names.
-.PP
-The comma-separated \fIpattern\fR specifies which groups to send to the site;
-it is interpreted to build a \*(L"subscription list\*(R" for the site.  The
-default subscription is to get all groups carried by the server.  It is a
-\&\fIuwildmat\fR\|(3) pattern supporting poison (\f(CW\*(C`@\*(C'\fR) wildcards; see the \fIuwildmat\fR\|(3)
-man page for full details on the pattern matching language.  \fIpattern\fR
-will be matched against every newsgroup carried by the server and all
-newsgroups that match will be added to the subscription list for the site.
-.PP
-Normally, a given article (or information about it) is sent to a site if
-any of the newsgroups to which the article was posted are in that site's
-subscription list.  If a newsgroup matches a \f(CW\*(C`@\*(C'\fR pattern in \fIpattern\fR,
-then not only is it not added to the subscription list, but any articles
-crossposted to that newsgroup also will not be sent to that site even if
-other newsgroups to which it was crossposted are in that site's
-subscription list.  This is called a poison pattern (because matching
-groups are \*(L"poisoned\*(R").
-.PP
-For example, to receive all comp.* groups, but only comp.sources.unix
-within the sources newsgroups, the following \fIpattern\fR can be used:
-.PP
-.Vb 1
-\&    comp.*,!comp.sources.*,comp.sources.unix
-.Ve
-.PP
-Note that the trailing \f(CW\*(C`.*\*(C'\fR is required; the pattern has to match the
-whole newsgroup name.  \f(CW\*(C`comp.sources.*\*(C'\fR could be written \f(CW\*(C`comp.sources*\*(C'\fR
-and would exclude the newsgroup comp.sources (if it exists) as well as the
-groups in the comp.sources.* hierarchy, but note that this would also
-exclude a newsgroup named comp.sources\-only (whereas the above pattern
-would add that group to the site subscription list since it matches
-\&\f(CW\*(C`comp.*\*(C'\fR and none of the other patterns.
-.PP
-For another example, to feed alt.* and misc.* to a given site but not any
-articles posted to alt.binaries.warez (even if they're also crossposted to
-other alt.* or misc.* groups), the following pattern can be used:
-.PP
-.Vb 1
-\&    alt.*,@alt.binaries.warez,misc.*
-.Ve
-.PP
-Note, however, that if you reversed the \f(CW\*(C`alt.*\*(C'\fR and <@alt.binaries.warez>
-entries, this pattern would be equivalent to \f(CW\*(C`alt.*,misc.*\*(C'\fR, since the
-last matching pattern determines whether a given newsgroup matches and the
-poison logic only applies if the poison entry is the last matching entry.
-.PP
-Control messages follow slightly different propagation rules than normal
-articles; see \fIinnd\fR\|(8) for the details.  Note that most subscriptions
-should have \f(CW\*(C`!junk,!control,!control.*\*(C'\fR in their pattern list due to those
-propagation rules (and since junk is a special internal newsgroup; see
-\&\fIwanttrash\fR in \fIinn.conf\fR\|(5) for more details on what it's used for) and
-that the best way to keep control messages local to a site is with a
-distribution.
-.PP
-A subscription can be further modified by specifying distributions that
-the site should or should not receive.  The default is to send all
-articles to all sites that subscribe to any of the groups where it has
-been posted, but if an article has a Distribution: header and any
-\&\fIdistribution\fRs are specified, then they are checked according to the
-following rules:
-.IP "1." 4
-If the Distribution: header matches any of the values in the sub\-field,
-the article is sent.
-.IP "2." 4
-If a \fIdistribution\fR starts with an exclamation point, and it matches the
-Distribution: header, the article is not sent.
-.IP "3." 4
-If the Distribution: header does not match any \fIdistribution\fR in the
-site's entry and no negations were used, the article is not sent.
-.IP "4." 4
-If the Distribution: header does not match any \fIdistribution\fR in the
-site's entry and any \fIdistribution\fR started with an exclamation point,
-the article is sent.
-.PP
-If an article has more than one distribution specified, then each one is
-handled according according to the above rules.  If any of the specified
-distributions indicate that the article should be sent, it is; if none do,
-it is not sent.  In other words, the rules are used as a logical or.
-.PP
-It is almost definitely a mistake to have a single feed that specifies
-distributions that start with an exclamation point along with some that
-don't.
-.PP
-Distributions are text words, not patterns; entries like \f(CW\*(C`*\*(C'\fR or \f(CW\*(C`all\*(C'\fR
-have no special meaning.
-.PP
-The \fIflag\fR field is described in \*(L"\s-1FLAG\s0 \s-1VALUES\s0\*(R".  The interpretation of
-the \fIparameter\fR field depends on the type of feed and is explained in
-more detail in \*(L"\s-1FEED\s0 \s-1TYPES\s0\*(R".  It can be omitted for some types of
-feeds.
-.PP
-The site named \f(CW\*(C`ME\*(C'\fR is special.  There must be exactly one such entry,
-and it should be the first entry in the file.  If the \f(CW\*(C`ME\*(C'\fR entry has an
-exclusion sub\-field, incoming articles are rejected completely if any of
-the names specified in that exclusion sub-field appear in their Path:
-headers.  If the \f(CW\*(C`ME\*(C'\fR entry has a subscription list, that list is
-prepended to the subscription list of all other entries.  For example,
-\&\f(CW\*(C`*,!control,!control.*,!junk,!foo.*\*(C'\fR could be used to set the default subscription
-list for all other feeds so that local postings are not propagated unless
-\&\f(CW\*(C`foo.*\*(C'\fR explicitly appears in the site's subscription list.  This feature
-tends to be somewhat confusing since the default subscription is prepended
-and can be overridden by other patterns.
-.PP
-If the \f(CW\*(C`ME\*(C'\fR entry has a distribution sub\-field, only articles that match
-that distribution list are accepted and all other articles are rejected.
-A common use for this is to put something like \f(CW\*(C`/!local\*(C'\fR in the \f(CW\*(C`ME\*(C'\fR
-entry to reject local postings from other misconfigured sites.
-.PP
-Finally, it is also possible to set variables in \fInewsfeeds\fR and use them
-later in the file.  A line starting with \f(CW\*(C`$\*(C'\fR sets a variable.  For
-example:
-.PP
-.Vb 1
-\&    $LOCALGROUPS=local.*,example.*
-.Ve
-.PP
-This sets the variable \f(CW\*(C`LOCALGROUPS\*(C'\fR to \f(CW\*(C`local.*,example.*\*(C'\fR.  This
-variable can later be used elsewhere in the file, such as in a site entry
-like:
-.PP
-.Vb 1
-\&    news.example.com:$LOCALGROUPS:Tf,Wnm:
-.Ve
-.PP
-which is then completely equivalent to:
-.PP
-.Vb 1
-\&    news.example.com:local.*,example.*:Tf,Wnm:
-.Ve
-.PP
-Variables aren't solely simple substitution.  If either \f(CW\*(C`!\*(C'\fR or \f(CW\*(C`@\*(C'\fR
-immediately preceeds the variable and the value of the variable contains
-commas, that character will be duplicated before each comma.  This
-somewhat odd-sounding behavior is designed to make it easier to use
-variables to construct feed patterns.  The utility becomes more obvious
-when you observe that the line:
-.PP
-.Vb 1
-\&    news.example.net:*,@$LOCALGROUPS:Tf,Wnm:
-.Ve
-.PP
-is therefore equivalent to:
-.PP
-.Vb 1
-\&    news.example.net:*,@local.*,@example.*:Tf,Wnm:
-.Ve
-.PP
-which (as explained below) excludes all of the groups in \f(CW$LOCALGROUPS\fR from
-the feed to that site.
-.SH "FLAG VALUES"
-.IX Header "FLAG VALUES"
-The \fIflags\fR parameter specifies miscellaneous parameters, including the
-type of feed, what information should be sent to it, and various
-limitations on what articles should be sent to a site.  They may be
-specified in any order and should be separated by commas.  Flags that take
-values should have the value immediately after the flag letter with no
-whitespace.  The valid flags are:
-.IP "\fB<\fR \fIsize\fR" 4
-.IX Item "< size"
-An article will only be sent to this site if it is less than \fIsize\fR bytes
-long.  The default is no limit.
-.IP "\fB>\fR \fIsize\fR" 4
-.IX Item "> size"
-An article will only be sent to this site if it is greater than \fIsize\fR
-bytes long.  The default is no limit.
-.IP "\fBA\fR \fIchecks\fR" 4
-.IX Item "A checks"
-An article will only be sent to this site if it meets the requirements
-specified in \fIchecks\fR, which should be chosen from the following set.
-\&\fIchecks\fR can be multiple letters if appropriate.
-.RS 4
-.IP "c" 3
-.IX Item "c"
-Exclude all kinds of control messages.
-.IP "C" 3
-.IX Item "C"
-Only send control messages, not regular articles.
-.IP "d" 3
-.IX Item "d"
-Only send articles with a Distribution header.  Combined with a particular
-distribution value in the \fIdistribution\fR part of the site entry, this can
-be used to limit articles sent to a site to just those with a particuliar
-distribution.
-.IP "e" 3
-.IX Item "e"
-Only send articles where every newsgroup listed in the Newsgroups: header
-exists in the active file.
-.IP "f" 3
-.IX Item "f"
-Don't send articles rejected by filters.  This is only useful when
-\&\fIdontrejectfiltered\fR is set in \fIinn.conf\fR.  With that variable set, this
-lets one accept all articles but not propagate filtered ones to some
-sites.
-.IP "o" 3
-Only send articles for which overview data was stored.
-.IP "O" 3
-.IX Item "O"
-Send articles to this site that don't have an X\-Trace: header, even if the
-\&\f(CW\*(C`O\*(C'\fR flag is also given.
-.IP "p" 3
-.IX Item "p"
-Only check the exclusions against the Path: header of articles; don't
-check the site name.  This is useful if your site names aren't the same as
-the Path: entries added by those remote sites, or for program feeds where
-the site name is arbitrary and unrelated to the Path: header.
-.RE
-.RS 4
-.Sp
-If both \f(CW\*(C`c\*(C'\fR and \f(CW\*(C`C\*(C'\fR are given, the last specified one takes precedence.
-.RE
-.IP "\fBB\fR \fIhigh\fR/\fIlow\fR" 4
-.IX Item "B high/low"
-If a site is being fed by a file, channel, or exploder (see below), the
-server will normally start trying to write the information as soon as
-possible.  Providing a buffer may give better system performance and help
-smooth out overall load if a large batch of news comes in.  The value of
-the this flag should be two numbers separated by a slash.  \fIhigh\fR
-specifies the point at which the server can start draining the feed's I/O
-buffer, and \fIlow\fR specifies when to stop writing and begin buffering
-again; the units are bytes.  The default is to do no buffering, sending
-output as soon as it is possible to do so.
-.IP "\fBC\fR \fIcount\fR" 4
-.IX Item "C count"
-If this flag is specified, an article will only be sent to this site if
-the number of groups it is posted to, plus the square of the number of
-groups followups would appear in, is no more than \fIcount\fR.  \f(CW30\fR is a
-good value for this flag, allowing crossposts to up to 29 groups when
-followups are set to a single group or poster and only allowing crossposts
-to 5 groups when followups aren't set.
-.IP "\fBF\fR \fIname\fR" 4
-.IX Item "F name"
-Specifies the name of the file that should be used if it's necessary to
-begin spooling for the site (see below).  If \fIname\fR is not an absolute
-path, it is taken to be relative to \fIpathoutgoing\fR in \fIinn.conf\fR.  If
-\&\fIname\fR is a directory, the file \fItogo\fR in that directory will be used as
-the file name.
-.IP "\fBG\fR \fIcount\fR" 4
-.IX Item "G count"
-If this flag is specified, an article will only be sent to this site if it
-is posted to no more than \fIcount\fR newsgroups.  This has the problem of
-filtering out many FAQs, as well as newsgroup creation postings and
-similar administrative announcements.  Either the \fBC\fR flag or the \fBU\fR
-flag is a better solution.
-.IP "\fBH\fR \fIcount\fR" 4
-.IX Item "H count"
-If this flag is specified, an article will only be sent to this site if it
-has \fIcount\fR or fewer sites in its Path: line.  This flag should only be
-used as a rough guide because of the loose interpretation of the Path:
-header; some sites put the poster's name in the header, and some sites
-that might logically be considered to be one hop become two because they
-put the posting workstation's name in the header.  The default value for
-\&\fIcount\fR if not specified is one.  (Also see the \fBO\fR flag, which is
-sometimes more appropriate for some uses of this flag.)
-.IP "\fBI\fR \fIsize\fR" 4
-.IX Item "I size"
-The flag specifies the size of the internal buffer for a file feed.  If
-there are more file feeds than allowed by the system, they will be
-buffered internally in least-recently-used order.  If the internal buffer
-grows bigger then \fIsize\fR bytes, however, the data will be written out to
-the appropriate file.  The default value is 16 \s-1KB\s0.
-.IP "\fBN\fR \fIstatus\fR" 4
-.IX Item "N status"
-Restricts the articles sent to this site to those in newsgroups with the
-moderation status given by \fIstatus\fR.  If \fIstatus\fR is \f(CW\*(C`m\*(C'\fR, only articles
-in moderated groups are sent; if \fIstatus\fR is \f(CW\*(C`u\*(C'\fR, only articles in
-unmoderated groups are sent.
-.IP "\fBO\fR \fIoriginator\fR" 4
-.IX Item "O originator"
-If this flag is specified, an article will only be sent to this site if it
-contains an X\-Trace: header and the first field of this header matches
-\&\fIoriginator\fR.  \fIoriginator\fR is a \fIuwildmat\fR\|(3) expression without commas or
-a list of such expressions, separated by \f(CW\*(C`/\*(C'\fR.  The article is never sent
-if the first character of the pattern begins with \f(CW\*(C`@\*(C'\fR and the rest of the
-pattern matches.  One use of this flag is to restrict the feed to locally
-generated posts by using an \fIoriginator\fR pattern that matches the
-X\-Trace: header added by the local server.
-.IP "\fBP\fR \fIpriority\fR" 4
-.IX Item "P priority"
-The nice priority that this channel or program feed should receive.  This
-should be a positive number between 0 and 20 and is the priority that the
-new process will run with.  This flag can be used to raise the priority to
-normal if you're using the \fInicekids\fR parameter in \fIinn.conf\fR.
-.IP "\fBQ\fR \fIhashfeed\fR" 4
-.IX Item "Q hashfeed"
-Specifies the \fIhashfeed\fR match expression for this site.  It must be in
-the form \f(CW\*(C`value/mod\*(C'\fR or \f(CW\*(C`start\-end/mod\*(C'\fR.  The Message-ID of the article
-is hashed using \s-1MD5\s0, which results in a 128\-bit hash.  The lowest
-32\ bits are then taken by default as the hashfeed value (which is an
-integer).  If the hashfeed value modulus \f(CW\*(C`mod\*(C'\fR plus one equals \f(CW\*(C`value\*(C'\fR or
-is between \f(CW\*(C`start\*(C'\fR and \f(CW\*(C`end\*(C'\fR, the article will be fed to this site.  All
-these numbers must be integers.
-.Sp
-It is a deterministic way to control the flow of articles and to split a feed.
-For instance:
-.Sp
-.Vb 2
-\&    Q1/2      Feeds about 50% of all articles to this site.
-\&    Q2/2      Feeds the other 50% of all articles.
-.Ve
-.Sp
-Another example with three sites:
-.Sp
-.Vb 3
-\&    Q1\-3/10   Feeds about 30% of all articles.
-\&    Q4\-5/10   Feeds about 20% of all articles.
-\&    Q6\-10/10  Feeds about 50% of all articles.
-.Ve
-.Sp
-If this flag is specified multiple times, the contents will be
-logically \f(CW\*(C`OR\*(C'\fRed together (just one match is needed).
-.Sp
-You can use an extended syntax of the form \f(CW\*(C`value/mod_offset\*(C'\fR or
-\&\f(CW\*(C`start\-end/mod_offset\*(C'\fR.  As \s-1MD5\s0 generates a 128\-bit return value,
-it is possible to specify from which byte-offset the 32\-bit integer
-used by hashfeed starts.  The default value for \f(CW\*(C`offset\*(C'\fR is \f(CW\*(C`_0\*(C'\fR
-and thirteen overlapping values from \f(CW\*(C`_0\*(C'\fR to \f(CW\*(C`_12\*(C'\fR can be used.
-Only up to four totally independent values exist:  \f(CW\*(C`_0\*(C'\fR, \f(CW\*(C`_4\*(C'\fR,
-\&\f(CW\*(C`_8\*(C'\fR and \f(CW\*(C`_12\*(C'\fR.
-.Sp
-Therefore, it allows to a generate a second level of deterministic
-distribution.  Indeed, if a news server is fed \f(CW\*(C`Q1/2\*(C'\fR, it can go on
-splitting thanks to \f(CW\*(C`Q1\-3/9_4\*(C'\fR for instance.
-.Sp
-The algorithm is compatible with the one used by Diablo\ 5.1 and up.
-If you want to use the legacy quickhashing method used by Diablo
-before 5.1, you can put an \f(CW\*(C`@\*(C'\fR sign just after the \fBQ\fR flag (for
-instance \f(CW\*(C`Q@1\-3/10\*(C'\fR, but the distribution of the messages is not
-perfect with this legacy method whose use is discouraged and for
-which offsets cannot be used).
-.IP "\fBS\fR \fIsize\fR" 4
-.IX Item "S size"
-If the amount of data queued for the site gets to be larger than \fIsize\fR
-bytes, the server will switch to spooling, appending to a file specified
-by the \fBF\fR flag, or \fIpathoutgoing\fR/\fIsitename\fR if \fBF\fR is not specified.
-Spooling usually happens only for channel or exploder feeds, when the
-spawned program isn't keeping up with its input.
-.IP "\fBT\fR \fItype\fR" 4
-.IX Item "T type"
-This flag specifies the type of feed for this site.  \fItype\fR should be a
-letter chosen from the following set:
-.Sp
-.Vb 6
-\&    c        Channel
-\&    f        File
-\&    l        Log entry only
-\&    m        Funnel (multiple entries feed into one)
-\&    p        Program
-\&    x        Exploder
-.Ve
-.Sp
-Each feed is described below in \*(L"\s-1FEED\s0 \s-1TYPES\s0\*(R".  The default is \fBTf\fR,
-for a file feed.
-.IP "\fBU\fR \fIcount\fR" 4
-.IX Item "U count"
-If this flag is specified, an article will only be sent to this site if
-followups to this article would be posted to no more than \fIcount\fR
-newsgroups.  (Also see \fBC\fR for a more complex way of handling this.)
-.IP "\fBW\fR \fIitems\fR" 4
-.IX Item "W items"
-For a file, channel, or exploder feed, this flag controls what information
-will be sent to this site.  For a program feed, only the asterisk (\f(CW\*(C`*\*(C'\fR)
-has any effect.  \fIitems\fR should be chosen from the following set:
-.RS 4
-.IP "b" 3
-.IX Item "b"
-Size of the article (in wire format, meaning with \s-1CRLF\s0 at the end of each
-line, periods doubled at the beginning of lines, and ending in a line with
-a single period) in bytes.
-.IP "e" 3
-.IX Item "e"
-The time the article will expire as seconds since epoch if it has an
-Expires: header, \f(CW0\fR otherwise.
-.IP "f" 3
-.IX Item "f"
-The storage \s-1API\s0 token of the article (the same as \f(CW\*(C`n\*(C'\fR).  The article can
-be retrieved given the storage \s-1API\s0 token by using \fIsm\fR\|(8).
-.IP "g" 3
-.IX Item "g"
-The newsgroup the article is in; if cross\-posted, then the first of the
-groups to which the article was posted that this site gets.  (The
-difference from \f(CW\*(C`G\*(C'\fR is that this sends the newsgroup to which the article
-was posted even if it is a control message.)
-.IP "h" 3
-.IX Item "h"
-The history hash key of the article (derived from the message \s-1ID\s0).
-.IP "m" 3
-.IX Item "m"
-The message \s-1ID\s0 of the article.
-.IP "n" 3
-.IX Item "n"
-The storage \s-1API\s0 token of the article.  The article can be retrieved given
-the storage \s-1API\s0 token by using \fIsm\fR\|(8).
-.IP "p" 3
-.IX Item "p"
-The time the article was posted a seconds since epoch.
-.IP "s" 3
-.IX Item "s"
-The site that fed the article to the server.  This is taken from either
-the Path: header or the \s-1IP\s0 address of the sending site depending on the
-value of \fIlogipaddr\fR in \fIinn.conf\fR.  If \fIlogipaddr\fR is true and the \s-1IP\s0
-address is \f(CW0.0.0.0\fR (meaning that the article was fed from localhost by
-a program like \fIrnews\fR\|(8)), the Path: header value will be sent instead.
-.IP "t" 3
-.IX Item "t"
-The time the article was received as seconds since epoch.
-.IP "\&*" 3
-The names of the appropriate funnel entries, or all sites that get the
-article (see below for more details).
-.IP "D" 3
-.IX Item "D"
-The value of the Distribution: header of the article, or \f(CW\*(C`?\*(C'\fR if there is
-no such header in the article.
-.IP "G" 3
-.IX Item "G"
-Where the article is stored.  If the newsgroup is crossposted, this is
-generally the first of the groups to which it was posted that this site
-receives; however, control messages are filed in control or control.*
-(which is the difference between this item and \f(CW\*(C`g\*(C'\fR).
-.IP "H" 3
-.IX Item "H"
-All of the headers, followed by a blank line.  The Xref header will
-already be present, and a Bytes header containing the article's size in
-bytes as in the \f(CW\*(C`b\*(C'\fR item will be added to the headers.  If used, this
-should be the only item in the list.
-.IP "N" 3
-.IX Item "N"
-The value of the Newsgroups: header.
-.IP "P" 3
-.IX Item "P"
-The value of the Path: header.
-.IP "O" 3
-.IX Item "O"
-Overview data for the article.
-.IP "R" 3
-.IX Item "R"
-Information needed for replication (the Xref header without the site
-name).
-.RE
-.RS 4
-.Sp
-More than one letter can be given.  If multiple items are specified, they
-will be written in the order specified separated by spaces.  (\f(CW\*(C`H\*(C'\fR should
-be the only item if given, but if it's not a newline will be sent before
-the beginning of the headers.)  The default is \fBWn\fR.
-.Sp
-The \f(CW\*(C`H\*(C'\fR and \f(CW\*(C`O\*(C'\fR items are intended for use by programs that create news
-overview databases or require similar information.  \fBWnteO\fR is the flag
-to generate input needed by the \fIoverchan\fR\|(8) program.
-.Sp
-The asterisk (\f(CW\*(C`*\*(C'\fR) has special meaning.  Normally it expands to a
-space-separated list of all sites that received the current article.  If,
-however, this site is a target of a funnel feed (in other words, if it is
-named by other sites which have the \fBTm\fR flag), then the asterisk expands
-to the names of the funnel feeds that received the article.  Similarly, if
-the site is a program feed, an asterisk in the \fIparameter\fR field will be
-expanded into the list of funnel feeds that received the article.  A
-program feed cannot get the site list unless it is the target of other
-\&\fBTm\fR feeds.
-.RE
-.SH "FEED TYPES"
-.IX Header "FEED TYPES"
-\&\fBinnd\fR provides four basic types of feeds:  log, file, program, and
-channel.  An exploder is a special type of channel.  In addition, several
-entries can feed into the same feed; these are funnel feeds, which refer
-to an entry that is one of the other types.  Funnel feeds are partially
-described above with the description of the \fBW*\fR flag.  A funnel feed
-gets every article that would be sent to any of the feeds that funnel into
-it and normally include the \fBW*\fR flag in their flags so that the program
-processing that feed knows which sites received which articles.  The most
-common funnel feed is \fIinnfeed\fR\|(8).
-.PP
-Note that the term \*(L"feed\*(R" is technically a misnomer, since the server
-doesn't transfer articles itself and only writes data to a file, program,
-or log telling another program to transfer the articles.
-.PP
-The simplest feed is a log feed (\fBTl\fR).  Other than a mention in the news
-log file, \fIpathlog\fR/news, no data is written out.  This is equivalent to
-a \fBTf\fR entry writing to \fI/dev/null\fR, except that no file is ever opened.
-Flushing a log feed does nothing.
-.PP
-A file feed (\fBTf\fR) is the next simplest type of feed.  When the site
-should receive an article, the specified data is written out to the file
-named by the \fIparameter\fR field.  If \fIparameter\fR is not an absolute path,
-it is taken to be relative to \fIpathoutgoing\fR in \fIinn.conf\fR.  If
-\&\fIparameter\fR is not given, it defaults to \fIpathoutgoing\fR/\fIsitename\fR.
-The file name should be unique (two file feeds should not ever point to
-the same file).
-.PP
-File feeds are designed for use by external programs that periodically
-process the written data.  To cooperate with \fBinnd\fR properly, such
-external programs should first rename the batch file and then send a flush
-command for that site to \fBinnd\fR using \fIctlinnd\fR\|(8).  \fBinnd\fR will then
-write out any buffered data, close the file, and reopen it (under the
-original name), and the program can process the data in the renamed file
-at its leisure.  File feeds are most frequently used in combination with
-\&\fInntpsend\fR\|(8).
-.PP
-A program feed (\fBTp\fR) spawns a given program for every article that the
-site receives.  The \fIparamter\fR field must be the command line to execute,
-and should contain one instance of \f(CW%s\fR, which will be replaced by the
-storage \s-1API\s0 token of the article (the actual article can be retrieved by
-the program using \fIsm\fR\|(8)).  The program will not receive anything on
-standard input (unlike earlier versions of \s-1INN\s0, where the article is sent
-to the program on stdin), and standard output and error from the program
-will be set to the error log (\fIpathlog\fR/errlog).  \fBinnd\fR will try to
-avoid spawning a shell if the command has no shell meta\-characters; this
-feature can be defeated if necessary for some reason by appending a
-semi-colon to the end of the command.  The full path name of the program
-to be run must be specified unless the command will be run by the shell
-(and it is strongly recommended that the full path name always be
-specified regardless).
-.PP
-If a program feed is the target of a funnel, and if \fBW*\fR appears in the
-flags of the site, a single asterisk may be present in the \fIparameter\fR
-and will be replaced by a space-separated list of names of the sites
-feeding into the funnel which received the relevant article.  If the site
-is not the target of a funnel, or if the \fBW*\fR flag is not used, the
-asterisk has no special meaning.
-.PP
-Flushing a program feed does nothing.
-.PP
-For a channel (\fBTc\fR) or exploder (\fBTx\fR) feed, the \fIparameter\fR field
-again names the process to start.  As with program feeds, the full path to
-the program must be specified.  However, rather than spawning the program
-for every article, it is spawned once and then whenever the site receives
-an article, the data specified by the site flags is written to the
-standard input of the spawned program.  Standard output and error are set
-as with program feeds.  If the process exits, it will be restarted
-automatically.  If the process cannot be started, the server will spool
-input to a file named \fIpathoutgoing\fR/\fIsitename\fR and will try to start
-the process again later.
-.PP
-When a channel or exploder feed is flushed, the server closes its end of
-the pipe to the program's standard input.  Any pending data that has not
-been written will be spooled; see the description of the \fBS\fR flag above.
-The server will then spawn a new instance of the program.  No signal is
-sent to the program; it is up to the program handling a channel or
-exploder feed to notice end of file on its standard input and exit
-appropriately.
-.PP
-Exploders are a special type of channel feed.  In addition to the channel
-feed behavior described above, exploders can also be sent command lines.
-These lines start with an exclamation point and their interpretation is up
-to the exploder.  The following commands are generated automatically by
-the server:
-.PP
-.Vb 4
-\&    !newgroup group
-\&    !rmgroup group
-\&    !flush
-\&    !flush site
-.Ve
-.PP
-These commands are sent whenever the \fIctlinnd\fR\|(8) command of the same name
-is received by the server.  In addition, the \fIctlinnd\fR\|(8) \f(CW\*(C`send\*(C'\fR command
-can be used to send an arbitrary command line to an exploder.  The primary
-exploder is \fIbuffchan\fR\|(8).
-.PP
-Finally, \fBTm\fR feeds are the input to a funnel.  The \fIparameter\fR field of
-the site should name the site handling articles for all of the funnel
-inputs.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-All of the following examples assume that \s-1INN\s0 was installed with a prefix
-of \fI/usr/local/news\fR; if you installed it somewhere else, modify the
-paths as appropriate.
-.PP
-The syntax of the \fInewsfeeds\fR file is so complex because you can specify
-a staggering variety of feeds.  \s-1INN\s0 is capable of interacting with a wide
-variety of programs that do various things with news articles.  Far and
-away the most common two entries in \fInewsfeeds\fR, however, are file feeds
-for \fInntpsend\fR\|(8) and funnel feeds for \fIinnfeed\fR\|(8).
-.PP
-The former look like this:
-.PP
-.Vb 1
-\&    feed.example.com:*,!control,!control.*,!junk:Tf,Wnm:
-.Ve
-.PP
-which generates a file named \fIpathoutgoing\fR/feed.example.com containing
-one line per article consisting of the storage \s-1API\s0 token, a space, and the
-message \s-1ID\s0.
-.PP
-The latter look like this:
-.PP
-.Vb 1
-\&    feed.example.com:*,!control,!control.*,!junk:Tm:innfeed!
-.Ve
-.PP
-Very similar, except that this is the input to a funnel feed named
-\&\f(CW\*(C`innfeed!\*(C'\fR.  One could also write this as:
-.PP
-.Vb 1
-\&    example/feed.example.com:*,!control,!control.*,!junk:Ap,Tm:innfeed!
-.Ve
-.PP
-(note the \fBAp\fR so that articles that contain just \f(CW\*(C`example\*(C'\fR in the Path:
-header will still be sent), which is completely equivalent except that
-this will be logged in \fIpathlog\fR/news as going to the site \f(CW\*(C`example\*(C'\fR
-rather than \f(CW\*(C`feed.example.com\*(C'\fR.
-.PP
-The typical feed entry for \fIinnfeed\fR\|(8) is a good example of a channel feed
-that's the target of various funnel feeds:
-.PP
-.Vb 1
-\&    innfeed!:!*:Tc,Wnm*:/usr/local/news/bin/startinnfeed \-y
-.Ve
-.PP
-Note that the \fIpattern\fR for this feed is just \f(CW\*(C`!*\*(C'\fR so that it won't
-receive any articles directly.  The feed should only receive those
-articles that would go to one of the funnel feeds that are feeding into
-it.  \fIinnfeed\fR\|(8) (spawned by \fBstartinnfeed\fR) will receive one line per
-article on its standard input containing the storage \s-1API\s0 token, the
-message \s-1ID\s0, and a space-separated list of sites that should receive that
-article.
-.PP
-Here's a more esoteric example of a channel feed:
-.PP
-.Vb 2
-\&    watcher!:*:Tc,Wbnm\e
-\&        :exec awk '$1 > 1000000 { print "BIG", $2, $3 }' > /dev/console
-.Ve
-.PP
-This receives the byte size of each article along with the storage \s-1API\s0
-token and message \s-1ID\s0, and prints to the console a line for every article
-that's over a million bytes.  This is actually rather a strange way to
-write this since \s-1INN\s0 can do the size check itself; the following is
-equivalent:
-.PP
-.Vb 2
-\&    watcher!:*:Tc,>1000000,Wbnm\e
-\&        :exec awk '{ print "BIG", $2, $3}' > /dev/console
-.Ve
-.PP
-Here's a cute, really simple news to mail gateway that also serves as an
-example of a fairly fancy program feed:
-.PP
-.Vb 2
-\&    mailer!:!*:W*,Tp\e
-\&        :sm %s | innmail \-s "News article" *
-.Ve
-.PP
-Remember that \f(CW%s\fR is replaced by the storage \s-1API\s0 token, so this
-retrieves the article and pipes it into \fBinnmail\fR (which is safer than
-programs like \fIMail\fR\|(1) because it doesn't parse the body for tilde
-commands) with a given subject line.  Note the use of \f(CW\*(C`*\*(C'\fR in the command
-line and \fBW*\fR in the flags; this entry is designed to be used as the
-target of funnel feeds such as:
-.PP
-.Vb 2
-\&    peter@example.com:news.software.nntp:Tm:mailer!
-\&    sue@example.com:news.admin.misc:Tm:mailer!
-.Ve
-.PP
-Suppose that the server receives an article crossposted between
-news.admin.misc and news.software.nntp.  The server will notice that the
-article should be sent to the site \f(CW\*(C`peter@example.com\*(C'\fR and the site
-\&\f(CW\*(C`bob@example.com\*(C'\fR, both of which funnel into \f(CW\*(C`mailer!\*(C'\fR, so it will look
-at the \f(CW\*(C`mailer!\*(C'\fR site and end up executing the command line:
-.PP
-.Vb 1
-\&    sm @...@ | innmail \-s "News article" peter@example.com sue@example.com
-.Ve
-.PP
-which will mail the article to both Peter and Sue.
-.PP
-Finally, another very useful example of a channel feed:  the standard
-entry for \fIcontrolchan\fR\|(8).
-.PP
-.Vb 3
-\&    controlchan!\e
-\&        :!*,control,control.*,!control.cancel/!collabra\-internal\e
-\&        :Tc,Wnsm:/usr/local/news/bin/controlchan
-.Ve
-.PP
-This program only wants information about articles posted to a control
-newsgroup other than control.cancel, which due to the sorting of control
-messages described in \fIinnd\fR\|(8) will send it all control messages except for
-cancel messages.  In this case, we also exclude any article with a
-distribution of \f(CW\*(C`collabra\-internal\*(C'\fR.  \fBcontrolchan\fR gets the storage
-\&\s-1API\s0 token, the name of the sending site (for processing old-style ihave
-and sendme control messages, be sure to read about \fIlogipaddr\fR in
-\&\fIcontrolchan\fR\|(8)), and the message \s-1ID\s0 for each article.
-.PP
-For many other examples, including examples of the special \f(CW\*(C`ME\*(C'\fR site
-entry, see the example \fInewsfeeds\fR file distributed with \s-1INN\s0.  Also see the
-install documentation that comes with \s-1INN\s0 for information about setting up
-the standard newsfeeds entries used by most sites.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Reformatted
-and rewritten in \s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: newsfeeds.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactive\fR\|(5), \fIbuffchan\fR\|(8), \fIcontrolchan\fR\|(8), \fIctlinnd\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8),
-\&\fIinnfeed\fR\|(8), \fIinnxmit\fR\|(8), \fInntpsend\fR\|(8), \fIuwildmat\fR\|(3).
diff --git a/doc/man/newslog.5 b/doc/man/newslog.5
deleted file mode 100644 (file)
index ca84f4e..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-.TH NEWSLOG 5
-.SH NAME
-newslog \- description of Usenet log files
-.SH DESCRIPTION
-Most log files created by Usenet programs reside in the
-.I <pathlog in inn.conf>
-directory and have a ``.log'' extension.
-Several versions are usually kept with an additional extension such as ``.1'',
-``.2'', etc. \(em the higher the number, the older the log.
-The older versions may be compressed and thus may have a ``.1.gz'',
-``.2.gz'', etc. extension.
-.PP
-The
-.I scanlogs
-script and related utilities (see
-.IR scanlogs (8))
-are responsible for rotating and compressing these files.
-.PP
-Some log files always have data, others only have data if there is a
-problem, and others are only created if a particular program is used
-or configuration parameter is set.
-The
-.I innstat
-script (see
-.IR innstat (8))
-monitors the size of all log files.
-.PP
-The following files will only accumulate data under the direction of
-.IR control.ctl (5):
-.sp 1
-.RS
-control.log
-miscctl.log
-newgroup.log
-rmgroup.log
-unwanted.log
-.RE
-.sp 1
-In order to create these files, the ``message'' and ``action'' fields of
-.I control.ctl
-should be chosen from the following table:
-.sp 1
-.RS
-.nf
-.ta \w'newgroup    'u +\w'doit=newgroup  'u
-Message        Action  Meaning
-all    log=miscctl     Log all messages by default
-default        log=miscctl     Log unknown messages
-newgroup       doit=newgroup   Create group and log message
-newgroup       log=newgroup    Log message
-rmgroup        doit=rmgroup    Remove group and log message
-rmgroup        log=rmgroup     Log message
-``other''      doit=miscctl    log and process the message
-``other''      log=miscctl     Log message
-.fi
-.RE
-.sp 1
-Here, ``other'' refers to any other control message such as:
-.sp 1
-.RS
-.nf
-checkgroups
-ihave
-sendme
-sendsys
-senduuname
-version
-.fi
-.RE
-.PP
-The following is a list of log files:
-.TP
-.I control.log
-This file maintains a count of the number of newgroup and rmgroup control
-messages seen for each newsgroup.
-The count is of the number of control messages with the indicated
-arguments, regardless if they were actually processed.
-All control arguments, including invalid ones, are counted.
-This file is updated by
-.IR tally.control ,
-which is invoked by
-.I scanlogs
-if either the newgroup or rmgroup logs exist.
-This file is not rotated.
-.TP
-.I errlog
-This file contains the standard output and standard error of any program
-spawned by
-.IR innd (8),
-such as channel feeds configured in
-.IR newsfeeds .
-This file should normally be empty.
-.I Scanlogs
-will print the entire contents of this log file if it is non-empty.
-.TP
-.I expire.log
-By default, when
-.I news.daily
-is going to expire old news articles, it writes the date to this file,
-followed by any output from
-.IR expire (8)
-and the ending date.
-All lines but the first are indented four spaces.
-.TP
-.I miscctl.log
-When
-.I control.ctl
-is configured as described above, all control messages except newgroup
-and rmgroup are appended to this file by
-.IR writelog .
-There will be a summary line describing the message and the action
-taken, followed by the article indented by four spaces, and a blank line.
-.TP
-.I newgroup.log
-When
-.I control.ctl
-is configured as described above, all newgroup messages are appended
-to this file using the same format as for
-.IR miscctl.log .
-.TP
-.I news
-This file logs articles received by
-.IR innd .
-.I Scanlogs
-summarizes the rejected articles reported in this file.
-.TP
-.I news.crit
-All critical error messages issued by
-.I innd
-are appended to this file via
-.IR syslog (3).
-This log file should be empty.
-.I Scanlogs
-will print the entire contents of this log file if it is non-empty.
-You should have the following line in your system
-.I syslog.conf
-file, using a tab character for the delimiter:
-.sp 1
-.RS
-.RS
-news.crit  <pathlog in inn.conf>/news.crit
-.RE
-.RE
-.sp 1
-(A typical entry is shown; it should agree with
-.I <pathlog in inn.conf>.)
-.TP
-.I news.err
-All major error messages issued by
-.I innd
-are appended to this file via
-.IR syslog (3).
-This log file should be empty.
-.I Scanlogs
-will print the entire contents of this log file if it is non-empty.
-You should have the following line in your system
-.I syslog.conf
-file, using a tab character for the delimiter:
-.sp 1
-.RS
-.RS
-news.err  <pathlog in inn.conf>/news.err
-.RE
-.RE
-.sp 1
-(A typical entry is shown; it should agree with
-.I <pathlog in inn.conf>.)
-.TP
-.I news.notice
-All standard error messages and status messages issued by
-.I innd
-are appended to this file via
-.IR syslog (3).
-.I Scanlogs
-uses the
-.IR perl (1)
-script
-.IR innreport (8)
-to summarize this file.
-You should have the following line in your system
-.I syslog.conf
-file, using a tab character for the delimiter:
-.sp 1
-.RS
-.RS
-news.notice  <pathlog in inn.conf>/news.notice
-.RE
-.RE
-(A typical entry is shown; it should agree with
-.I <pathlog in inn.conf>.)
-.TP
-.I nntpsend.log
-The
-.IR nntpsend (8)
-programs appends all status messages to this file.
-.TP
-.I rmgroup.log
-When
-.I control.ctl
-is configured as described above, all rmgroup messages are appended to this
-file using the same format as for
-.IR miscctl.log .
-.TP
-.I unwanted.log
-This log maintains a count of the number of articles that were rejected
-because they were posted to newsgroups that do not exist at the local site.
-This file is updated by
-.I tally.unwanted
-and maintained in reverse numeric order (the most popular rejected group
-first).
-This file is not rotated.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: newslog.5 6398 2003-07-12 19:15:50Z rra $
-.SH "SEE ALSO"
-control.ctl(5),
-ctlinnd(8),
-expire(8),
-inn.conf(5),
-innd(8),
-news.daily(8),
-nntpsend(8),
-syslog.conf(5).
diff --git a/doc/man/ninpaths.8 b/doc/man/ninpaths.8
deleted file mode 100644 (file)
index 69f20ac..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-.\" 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 "NINPATHS 8"
-.TH NINPATHS 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ninpaths \- Report Usenet Path statistics (new inpaths)
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBninpaths\fR \fB\-p\fR \fB\-d\fR \fIdumpfile\fR
-.PP
-\&\fBninpaths\fR \fB\-r\fR \fIsite\fR \fB\-u\fR \fIdumpfile\fR [\fB\-u\fR \fIdumpfile\fR ...] \fB\-v\fR
-\&\fIlevel\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This is an efficient and space-saving inpaths reporting program.  It works
-as follows:  you feed it the Path lines via an \s-1INN\s0 channel feed or some
-other similar method, and from time to time the program writes all its
-internal counters accumulated so far to a dump file.  Another instance of
-the program picks up all the dump files, adds them up and formats them
-into the report.  The purpose of the final report is to summarize the
-frequency of occurrence of sites in the Path headers of articles.
-.PP
-Some central sites accumulate the Path data from many news servers running
-this program or one like it, and then report statistics on the most
-frequently seen news servers in Usenet article Path lines.  The
-\&\fBsendinpaths\fR shell script can be run once a month to mail the
-accumulated statistics to such a site and remove the old dump files.
-.PP
-You can get a working setup by doing the following:
-.IP "1." 4
-Create a directory at \fIpathlog\fR/path (replacing \fIpathlog\fR here and in
-all steps that follow with the full path to your \s-1INN\s0 log directory).
-.IP "2." 4
-Set up a channel feed using an entry like:
-.Sp
-.Vb 1
-\&    inpaths!:*:Tc,WP:ninpaths \-p \-d <pathlog>/path/inpaths.%d
-.Ve
-.Sp
-if your version of \s-1INN\s0 supports \s-1WP\s0 (2.0 and later all do).  Replace
-<pathlog> with the full path to your \s-1INN\s0 log directory.
-.IP "3." 4
-Enter into your news user crontab something like:
-.Sp
-.Vb 1
-\&    6 6 * * *   ctlinnd flush inpaths!
-.Ve
-.Sp
-(the actual time doesn't matter).  This will force \fBninpaths\fR to generate
-a dump file once a day.
-.IP "4." 4
-Once per month, run the \fBsendinpaths\fR script, which collects the dumps,
-makes a report, and then deletes the old dumps.  (You can generate a
-report without mailing it and without deleting it with \f(CW\*(C`sendinpaths \-n\*(C'\fR.)
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-d\fR \fIdumpfile\fR" 4
-.IX Item "-d dumpfile"
-Save dumps in \fIdumpfile\fR.  Any \f(CW%d\fR in \fIdumpfile\fR will be replaced with
-the current system time when the dump is made.  This option should be used
-with \fB\-p\fR.
-.IP "\fB\-p\fR" 4
-.IX Item "-p"
-Read Path lines from standard input.
-.IP "\fB\-r\fR \fIsite\fR" 4
-.IX Item "-r site"
-Generate a report for \fIsite\fR.  Generally \fIsite\fR should be the value of
-\&\fIpathhost\fR from \fIinn.conf\fR.
-.IP "\fB\-u\fR \fIdumpfile\fR" 4
-.IX Item "-u dumpfile"
-Read data from \fIdumpfile\fR.  This option can be repeated to read data from
-multiple dump files.
-.IP "\fB\-v\fR \fIlevel\fR" 4
-.IX Item "-v level"
-Set the verbosity level of the report.  Valid values for \fIlevel\fR are 0,
-1, and 2, with 2 being the default.
-.SH "NOTES"
-.IX Header "NOTES"
-If your \s-1INN\s0 doesn't have the \s-1WP\s0 feed flag (1.5 does not, 1.6 does, 1.7 I
-don't know, 2.0 and later all do), use the following newsfeeds entry:
-.PP
-.Vb 1
-\&   inpaths!:*:Tc,WH:ginpaths
-.Ve
-.PP
-where \fBginpaths\fR is the following script:
-.PP
-.Vb 2
-\&    #!/bin/sh
-\&    exec egrep '^Path: ' | ninpaths \-p \-d <pathlog>/path/inpaths.%d
-.Ve
-.PP
-replacing <pathlog> as above.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInewsfeeds\fR\|(5), \fIsendinpaths\fR\|(8)
-.PP
-This is a slightly modified version of Olaf Titz's original ninpaths
-program, which is posted to alt.sources and kept on his \s-1WWW\s0 archive under
-<http://sites.inka.de/~bigred/sw/>.
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBninpaths\fR was written by Olaf Titz <olaf@bigred.inka.de>.
-.PP
-The idea and some implementation details for ninpaths come from the
-original inpaths program, but most of the code has been rewritten for
-clarity.  This program is in the public domain.
diff --git a/doc/man/nnrpd.8 b/doc/man/nnrpd.8
deleted file mode 100644 (file)
index dabf059..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-.\" 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 "NNRPD 8"
-.TH NNRPD 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-nnrpd \- NNTP server for reader clients
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBnnrpd\fR [\fB\-DfnoSt\fR] [\fB\-b\fR \fIaddress\fR] [\fB\-c\fR \fIconfigfile\fR]
-[\fB\-g\fR \fIshadowgroup\fR>] [\fB\-i\fR \fIinitial\fR] [\fB\-I\fR \fIinstance\fR] [\fB\-p\fR \fIport\fR]
-[\fB\-P\fR \fIprefork\fR] [\fB\-r\fR \fIreason\fR] [\fB\-s\fR \fIpadding\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBnnrpd\fR is an \s-1NNTP\s0 server for newsreaders.  It accepts commands on its
-standard input and responds on its standard output.  It is normally
-invoked by \fIinnd\fR\|(8) with those descriptors attached to a remote client
-connection.  \fBnnrpd\fR also supports running as a standalone daemon.
-.PP
-Unlike \fIinnd\fR\|(8) \fBnnrpd\fR supports all \s-1NNTP\s0 commands for user-oriented
-reading and posting.  \fBnnrpd\fR uses the \fIreaders.conf\fR file to control
-who is authorized to access the Usenet database.
-.PP
-On exit, \fBnnrpd\fR will report usage statistics through \fIsyslog\fR\|(3).
-.PP
-\&\fBnnrpd\fR only reads config files (both \fIreaders.conf\fR and \fIinn.conf\fR)
-when it is spawned.  You can therefore never change the behavior of a
-client that's already connected.  If \fBnnrpd\fR is run from \fBinnd\fR (the
-default) or from \fIinetd\fR\|(8), \fIxinetd\fR\|(8), or some equivalent, a new \fBnnrpd\fR
-process is spawned for every connection and therefore any changes to
-configuration files will be immediately effective for all new
-connections.  If you are instead running \fBnnrpd\fR with the \fB\-D\fR option,
-any configuration changes won't take effect until \fBnnrpd\fR is restarted.
-.PP
-The \fIinn.conf\fR setting \fInnrpdflags\fR can be used to pass any of the
-options below to instances of \fBnnrpd\fR that are spawned directly from
-\&\fBinnd\fR.  Many options only make sense when \fB\-D\fR is used, so these
-options should not be used with \fInnrpdflags\fR.  See also the discussion
-of \fInnrpdflags\fR in \fIinn.conf\fR\|(5).
-.PP
-When \fInnrpdloadlimit\fR in \fIinn.conf\fR is not 0, it will also reject
-connections if the load average is greater than that value (typically 16).
-\&\fBnnrpd\fR can also prevent high-volume posters from abusing your
-resources. See the discussion of exponential backoff in \fIinn.conf\fR\|(5).
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-b\fR \fIaddress\fR" 4
-.IX Item "-b address"
-The \fB\-b\fR parameter instructs \fBnnrpd\fR to bind to the specified \s-1IP\s0
-address when started as a standalone daemon using the \fB\-D\fR flag. This
-has to be a valid IPv4 or IPv6 address belonging to an interface of
-the local host.  It can also be ::0 (although the default is 0.0.0.0
-if unspecified).
-.IP "\fB\-c\fR \fIconfigfile\fR" 4
-.IX Item "-c configfile"
-By default, \fBnnrpd\fR reads the \fIreaders.conf\fR to determine how to
-authenticate connections.  The \fB\-c\fR flag specifies an alternate file
-for this purpose.  If the file name isn't fully qualified, it is taken
-to be relative to \fIpathetc\fR in \fIinn.conf\fR (this is useful to have
-several instances of \fBnnrpd\fR running on different ports or \s-1IP\s0
-addresses with different settings.)
-.IP "\fB\-D\fR" 4
-.IX Item "-D"
-If specified, this parameter causes \fBnnrpd\fR to operate as a
-daemon. That is, it detaches itself and runs in the background,
-forking a process for every connection. By default \fBnnrpd\fR listens on
-the \s-1NNTP\s0 port (119), so either \fIinnd\fR\|(8) has to be started on another
-port or \fBnnrpd\fR \fB\-p\fR parameter.  Note that with this parameter,
-\&\fBnnrpd\fR continues running until killed.  This means that it reads
-\&\fIinn.conf\fR once on startup and never again until restarted. \fBnnrpd\fR
-should therefore be restarted if inn.conf is changed.
-.Sp
-When started in daemon mode, \fBnnrpd\fR will write its \s-1PID\s0 into a file in
-the \fIpathrun\fR directory.  The file will be named \fInnrpd\-%d.pid\fR, where
-\&\f(CW%d\fR is replaced with the port that \fBnnrpd\fR is configured to listen on
-(119 unless the \fB\-p\fR option is given).
-.IP "\fB\-f\fR" 4
-.IX Item "-f"
-If specified, \fBnnrpd\fR does not detach itself and runs in the
-foreground when started as a standalone daemon using the \fB\-D\fR flag.
-.IP "\fB\-g\fR \fIshadowgroup\fR" 4
-.IX Item "-g shadowgroup"
-On systems that have a shadow password file, \fBnnrpd\fR tries to add the
-group \fIshadow\fR as a supplementary group if it is running in
-standalone mode. On many systems, members of that group have read
-permission for the shadow password file. The \fB\-g\fR parameter instructs
-\&\fBnnrpd\fR to try to add the named group as a supplementary group on
-shadow systems instead of \fIshadow\fR. This only works if
-\&\f(CW\*(C`HAVE_GETSPNAM\*(C'\fR in \fIinclude/config.h\fR is defined and \fBnnrpd\fR is
-running in standalone mode since this call only works when \fBnnrpd\fR is
-started as root.
-.IP "\fB\-i\fR \fIinitial\fR" 4
-.IX Item "-i initial"
-Specify an initial command to \fBnnrpd\fR. When used, \fIinitial\fR is taken
-as if it were the first command received by \fBnnrpd\fR.
-.IP "\fB\-I\fR \fIinstance\fR" 4
-.IX Item "-I instance"
-If specified \fIinstance\fR is used as an additional static portion
-within MessageIDs generated by \fBnnrpd\fR; typically this option would
-be used where a cluster of machines exist with the same virtual
-hostname and must be disambiguated during posts.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-The \fB\-n\fR flag turns off resolution of \s-1IP\s0 addresses to names.  If you
-only use IP-based restrictions in \fIreaders.conf\fR and can handle \s-1IP\s0
-addresses in your logs, using this flag may result in some additional
-speed.
-.IP "\fB\-o\fR" 4
-.IX Item "-o"
-The \fB\-o\fR flag causes all articles to be spooled instead of sending
-them to \fIinnd\fR\|(8). \fBrnews\fR with the \fB\-U\fR flag should be invoked from
-cron on a regular basis to take care of these articles. This flag is
-useful if \fIinnd\fR\|(8) in accepting articles and \fBnnrpd\fR is started
-standalone or using \fIinetd\fR\|(8).
-.IP "\fB\-p\fR \fIport\fR" 4
-.IX Item "-p port"
-The \fB\-p\fR parameter instructs \fBnnrpd\fR to listen on \fIport\fR when
-started as a standalone daemon using the \fB\-D\fR flag.
-.IP "\fB\-P\fR \fIprefork\fR" 4
-.IX Item "-P prefork"
-The \fB\-P\fR parameter instructs \fBnnrpd\fR to prefork \fIprefork\fR children
-awaiting connections when started as a standalone daemon using the
-\&\fB\-D\fR flag.
-.IP "\fB\-r\fR \fIreason\fR" 4
-.IX Item "-r reason"
-If the \fB\-r\fR flag is used, then \fBnnrpd\fR will reject the incoming
-connection giving \fIreason\fR as the text. This flag is used by \fIinnd\fR\|(8)
-when it is paused or throttled.
-.IP "\fB\-s\fR \fIpadding\fR" 4
-.IX Item "-s padding"
-As each command is received, \fBnnrpd\fR tries to change its \f(CW\*(C`argv\*(C'\fR
-array so that \fIps\fR\|(1) will print out the command being executed. To get
-a full display, the \fB\-s\fR flag may be used with a long string as its
-argument, which will be overwritten when the program changes its
-title.
-.IP "\fB\-S\fR" 4
-.IX Item "-S"
-If specified, \fBnnrpd\fR will start a negotiation for \s-1SSL\s0 session as
-soon as connected. To use this flag, \f(CW\*(C`\-\-with\-openssl\*(C'\fR must have been
-specified at \f(CW\*(C`configure\*(C'\fR time.
-.IP "\fB\-t\fR" 4
-.IX Item "-t"
-If the \fB\-t\fR flag is used then all client commands and initial
-responses will be traced by reporting them in syslog. This flag is set
-by \fIinnd\fR\|(8) under the control of the \fIctlinnd\fR\|(8) \f(CW\*(C`trace\*(C'\fR command, and
-is toggled upon receipt of a \f(CW\*(C`SIGHUP\*(C'\fR; see \fIsignal\fR\|(2).
-.SH "SSL SUPPORT"
-.IX Header "SSL SUPPORT"
-If \s-1INN\s0 is built with \f(CW\*(C`\-\-with\-openssl\*(C'\fR, \fBnnrpd\fR will support news reading
-over \s-1TLS\s0 (also known as \s-1SSL\s0).  For clients that use the \s-1STARTTLS\s0 command,
-no special configuration is needed beyond creating a \s-1TLS/SSL\s0 certificate
-for the server.  You should do this in exactly the same way that you would
-generate a certificate for a web server.
-.PP
-If you're happy with a self-signed certificate (which will generate
-warnings with some news reader clients), you can create and install one in
-the default path by running \f(CW\*(C`make cert\*(C'\fR after \f(CW\*(C`make install\*(C'\fR when
-installing \s-1INN\s0, or by running the following commands:
-.PP
-.Vb 6
-\&    openssl req \-new \-x509 \-nodes \-out /usr/local/news/lib/cert.pem \e
-\&        \-days 366 \-keyout /usr/local/news/lib/key.pem
-\&    chown news:news /usr/local/news/lib/cert.pem
-\&    chmod 640 /usr/local/news/lib/cert.pem
-\&    chown news:news /usr/local/news/lib/key.pem
-\&    chmod 600 /usr/local/news/lib/key.pem
-.Ve
-.PP
-Replace the paths with something appropriate to your \s-1INN\s0 installation.
-This will create a self-signed certificate that will expire in a year.
-The \fBopenssl\fR program will ask you a variety of questions about your
-organization.  Enter the fully qualified domain name of the server as the
-name the certificate is for.
-.PP
-Most news clients currently do not use the \s-1STARTTLS\s0 command, however, and
-instead expect to connect to a separate port (563) and start an \s-1SSL\s0
-negotiation immediately.  \fBinnd\fR does not, however, know how to listen
-for connections to that port and then spawn \fBnnrpd\fR the way that it does
-for regular reader connections.  You will therefore need to arrange for
-\&\fBnnrpd\fR to listen on that port through some other means.  This can be
-done with the \fB\-D\fR flag (and \f(CW\*(C`\-P 563\*(C'\fR), but the easiest way is probably
-to add a line like:
-.PP
-.Vb 1
-\&    nntps stream tcp nowait news /usr/lib/news/bin/nnrpd nnrpd \-S
-.Ve
-.PP
-to \fI/etc/inetd.conf\fR or the equivalent on your system and let \fBinetd\fR
-run \fBnnrpd\fR.  (Change the path to \fBnnrpd\fR to match your installation if
-needed.)  You may need to replace \f(CW\*(C`nntps\*(C'\fR with \f(CW563\fR if \f(CW\*(C`nntps\*(C'\fR isn't
-defined in \fI/etc/services\fR on your system.
-.SH "PROTOCOL DIFFERENCES"
-.IX Header "PROTOCOL DIFFERENCES"
-\&\fBnnrpd\fR implements the \s-1NNTP\s0 commands defined in \s-1RFC\s0 977, with the
-following differences:
-.IP "1." 4
-The \f(CW\*(C`slave\*(C'\fR command is not implemented.  This command has never been
-fully defined.
-.IP "2." 4
-The \f(CW\*(C`list\*(C'\fR command may be followed by the optional word \f(CW\*(C`active.times\*(C'\fR,
-\&\f(CW\*(C`distributions\*(C'\fR, \f(CW\*(C`distrib.pats\*(C'\fR, \f(CW\*(C`moderators\*(C'\fR, \f(CW\*(C`newsgroups\*(C'\fR,
-\&\f(CW\*(C`subscriptions\*(C'\fR, or \f(CW\*(C`Ioverview.fmt\*(C'\fR to get a list of when newsgroups
-where created, a list of valid distributions, a file specifying default
-distribution patterns, moderators list, a one-per-line description of the
-current set of newsgroups, a list of the automatic group subscriptions, or
-a listing of the \fIoverview.fmt\fR file.
-.Sp
-The command \f(CW\*(C`list active\*(C'\fR is equivalent to the \f(CW\*(C`list\*(C'\fR command. This
-is a common extension.
-.IP "3." 4
-The \f(CW\*(C`xhdr\*(C'\fR, \f(CW\*(C`authinfo user\*(C'\fR and \f(CW\*(C`authinfo pass\*(C'\fR commands are
-implemented.  These are based on the reference Unix implementation.  See
-\&\s-1RFC\s0 2980.
-.IP "4." 4
-A new command, \f(CW\*(C`xpat header range|MessageID pat [morepat...]\*(C'\fR, is
-provided.  The first argument is the case-insensitive name of the header
-to be searched.  The second argument is either an article range or a
-single Message\-ID, as specified in \s-1RFC\s0 977.  The third argument is a
-\&\f(CW\*(C`uwildmat\*(C'\fR(3)\-style pattern; if there are additional arguments they are
-joined together separated by a single space to form the complete pattern.
-This command is similar to the \f(CW\*(C`xhdr\*(C'\fR command.  It returns a \f(CW221\fR
-response code, followed by the text response of all article numbers that
-match the pattern.
-.IP "5." 4
-The \f(CW\*(C`listgroup group\*(C'\fR command is provided.  This is a comment extension.
-It is equivalent to the \f(CW\*(C`group\*(C'\fR command, except that the reply is a
-multi-line response containing the list of all article numbers in the
-group.
-.IP "6." 4
-The \f(CW\*(C`xgtitle [group]\*(C'\fR command is provided. This extension is used by
-ANU\-News.  It returns a \f(CW282\fR reply code, followed by a one-line
-description of all newsgroups thatmatch the pattern.  The default is the
-current group.
-.IP "7." 4
-The \f(CW\*(C`xover [range]\*(C'\fR command is provided. It returns a \f(CW224\fR reply code,
-followed by the overview data for the specified range; the default is to
-return the data for the current article.
-.IP "8." 4
-The \f(CW\*(C`xpath MessageID\*(C'\fR command is provided; see \fIinnd\fR\|(8).
-.IP "9." 4
-The \f(CW\*(C`date\*(C'\fR command is provided; this is based on the draft \s-1NNTP\s0 protocol
-revision (draft\-ietf\-nntpext\-imp\-04.txt).  It returns a one-line response
-code of \f(CW111\fR followed by the \s-1GMT\s0 date and time on the server in the form
-\&\f(CW\*(C`YYYYMMDDhhmmss\*(C'\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Overview
-support added by Rob Robertston <rob@violet.berkeley.edu> and Rich in
-January, 1993.  Exponential backoff (for posting) added by Dave Hayes in
-Febuary 1998.
-.PP
-$Id: nnrpd.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIctlinnd\fR\|(8), \fIinnd\fR\|(8), \fIinn.conf\fR\|(5), \fIsignal\fR\|(2), \fIuwildmat\fR\|(3).
diff --git a/doc/man/nnrpd.track.5 b/doc/man/nnrpd.track.5
deleted file mode 100644 (file)
index 55fdc93..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-.\" $Revision: 5909 $
-.TH NNRPD.TRACK 5
-.SH NAME
-nnrpd.track \- file to specify hosts to be tracked by nnrpd.
-.SH DESCRIPTION
-This file, which is located in
-.I <pathetc in inn.conf>,
-specifies which hosts are to have their activities recorded during an
-.I nnrpd
-session.
-The
-.I nnrpd
-server reads it when first spawned by
-.IR innd ,
-provided
-.I readertrack
-in
-.I inn.conf
-is true; otherwise this file is not used.
-.PP
-Entries consist of one host specification per line, each line having two
-fields, separated by a colon:
-.RS
-.nf
-
-host:identity
-.fi
-.RE
-.PP
-The first field is either the FQDN of a host, or a domain name (in 
-the form *.domain.com).
-.PP
-The second field is simply a segment of text which may be used to
-more easily identify the client, typically an e-mail address or other
-identifying mark.
-.PP
-For example:
-.RS
-.nf
-
-nasty.foo.com:nasty@foo.com
-*.bar.com:VeryNastyClient
-.fi
-.RE
-.PP
-Written by Steve Carrie <stephenc@uk.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: nnrpd.track.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5),
-innd(8),
-newsfeeds(5),
-nnrpd(8),
diff --git a/doc/man/nntpget.1 b/doc/man/nntpget.1
deleted file mode 100644 (file)
index 51fd863..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-.\" $Revision: 5909 $
-.TH NNTPGET 1
-.SH NAME
-nntpget \- get Usenet articles from a remote NNTP server
-.SH SYNOPSIS
-.I nntpget
-[
-.BI \-d " dist"
-]
-[
-.BI \-f " file"
-]
-[
-.BI \-n " newsgroups"
-]
-[
-.BI \-t " timestring"
-]
-[
-.B \-o
-]
-[
-.BI \-u " file"
-]
-[
-.B \-v
-]
-.I host
-.SH DESCRIPTION
-.I Nntpget
-connects to the NNTP server at the specified
-.I host
-and retrieves articles from it. The Message-ID's of the desired articles
-are read from standard input. The articles are sent to standard output.
-.SH OPTIONS
-.TP
-.B \-o
-The ``\-o'' option may be used only if the command is executed on the
-host where the
-.IR innd (8)
-server is running.
-If this option is used,
-.I nntpget
-connects to the specified remote
-.I host
-to retrieve articles.
-Any article not present in the local
-.I history
-database is then fetched from the remote site and offered to the local server.
-.TP
-.B \-v
-If the ``\fB\-v\fP'' option is used with the ``\fB\-o\fP'' option then the
-Message-ID
-of each article will be sent to standard output as it is processed.
-.TP
-.B \-f
-The list of article Message-ID's is normally read from standard input.
-If the ``\fB\-f\fP'' option is used, then a ``newnews'' command is used
-to retrieve
-all articles newer then the modification date of the specified
-.IR file .
-.TP
-.B \-u
-The ``\fB\-u\fP'' option is like ``\fB\-f\fP'' except that if the transfer
-succeedes, the file will be updated with a statistics line, modifying its
-timestamp so that it can be used in later invocations.
-.TP
-.B \-t
-If the ``\-t'' option is used, then the specified
-.I timestring
-is used as the time and date parameter to the ``newnews'' command.
-.TP
-.B \-n
-If either the ``\fB\-u\fP'' or ``\fB\-f\fP'' options are used, then 
-the ``\fB\-n\fP'' option
-may be used to specify a newsgroup list. The default is ``*''.
-.TP
-.B \-d
-The ``\fB\-d\fP'' option may be
-used to specify a distribution list when using the ``\fB\-u\fP''
-or ``\fB\-f\fP'' options.
-The default is no distribution list.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: nntpget.1 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-innd(8).
diff --git a/doc/man/nntpsend.8 b/doc/man/nntpsend.8
deleted file mode 100644 (file)
index 9cee56b..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-.TH NNTPSEND 8
-.SH NAME
-nntpsend \- send Usenet articles to remote site
-.SH SYNOPSIS
-.B nntpsend
-[
-.B \-a
-]
-[
-.B \-c
-]
-[
-.B \-D
-]
-[
-.B \-d
-]
-[
-.B \-l
-]
-[
-.B \-N
-]
-[
-.B \-n
-]
-[
-.BI \-P " portnum"
-]
-[
-.B \-p
-]
-[
-.B \-r
-]
-[
-.B \-S
-]
-[
-.BI \-s " size"
-]
-[
-.BI \-T " timelimit"
-]
-[
-.BI \-t " timeout"
-]
-[
-.BI \-w " delay"
-]
-[
-.I sitename
-.I fqdn
-] ...
-.SH DESCRIPTION
-.I Nntpsend
-is a front-end that invokes
-.IR innxmit (1)
-to send Usenet articles to a remote NNTP site.
-.PP
-The sites to be fed may be specified by giving
-.I sitename
-.I fqdn
-pairs on the command line.
-If no such pairs are given,
-.I nntpsend
-defaults to the information given in the
-.I nntpsend.ctl
-config file.
-.PP
-The
-.I sitename
-should be the name of the site as specified in the
-.IR newsfeeds (5) 
-file.
-The 
-.I fqdn 
-should be the hostname or IP address of the remote site.
-.PP
-An
-.I innxmit
-is launched for sites with queued news.
-All
-.I innxmit
-processes are spawned in the background and the script waits for
-them all to finish before returning.
-Output is sent to the file
-.IR <pathlog\ in\ inn.conf>/nntpsend.log .
-In order to keep from overwhelming the local system, 
-.I nntpsend
-waits five seconds before spawning each child.
-.PP
-.I Nntpsend
-expects that the batchfile for a site is named
-.IR <pathoutgoing\ in\ inn.conf>/sitename .
-To prevent batchfile corruption,
-.IR shlock (1)
-is used to ``lock'' these files.
-.PP
-When
-.I sitename
-.I fqdn
-pairs are given on the command line, 
-any flags given on the command completely describe how
-.I innxmit
-and
-.I shrinkfile
-operate.
-When no such pairs are given on the command line, then
-the information found in
-.I nntpsend.ctl
-becomes the default flags for that site.
-Any flags given on the command line override the default flags
-for the site.
-.SH OPTIONS
-.TP
-.B "\-d \-D"
-The ``\-d'' flag causes
-.I nntpsend
-to send output to stdout rather than the log file
-.IR <pathlog\ in\ inn.conf>/nntpsend.log .
-The ``\-D'' flag does the same
-and it passes ``\-d'' to all
-.I innxmit
-invocations, which in turn causes
-.I innxmit
-to go into debug mode.
-.TP
-.B -n
-If the ``\-n'' flag is used, then
-.I nntpsend
-does not use
-.IR shlock (1)
-and does not lock batch files.
-.TP
-.B \-s size
-If the ``\-s'' flag is used, then
-.IR shrinkfile (1)
-will be invoked to perform a head truncation on the batchfile and the flag
-will be passed to it.
-.TP
-.B \-w delay
-If the ``\-w'' flag is used, then
-.I nntpsend
-waits for
-.I delay
-seconds after flushing the site before launching
-.IR innxmit .
-.TP
-.B "\-a \-c \-l \-N \-P \-p \-r \-S \-T \-t"
-The ``\fB\-a\fP'', ``\fB\-c\fP'', ``\fB\-l\fP'', ``\fB\-P\fP'', ``\fB\-p\fP'',
-``\fB\-r\fP'', \``\fB\-S\fP'', ``\fB\-T\fP'' and ``\fB\-t\fP''
-flags are passed on to the child
-.I innxmit
-program. The ``\-N'' flag is passed as ``\fB\-s\fP'' flag to the child
-.I innxmit
-program.
-See 
-.IR innxmit (8)
-for more details.
-Note that if the ``\-p'' flag is used then no connection is made and
-no articles are fed to the remote site.
-It is useful to have
-.IR cron (8)
-invoke
-.I nntpsend
-with this flag in case a site cannot be reached for an extended period of time.
-.SH EXAMPLES
-With the following
-.IR nntpsend.ctl (5)
-control file:
-.PP
-.RS
-.nf
-nsavax:erehwon.nsavax.gov::-S -t60
-group70:group70.org::
-walldrug:walldrug.com:4m-1m:-T1800 -t300
-kremvax:kremvax.cis:2m:
-.fi
-.RE
-.PP
-The command:
-.PP
-.RS
-nntpsend
-.PP
-.RE
-will result in the following:
-.PP
-.RS
-.nf
-Sitename        Truncation      Innxmit flags
-nsavax          (none)          \-a \-S \-t60
-group70         (none)          \-a \-t180
-walldrug        1m if >4m       \-a \-T1800 \-t300
-kremvax         2m              \-a \-t180
-.fi
-.RE
-.PP
-The command:
-.PP
-.RS
-nntpsend \-d \-T1200
-.RE
-.PP
-will result in the following:
-.PP
-.RS
-.nf
-Sitename        Truncation      Innxmit flags
-nsavax          (none)          \-a \-d \-S \-T1200 \-t60
-group70         (none)          \-a \-d \-T1200 \-t180
-walldrug        1m if >4m       \-a \-d \-T1200 \-t300
-kremvax         2m              \-a \-d \-T1200 \-t180
-.fi
-.RE
-.PP
-The command:
-.PP
-.RS
-nntpsend \-s 5m \-T1200 nsavax erehwon.nsavax.gov group70 group70.org
-.PP
-.RE
-will result in the following:
-.PP
-.RS
-.nf
-Sitename        Truncation      Innxmit flags
-nsavax          5m              \-a \-T1200 \-t180
-group70         5m              \-a \-T1200 \-t180
-.fi
-.RE
-.PP
-Remember that ``\-a'' is always given, and ``\-t'' defaults to 180.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com>
-and Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: nntpsend.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5),
-innxmit(1), 
-newsfeeds(5),
-nntpsend.ctl(5),
-shrinkfile(1).
diff --git a/doc/man/nntpsend.ctl.5 b/doc/man/nntpsend.ctl.5
deleted file mode 100644 (file)
index 0561d07..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-.TH NNTPSEND.CTL 5
-.SH NAME
-nntpsend.ctl \- list of sites to feed via nntpsend
-.SH DESCRIPTION
-The file
-.I <pathetc in inn.conf>/nntpsend.ctl
-specifies the default list of sites to be fed by
-.IR nntpsend (8).
-.PP
-Comments begin with a number sign (``#'') and continue through the end
-of the line.
-Blank lines and comments are ignored.
-All other lines should consist of four fields separated by a colon.
-.PP
-The first field is the name of the site as specified in the
-.I newsfeeds
-file.
-.PP
-The second field should be the hostname or IP address of the remote site.
-.PP
-The third field, if non-empty, specifies the default head truncation size of
-site's batchfile.
-If this field is empty, no truncation is performed.
-This field may be of the form ``\fRmaxsize-truncsize\fP'', in which case  it
-is passed to
-.I shrinkfile
-as ``\fR\-m maxsize \-s truncsize\fP''; otherwise it is of the form
-``\fRtruncsize\fP'', in which case it is passed as ``\fR\-s truncsize\fP''.
-.PP
-The fourth field specifies some default flags passed to
-.IR innxmit (8).
-The flag ``\-a'' is always given to
-.I innxmit
-and need not appear here.
-If no ``\-t timeout'' flag is given in this field or on the
-.I nntpsend
-command line, ``\-t\ 180'' will be given to
-.IR innxmit .
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: nntpsend.ctl.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-innxmit(8), newsfeeds(5), nntpsend(8), trunc(1).
diff --git a/doc/man/ovdb.5 b/doc/man/ovdb.5
deleted file mode 100644 (file)
index 528e99e..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-.\" 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 "OVDB 5"
-.TH OVDB 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ovdb \- Overview storage method for INN
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-Ovdb is a storage method that uses the BerkeleyDB library to store
-overview data.  It requires version 2.6.x or later of the BerkeleyDB
-library, but has mostly been tested with version 3 and 4.
-.PP
-Ovdb makes use of the full transaction/logging/locking functionality of
-the BerkeleyDB environment.  BerkeleyDB may be downloaded from
-<http://www.sleepycat.com> and is needed to build the ovdb backend.
-.SH "UPGRADING"
-.IX Header "UPGRADING"
-This is version 2 of ovdb.  If you have a database created with a previous
-version of ovdb (such as the one shipped with \s-1INN\s0 2.3.0) your database
-will need to be upgraded using \fIovdb_init\fR\|(8).  See the man page
-\&\fIovdb_init\fR\|(8) for upgrade instructions.
-.SH "INSTALLATION"
-.IX Header "INSTALLATION"
-To build ovdb support into \s-1INN\s0, specify the option \f(CW\*(C`\-\-with\-berkeleydb\*(C'\fR
-when running the configure script.  By default, configure will search for
-a BerkeleyDB tree in several likely locations, and choose the highest
-version (based on the name of the directory, e.g., \fIBerkeleyDB.3.0\fR) that
-it finds.  There will be a message in the configure output indicating the
-chosen pathname.
-.PP
-You can override this pathname by adding a path to the option, e.g.,
-\&\f(CW\*(C`\-\-with\-berkeleydb=/usr/BerkeleyDB.3.1\*(C'\fR.  This directory is expected to
-have subdirectories \fIinclude\fR and \fIlib\fR, containing \fIdb.h\fR, and the
-library itself, respectively.
-.PP
-The ovdb database will take up more disk space for a given spool than the
-other overview methods.  Plan on needing at least 1.1 \s-1KB\s0 for every article
-in your spool (not counting crossposts).  So, if you have 5 million
-articles, you'll need at least 5.5 \s-1GB\s0 of disk space for ovdb.  With
-BerkeleyDB 2.x, the db files are 'grow only'; the library will not shrink
-them, even if data is removed.  So, reserving extra space above the
-estimate is a good idea.  Plus, you'll need additional space for
-transaction logs: at least 100 \s-1MB\s0.  By default the transaction logs go in
-the same directory as the database.  To improve performance, they can be
-placed on a different disk \*(-- see the \s-1DB_CONFIG\s0 section.
-.SH "CONFIGURATION"
-.IX Header "CONFIGURATION"
-To enable ovdb, set the \fIovmethod\fR parameter in \fIinn.conf\fR to \f(CW\*(C`ovdb\*(C'\fR.
-The ovdb database is stored in the directory specified by the
-\&\fIpathoverview\fR paramter in \fIinn.conf\fR.  This is the \*(L"\s-1DB_HOME\s0\*(R" directory.
-To start out, this directory should be empty (other than an optional
-\&\fI\s-1DB_CONFIG\s0\fR file; see \s-1DB_CONFIG\s0 for details) and \fBinnd\fR (or
-\&\fBmakehistory\fR) will create the files as necessary in that directory.
-Make sure the directory is owned by the news user.
-.PP
-Other parameters for configuring ovdb are in the \fIovdb.conf\fR\|(5)
-configuration file.  See also the sample \fIovdb.conf\fR.
-.IP "cachesize" 4
-.IX Item "cachesize"
-Size of the memory pool cache, in kilobytes.  The cache will have a
-backing store file in the \s-1DB\s0 directory which will be at least as big.  In
-general, the bigger the cache, the better.  Use \f(CW\*(C`ovdb_stat \-m\*(C'\fR to see
-cache hit percentages.  To make a change of this parameter take effect,
-shut down and restart \s-1INN\s0 (be sure to kill all of the nnrpds when shutting
-down).  Default is 8000, which is adequate for small to medium sized
-servers.  Large servers will probably need at least 20000.
-.IP "numdbfiles" 4
-.IX Item "numdbfiles"
-Overview data is split between this many files.  Currently, \fBinnd\fR will
-keep all of the files open, so don't set this too high or \fBinnd\fR may run
-out of file descriptors.  \fBnnrpd\fR only opens one at a time, regardless.
-May be set to one, or just a few, but only do that if your \s-1OS\s0 supports
-large (>2G) files.  Changing this parameter has no effect on an
-already-established database.  Default is 32.
-.IP "txn_nosync" 4
-.IX Item "txn_nosync"
-If txn_nosync is set to false, BerkeleyDB flushes the log after every
-transaction.  This minimizes the number of transactions that may be lost
-in the event of a crash, but results in significantly degraded
-performance.  Default is true.
-.IP "useshm" 4
-.IX Item "useshm"
-If useshm is set to true, BerkeleyDB will use shared memory instead of
-mmap for its environment regions (cache, lock, etc).  With some platforms,
-this may improve performance.  Default is false.  This parameter is
-ignored if you have BerkeleyDB 2.x
-.IP "shmkey" 4
-.IX Item "shmkey"
-Sets the shared memory key used by BerkeleyDB when 'useshm' is true.
-BerkeleyDB will create several (usually 5) shared memory segments, using
-sequentially numbered keys starting with 'shmkey'.  Choose a key that does
-not conflict with any existing shared memory segments on your system.
-Default is 6400.  This parameter is only used with BerkeleyDB 3.1 or
-newer.
-.IP "pagesize" 4
-.IX Item "pagesize"
-Sets the page size for the \s-1DB\s0 files (in bytes).  Must be a power of 2.
-Best choices are 4096 or 8192.  The default is 8192.  Changing this
-parameter has no effect on an already-established database.
-.IP "minkey" 4
-.IX Item "minkey"
-Sets the minimum number of keys per page.  See the BerkeleyDB
-documentation for more info.  Default is based on page size:
-.Sp
-.Vb 1
-\&   default_minkey = MAX(2, pagesize / 2048 \- 1)
-.Ve
-.Sp
-The lowest allowed minkey is 2.  Setting minkey higher than the default is
-not recommended, as it will cause the databases to have a lot of overflow
-pages.  Changing this parameter has no effect on an already-established
-database.
-.IP "maxlocks" 4
-.IX Item "maxlocks"
-Sets the BerkeleyDB \*(L"lk_max\*(R" parameter, which is the maxmium number of
-locks that can exist in the database at the same time.  Default is 4000.
-.IP "nocompact" 4
-.IX Item "nocompact"
-The nocompact parameter affects expireover's behavior.  The expireover
-function in ovdb can do its job in one of two ways:  by simply deleting
-expired records from the database, or by re-writing the overview records
-into a different location leaving out the expired records.  The first
-method is faster, but it leaves 'holes' that result in space that can not
-immediately be reused.  The second method 'compacts' the records by
-rewriting them.
-.Sp
-If this parameter is set to 0, expireover will compact all newsgroups; if
-set to 1, expireover will not compact any newsgroups; and if set to a
-value greater than one, expireover will only compact groups that have less
-than that number of articles.
-.Sp
-Experience has shown that compacting has minimal effect (other than
-making expireover take longer) so the default is now 1.  This parameter
-will probably be removed in the future.
-.IP "readserver" 4
-.IX Item "readserver"
-Normally, each nnrpd process directly accesses the BerkeleyDB environment.
-The process of attaching to the database (and detaching when finished) is
-fairly expensive, and can result in high loads in situations when there
-are lots of reader connections of relatively short duration.
-.Sp
-When the readserver parameter is \*(L"true\*(R", the nnrpds will access overview
-via a helper server (\fBovdb_server\fR \*(-- which is started by \fBovdb_init\fR).
-This can also result in cleaner shutdowns for the database, improving
-stability and avoiding deadlocks and corrupted databases.  If you are
-experiencing any instability in ovdb, try setting this parameter to true.
-Default is false.
-.IP "numrsprocs" 4
-.IX Item "numrsprocs"
-This parameter is only used when \fIreadserver\fR is true.  It sets the
-number of ovdb_server processes.  As each ovdb_server can process only one
-transaction at a time, running more servers can improve reader response
-times.  Default is 5.
-.IP "maxrsconn" 4
-.IX Item "maxrsconn"
-This parameter is only used when \fIreadserver\fR is true.  It sets a maximum
-number of readers that a given ovdb_server process will serve at one time.
-This means the maximum number of readers for all of the ovdb_server
-processes is (numrsprocs * maxrsconn).  Default is 0, which means an
-umlimited number of connections is allowed.
-.SH "DB_CONFIG"
-.IX Header "DB_CONFIG"
-A file called \fI\s-1DB_CONFIG\s0\fR may be placed in the database directory to
-customize where the various database files and transaction logs are
-written.  By default, all of the files are written in the \*(L"\s-1DB_HOME\s0\*(R"
-directory.  One way to improve performance is to put the transaction logs
-on a different disk.  To do this, put:
-.PP
-.Vb 1
-\&    DB_LOG_DIR /path/to/logs
-.Ve
-.PP
-in the \fI\s-1DB_CONFIG\s0\fR file.  If the pathname you give starts with a /, it is
-treated as an absolute path; otherwise, it is relative to the \*(L"\s-1DB_HOME\s0\*(R"
-directory.  Make sure that any directories you specify exist and have
-proper ownership/mode before starting \s-1INN\s0, because they won't be created
-automatically.  Also, don't change the \s-1DB_CONFIG\s0 file while anything that
-uses ovdb is running.
-.PP
-Another thing that you can do with this file is to split the overview
-database across multiple disks.  In the \fI\s-1DB_CONFIG\s0\fR file, you can list
-directories that BerkeleyDB will search when it goes to open a database.
-.PP
-For example, let's say that you have \fIpathoverview\fR set to
-\&\fI/mnt/overview\fR and you have four additional file systems created on
-\&\fI/mnt/ov?\fR.  You would create a file \*(L"/mnt/overview/DB_CONFIG\*(R" containing
-the following lines:
-.PP
-.Vb 5
-\&    set_data_dir /mnt/overview
-\&    set_data_dir /mnt/ov1
-\&    set_data_dir /mnt/ov2
-\&    set_data_dir /mnt/ov3
-\&    set_data_dir /mnt/ov4
-.Ve
-.PP
-(For BerkeleyDB 2.x, replace \f(CW\*(C`set_data_dir\*(C'\fR with \f(CW\*(C`DB_DATA_DIR\*(C'\fR.)
-.PP
-Distribute your ovNNNNN files into the four filesystems.  (say, 8 each).
-When called upon to open a database file, the db library will look for it
-in each of the specified directories (in order).  If said file is not
-found, one will be created in the first of those directories.
-.PP
-Whenever you change \s-1DB_CONFIG\s0 or move database files around, make sure all
-news processes that use the database are shut down first (including
-nnrpds).
-.PP
-The \s-1DB_CONFIG\s0 functionality is part of BerkeleyDB itself, rather than
-something provided by ovdb.  See the BerkeleyDB documentation for complete
-details for the version of BerkeleyDB that you're running.
-.SH "RUNNING"
-.IX Header "RUNNING"
-When starting the news system, \fBrc.news\fR will invoke \fBovdb_init\fR.
-\&\fBovdb_init\fR must be run before using the database.  It performs the
-following tasks:
-.IP "\(bu" 4
-Creates the database environment, if necessary.
-.IP "\(bu" 4
-If the database is idle, it performs a normal recovery.  The recovery will
-remove stale locks, recreate the memory pool cache, and repair any damage
-caused by a system crash or improper shutdown.
-.IP "\(bu" 4
-Starts the \s-1DB\s0 housekeeping processes (\fBovdb_monitor\fR) if they're not
-already running.
-.PP
-And when stopping \s-1INN\s0, \fBrc.news\fR kills the ovdb_monitor processes after
-the other \s-1INN\s0 processes have been shut down.
-.SH "DIAGNOSTICS"
-.IX Header "DIAGNOSTICS"
-Problems relating to ovdb are logged to news.err with \*(L"\s-1OVDB\s0\*(R" in the error
-message.
-.PP
-\&\s-1INN\s0 programs that use overview will fail to start up if the ovdb_monitor
-processes aren't running.  Be sure to run \fBovdb_init\fR before running
-anything that accesses overview.
-.PP
-Also, \s-1INN\s0 programs that use overview will fail to start up if the user
-running them is not the \*(L"news\*(R" user.
-.PP
-If a program accessing the database crashes, or otherwise exits uncleanly,
-it might leave a stale lock in the database.  This lock could cause other
-processes to deadlock on that stale lock.  To fix this, shut down all news
-processes (using \f(CW\*(C`kill \-9\*(C'\fR if necessary) and then restart.  \fBovdb_init\fR
-should perform a recovery operation which will remove the locks and repair
-damage caused by killing the deadlocked processes.
-.SH "FILES"
-.IX Header "FILES"
-.IP "inn.conf" 4
-.IX Item "inn.conf"
-The \fIovmethod\fR and \fIpathoverview\fR parameters are relevant to ovdb.
-.IP "ovdb.conf" 4
-.IX Item "ovdb.conf"
-Optional configuration file for tuning.  See \s-1CONFIGURATION\s0 above.
-.IP "\fIpathoverview\fR" 4
-.IX Item "pathoverview"
-Directory where the database goes.  BerkeleyDB calls it the '\s-1DB_HOME\s0'
-directory.
-.IP "\fIpathoverview\fR/DB_CONFIG" 4
-.IX Item "pathoverview/DB_CONFIG"
-Optional file to configure the layout of the database files.
-.IP "\fIpathrun\fR/ovdb.sem" 4
-.IX Item "pathrun/ovdb.sem"
-A file that gets locked by every process that is accessing the database.
-This is used by \fBovdb_init\fR to determine whether the database is active
-or quiescent.
-.IP "\fIpathrun\fR/ovdb_monitor.pid" 4
-.IX Item "pathrun/ovdb_monitor.pid"
-Contains the process \s-1ID\s0 of \fBovdb_monitor\fR.
-.SH "TO DO"
-.IX Header "TO DO"
-Implement a way to limit how many databases can be open at once (to reduce
-file descriptor usage); maybe using something similar to the cache code in
-ov3.c
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInnrpd\fR\|(8), \fIovdb_init\fR\|(8), \fIovdb_monitor\fR\|(8),
-\&\fIovdb_stat\fR\|(8)
-.PP
-BerkeleyDB documentation: in the \fIdocs\fR directory of the BerkeleyDB
-source distribution, or on the Sleepycat web page:
-<http://www.sleepycat.com/>.
diff --git a/doc/man/ovdb_init.8 b/doc/man/ovdb_init.8
deleted file mode 100644 (file)
index 92075ea..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-.\" 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 "OVDB_INIT 8"
-.TH OVDB_INIT 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ovdb_init \- Prepare ovdb database for use
-.SH "SYNOPSYS"
-.IX Header "SYNOPSYS"
-ovdb_init [\f(CW\*(C`\-u\*(C'\fR|\f(CW\*(C`\-r\*(C'\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This command must be run before any other process can access the
-overview database.  It performs the following steps:
-.IP "1" 4
-.IX Item "1"
-Creates the database environment, if necessary
-.IP "2" 4
-.IX Item "2"
-If the database is idle (and if the \f(CW\*(C`\-u\*(C'\fR option is not specified),
-it performs a normal recovery.  The recovery will remove stale locks,
-recreate the memory pool cache, and repair any damage caused by a system
-crash or improper shutdown.
-.IP "3" 4
-.IX Item "3"
-If the \f(CW\*(C`\-u\*(C'\fR option is specified, it performs any necessary upgrades
-to the database.  See the \s-1UPGRADING\s0 section below.
-.IP "4" 4
-.IX Item "4"
-Starts the \s-1DB\s0 housekeeping processes (ovdb_monitor) if they're not
-already running. (Unless the \f(CW\*(C`\-r\*(C'\fR option is specified).
-.IP "5" 4
-.IX Item "5"
-Starts the ovdb readserver (ovdb_server) processes if \f(CW\*(C`readserver\*(C'\fR
-in \fIovdb.conf\fR is \f(CW\*(C`true\*(C'\fR, and if they're not
-already running. (Unless the \f(CW\*(C`\-r\*(C'\fR option is specified).
-.PP
-Returns exit status of 0 if all steps were completed successfully.
-In the event of an error, messages are written to syslog and/or stderr.
-.PP
-If a recovery was attempted but it failed, the database may be
-damaged beyond repair, requiring a rebuild with \fImakehistory\fR\|(8).
-.PP
-This command is normally invoked automatically by \fIrc.news\fR\|(8).
-.PP
-It is \s-1OK\s0 to run this command multiple times.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.ie n .IP """\-r""" 4
-.el .IP "\f(CW\-r\fR" 4
-.IX Item "-r"
-Perform recovery only.  \f(CW\*(C`ovdb_monitor\*(C'\fR is not started.
-.ie n .IP """\-u""" 4
-.el .IP "\f(CW\-u\fR" 4
-.IX Item "-u"
-Perform any needed upgrades.  Recovery is not attempted.
-\&\f(CW\*(C`ovdb_monitor\*(C'\fR is started if the upgrade succeeded.
-.SH "UPGRADING"
-.IX Header "UPGRADING"
-There are two situations in which the database will need to be
-upgraded:
-.IP "\(bu" 4
-You upgrade the BerkeleyDB library to a newer version, for example
-from 2.7.7 to 3.1.17.  In this case, the BerkeleyDB db\->\fIupgrade()\fR
-method is used.
-.IP "\(bu" 4
-You upgrade ovdb to a newer major version; i.e., ovdb\-1.0 to ovdb\-2.0.
-.PP
-In both of these cases, the database is upgraded in\-place; and the
-upgrade can not be undone.  Do not interrupt the upgrade process once
-it has started, because there is a risk of irrepairable corruption.
-The upgrade may take several minutes to complete.
-If an upgrade does get interrupted, try running the upgrade again.
-.PP
-Here's an example procedure to upgrade a database created with BerkeleyDB
-2.7.7 to use BerkeleyDB 3.1.17:
-.IP "1" 4
-.IX Item "1"
-Build and install the BerkeleyDB 3.1.17
-.IP "2" 4
-.IX Item "2"
-Run configure in the \s-1INN\s0 source tree and make sure it picks up the
-right BerkeleyDB directory (e.g., /usr/local/BerkeleyDB.3.1)
-.IP "3" 4
-.IX Item "3"
-Do a \f(CW\*(C`make\*(C'\fR
-.IP "4" 4
-.IX Item "4"
-Shut down \s-1INN\s0 (e.g., with \f(CW\*(C`rc.news stop\*(C'\fR).  Be sure to kill all nnrpds as
-well.
-.IP "5" 4
-.IX Item "5"
-Do a \f(CW\*(C`make update\*(C'\fR to install the new binaries.
-.IP "6" 4
-.IX Item "6"
-Run \f(CW\*(C`ovdb_init \-u\*(C'\fR as the news user.
-.IP "7" 4
-.IX Item "7"
-Start \s-1INN\s0 with \f(CW\*(C`rc.news\*(C'\fR
-.PP
-It is \s-1OK\s0 to specify \f(CW\*(C`\-u\*(C'\fR even if no upgrades are needed.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIovdb\fR\|(5), \fImakehistory\fR\|(8)
diff --git a/doc/man/ovdb_monitor.8 b/doc/man/ovdb_monitor.8
deleted file mode 100644 (file)
index 407ca1b..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-.\" 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 "OVDB_MONITOR 8"
-.TH OVDB_MONITOR 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ovdb_monitor \- Database maintenance
-.SH "SYNOPSYS"
-.IX Header "SYNOPSYS"
-Use \f(CW\*(C`ovdb_init\*(C'\fR to start ovdb_monitor
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-When started (by \f(CW\*(C`ovdb_init\*(C'\fR), \f(CW\*(C`ovdb_monitor\*(C'\fR forks three processes
-that perform routine database maintenance tasks.  These are:
-transaction checkpointing, deadlock detection, and transaction log
-removal.  The process \s-1ID\s0 of the parent is written to
-\&\fI\fIpathrun\fI/ovdb_monitor.pid\fR.  This \s-1PID\s0 is used by other \s-1INN\s0
-commands to verify that ovdb_monitor is running.
-.PP
-To shut down ovdb_monitor, send a \s-1TERM\s0 signal to the process \s-1ID\s0
-in \fI\fIpathrun\fI/ovdb_monitor.pid\fR .  The parent process will shut
-down the three children and wait for their exit before exiting itself.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIovdb\fR\|(5), \fIovdb_init\fR\|(8)
diff --git a/doc/man/ovdb_server.8 b/doc/man/ovdb_server.8
deleted file mode 100644 (file)
index 09d3932..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-.\" 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 "OVDB_SERVER 8"
-.TH OVDB_SERVER 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ovdb_server \- overview 'helper' server
-.SH "SYNOPSYS"
-.IX Header "SYNOPSYS"
-Use \f(CW\*(C`ovdb_init\*(C'\fR to start ovdb_server
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-If the \f(CW\*(C`readserver\*(C'\fR parameter in \fIovdb.conf\fR is true,
-\&\f(CW\*(C`ovdb_init\*(C'\fR will start \f(CW\*(C`ovdb_server\*(C'\fR.
-.PP
-\&\f(CW\*(C`ovdb_server\*(C'\fR opens the overview database, and accesses it
-on behalf of the nnrpd reader processes.
-.PP
-To shut down ovdb_server, send a \s-1TERM\s0 signal to the process \s-1ID\s0
-in \fI\fIpathrun\fI/ovdb_server.pid\fR .  The parent process will shut
-down its children and wait for their exit before exiting itself.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIovdb\fR\|(5), \fIovdb_init\fR\|(8)
diff --git a/doc/man/ovdb_stat.8 b/doc/man/ovdb_stat.8
deleted file mode 100644 (file)
index 7cb3742..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-.\" 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 "OVDB_STAT 8"
-.TH OVDB_STAT 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-ovdb_stat \- Display information from the ovdb database
-.SH "SYNOPSYS"
-.IX Header "SYNOPSYS"
-\&\fBovdb_stat\fR \fB\-Hgci\fR [\fB\-r\fR \fIartnumrange\fR] newsgroup [newsgroup ...]
-.PP
-\&\fBovdb_stat\fR \fB\-Hklmtv\fR [\fB\-d\fR \fIdatabase\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBovdb_stat\fR displays information from the ovdb database: BerkeleyDB
-statistics, newsgroup data, and overview records; and optionally
-outputs in \s-1HTML\s0 format.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-g\fR" 4
-.IX Item "-g"
-Newsgroup himark, lowmark, article count, and flag for the given newsgroups
-(as stored in the ovdb \*(L"groupinfo\*(R" database) are displayed.
-.IP "\fB\-c\fR" 4
-.IX Item "-c"
-Similar to \fB\-g\fR, except the himark, lowmark, and count are calculated
-by actually scanning the overview records and counting them.
-This can be a lengthy operation on groups with lots of articles.
-.IP "\fB\-i\fR" 4
-.IX Item "-i"
-Internal data regarding the given newsgroups are displayed.
-.IP "\fB\-r\fR \fIartnumrange\fR" 4
-.IX Item "-r artnumrange"
-Overview records are retrieved.  The \fIartnumrange\fR parameter may be
-a single article number, or a range of articles in the format \f(CW\*(C`low\-hi\*(C'\fR.
-.IP "\fB\-H\fR" 4
-.IX Item "-H"
-Output is presented in \s-1HTML\s0 format.
-.IP "\fB\-k\fR" 4
-.IX Item "-k"
-Displays lock region statistics, as returned by the BerkeleyDB \fIlock_stat()\fR
-call.
-.IP "\fB\-l\fR" 4
-.IX Item "-l"
-Displays log region statistics, as returned by the BerkeleyDB \fIlog_stat()\fR
-call.
-.IP "\fB\-m\fR" 4
-.IX Item "-m"
-Displays global memory pool statistics, as returned by the
-BerkeleyDB \fImemp_stat()\fR call.
-.IP "\fB\-M\fR" 4
-.IX Item "-M"
-Same as \fB\-m\fR, and also displays memory pool statistics for each
-database file.
-.IP "\fB\-t\fR" 4
-.IX Item "-t"
-Displays log region statistics, as returned by the BerkeleyDB \fItxn_stat()\fR
-call.
-.IP "\fB\-v\fR" 4
-.IX Item "-v"
-Displays ovdb version, and BerkeleyDB version.
-.IP "\fB\-d\fR \fIdatabase\fR" 4
-.IX Item "-d database"
-Displays information about the given database, as returned by the
-BerkeleyDB db\->\fIstat()\fR call.  This operation may take a long time
-on busy systems (several minutes or more).
-.SH "WARNINGS"
-.IX Header "WARNINGS"
-ovdb_stat may be safely killed with the \s-1INT\s0, \s-1TERM\s0, or \s-1HUP\s0 signals.
-It catches those signals and exits cleanly.
-Do not kill ovdb_stat with other signals, unless absolutely necessary,
-because it may leave stale locks in the \s-1DB\s0 environment.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIovdb\fR\|(5)
diff --git a/doc/man/overchan.8 b/doc/man/overchan.8
deleted file mode 100644 (file)
index 02ed021..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-.\" $Revision: 5909 $
-.TH OVERCHAN 8
-.SH NAME
-overchan \- update the news overview database
-.SH SYNOPSIS
-.B overchan
-[
-.BR file \ ...
-]
-.SH DESCRIPTION
-.I Overchan
-reads article data from
-.I files
-or standard input if none are specified.
-(A single dash in the file list means to read standard input.)
-It uses this information to update the news overview database.
-.I Overchan
-was originally designed to be used by InterNetNews or the C News ``mkov'' packages
-to update the database as the articles come in.
-For current INN, the database is stored in a selected overview method.
-This can be done within
-.IR innd (8)
-itself, but
-.IR overchan (8)
-can be used instead, if
-.I <useoverchan in inn.conf>
-is ``true'' and appropriate setup is done in
-.IR newsfeeds ,
-for example:
-.PP
-.RS
-overview!:*:Tc,WnteO:<pathbin in inn.conf>/overchan
-.RE
-.PP
-.I Overchan
-input data consists of a line of text, separated into four parts by a space.
-The first part is a token for the article.
-The second part is time when the article was received.
-The third part is time when the article will be expired (which represents
-the Expires header).
-The fourth part is the data to be stored.
-.PP
-The data in the overview files should be expired by running
-.IR expireover (8).
-This is normally done by adding the ``expireover'' flag to the
-.IR news.daily (8)
-invocation.
-.PP
-.SH HISTORY
-Written by Rob Robertson <rob@violet.berkeley.edu>
-and Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: overchan.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-expireover(8),
-inn.conf(5),
-news.daily(8),
-newsfeeds(5).
diff --git a/doc/man/overview.fmt.5 b/doc/man/overview.fmt.5
deleted file mode 100644 (file)
index 407456a..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-.\" $Revision: 5909 $
-.TH OVERVIEW.FMT 5
-.SH NAME
-overview.fmt \- format of news overview database
-.SH DESCRIPTION
-The file
-.I <pathetc in inn.conf>/overview.fmt
-specifies the organization of the news overview database.
-Blank lines and lines beginning with a number sign (``#'') are ignored.
-The order of lines in this file is important; it determines the order
-in which the fields will appear in the database.
-.PP
-Most lines will consist of an article header name, optionally
-followed by a colon.
-A trailing set of lines can have the word ``full'' appear after the
-colon; this indicates that the header should appear as well as its value.
-.PP
-If this file is changed, new overview records will be constructed with
-the modified format.  If it is desired that existing records be updated to
-the new format, it is necessary to rebuild the overview database using
-.IR makehistory (8)
-after removing all existing overview files.
-.PP
-\&``Xref:full'' must be included, or
-.IR innd (8)
-and other programs which utilize overview method cannot start.
-.PP
-The default file, show below, is compatible with Geoff Collyer's ``nov''
-package:
-.PP
-.RS
-.nf
-Subject:
-From:
-Date:
-Message-ID:
-References:
-Bytes:
-Lines:
-Xref:full
-.fi
-.RE
-.PP
-Usually the only modifications which should be made to the default file
-are additions of new fields to the end of the file; all such fields
-should have ``full'' after the colon.  The first eight fields should
-remain in the same order as above.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-Intended to be compatible with the
-.I nov
-package written by Geoff Collyer <geoff@world.std.com>.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: overview.fmt.5 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5)
diff --git a/doc/man/parsedate.3 b/doc/man/parsedate.3
deleted file mode 100644 (file)
index 4d04b28..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-.\" $Revision: 6312 $
-.TH PARSEDATE 3
-.SH NAME
-parsedate \- convert time and date string to number
-.SH SYNOPSIS
-.nf
-.ta \w'    unsigned long    'u
-.B "#include <sys/types.h>"
-
-.B "typedef struct _TIMEINFO {"
-.B "    time_t time;"
-.B "    long   usec;"
-.B "    long   tzone;
-.B "} TIMEINFO;"
-
-.B "time_t"
-.B "parsedate(text, now)"
-.B "    char   *text;"
-.B "    TIMEINFO       *now;"
-.fi
-.SH DESCRIPTION
-.I Parsedate
-converts many common time specifications into the number of seconds
-since the epoch \(em
-.IR i.e. ,
-a
-.IR time_t ;
-see
-.IR time (2).
-.PP
-.I Parsedate
-returns the time, or \-1 on error.
-.I Text
-is a character string containing the time and date.
-.I Now
-is a pointer to the time that should be used for calculating relative dates.
-If
-.I now
-is NULL, then
-.I GetTimeInfo in
-.IR libinn (3)
-is used to obtain the current time and timezone.
-.PP
-The character string consists of zero or more specifications of the following
-form:
-.TP
-.I time
-A time of day, which is of the form
-.IR hh [ :mm [ :ss ]]
-.RI [ meridian ]
-.RI [ zone ]
-or
-.IR hhmm
-.RI [ meridian ]
-.RI [ zone ].
-If no meridian is specified,
-.I hh
-is interpreted on a 24-hour clock.
-.TP
-.I date
-A specific month and day with optional year.
-The acceptable formats are
-.IR mm/dd [ /yy ],
-.IR yyyy/mm/dd ,
-.IR "monthname dd" "[, " yy ],
-.IR "dd monthname" " [" yy "],
-and
-.IR "day, dd monthname yy" .
-The default year is the current year.
-If the year is less then 100, then 1900 is added to it; if it is
-less then 21, then 2000 is added to it.
-.TP
-.I "relative time"
-A specification relative to the current time.
-The format is
-.IR "number unit" ;
-acceptable units are
-.IR year ,
-.IR month ,
-.IR week ,
-.IR day ,
-.IR hour ,
-.I minute
-(or
-.IR min ),
-and
-.I second
-(or
-.IR sec ).
-The unit can be specified as a singular or plural, as in
-.IR "3 weeks" .
-.PP
-The actual date is calculated according to the following steps.
-First, any absolute date and/or time is processed and converted.
-Using that time as the base, day-of-week specifications are added.
-Next, relative specifications are used.
-If a date or day is specified, and no absolute or relative time is given,
-midnight is used.
-Finally, a correction is applied so that the correct hour of the day is
-produced after allowing for daylight savings time differences.
-.PP
-.I Parsedate
-ignores case when parsing all words; unknown words are taken to be unknown
-timezones, which are treated as GMT.
-The names of the months and days of the week can be abbreviated to their
-first three letters, with optional trailing period.
-Periods are ignored in any timezone or meridian values.
-.SH BUGS
-.I Parsedate
-does not accept all desirable and unambiguous constructions.
-Semantically incorrect dates such as ``February 31'' are accepted.
-.PP
-Daylight savings time is always taken as a one-hour change which is wrong
-for some places.
-The daylight savings time correction can get confused if parsing a
-time within an hour of when the reckoning changes, or if given a
-partial date.
-.SH HISTORY
-Originally written by Steven M. Bellovin <smb@research.att.com> while
-at the University of North Carolina at Chapel Hill and distributed
-under the name
-.IR getdate .
-.PP
-A major overhaul was done by Rich $alz <rsalz@bbn.com> and Jim Berets
-<jberets@bbn.com> in August, 1990.
-.PP
-It was further revised (primarily to remove obsolete constructs and timezone
-names) a year later by Rich (now <rsalz@osf.org>) for InterNetNews,
-and the name was changed.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: parsedate.3 6312 2003-05-04 21:40:11Z rra $
-.SH "SEE ALSO"
-date(1),
-ctime(3),
-libinn(3),
-time(2).
diff --git a/doc/man/passwd.nntp.5 b/doc/man/passwd.nntp.5
deleted file mode 100644 (file)
index 91d4e72..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-.\" 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 "PASSWD.NNTP 5"
-.TH PASSWD.NNTP 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-passwd.nntp \- passwords for connecting to remote NNTP servers
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIpasswd.nntp\fR in \fIpathetc\fR contains host / name / password
-triplets for use when authenticating client programs to \s-1NNTP\s0 servers.
-This file is normally interpreted by \fINNTPsendpassword()\fR in \fIlibinn\fR\|(3).
-Blank lines and lines beginning with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored.
-All other lines should consist of three or four fields separated by
-colons:
-.PP
-.Vb 2
-\&    host:name:password
-\&    host:name:password:style
-.Ve
-.PP
-The first field is the name of a host, and is matched in a
-case-insensitive manner.  (No detailed matching, such as comparing \s-1IP\s0
-addresses, is done.)
-.PP
-The second field is a user name, and the third is a password.  If either
-the username or password is empty, then that portion of the
-authentication will not occur.  (For example, when connecting to a
-remote \s-1INN\s0 for peering, only the password is needed.)
-.PP
-The optional fourth field specifies the type of authentication to use.
-At present, the only recognized \*(L"authentication style\*(R" is \f(CW\*(C`authinfo\*(C'\fR;
-this is also the default.  It means that \s-1NNTP\s0 \*(L"authinfo\*(R" commands are
-used to authenticate to the remote host.  (The \f(CW\*(C`authinfo\*(C'\fR command is a
-common extension to \s-1RFC\s0 977.)
-.PP
-For example:
-.PP
-.Vb 3
-\&    ##  UUNET needs a password, MIT doesn't.
-\&    mit.edu:bbn::authinfo
-\&    uunet.uu.net:bbn:yoyoma:authinfo
-.Ve
-.PP
-This file should not be world\-readable.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  This is
-revision \f(CW$Revision:\fR 5089 $, dated \f(CW$Date:\fR 2002\-02\-03 20:03:41 +0100 (dim, 03 fév 2002) $.
-.PP
-$Id: passwd.nntp.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fIlibinn\fR\|(3).
diff --git a/doc/man/perl-nocem.8 b/doc/man/perl-nocem.8
deleted file mode 100644 (file)
index 12f9b67..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-.\" 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 3
-\&    gpg \-\-no\-default\-keyring \-\-primary\-keyring=/etc/news/pgp/ncmring.gpg \e
-\&        \-\-no\-options \-\-allow\-non\-selfsigned\-uid \-\-no\-permission\-warning \e
-\&        \-\-batch \-\-import <key\-file>
-.Ve
-.Sp
-where <pathetc> is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR
-and <key\-file> the file containing the key(s) to import.  The keyring
-must be located in \fIpathetc\fR/pgp/ncmring.gpg (create the directory
-before using \fBgpg\fR).  For old PGP-generated keys, you may have to use
-\&\fB\-\-allow\-non\-selfsigned\-uid\fR if they are not properly self\-signed,
-but anyone creating a key really should self-sign the key.  Current
-\&\s-1PGP\s0 implementations do this automatically.
-.Sp
-The keys of NoCeM issuers can be found in the web site of \fIThe NoCeM Registry\fR:
-<http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html>.  You can even
-download there a unique file which contains all the keys.
-.IP "2." 4
-Create a \fInocem.ctl\fR config file in \fIpathetc\fR indicating the NoCeM issuers
-and notices you want to follow.  This permission file contains lines like:
-.Sp
-.Vb 3
-\&    annihilator\-1:*
-\&    clewis@ferret.ocunix:mmf
-\&    stephane@asynchrone:mmf,openproxy,spam
-.Ve
-.Sp
-This will remove all articles for which the issuer (first part of the line,
-before the colon \f(CW\*(C`:\*(C'\fR) has issued NoCeM notices corresponding to the
-criteria specified after the colon.
-.Sp
-You will also find information about that on the web site of
-\&\fIThe NoCeM Registry\fR.
-.IP "3." 4
-Add to the \fInewsfeeds\fR file an entry like this one in order to feed
-\&\fBperl-nocem\fR the NoCeM notices posted to alt.nocem.misc and
-news.lists.filters:
-.Sp
-.Vb 3
-\&    nocem!\e
-\&        :!*,alt.nocem.misc,news.lists.filters\e
-\&        :Tc,Wf,Ap:<pathbin>/perl\-nocem
-.Ve
-.Sp
-with the correct path to \fBperl-nocem\fR, located in <pathbin>.  Then, reload
-the \fInewsfeeds\fR file (\f(CW\*(C`ctlinnd reload newsfeeds 'NoCeM channel feed'\*(C'\fR).
-.Sp
-Note that you should at least carry news.lists.filters on your news
-server (or other newsgroups where NoCeM notices are sent) if you wish
-to process them.
-.IP "4." 4
-Everything should now work.  However, do not hesitate to manually test
-\&\fBperl-nocem\fR with a NoCeM notice, using:
-.Sp
-.Vb 1
-\&    grephistory '<Message\-ID>' | perl\-nocem
-.Ve
-.Sp
-Indeed, \fBperl-nocem\fR expects tokens on its standard input, and
-\&\fBgrephistory\fR can easily give it the token of a known article,
-thanks to its Message\-ID.
-.PP
-When you have verified that everything works, you can eventually turn
-off regular spam cancels, if you want, not processing any longer
-cancels containing \f(CW\*(C`cyberspam\*(C'\fR in the Path: header (see the
-\&\fIrefusecybercancels\fR parameter in \fIinn.conf\fR).
-.SH "FILES"
-.IX Header "FILES"
-.IP "\fIpathbin\fR/perl\-nocem" 4
-.IX Item "pathbin/perl-nocem"
-The Perl script itself used to process NoCeM notices.
-.IP "\fIpathetc\fR/nocem.ctl" 4
-.IX Item "pathetc/nocem.ctl"
-The configuration file which specifies the NoCeM notices to be processed.
-.IP "\fIpathetc\fR/pgp/ncmring.gpg" 4
-.IX Item "pathetc/pgp/ncmring.gpg"
-The keyring which contains the public keys of trusted NoCeM issuers.
-.SH "BUGS"
-.IX Header "BUGS"
-The Subject: header is not checked for the @@NCM string and there is no
-check for the presence of the References: header.
-.PP
-The Newsgroups: pseudo header is not checked, but this can be done in
-\&\fIlocal_want_cancel_id()\fR.
-.PP
-The Hierarchies: header is ignored.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>.
-.PP
-Copyright 2001 by Marco d'Itri <md@linux.it>.
-.PP
-$Id: perl-nocem.8 7733 2008-04-06 09:16:20Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIgpgv\fR\|(1), \fIgrephistory\fR\|(1), \fIinn.conf\fR\|(5), \fInewsfeeds\fR\|(5), \fIpgp\fR\|(1).
diff --git a/doc/man/pgpverify.1 b/doc/man/pgpverify.1
deleted file mode 100644 (file)
index d0d09f4..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-.\" 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 "PGPVERIFY 1"
-.TH PGPVERIFY 1 "2008-04-06" "INN 2.4.4" "InterNetNews Documentation"
-.SH "NAME"
-pgpverify \- Cryptographically verify Usenet control messages
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBpgpverify\fR [\fB\-test\fR] < \fImessage\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The \fBpgpverify\fR program reads (on standard input) a Usenet control
-message that has been cryptographically signed using the \fBsigncontrol\fR
-program (or some other program that produces a compatible format).
-\&\fBpgpverify\fR then uses a \s-1PGP\s0 implementation to determine who signed the
-control message.  If the control message has a valid signature,
-\&\fBpgpverify\fR prints (to stdout) the user \s-1ID\s0 of the key that signed the
-message.  Otherwise, it exits with a non-zero exit status.
-.PP
-If \fBpgpverify\fR is installed as part of \s-1INN\s0, it uses \s-1INN\s0's configuration
-to determine what signature verification program to use, how to log
-errors, what temporary directory to use, and what keyring to use.
-Otherwise, all of those parameters can be set by editing the beginning of
-this script.
-.PP
-By default, when running as part of \s-1INN\s0, \fBpgpverify\fR expects the \s-1PGP\s0 key
-ring to be found in \fIpathetc\fR/pgp (as either \fIpubring.pgp\fR or
-\&\fIpubring.gpg\fR depending on whether \s-1PGP\s0 or GnuPG is used to verify
-signatures).  If that directory doesn't exist, it will fall back on using
-the default key ring, which is in a \fI.pgp\fR or \fI.gnupg\fR subdirectory of
-the running user's home directory.
-.PP
-\&\s-1INN\s0, when using GnuPG, configures \fBpgpverify\fR to use \fBgpgv\fR, which by
-default expects keys to be in a keyring named \fItrustedkeys.gpg\fR, since it
-doesn't implement trust checking directly.  \fBpgpverify\fR uses that file if
-present but falls back to \fIpubring.gpg\fR if it's not found.  This bypasses
-the trust model for checking keys, but is compatible with the way that
-\&\fBpgpverify\fR used to behave.  Of course, if a keyring is found in
-\&\fIpathetc\fR/pgp or configured at the top of the script, that overrides all of
-this behavior.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-The \fB\-test\fR flag causes \fBpgpverify\fR to print out the input that it is
-passing to \s-1PGP\s0 (which is a reconstructed version of the input that
-supposedly created the control message) as well as the output from \s-1PGP\s0's
-analysis of the message.
-.SH "EXIT STATUS"
-.IX Header "EXIT STATUS"
-\&\fBpgpverify\fR may exit with the following statuses:
-.IP "0\&" 4
-.IX Item "0"
-The control message had a good \s-1PGP\s0 signature.
-.IP "1" 4
-.IX Item "1"
-The control message had no \s-1PGP\s0 signature.
-.IP "2" 4
-.IX Item "2"
-The control message had an unknown \s-1PGP\s0 signature.
-.IP "3" 4
-.IX Item "3"
-The control message had a bad \s-1PGP\s0 signature.
-.IP "255" 4
-.IX Item "255"
-A problem occurred not directly related to \s-1PGP\s0 analysis of signature.
-.SH "ENVIRONMENT"
-.IX Header "ENVIRONMENT"
-\&\fBpgpverify\fR does not modify or otherwise alter the environment before
-invoking the \fBpgp\fR or \fBgpgv\fR program.  It is the responsibility of the
-person who installs \fBpgpverify\fR to ensure that when \fBpgp\fR or \fBgpgv\fR
-runs, it has the ability to locate and read a \s-1PGP\s0 key file that contains
-the \s-1PGP\s0 public keys for the appropriate Usenet hierarchy administrators.
-\&\fBpgpverify\fR can be pointed to an appropriate key ring by editing
-variables at the beginning of this script.
-.SH "NOTES"
-.IX Header "NOTES"
-Historically, Usenet news server administrators have configured their news
-servers to automatically honor Usenet control messages based on the
-originator of the control messages and the hierarchies for which the
-control messages applied.  For example, in the past, David Lawrence always
-issued control messages for the \*(L"Big\ 8\*(R" hierarchies (comp, humanities,
-misc, news, rec, sci, soc, talk).  Usenet news administrators would
-configure their news server software to automatically honor newgroup and
-rmgroup control messages that originated from David Lawrence and applied
-to any of the Big\ 8 hierarchies.
-.PP
-Unfortunately, Usenet news articles (including control messages) are
-notoriously easy to forge.  Soon, malicious users realized they could
-create or remove (at least temporarily) any Big\ 8 newsgroup they wanted by
-simply forging an appropriate control message in David Lawrence's name.
-As Usenet became more widely used, forgeries became more common.
-.PP
-The \fBpgpverify\fR program was designed to allow Usenet news administrators
-to configure their servers to cryptographically verify control messages
-before automatically acting on them.  Under the \fBpgpverify\fR system, a Usenet
-hierarchy maintainer creates a \s-1PGP\s0 public/private key pair and
-disseminates the public key.  Whenever the hierarchy maintainer issues a
-control message, he uses the \fBsigncontrol\fR program to sign the control
-message with the \s-1PGP\s0 private key.  Usenet news administrators configure
-their news servers to run the \fBpgpverify\fR program on the appropriate
-control messages, and take action based on the \s-1PGP\s0 key User \s-1ID\s0 that signed
-the control message, not the name and address that appear in the control
-message's From: or Sender: headers.
-.PP
-Thus, appropriate use of the \fBsigncontrol\fR and \fBpgpverify\fR programs
-essentially eliminates the possibility of malicious users forging Usenet
-control messages that sites will act upon, as such users would have to
-obtain the \s-1PGP\s0 private key in order to forge a control message that would
-pass the cryptographic verification step.  If the hierarchy administrators
-properly protect their \s-1PGP\s0 private keys, the only way a malicious user
-could forge a validly-signed control message would be by breaking the
-public key encryption algorithm, which (at least at this time) is believed
-to be prohibitively difficult for \s-1PGP\s0 keys of a sufficient bit length.
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBpgpverify\fR was written by David C Lawrence <tale@isc.org>.  Manual page
-provided by James Ralston.  It is currently maintained by Russ Allbery
-<rra@stanford.edu>.
-.SH "COPYRIGHT AND LICENSE"
-.IX Header "COPYRIGHT AND LICENSE"
-David Lawrence wrote:  \*(L"Our lawyer told me to include the following.  The
-upshot of it is that you can use the software for free as much as you
-like.\*(R"
-.PP
-Copyright (c) 1996 \s-1UUNET\s0 Technologies, Inc.
-All rights reserved.
-.PP
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-.IP "1." 4
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-.IP "2." 4
-Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation
-and/or other materials provided with the distribution.
-.IP "3." 4
-All advertising materials mentioning features or use of this software must
-display the following acknowledgement:
-.Sp
-.Vb 1
-\&  This product includes software developed by UUNET Technologies, Inc.
-.Ve
-.IP "4." 4
-The name of \s-1UUNET\s0 Technologies (\*(L"\s-1UUNET\s0\*(R") may not be used to endorse or
-promote products derived from this software without specific prior written
-permission.
-.PP
-\&\s-1THIS\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1PROVIDED\s0 \s-1BY\s0 \s-1UUNET\s0 \*(L"\s-1AS\s0 \s-1IS\s0\*(R" \s-1AND\s0 \s-1ANY\s0 \s-1EXPRESS\s0 \s-1OR\s0 \s-1IMPLIED\s0
-\&\s-1WARRANTIES\s0, \s-1INCLUDING\s0, \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0, \s-1THE\s0 \s-1IMPLIED\s0 \s-1WARRANTIES\s0 \s-1OF\s0
-\&\s-1MERCHANTABILITY\s0 \s-1AND\s0 \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0 \s-1ARE\s0 \s-1DISCLAIMED\s0.  \s-1IN\s0
-\&\s-1NO\s0 \s-1EVENT\s0 \s-1SHALL\s0 \s-1UUNET\s0 \s-1BE\s0 \s-1LIABLE\s0 \s-1FOR\s0 \s-1ANY\s0 \s-1DIRECT\s0, \s-1INDIRECT\s0, \s-1INCIDENTAL\s0,
-\&\s-1SPECIAL\s0, \s-1EXEMPLARY\s0, \s-1OR\s0 \s-1CONSEQUENTIAL\s0 \s-1DAMAGES\s0 (\s-1INCLUDING\s0, \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0
-\&\s-1TO\s0, \s-1PROCUREMENT\s0 \s-1OF\s0 \s-1SUBSTITUTE\s0 \s-1GOODS\s0 \s-1OR\s0 \s-1SERVICES\s0; \s-1LOSS\s0 \s-1OF\s0 \s-1USE\s0, \s-1DATA\s0, \s-1OR\s0
-\&\s-1PROFITS\s0; \s-1OR\s0 \s-1BUSINESS\s0 \s-1INTERRUPTION\s0) \s-1HOWEVER\s0 \s-1CAUSED\s0 \s-1AND\s0 \s-1ON\s0 \s-1ANY\s0 \s-1THEORY\s0 \s-1OF\s0
-\&\s-1LIABILITY\s0, \s-1WHETHER\s0 \s-1IN\s0 \s-1CONTRACT\s0, \s-1STRICT\s0 \s-1LIABILITY\s0, \s-1OR\s0 \s-1TORT\s0 (\s-1INCLUDING\s0
-\&\s-1NEGLIGENCE\s0 \s-1OR\s0 \s-1OTHERWISE\s0) \s-1ARISING\s0 \s-1IN\s0 \s-1ANY\s0 \s-1WAY\s0 \s-1OUT\s0 \s-1OF\s0 \s-1THE\s0 \s-1USE\s0 \s-1OF\s0 \s-1THIS\s0
-\&\s-1SOFTWARE\s0, \s-1EVEN\s0 \s-1IF\s0 \s-1ADVISED\s0 \s-1OF\s0 \s-1THE\s0 \s-1POSSIBILITY\s0 \s-1OF\s0 \s-1SUCH\s0 \s-1DAMAGE\s0.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIgpgv\fR\|(1), \fIpgp\fR\|(1).
-.PP
-<ftp://ftp.isc.org/pub/pgpcontrol/> is where the most recent versions of
-\&\fBsigncontrol\fR and \fBpgpverify\fR live, along with \s-1PGP\s0 public keys used for
-hierarchy administration.
diff --git a/doc/man/prunehistory.8 b/doc/man/prunehistory.8
deleted file mode 100644 (file)
index 8cc0c97..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-.\" $Revision: 5909 $
-.TH PRUNEHISTORY 8
-.SH NAME
-prunehistory \- remove tokens from Usenet history file
-.SH SYNOPSIS
-.B prunehistory
-[
-.BI \-f " filename"
-]
-[
-.B \-p
-]
-.SH DESCRIPTION
-.I Prunehistory
-modifies a
-.IR history (5)-format
-text file to ``remove'' a set of tokens from it.
-The tokens are removed by overwriting them with spaces, so that the
-size and position of any following entries does not change.  This has an
-effect similar to expiring the article, in that it is still mentioned in
-the history database but cannot be retrieved.
-.PP
-.I Prunehistory
-reads the standard input.
-The input is taken as a set of lines.
-Blank lines and lines starting with a number sign (``#'') are ignored.
-All other lines are should consist of a Message-ID followed by zero or
-more other fields (which are ignored).
-.PP
-The Message-ID is used as the
-.IR dbz (3)
-key to get an offset into the text file.
-.PP
-Since
-.IR innd (8)
-only appends
-to the text file,
-.I prunehistory
-does not need to have any interaction with it.
-.SH OPTIONS
-.TP
-.B \-p
-.I Prunehistory
-will normally complain about lines that do not follow the correct format.
-If the ``\-p'' flag is used, then the program will silently print any
-invalid lines on its standard output.
-(Blank lines and comment lines are also passed through.)
-This can be useful when
-.I prunehistory
-is used as a filter for other programs such as
-.IR reap .
-.TP
-.BI \-f " filename"
-The default name of the history file is
-.IR <pathdb\ in\ inn.conf>/history ;
-to specify a different name, use the ``\-f'' flag.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: prunehistory.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-dbz(3),
-history(5),
-inn.conf(5),
-innd(8).
diff --git a/doc/man/pullnews.1 b/doc/man/pullnews.1
deleted file mode 100644 (file)
index b8936a3..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-.\" 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 "PULLNEWS 1"
-.TH PULLNEWS 1 "2008-06-05" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-pullnews \- Pull news from multiple news servers and feed it to another
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBpullnews\fR [\fB\-hnqRx\fR] [\fB\-b\fR \fIfraction\fR] [\fB\-c\fR \fIconfig\fR] [\fB\-C\fR \fIwidth\fR]
-[\fB\-d\fR \fIlevel\fR] [\fB\-f\fR \fIfraction\fR] [\fB\-F\fR \fIfakehop\fR] [\fB\-g\fR \fIgroups\fR]
-[\fB\-G\fR \fInewsgroups\fR] [\fB\-H\fR \fIheaders\fR] [\fB\-k\fR \fIcheckpt\fR] [\fB\-l\fR \fIlogfile\fR]
-[\fB\-m\fR \fIheader_pats\fR] [\fB\-M\fR \fInum\fR] [\fB\-N\fR \fItimeout\fR] [\fB\-p\fR \fIport\fR]
-[\fB\-P\fR \fIhop_limit\fR] [\fB\-Q\fR \fIlevel\fR] [\fB\-r\fR \fIfile\fR] [\fB\-s\fR \fIto-server\fR[:\fIport\fR]]
-[\fB\-S\fR \fImax-run\fR] [\fB\-t\fR \fIretries\fR] [\fB\-T\fR \fIconnect-pause\fR] [\fB\-w\fR \fInum\fR]
-[\fB\-z\fR \fIarticle-pause\fR] [\fB\-Z\fR \fIgroup-pause\fR] [\fIfrom-server\fR ...]
-.SH "REQUIREMENTS"
-.IX Header "REQUIREMENTS"
-The \f(CW\*(C`Net::NNTP\*(C'\fR module must be installed.  This module is available as part
-of the libnet distribution and comes with recent versions of Perl.  For
-older versions of Perl, you can download it from <http://www.cpan.org/>.
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBpullnews\fR reads a config file in the running user's home directory
-(normally called \fI~/.pullnews\fR) and connects to the upstream servers
-given there as a reader client.  By default, it connects to all servers
-listed in the configuration file, but you can limit \fBpullnews\fR to
-specific servers by listing them on the command line:  a whitespace-separated
-list of server names can be specified, like \fIfrom-server\fR for one of them.
-For each server it connects to, it pulls over articles and feeds them to the
-destination server via the \s-1IHAVE\s0 or \s-1POST\s0 commands.  This means that the system
-\&\fBpullnews\fR is run on must have feeding access to the destination news server.
-.PP
-\&\fBpullnews\fR is designed for very small sites that do not want to bother
-setting up traditional peering and is not meant for handling large feeds.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-b\fR \fIfraction\fR" 4
-.IX Item "-b fraction"
-Backtrack on server numbering reset.  Specify the proportion (\f(CW0.0\fR to \f(CW1.0\fR)
-of a group's articles to pull when the server's article number is less than
-our high for that group.  When \fIfraction\fR is \f(CW1.0\fR, pull all the articles on
-a renumbered server.  The default is to do nothing.
-.IP "\fB\-c\fR \fIconfig\fR" 4
-.IX Item "-c config"
-Normally, the config file is stored in \fI~/.pullnews\fR for the user running
-\&\fBpullnews\fR.  If \fB\-c\fR is given, \fIconfig\fR will be used as the config file
-instead.  This is useful if you're running \fBpullnews\fR as a system user on
-an automated basis out of cron rather than as an individual user.
-.Sp
-See \*(L"\s-1CONFIG\s0 \s-1FILE\s0\*(R" below for the format of this file.
-.IP "\fB\-C\fR \fIwidth\fR" 4
-.IX Item "-C width"
-Use \fIwidth\fR characters per line for the progress table.  The default value
-is \f(CW50\fR.
-.IP "\fB\-d\fR \fIlevel\fR" 4
-.IX Item "-d level"
-Set the debugging level to the integer \fIlevel\fR; more debugging output
-will be logged as this increases.  The default value is \f(CW0\fR.
-.IP "\fB\-f\fR \fIfraction\fR" 4
-.IX Item "-f fraction"
-This changes the proportion of articles to get from each group to
-\&\fIfraction\fR and should be in the range \f(CW0.0\fR to \f(CW1.0\fR (\f(CW1.0\fR being
-the default).
-.IP "\fB\-F\fR \fIfakehop\fR" 4
-.IX Item "-F fakehop"
-Prepend \fIfakehop\fR as a host to the Path: header of articles fed.
-.IP "\fB\-g\fR \fIgroups\fR" 4
-.IX Item "-g groups"
-Specify a collection of groups to get.  \fIgroups\fR is a list of
-newsgroups separated by commas (only commas, no spaces).  Each group must
-be defined in the config file, and only the remote hosts that carry those
-groups will be contacted.  Note that this is a simple list of groups, not
-a wildmat expression, and wildcards are not supported.
-.IP "\fB\-G\fR \fInewsgroups\fR" 4
-.IX Item "-G newsgroups"
-Add the comma-separated list of groups \fInewsgroups\fR to each server in the
-configuration file (see also \fB\-g\fR and \fB\-w\fR).
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Print a usage message and exit.
-.IP "\fB\-H\fR \fIheaders\fR" 4
-.IX Item "-H headers"
-Remove these named headers (colon\-separated list) from fed articles.
-.IP "\fB\-k\fR \fIcheckpt\fR" 4
-.IX Item "-k checkpt"
-Checkpoint (save) the config file every \fIcheckpt\fR articles
-(default is \f(CW0\fR, that is to say at the end of the session).
-.IP "\fB\-l\fR \fIlogfile\fR" 4
-.IX Item "-l logfile"
-Log progress/stats to \fIlogfile\fR (default is \f(CW\*(C`stdout\*(C'\fR).
-.IP "\fB\-m\fR \fIheader_pats\fR" 4
-.IX Item "-m header_pats"
-Feed an article based on header matching.  The argument is a number of
-whitespace-separated tuples (each tuple being a colon-separated header and
-regular expression).  For instance:
-.Sp
-.Vb 1
-\&    Hdr1:regexp1 !Hdr2:regexp2
-.Ve
-.Sp
-specifies that the article will be passed only if the \f(CW\*(C`Hdr1:\*(C'\fR header
-matches \f(CW\*(C`regexp1\*(C'\fR and the \f(CW\*(C`Hdr2:\*(C'\fR header does not match \f(CW\*(C`regexp2\*(C'\fR.
-.IP "\fB\-M\fR \fInum\fR" 4
-.IX Item "-M num"
-Specify the maximum number of articles (per group) to process.
-The default is to process all new articles.  See also \fB\-f\fR.
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-Do nothing but read articles \-\-\ does not feed articles downstream,
-writes no \fBrnews\fR file, does not update the config file.
-.IP "\fB\-N\fR \fItimeout\fR" 4
-.IX Item "-N timeout"
-Specify the timeout length, as \fItimeout\fR seconds,
-when establishing an \s-1NNTP\s0 connection.
-.IP "\fB\-p\fR \fIport\fR" 4
-.IX Item "-p port"
-Connect to the destination news server on a port other than the default of
-\&\f(CW119\fR.  This option does not change the port used to connect to the source
-news servers.
-.IP "\fB\-P\fR \fIhop_limit\fR" 4
-.IX Item "-P hop_limit"
-Restrict feeding an article based on the number of hops it has already made.
-Count the hops in the Path: header (\fIhop_count\fR), feeding the article only
-when \fIhop_limit\fR is \f(CW\*(C`+num\*(C'\fR and \fIhop_count\fR is more than \fInum\fR;
-or \fIhop_limit\fR is \f(CW\*(C`\-num\*(C'\fR and \fIhop_count\fR is less than \fInum\fR.
-.IP "\fB\-q\fR" 4
-.IX Item "-q"
-Print out less status information while running.
-.IP "\fB\-Q\fR \fIlevel\fR" 4
-.IX Item "-Q level"
-Set the quietness level (\f(CW\*(C`\-Q 2\*(C'\fR is equivalent to \f(CW\*(C`\-q\*(C'\fR).  The higher this
-value, the less gets logged.  The default is \f(CW0\fR.
-.IP "\fB\-r\fR \fIfile\fR" 4
-.IX Item "-r file"
-Rather than feeding the downloaded articles to a destination server, instead
-create a batch file that can later be fed to a server using \fBrnews\fR.  See
-\&\fIrnews\fR\|(1) for more information about the batch file format.
-.IP "\fB\-R\fR" 4
-.IX Item "-R"
-Be a reader (use \s-1MODE\s0 \s-1READER\s0 and \s-1POST\s0 commands) to the downstream
-server.  The default is to use the \s-1IHAVE\s0 command.
-.IP "\fB\-s\fR \fIto-server\fR[:\fIport\fR]" 4
-.IX Item "-s to-server[:port]"
-Normally, \fBpullnews\fR will feed the articles it retrieves to the news
-server running on localhost.  To connect to a different host, specify a
-server with the \fB\-s\fR flag.  You can also specify the port with this same
-flag or use \fB\-p\fR.
-.IP "\fB\-S\fR \fImax-run\fR" 4
-.IX Item "-S max-run"
-Specify the maximum time \fImax-run\fR in seconds for \fBpullnews\fR to run.
-.IP "\fB\-t\fR \fIretries\fR" 4
-.IX Item "-t retries"
-The maximum number (\fIretries\fR) of attempts to connect to a server
-(see also \fB\-T\fR).  The default is \f(CW0\fR.
-.IP "\fB\-T\fR \fIconnect-pause\fR" 4
-.IX Item "-T connect-pause"
-Pause \fIconnect-pause\fR seconds between connection retries (see also \fB\-t\fR).
-The default is \f(CW1\fR.
-.IP "\fB\-w\fR \fInum\fR" 4
-.IX Item "-w num"
-Set each group's high watermark (last received article number) to \fInum\fR.
-If \fInum\fR is negative, calculate \fICurrent\fR+\fInum\fR instead (i.e. get the last
-\&\fInum\fR articles).  Therefore, a \fInum\fR of \f(CW0\fR will re-get all articles on the
-server; whereas a \fInum\fR of \f(CW\*(C`\-0\*(C'\fR will get no old articles, setting the
-watermark to \fICurrent\fR (the most recent article on the server).
-.IP "\fB\-x\fR" 4
-.IX Item "-x"
-If the \fB\-x\fR flag is used, an Xref: header is added to any article
-that lacks one.  It can be useful for instance if articles are fed
-to a news server which has \fIxrefslave\fR set in \fIinn.conf\fR.
-.IP "\fB\-z\fR \fIarticle-pause\fR" 4
-.IX Item "-z article-pause"
-Sleep \fIarticle-pause\fR seconds between articles.  The default is \f(CW0\fR.
-.IP "\fB\-Z\fR \fIgroup-pause\fR" 4
-.IX Item "-Z group-pause"
-Sleep \fIgroup-pause\fR seconds between groups.  The default is \f(CW0\fR.
-.SH "CONFIG FILE"
-.IX Header "CONFIG FILE"
-The config file for \fBpullnews\fR is divided into blocks, one block for each
-remote server to connect to.  A block begins with the host line, which
-must have no leading whitespace and contains just the hostname of the
-remote server, optionally followed by authentication details (username
-and password for that server).
-.PP
-Following the host line should be one or more newsgroup lines which start
-with whitespace followed by the name of a newsgroup to retrieve.  Only one
-newsgroup should be listed on each line.
-.PP
-\&\fBpullnews\fR will update the config file to include the time the group was
-last checked and the highest numbered article successfully retrieved and
-transferred to the destination server.  It uses this data to avoid doing
-duplicate work the next time it runs.
-.PP
-The full syntax is:
-.PP
-.Vb 3
-\&    <host> [<username> <password>]
-\&            <group> [<time> <high>]
-\&            <group> [<time> <high>]
-.Ve
-.PP
-where the <host> line must not have leading whitespace and the <group>
-lines must.
-.PP
-A typical configuration file would be:
-.PP
-.Vb 7
-\&    # Format group date high
-\&    data.pa.vix.com
-\&            rec.bicycles.racing 908086612 783
-\&            rec.humor.funny 908086613 18
-\&            comp.programming.threads
-\&    nnrp.vix.com pull sekret
-\&            comp.std.lisp
-.Ve
-.PP
-Note that an earlier run of \fBpullnews\fR has filled in details about the
-last article downloads from the two rec.* groups.  The two comp.* groups
-were just added by the user and have not yet been checked.
-.PP
-The nnrp.vix.com server requires authentication, and \fBpullnews\fR will use
-the username \f(CW\*(C`pull\*(C'\fR and the password \f(CW\*(C`sekret\*(C'\fR.
-.SH "FILES"
-.IX Header "FILES"
-.IP "\fIpathbin\fR/pullnews" 4
-.IX Item "pathbin/pullnews"
-The Perl script itself used to pull news from upstream servers and feed
-it to another news server.
-.IP "\fI$HOME\fR/.pullnews" 4
-.IX Item "$HOME/.pullnews"
-The default config file.  It is in the running user's home directory
-(normally called \fI~/.pullnews\fR).
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBpullnews\fR was written by James Brister for \s-1INN\s0.  The documentation was
-rewritten in \s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-Geraint A. Edwards greatly improved \fBpullnews\fR, adding no more than 16\ new
-recognized flags, fixing some bugs and integrating the \fBbackupfeed\fR
-contrib script by Kai Henningsen, adding again 6\ other flags.
-.PP
-$Id: pullnews.pod 7853 2008\-05\-27 19:07:45Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIincoming.conf\fR\|(5), \fIrnews\fR\|(1).
diff --git a/doc/man/putman.sh b/doc/man/putman.sh
deleted file mode 100644 (file)
index 36a8f19..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#! /bin/sh
-##  $Revision: 2790 $
-##
-##  Prepare a manpage for installation, and install it.  Usage:
-##     putman <style> "<installitflags>" <source> <dest-dir>
-case $# in
-4)
-    ;;
-*)
-    echo "Can't install manpage:  wrong number of arguments." 1>&2
-esac
-
-STYLE="$1"
-FLAGS="$2"
-SRC="$3"
-DEST="$4"
-
-case "X${STYLE}" in
-XNONE)
-    exit 0
-    ;;
-XSOURCE)
-    exec /bin/sh ../../support/install-sh ${FLAGS} ${SRC} ${DEST}
-    ;;
-XNROFF-PACK)
-    T=${TMPDIR-/tmp}/man$$
-    nroff -man ${SRC} >$T
-    /bin/sh ../../support/install-sh ${FLAGS} $T ${DEST} && pack ${DEST}
-    rm -f $T
-    exit
-    ;;
-XNROFF-PACK-SCO)
-    T=${TMPDIR-/tmp}/man$$
-    nroff -man ${SRC} >$T
-    DEST2=`echo ${DEST} | sed -e 's/\..$/.INN/'`
-    /bin/sh ../../support/install-sh ${FLAGS} $T ${DEST2} && pack ${DEST2}
-    rm -f $T
-    exit
-    ;;
-XBSD4.4)
-    T=${TMPDIR-/tmp}/man$$
-    nroff -man ${SRC} >$T
-    DEST2=`echo ${DEST} | sed -e 's/\..$/.0/'`
-    /bin/sh ../../support/install-sh ${FLAGS} $T ${DEST2}
-    rm -f $T
-    exit
-    ;;
-esac
-
-echo "Can't install manpage:  unknown method ${STYLE}." 1>&2
-exit 1
diff --git a/doc/man/qio.3 b/doc/man/qio.3
deleted file mode 100644 (file)
index 4345d79..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-.\" 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 "qio 3"
-.TH qio 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-qio \- Quick I/O routines for reading files
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fB#include <inn/qio.h>\fR
-.PP
-\&\fB\s-1QIOSTATE\s0 *QIOopen(const char *\fR\fIname\fR\fB);\fR
-.PP
-\&\fB\s-1QIOSTATE\s0 *QIOfdopen(int\fR \fIfd\fR\fB);\fR
-.PP
-\&\fBvoid QIOclose(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBchar *QIOread(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBint QIOfileno(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBsize_t QIOlength(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBint QIOrewind(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBoff_t QIOtell(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBbool QIOerror(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.PP
-\&\fBbool QIOtoolong(\s-1QIOSTATE\s0 *\fR\fIqp\fR\fB);\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The routines described in this manual page are part of \fIlibinn\fR\|(3).  They
-are used to provide quick read access to files; the \s-1QIO\s0 routines use
-buffering adapted to the block size of the device, similar to stdio, but
-with a more convenient syntax for reading newline-terminated lines.  \s-1QIO\s0
-is short for \*(L"Quick I/O\*(R" (a bit of a misnomer, as \s-1QIO\s0 provides read-only
-access to files only).
-.PP
-The \s-1QIOSTATE\s0 structure returned by \fBQIOopen\fR and \fBQIOfdopen\fR is the
-analog to stdio's \s-1FILE\s0 structure and should be treated as a black box by
-all users of these routines.  Only the above \s-1API\s0 should be used.
-.PP
-\&\fBQIOopen\fR opens the given file for reading.  For regular files, if your
-system provides that information and the size is reasonable, \s-1QIO\s0 will use
-the block size of the underlying file system as its buffer size;
-otherwise, it will default to a buffer of 8 \s-1KB\s0.  Returns a pointer to use
-for subsequent calls, or \s-1NULL\s0 on error.  \fBQIOfdopen\fR performs the same
-operation except on an already-open file descriptor (\fIfd\fR must designate
-a file open for reading).
-.PP
-\&\fBQIOclose\fR closes the open file and releases any resources used by the
-\&\s-1QIOSTATE\s0 structure.  The \s-1QIOSTATE\s0 pointer should not be used again after
-it has been passed to this function.
-.PP
-\&\fBQIOread\fR reads the next newline-terminated line in the file and returns
-a pointer to it, with the trailing newline replaced by nul.  The returned
-pointer is a pointer into a buffer in the \s-1QIOSTATE\s0 object and therefore
-will remain valid until \fBQIOclose\fR is called on that object.  If \s-1EOF\s0 is
-reached, an error occurs, or if the line is longer than the buffer size,
-\&\s-1NULL\s0 is returned instead.  To distinguish between the error cases, use
-\&\fBQIOerror\fR and \fBQIOtoolong\fR.
-.PP
-\&\fBQIOfileno\fR returns the descriptor of the open file.
-.PP
-\&\fBQIOlength\fR returns the length in bytes of the last line returned by
-\&\fBQIOread\fR.  Its return value is only defined after a successful call to
-\&\fBQIOread\fR.
-.PP
-\&\fBQIOrewind\fR sets the read pointer back to the beginning of the file and
-reads the first block of the file in anticipation of future reads.  It
-returns 0 if successful and \-1 on error.
-.PP
-\&\fBQIOtell\fR returns the current value of the read pointer (the \fIlseek\fR\|(2)
-offset at which the next line will start).
-.PP
-\&\fBQIOerror\fR returns true if there was an error in the last call to
-\&\fBQIOread\fR, false otherwise.  \fBQIOtoolong\fR returns true if there was an
-error and the error was that the line was too long.  If \fBQIOread\fR returns
-\&\s-1NULL\s0, these functions should be called to determine what happened.  If
-\&\fBQIOread\fR returned \s-1NULL\s0 and \fBQIOerror\fR is false, \s-1EOF\s0 was reached.  Note
-that if \fBQIOtoolong\fR returns true, the next call to \fBQIOread\fR will try
-to read the remainder of the line and will likely return a partial line;
-users of this library should in general treat long lines as fatal errors.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-This block of code opens \fI/etc/motd\fR and reads it a line at a time,
-printing out each line preceeded by its offset in the file.
-.PP
-.Vb 3
-\&    QIOSTATE *qp;
-\&    off_t offset;
-\&    char *p;
-.Ve
-.PP
-.Vb 12
-\&    qp = QIOopen("/etc/motd");
-\&    if (qp == NULL) {
-\&        perror("Open error");
-\&        exit(1);
-\&    }
-\&    for (p = QIOread(qp); p != NULL; p = QIOread(qp))
-\&        printf("%ld: %s\en", (unsigned long) QIOtell(qp), p);
-\&    if (QIOerror(qp)) {
-\&        perror("Read error");
-\&        exit(1);
-\&    }
-\&    QIOclose(qp);
-.Ve
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews.  Updated by
-Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: qio.3 7880 2008-06-16 20:37:13Z iulius $
diff --git a/doc/man/radius.8 b/doc/man/radius.8
deleted file mode 100644 (file)
index ce32e0e..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-.\" 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 "RADIUS 8"
-.TH RADIUS 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-radius \- nnrpd RADIUS password authenticator
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBradius\fR [\fB\-h\fR] [\fB\-f\fR \fIconfig\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBradius\fR is an nnrpd authenticator, accepting a username and password
-from nnrpd (given to nnrpd by a reader connection) and attempting to
-authenticate that username and password against a \s-1RADIUS\s0 server.  See
-\&\fIreaders.conf\fR\|(5) for more information on how to configure an nnrpd
-authenticator.  It is useful for a site that already does user
-authentication via \s-1RADIUS\s0 and wants to authenticate news reading
-connections as well.
-.PP
-By default, \fBradius\fR reads \fIpathetc\fR/radius.conf for configuration
-information, but a different configuration file can be specified with
-\&\fB\-f\fR.  See \fIradius.conf\fR\|(5) for a description of the configuration file.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-f\fR \fIconfig\fR" 4
-.IX Item "-f config"
-Read \fIconfig\fR instead of \fIpathetc\fR/radius.conf for configuration
-information.
-.IP "\fB\-h\fR" 4
-.IX Item "-h"
-Print out a usage message and exit.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-The following \fIreaders.conf\fR\|(5) fragment tells nnrpd to authenticate all
-connections using this authenticator:
-.PP
-.Vb 5
-\&    auth radius {
-\&        auth: radius
-\&        default: <FAIL>
-\&        default\-domain: example.com
-\&    }
-.Ve
-.PP
-\&\f(CW\*(C`@example.com\*(C'\fR will be appended to the user-supplied identity, and if
-\&\s-1RADIUS\s0 authentication failes, the user will be assigned an identity of
-\&\f(CW\*(C`<FAIL>@example.com\*(C'\fR.
-.SH "BUGS"
-.IX Header "BUGS"
-It has been reported that this authenticator doesn't work with Ascend
-\&\s-1RADIUS\s0 servers, but does work with Cistron \s-1RADIUS\s0 servers.  It's also
-believed to work with Livingston's \s-1RADIUS\s0 server.  Contributions to make
-it work better with different types of \s-1RADIUS\s0 servers would be gratefully
-accepted.
-.PP
-This code has not been audited against the \s-1RADIUS\s0 protocol and may not
-implement it correctly.
-.SH "HISTORY"
-.IX Header "HISTORY"
-The \s-1RADIUS\s0 authenticator was originally written by Aidan Cully.  This
-documentation was written by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: radius.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8), \fIradius.conf\fR\|(5), \fIreaders.conf\fR\|(5)
-.PP
-\&\s-1RFC\s0 2865, Remote Authentication Dial In User Service.
diff --git a/doc/man/radius.conf.5 b/doc/man/radius.conf.5
deleted file mode 100644 (file)
index 9581607..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-.\" 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 "RADIUS.CONF 5"
-.TH RADIUS.CONF 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-radius.conf \- Configuration for nnrpd RADIUS authenticator
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-This describes the format and attributes of the configuration file for the
-nnrpd \s-1RADIUS\s0 authenticator.  See \fIradius\fR\|(1) for more information about the
-authenticator program.  The default location for this file is
-\&\fIradius.conf\fR in \fIpathetc\fR.
-.PP
-Blank lines and lines beginning with \f(CW\*(C`#\*(C'\fR are ignored, as is anything
-after a \f(CW\*(C`#\*(C'\fR on a line.  All other lines should begin with a parameter
-name followed by a colon and the value of that key, except that each
-section of configuration for a particular server should be enclosed in:
-.PP
-.Vb 3
-\&    server <name> {
-\&        # parameters...
-\&    }
-.Ve
-.PP
-where <name> is just some convenient label for that server.
-.PP
-The available parameters are:
-.IP "\fIradhost\fR" 4
-.IX Item "radhost"
-The hostname of the \s-1RADIUS\s0 server to use for authentication.  This
-parameter must be set.
-.IP "\fIradport\fR" 4
-.IX Item "radport"
-The port to query on the \s-1RADIUS\s0 server.  Defaults to 1645 if not set.
-.IP "\fIlochost\fR" 4
-.IX Item "lochost"
-The hostname or \s-1IP\s0 address making the request.  The \s-1RADIUS\s0 server expects
-an \s-1IP\s0 address; a hostname will be translated into an \s-1IP\s0 address with
-\&\fIgethostbyname()\fR.  If not given, this information isn't included in the
-request (not all \s-1RADIUS\s0 setups require this information).
-.IP "\fIlocport\fR" 4
-.IX Item "locport"
-The port the client being authenticated is connecting to.  If not given,
-defaults to 119.  This doesn't need to be set unless readers are
-connecting to a non-standard port.
-.IP "\fIsecret\fR" 4
-.IX Item "secret"
-The shared secret with the \s-1RADIUS\s0 server.  If your secret includes spaces,
-tabs, or \f(CW\*(C`#\*(C'\fR, be sure to include it in double quotes.  This parameter
-must be set.
-.IP "\fIprefix\fR" 4
-.IX Item "prefix"
-Prepend the value of this parameter to all usernames before passing them
-to the \s-1RADIUS\s0 server.  Can be used to prepend something like \f(CW\*(C`news\-\*(C'\fR to
-all usernames in order to put news users into a different namespace from
-other accounts served by the same server.  If not set, nothing is
-prepended.
-.IP "\fIsuffix\fR" 4
-.IX Item "suffix"
-Append the value of this parameter to all usernames before passing them to
-the \s-1RADIUS\s0 server.  This is often something like \f(CW\*(C`@example.com\*(C'\fR,
-depending on how your \s-1RADIUS\s0 server is set up.  If not set, nothing is
-appended.
-.IP "\fIignore-source\fR" 4
-.IX Item "ignore-source"
-Can be set to \f(CW\*(C`true\*(C'\fR or \f(CW\*(C`false\*(C'\fR.  If set to false, the \s-1RADIUS\s0
-authenticator will check to ensure that the response it receives is from
-the same \s-1IP\s0 address as it sent the request to (for some added security).
-If set to true, it will skip this verification check (if your \s-1RADIUS\s0
-server has multiple \s-1IP\s0 addresses or if other odd things are going on, it
-may be perfectly normal for the response to come from a different \s-1IP\s0
-address).
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-Here is a configuration for a news server named news.example.com,
-authenticating users against radius.example.com and appending
-\&\f(CW\*(C`@example.com\*(C'\fR to all client-supplied usernames before passing them to
-the \s-1RADIUS\s0 server:
-.PP
-.Vb 6
-\&    server example {
-\&        radhost: radius.example.com
-\&        lochost: news.example.com
-\&        secret: IamARADIUSsecRET
-\&        suffix: @example.com
-\&    }
-.Ve
-.PP
-The shared secret with the \s-1RADIUS\s0 server is \f(CW\*(C`IamARADIUSsecRET\*(C'\fR.
-.SH "HISTORY"
-.IX Header "HISTORY"
-This documentation was written by Russ Allbery <rra@stanford.edu> based on
-the comments in the sample radius.conf file by Yury B. Razbegin.
-.PP
-$Id: radius.conf.5 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIradius\fR\|(1)
diff --git a/doc/man/rc.news.8 b/doc/man/rc.news.8
deleted file mode 100644 (file)
index a98bb5a..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-.\" 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 "RC.NEWS 8"
-.TH RC.NEWS 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-rc.news \- Start or stop INN daemons
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBrc.news\fR [start | stop]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBrc.news\fR can be used to start or stop \fBinnd\fR and supporting programs.
-It checks to make sure \s-1INN\s0 is not already running, handles cases of
-unclean shutdown, finishes up tasks which might have been interrupted by
-the preceeding shutdown, emails certain boot-time warnings to
-\&\fInewsmaster\fR (as set in \fIinn.conf\fR), and is generally safer and easier
-than starting and stopping everything directly.  It needs to be run as the
-news user so that files in \fIpathrun\fR are created with the right ownership
-(though this is less important for \f(CW\*(C`rc.news stop\*(C'\fR), and therefore
-requires that \fIinndstart\fR be setuid root, see \fIinndstart\fR\|(8) for
-discussion.
-.PP
-Programs run and stopped by this script include:
-.IP "\(bu" 4
-Always:  \fBinndstart\fR is run, and \fBinnd\fR is stopped.
-.IP "\(bu" 4
-If \fIdoinnwatch\fR is true in \fIinn.conf\fR:  \fBinnwatch\fR is started and
-stopped.
-.IP "\(bu" 4
-If \fIdocnfsstat\fR is true in \fIinn.conf\fR:  \fBovdb_init\fR is run;
-\&\fBovdb_server\fR and \fBovdb_monitor\fR are stopped.
-.IP "\(bu" 4
-If \fIrc.news.local\fR exists in \fIpathbin\fR:  \fBrc.news.local\fR is run with
-argument \f(CW\*(C`start\*(C'\fR or \f(CW\*(C`stop\*(C'\fR (to perform site-specific startup or shutdown
-tasks).
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.ie n .IP """start""" 4
-.el .IP "\f(CWstart\fR" 4
-.IX Item "start"
-If the first argument is \f(CW\*(C`start\*(C'\fR, or no first argument is given,
-\&\fBrc.news\fR initiates \s-1INN\s0 startup.
-.ie n .IP """stop""" 4
-.el .IP "\f(CWstop\fR" 4
-.IX Item "stop"
-If the first argument is \f(CW\*(C`stop\*(C'\fR, \fBrc.news\fR initiates \s-1INN\s0 shutdown.  It
-is recommended to throttle the server first as described in \fIctlinnd\fR\|(8).
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-To start \s-1INN\s0 and leave certain error messages going to the terminal:
-.PP
-.Vb 1
-\&       su \- news \-c ~news/bin/rc.news
-.Ve
-.PP
-To run \s-1INN\s0 at startup time from appropriate system boot scripts:
-.PP
-.Vb 1
-\&       su \- news \-c ~news/bin/rc.news >/dev/console
-.Ve
-.PP
-To stop \s-1INN\s0 (throttling first):
-.PP
-.Vb 2
-\&       ~news/bin/ctlinnd throttle reason
-\&       su \- news \-c '~news/bin/rc.news stop'
-.Ve
-.SH "BUGS"
-.IX Header "BUGS"
-Running \f(CW\*(C`rc.news start\*(C'\fR as root is never the right thing to do, so we
-should at minimum check for this and error, or perhaps change effective
-user \s-1ID\s0.
-.SH "HISTORY"
-.IX Header "HISTORY"
-// \s-1FIXME:\s0  any attribution for rc.news itself?
-.PP
-This manual page written by Jeffrey M. Vinocur <jeff@litech.org> for
-InterNetNews.
-.PP
-$Id: rc.news.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIctlinnd\fR\|(8),
-\&\fIcnfsstat\fR\|(8),
-\&\fIinn.conf\fR\|(5),
-\&\fIinndstart\fR\|(8),
-\&\fIinnwatch\fR\|(8),
-\&\fIovdb\fR\|(5).
diff --git a/doc/man/readers.conf.5 b/doc/man/readers.conf.5
deleted file mode 100644 (file)
index fa8ce69..0000000
+++ /dev/null
@@ -1,932 +0,0 @@
-.\" 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 "READERS.CONF 5"
-.TH READERS.CONF 5 "2008-06-22" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-readers.conf \- Access control and configuration for nnrpd
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fIreaders.conf\fR in \fIpathetc\fR specifies access control for \fInnrpd\fR\|(8).  It
-controls who is allowed to connect as a news reader and what they're
-allowed to do after they connect.  nnrpd reads this file when it starts
-up.  This generally means that any changes take effect immediately on all
-subsequent connections, but \fBnnrpd\fR may have to be restarted if you use
-the \fB\-D\fR option.  (The location \fIpathetc\fR/readers.conf is only the
-default; the same format applies to any file specified with \f(CW\*(C`nnrpd \-c\*(C'\fR.)
-.PP
-There are two types of entries in \fIreaders.conf\fR:  parameter/value pairs
-and configuration groups.  Blank lines and anything after a number sign
-(\f(CW\*(C`#\*(C'\fR) are ignored, unless the character \f(CW\*(C`#\*(C'\fR is escaped with \f(CW\*(C`\e\*(C'\fR.  The
-maximum number of characters on each line is 8,191.
-.PP
-Parameter/value pairs consist of a keyword immediately followed by a
-colon, at least one whitespace character, and a value.  The case of the
-parameter is significant (parameter should generally be in all lowercase),
-and a parameter may contain any characters except colon, \f(CW\*(C`#\*(C'\fR, and
-whitespace.  An example:
-.PP
-.Vb 1
-\&    hosts: *.example.com
-.Ve
-.PP
-Values that contain whitespace should be quoted with double quotes, as in:
-.PP
-.Vb 1
-\&    hosts: "*.example.com, *.example.net"
-.Ve
-.PP
-If the parameter does not contain whitespace, such as:
-.PP
-.Vb 1
-\&    hosts: *.example.com,*.example.net
-.Ve
-.PP
-it's not necessary to quote it, although you may wish to anyway for
-clarity.
-.PP
-There is no way to continue a line on the next line, and therefore no way
-to have a single parameter with a value longer than about 8,180
-characters.
-.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
-not significant.
-.PP
-There are two basic types of configuration groups, auth and access.  The
-auth group provides mechanisms to establish the identity of the user, who
-they are.  The access group determines, given the user's identity, what
-that user is permitted to do.  Writing a \fIreaders.conf\fR file for your
-setup is a two-step process: first assigning an identity to each incoming
-connection using auth groups, and then giving each identity appropriate
-privileges with access group.  We recommend \fInot\fR intermingling auth
-groups and access groups in the config file; it is often more sensible (in
-the absence of the \fIkey\fR parameter) to put all of the auth groups first,
-and all of the access groups below.
-.PP
-A user identity, as established by an auth group, looks like an e\-mail
-address; in other words, it's in the form \*(L"<username>@<domain>\*(R" (or
-sometimes just \*(L"<username>\*(R" if no domain is specified.
-.PP
-If \fInnrpdauthsender\fR is set in \fIinn.conf\fR, the user identity is also put
-into the Sender: header of posts made by that user.  See the documentation
-of that option in \fIinn.conf\fR\|(5) for more details.
-.PP
-An auth group definition looks like:
-.PP
-.Vb 8
-\&    auth <name> {
-\&        hosts: <host\-wildmat>
-\&        auth: <auth\-program>
-\&        res: <res\-program>
-\&        default: <defuser>
-\&        default\-domain: <defdomain>
-\&        # ...possibly other settings
-\&    }
-.Ve
-.PP
-The <name> is used as a label for the group and is only for documentation
-purposes.  (If your syslog configuration records the \f(CW\*(C`news.debug\*(C'\fR
-facility, the <name> will appear in the debugging output of nnrpd.
-Examining that output can be very helpful in understanding why your
-configuration doesn't do what you expect it to.)
-.PP
-A given auth group applies only to hosts whose name or \s-1IP\s0 address matches
-the wildmat expression given with the hosts: parameter (comma\-separated
-wildmat expressions allowed, but \f(CW\*(C`@\*(C'\fR is not supported).  Rather than
-wildmat expressions, you may also use \s-1CIDR\s0 notation to match any \s-1IP\s0
-address in a netblock; for example, \*(L"10.10.10.0/24\*(R" will match any \s-1IP\s0
-address between 10.10.10.0 and 10.10.10.255 inclusive.
-.PP
-If compiled against the \s-1SSL\s0 libraries, an auth group with the require_ssl:
-parameter set to true only applies if the incoming connection is using
-\&\s-1SSL\s0.
-.PP
-For any connection from a host that matches that wildmat expression or
-netblock, each <res\-program> (multiple res: lines may be present in a
-block; they are run in sequence until one succeeds), if any, is run to
-determine the identity of the user just from the connection information.
-If all the resolvers fail, or if the res: parameter isn't present, the
-user is assigned an identity of \*(L"<defuser>@<defdomain>\*(R"; in other words,
-the values of the default: and default\-domain: parameters are used.  If
-<res\-program> only returns a username, <defdomain> is used as the
-domain.
-.PP
-If the user later authenticates via the \s-1AUTHINFO\s0 \s-1USER/PASS\s0 commands, the
-provided username and password are passed to each <auth\-program> (multiple
-auth, perl_auth, or python_auth lines may be present in a block; they are
-run in sequence until one succeeds), if any.  If one succeeds and returns
-a different identity than the one assigned at the time of the connection,
-it is matched against the available access groups again and the actions
-the user is authorized to do may change.  The most common <auth\-program>
-to use is \fBckpasswd\fR, which supports several ways of checking passwords
-including using \s-1PAM\s0.  See the \fIckpasswd\fR\|(8) man page for more details.
-.PP
-When matching auth groups, the last auth group in the file that matches a
-given connection and username/password combination is used.
-.PP
-An access group definition usually looks like:
-.PP
-.Vb 5
-\&    access <name> {
-\&        users: <identity\-wildmat>
-\&        newsgroups: <group\-wildmat>
-\&        # ...possibly other settings
-\&    }
-.Ve
-.PP
-Again, <name> is just for documentation purposes.  This says that all
-users whose identity matches <identity\-wildmat> can read and post to all
-newsgroups matching <group\-wildmat> (as before, comma-separated wildmat
-expressions are allowed, but \f(CW\*(C`@\*(C'\fR is not supported).  Alternately, you can
-use the form:
-.PP
-.Vb 5
-\&    access <name> {
-\&        users: <identity\-wildmat>
-\&        read: <read\-wildmat>
-\&        post: <post\-wildmat>
-\&    }
-.Ve
-.PP
-and matching users will be able to read any group that matches
-<read\-wildmat> and post to any group that matches <post\-wildmat>.  You can
-also set several other things in the access group as well as override
-various \fIinn.conf\fR\|(5) parameters for just a particular group of users.
-.PP
-Just like with auth groups, when matching access groups the last matching
-one in the file is used to determine the user's permissions.  There is
-an exception to this rule: if the auth group which matched the client
-contains a perl_access: or python_access: parameter, then the script
-given as argument is used to dynamically generate an access group.
-This new access group is then used to determine the access rights of
-the client; the access groups in the file are ignored.
-.PP
-There is one additional special case to be aware of.  When forming
-particularly complex authentication and authorization rules, it is
-sometimes useful for the identities provided by a given auth group to only
-apply to particular access groups; in other words, rather than checking
-the identity against the users: parameter of every access group, it's
-checked against the users: parameter of only some specific access groups.
-This is done with the key: parameter.  For example:
-.PP
-.Vb 5
-\&    auth example {
-\&        key: special
-\&        hosts: *.example.com
-\&        default: <SPECIAL>
-\&    }
-.Ve
-.PP
-.Vb 5
-\&    access example {
-\&        key: special
-\&        users: <SPECIAL>
-\&        newsgroups: *
-\&    }
-.Ve
-.PP
-In this case, the two key: parameters bind this auth group with this
-access group.  For any incoming connection matching \*(L"*.example.com\*(R"
-(assuming there isn't any later auth group that also matches such hosts),
-no access group that doesn't have \*(L"key: special\*(R" will even be considered.
-Similarly, the above access group will only be checked if the user was
-authenticated with an auth group containing \*(L"key: special\*(R".  This
-mechanism normally isn't useful; there is almost always a better way to
-achieve the same result.
-.PP
-Also note in the example that there's no default\-domain: parameter, which
-means that no domain is appended to the default username and the identity
-for such connections is just \*(L"<\s-1SPECIAL\s0>\*(R".  Note that some additional
-add-ons to \s-1INN\s0 may prefer that authenticated identities always return a
-full e\-mail address (including a domain), so you may want to set up your
-system that way.
-.PP
-Below is the full list of allowable parameters for auth groups and access
-groups, and after that are some examples that may make this somewhat
-clearer.
-.SH "AUTH GROUP PARAMETERS"
-.IX Header "AUTH GROUP PARAMETERS"
-An access group without at least one of the res:, auth:, perl_auth:,
-python_auth:, or default: parameters makes no sense (and in practice will
-just be ignored).
-.IP "\fBhosts:\fR" 4
-.IX Item "hosts:"
-A comma-separated list of remote hosts, wildmat patterns matching either
-hostnames or \s-1IP\s0 addresses, or \s-1IP\s0 netblocks specified in \s-1CIDR\s0 notation.  If
-a user connects from a host that doesn't match this parameter, this auth
-group will not match the connection and is ignored.
-.Sp
-Note that if you have a large number of patterns that can't be merged into
-broader patterns (such as a large number of individual systems scattered
-around the net that should have access), the hosts: parameter may exceed
-the maximum line length of 8,192 characters.  In that case, you'll need to
-break that auth group into multiple auth groups, each with a portion of
-the hosts listed in its hosts: parameter, and each assigning the same user
-identity.
-.Sp
-All hosts match if this parameter is not given.
-.IP "\fBlocaladdress:\fR" 4
-.IX Item "localaddress:"
-A comma-separated list of local host or address patterns with the same
-syntax as the same as with the hosts: parameter.  If this parameter is
-specified, its auth group will only match connections made to a matching
-local interface.  (Obviously, this is only useful for servers with
-multiple interfaces.)
-.Sp
-All local addresses match if this parameter is not given.
-.IP "\fBres:\fR" 4
-.IX Item "res:"
-A simple command line for a user resolver (shell metacharacters are not
-supported).  If a full path is not given, the program executed must be in
-the \fIpathbin\fR/auth/resolv directory.  A resolver is an authentication
-program which attempts to figure out the identity of the connecting user
-using nothing but the connection information (in other words, the user
-has not provided a username and password).  An examples of a resolver
-would be a program that assigns an identity from an ident callback or
-from the user's hostname.
-.Sp
-One auth group can have multiple res: parameters, and they will be tried
-in the order they're listed.  The results of the first successful one
-will be used.
-.IP "\fBauth:\fR" 4
-.IX Item "auth:"
-A simple command line for a user authenticator (shell metacharacters are
-not supported).  If a full path is not given, the program executed must be
-located in the \fIpathbin\fR/auth/passwd directory.  An authenticator is a
-program used to handle a user-supplied username and password, via a
-mechanism such as \s-1AUTHINFO\s0 \s-1USER/PASS\s0.  Like with res:, one auth group can
-have multiple auth: parameters; they will be tried in order and the
-results of the first successful one will be used.  See also perl_auth:
-below.
-.Sp
-The most common authenticator to use is \fIckpasswd\fR\|(8); see its man page for
-more information.
-.IP "\fBperl_auth:\fR" 4
-.IX Item "perl_auth:"
-A path to a perl script for authentication.  The perl_auth: parameter
-works exactly like auth:, except that it calls the named script using
-the perl hook rather then an external program.  Multiple/mixed use of
-the auth, perl_auth, and python_auth parameters is permitted within any
-auth group; each line is tried in the order it appears.  perl_auth:
-has more power than auth: in that it provides the authentication
-program with additional information about the client and the ability
-to return an error string and a username.  This parameter is only
-valid if \s-1INN\s0 is compiled with Perl support (\fB\-\-with\-perl\fR passed to
-configure).  More information may be found in \fIdoc/hook\-perl\fR.
-.IP "\fBpython_auth:\fR" 4
-.IX Item "python_auth:"
-A Python script for authentication.  The \fIpython_auth\fR parameter works
-exactly like \fIauth\fR, except that it calls the named script (without its
-\&\f(CW\*(C`.py\*(C'\fR extension) using the Python hook rather then an external program.
-Multiple/mixed use of the \fIauth\fR, \fIperl_auth\fR, and \fIpython_auth\fR
-parameters is permitted within any auth group; each line is tried
-in the order it appears.  \fIpython_auth\fR has more power than \fIauth\fR
-in that it provides the authentication program with additional information
-about the client and the ability to return an error string and a username.
-This parameter is only valid if \s-1INN\s0 is compiled with Python support
-(\fB\-\-with\-python\fR passed to \fBconfigure\fR).  More information may be
-found in \fIdoc/hook\-python\fR.
-.IP "\fBdefault:\fR" 4
-.IX Item "default:"
-The default username for connections matching this auth group.  This is
-the username assigned to the user at connection time if all resolvers fail
-or if there are no res: parameters.  Note that it can be either a bare
-username, in which case default\-domain: (if present) is appended after
-an \f(CW\*(C`@\*(C'\fR, or a full identity string containing an \f(CW\*(C`@\*(C'\fR, in which case it
-will be used verbatim.
-.IP "\fBdefault\-domain:\fR" 4
-.IX Item "default-domain:"
-The default domain string for this auth group.  If a user resolver or
-authenticator doesn't provide a domain, or if the default username is used
-and it doesn't contain a \f(CW\*(C`@\*(C'\fR, this domain is used to form the user
-identity.  (Note that for a lot of setups, it's not really necessary for
-user identities to be qualified with a domain name, in which case there's
-no need to use this parameter.)
-.IP "\fBkey:\fR" 4
-.IX Item "key:"
-If this parameter is present, any connection matching this auth group will
-have its privileges determined only by the subset of access groups
-containing a matching key parameter.
-.IP "\fBrequire_ssl:\fR" 4
-.IX Item "require_ssl:"
-If set to true, an incoming connection only matches this auth group if
-it is encrypted using \s-1SSL\s0.  This parameter is only valid if \s-1INN\s0 is
-compiled with \s-1SSL\s0 support (\fB\-\-with\-openssl\fR passed to configure).
-.IP "\fBperl_access:\fR" 4
-.IX Item "perl_access:"
-A path to a perl script for dynamically generating an access group.  If
-an auth group matches successfully and contains a perl_access parameter,
-then the argument perl script will be used to create an access group.
-This group will then determine the access rights of the client,
-overriding any access groups in \fIreaders.conf\fR.  If and only if a
-sucessful auth group contains the perl_access parameter, \fIreaders.conf\fR
-access groups are ignored and the client's rights are instead determined
-dynamically.  This parameter is only valid if \s-1INN\s0 is compiled with Perl
-support (\fB\-\-with\-perl\fR passed to configure).  More information may be
-found in the file \fIdoc/hook\-perl\fR.
-.IP "\fBpython_access:\fR" 4
-.IX Item "python_access:"
-A Python script for dynamically generating an access group.  If
-an auth group matches successfully and contains a \fIpython_access\fR parameter,
-then the argument script (without its \f(CW\*(C`.py\*(C'\fR extension) will be used to
-create an access group.  This group will then determine the access rights
-of the client, overriding any access groups in \fIreaders.conf\fR.  If and only
-if a successful auth group contains the \fIpython_access\fR parameter, \fIreaders.conf\fR
-access groups are ignored and the client's rights are instead determined
-dynamically.  This parameter is only valid if \s-1INN\s0 is compiled with Python
-support (\fB\-\-with\-python\fR passed to \fBconfigure\fR).  More information may be
-found in the file \fIdoc/hook\-python\fR.
-.IP "\fBpython_dynamic:\fR" 4
-.IX Item "python_dynamic:"
-A Python script for applying access control dynamically on a per newsgroup
-basis.  If an auth group matches successfully and contains a
-\&\fIpython_dynamic\fR parameter, then the argument script (without its
-\&\f(CW\*(C`.py\*(C'\fR extension) will be used to determine the clients rights each time
-the user attempts to view a newsgroup, or read or post an article.  Access
-rights as determined by \fIpython_dynamic\fR override the values of access
-group parameters such as \fInewsgroups\fR, \fIread\fR and \fIpost\fR.  This parameter
-is only valid if \s-1INN\s0 is compiled with Python support (\fB\-\-with\-python\fR
-passed to \fBconfigure\fR).  More information may be found in the file
-\&\fIdoc/hook\-python\fR.
-.SH "ACCESS GROUP PARAMETERS"
-.IX Header "ACCESS GROUP PARAMETERS"
-.IP "\fBusers:\fR" 4
-.IX Item "users:"
-The privileges given by this access group apply to any user identity which
-matches this comma-separated list of wildmat patterns.  If this parameter
-isn't given, the access group applies to all users (and is essentially
-equivalent to \f(CW\*(C`users: *\*(C'\fR).
-.IP "\fBnewsgroups:\fR" 4
-.IX Item "newsgroups:"
-Users that match this access group are allowed to read and post to all
-newsgroups matching this comma-separated list of wildmat patterns.  The
-empty string is equivalent to \f(CW\*(C`newsgroups: *\*(C'\fR; if this parameter is
-missing, the connection will be rejected (unless read: and/or post: are
-used instead, see below).
-.IP "\fBread:\fR" 4
-.IX Item "read:"
-Like the newsgroups: parameter, but the client is only given permission to
-read the matching newsgroups.  This parameter is often used with post:
-(below) to specify some read-only groups; it cannot be used in the same
-access group with a newsgroups: parameter.  (If read: is used and post:
-is missing, the client will have only read-only access.)
-.IP "\fBpost:\fR" 4
-.IX Item "post:"
-Like the newsgroups: parameter, but the client is only given permission to
-post to the matching newsgroups.  This parameter is often used with read:
-(above) to define the patterns for reading and posting separately (usually
-to give the user permission to read more newsgroups than they're permitted
-to post to).  It cannot be used in the same access group with a
-newsgroups: parameter.
-.IP "\fBaccess:\fR" 4
-.IX Item "access:"
-A set of letters specifying the permissions granted to the client.  The
-letters are chosen from the following set:
-.RS 4
-.IP "R" 3
-.IX Item "R"
-The client may read articles.
-.IP "P" 3
-.IX Item "P"
-The client may post articles.
-.IP "I" 3
-.IX Item "I"
-The client may inject articles with \s-1IHAVE\s0.  Note that in order to
-inject articles with the \s-1IHAVE\s0 the user must also have \s-1POST\s0 permission
-(the \f(CW\*(C`P\*(C'\fR option).
-.IP "A" 3
-.IX Item "A"
-The client may post articles with Approved: headers (in other words, may
-approve articles for moderated newsgroups).  By default, this is not
-allowed.
-.IP "N" 3
-.IX Item "N"
-The client may use the \s-1NEWNEWS\s0 command, overriding the global setting.
-.IP "L" 3
-.IX Item "L"
-The client may post to newsgroups that are set to disallow local posting
-(mode \f(CW\*(C`n\*(C'\fR in the \fIactive\fR\|(5) file).
-.RE
-.RS 4
-.Sp
-Note that if this parameter is given, \fIallownewnews\fR in \fIinn.conf\fR is
-ignored for connections matching this access group and the ability of the
-client to use \s-1NEWNEWS\s0 is entirely determined by the presence of \f(CW\*(C`N\*(C'\fR in
-the access string.  If you want to support \s-1NEWNEWS\s0, make sure to include
-\&\f(CW\*(C`N\*(C'\fR in the access string when you use this parameter.
-.Sp
-Note that if this parameter is given and \f(CW\*(C`R\*(C'\fR isn't present in the access
-string, the client cannot read regardless of newsgroups: or read:
-parameters.  Similarly, if this parameter is given and \f(CW\*(C`P\*(C'\fR isn't present,
-the client cannot post.  This use of access: is deprecated and confusing;
-it's strongly recommended that if the access: parameter is used, \f(CW\*(C`R\*(C'\fR and
-\&\f(CW\*(C`P\*(C'\fR always be included in the access string and newsgroups:, read:, and
-post: be used to control access.  (To grant read access but no posting
-access, one can have just a read: parameter and no post: parameter.)
-.RE
-.IP "\fBkey:\fR" 4
-.IX Item "key:"
-If this parameter is present, this access group is only considered when
-finding privileges for users matching auth groups with this same key:
-parameter.
-.IP "\fBreject_with:\fR" 4
-.IX Item "reject_with:"
-If this parameter is present, a client matching this block will be
-disconnected with a \*(L"Permission denied\*(R" message containing the contents
-(a \*(L"reason\*(R" string) of this parameter.  Some newsreaders will then
-display the reason to the user.
-.IP "\fBmax_rate:\fR" 4
-.IX Item "max_rate:"
-If this parameter is present (and nonzero), it is used for \fBnnrpd\fR's
-rate-limiting code.  The client will only be able to download at this
-speed (in bytes/second).  Note that if \s-1SSL\s0 is being used, limiting
-is applied to the pre-encryption datastream.
-.IP "\fBlocaltime:\fR" 4
-.IX Item "localtime:"
-If a Date: header is not included in a posted article, \fInnrpd\fR\|(8) normally
-adds a new Date: header in \s-1UTC\s0.  If this is set to true, the Date: header
-will be formatted in local time instead.  This is a boolean value and the
-default is false.
-.IP "\fBnewsmaster:\fR" 4
-.IX Item "newsmaster:"
-Used as the contact address in the help message returned by \fInnrpd\fR\|(8), if
-the virtualhost: parameter is set to true.
-.IP "\fBstrippath:\fR" 4
-.IX Item "strippath:"
-If set to true, any Path: header provided by a user in a post is stripped
-rather than used as the beginning of the Path: header of the article.
-This is a boolean value and the default is false.
-.IP "\fBperlfilter:\fR" 4
-.IX Item "perlfilter:"
-If set to false, posts made by these users do not pass through the Perl
-filter even if it is otherwise enabled.  This is a boolean value and the
-default is true.
-.IP "\fBpythonfilter:\fR" 4
-.IX Item "pythonfilter:"
-If set to false, posts made by these users do not pass through the Python
-filter even if it is otherwise enabled.  This is a boolean value and the
-default is true.
-.IP "\fBvirtualhost:\fR" 4
-.IX Item "virtualhost:"
-Set this parameter to true in order to make \fBnnrpd\fR behave as if it is
-running on a server with a different name than it actually is.  If you
-set this parameter to true, you must also set either pathhost: or domain:
-in the relevant access group in \fIreaders.conf\fR to something different
-than is set in \fIinn.conf\fR.  All articles displayed to clients will then have
-their Path: and Xref: headers altered to appear to be from the server
-named in pathhost: or domain: (whichever is set), and posted articles will
-use that server name in the Path:, Message\-ID:, and X\-Trace: headers.
-.Sp
-Note that setting this parameter requires the server modify all posts
-before presenting them to the client and therefore may decrease
-performance slightly.
-.PP
-In addition, all of the following parameters are valid in access groups
-and override the global setting in \fIinn.conf\fR.  See \fIinn.conf\fR\|(5) for the
-descriptions of these parameters:
-.PP
-.Vb 6
-\&    addnntppostingdate, addnntppostinghost, backoff_auth, backoff_db,
-\&    backoff_k, backoff_postfast, backoff_postslow, backoff_trigger,
-\&    checkincludedtext, clienttimeout, complaints, domain,
-\&    fromhost, localmaxartsize, moderatormailer, nnrpdauthsender,
-\&    nnrpdcheckart, nnrpdoverstats, nnrpdposthost, nnrpdpostport, organization,
-\&    pathhost, readertrack, spoolfirst, strippostcc.
-.Ve
-.SH "SUMMARY"
-.IX Header "SUMMARY"
-Here's a basic summary of what happens when a client connects:
-.IP "\(bu" 2
-All auth groups are scanned and the ones that don't match the client
-(due to hosts:, localaddress:, require_ssl:, etc) are eliminated.
-.IP "\(bu" 2
-The remaining auth groups are scanned from the last to the first, and an
-attempt is made to apply it to the current connection.  This means running
-res: programs, if any, and otherwise applying default:.  The first auth
-group (starting from the bottom) to return a valid user is kept as the
-active auth group.
-.IP "\(bu" 2
-If no auth groups yield a valid user (none have default: parameters or
-successful res: programs) but some of the auth groups have auth: lines
-(indicating a possibility that the user can authenticate and then obtain
-permissions), the connection is considered to have no valid auth group
-(which means that the access groups are ignored completely) but the
-connection isn't closed.  Instead, 480 is returned for everything until
-the user authenticates.
-.IP "\(bu" 2
-When the user authenticates, the auth groups are rescanned, and only the
-matching ones which contain at least one auth, perl_auth, or
-python_auth line are considered.  These auth groups are scanned from
-the last to the first, running auth: programs and perl_auth: or
-python_auth: scripts.  The first auth group (starting from the bottom)
-to return a valid user is kept as the active auth group.
-.IP "\(bu" 2
-Regardless of how an auth group is established, as soon as one is, that
-auth group is used to assign a user identity by taking the result of the
-successful res, auth, perl_auth, or python_auth line (or the
-default: if necessary), and appending the default-domain if
-necessary.  (If the perl_access: or python_access: parameter is
-present, see below.)
-.IP "\(bu" 2
-Finally, an access group is selected by scanning the access groups from
-bottom up and finding the first match.  (If the established auth group
-contained a perl_access: or python_access line, the dynamically
-generated access group returned by the script is used instead.)
-User permissions are granted based on the established access group.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Probably the simplest useful example of a complete \fIreaders.conf\fR,
-this gives permissions to read and post to all groups to any connections
-from the \*(L"example.com\*(R" domain, and no privileges for anyone connecting
-elsewhere:
-.PP
-.Vb 4
-\&    auth example.com {
-\&        hosts: "*.example.com, example.com"
-\&        default: <LOCAL>
-\&    }
-.Ve
-.PP
-.Vb 3
-\&    access full {
-\&        newsgroups: *
-\&    }
-.Ve
-.PP
-Note that the access realm has no users: key and therefore applies to any
-user identity.  The only available auth realm only matches hosts in the
-\&\*(L"example.com\*(R" domain, though, so any connections from other hosts will be
-rejected immediately.
-.PP
-If you have some systems that should only have read-only access to the
-server, you can modify the example above slightly by adding an additional
-auth and access group:
-.PP
-.Vb 4
-\&    auth lab {
-\&        hosts: "*.lab.example.com"
-\&        default: <LAB>
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access lab {
-\&        users: <LAB>
-\&        read: *
-\&    }
-.Ve
-.PP
-If those are put in the file after the above example, they'll take
-precedence (because they're later in the file) for any user coming from a
-machine in the lab.example.com domain, everyone will only have read
-access, not posting access.
-.PP
-Here's a similar example for a news server that accepts connections from
-anywhere but requires the user to specify a username and password.  The
-username and password are first checked against an external database of
-usernames and passwords, and then against the system shadow password file:
-.PP
-.Vb 4
-\&    auth all {
-\&        auth: "ckpasswd \-d <pathdb in inn.conf>/newsusers"
-\&        auth: "ckpasswd \-s"
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access full {
-\&        users: *
-\&        newsgroups: *
-\&    }
-.Ve
-.PP
-When the user first connects, there are no res: keys and no default, so
-they don't receive any valid identity and the connection won't match any
-access groups (even ones with \f(CW\*(C`users: *\*(C'\fR).  Such users receive nothing
-but authentication-required responses from nnrpd until they authenticate.
-.PP
-If they then later authenticate, the username and password are checked
-first by running \fBckpasswd\fR with the \fB\-d\fR option for an external dbm
-file of encrypted passwords, and then with the \fB\-s\fR option to check the
-shadow password database (note that this option may require ckpasswd to
-be setgid to a shadow group, and there are security considerations; see
-\&\fIckpasswd\fR\|(8) for details).  If both of those fail, the user will continue
-to have no identity; otherwise, an identity will be assigned (usually
-the supplied username, perhaps with a domain appended, although an
-authenticator technically can provide a completely different username
-for the identity), and the access group will match, giving full access.
-.PP
-It may be educational to consider how to combine the above examples;
-general groups always go first.  The order of the auth groups actually
-doesn't matter, since the \*(L"hosts: example.com\*(R" one only matches
-connections before username/password is sent, and the \*(L"auth: ckpasswd\*(R"
-one only matches after; order would matter if either group applied to
-both cases.  The order of the access groups in this case does matter,
-provided the newsgroups: lines differ; the access group with no users:
-line needs to be first, with the \*(L"users: <\s-1LOCAL\s0>\*(R" group after.
-.PP
-Here's a very complicated example.  This is for an organization that has
-an internal hierarchy \*(L"example.*\*(R" only available to local shell users, who
-are on machines where identd can be trusted.  Dialup users must provide a
-username and password, which is then checked against \s-1RADIUS\s0.  Remote users
-have to use a username and password that's checked against a database on
-the news server.  Finally, the admin staff (users \*(L"joe\*(R" and \*(L"jane\*(R") can
-post anywhere (including the \*(L"example.admin.*\*(R" groups that are read-only
-for everyone else), and are exempted from the Perl filter.  For an
-additional twist, posts from dialup users have their Sender: header
-replaced by their authenticated identity.
-.PP
-Since this organization has some internal moderated newsgroups, the admin
-staff can also post messages with Approved: headers, but other users
-cannot.
-.PP
-.Vb 5
-\&    auth default {
-\&        auth: "ckpasswd \-f <pathdb in inn.conf>/newsusers"
-\&        default: <FAIL>
-\&        default\-domain: example.com
-\&    }
-.Ve
-.PP
-.Vb 7
-\&    auth shell {
-\&        hosts: *.shell.example.com
-\&        res: ident
-\&        auth: "ckpasswd \-s"
-\&        default: <FAIL>
-\&        default\-domain: shell.example.com
-\&    }
-.Ve
-.PP
-.Vb 6
-\&    auth dialup {
-\&        hosts: *.dialup.example.com
-\&        auth: radius
-\&        default: <FAIL>
-\&        default\-domain: dialup.example.com
-\&    }
-.Ve
-.PP
-.Vb 5
-\&    access shell {
-\&        users: *@shell.example.com
-\&        read: *
-\&        post: "*, !example.admin.*"
-\&    }
-.Ve
-.PP
-.Vb 5
-\&    access dialup {
-\&        users: *@dialup.example.com
-\&        newsgroups: *,!example.*
-\&        nnrpdauthsender: true
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access other {
-\&        users: "*@example.com, !<FAIL>@example.com"
-\&        newsgroups: *,!example.*
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access fail {
-\&        users: "<FAIL>@*"
-\&        newsgroups: !*
-\&    }
-.Ve
-.PP
-.Vb 6
-\&    access admin {
-\&        users: "joe@*,jane@*"
-\&        newsgroups: *
-\&        access: "RPA"
-\&        perlfilter: false
-\&    }
-.Ve
-.PP
-Note the use of different domains to separate dialup from shell users
-easily.  Another way to do that would be with key: parameters, but this
-way provides slightly more intuitive identity strings.  Note also that the
-fail access group catches not only failing connections from external users
-but also failed authentication of shell and dialup users and dialup users
-before they've authenticated.  The identity string given for, say, dialup
-users before \s-1RADIUS\s0 authentication has been attempted matches both the
-dialup access group and the fail access group, since it's
-\&\*(L"<\s-1FAIL\s0>@dialup.example.com\*(R", but the fail group is last so it takes
-precedence.
-.PP
-The shell auth group has an auth: parameter so that users joe and jane
-can, if they choose, use username and password authentication to gain
-their special privileges even if they're logged on as a different user on
-the shell machines (or if ident isn't working).  When they first connect,
-they'd have the default access for that user, but they could then send
-\&\s-1AUTHINFO\s0 \s-1USER\s0 and \s-1AUTHINFO\s0 \s-1PASS\s0 (or \s-1AUTHINFO\s0 \s-1SIMPLE\s0) and get their
-extended access.
-.PP
-Also note that if the users joe and jane are using their own accounts,
-they get their special privileges regardless of how they connect, whether
-the dialups, the shell machines, or even externally with a username and
-password.
-.PP
-Finally, here's a very simple example of a configuration for a public
-server for a particular hierarchy.
-.PP
-.Vb 4
-\&    auth default {
-\&        hosts: *
-\&        default: <PUBLIC>
-\&    }
-.Ve
-.PP
-.Vb 4
-\&    access default {
-\&        users: <PUBLIC>
-\&        newsgroups: example.*
-\&    }
-.Ve
-.PP
-Notice that clients aren't allowed to read any other groups; this keeps
-them from getting access to administrative groups or reading control
-messages, just as a precaution.  When running a public server like this,
-be aware that many public hierarchies will later be pulled down and
-reinjected into the main Usenet, so it's highly recommended that you also
-run a Perl or Python filter to reject any messages crossposted out of your
-local hierarchy and any messages containing a Supersedes: header.  This
-will keep messages posted to your public hierarchy from hurting any of the
-rest of Usenet if they leak out.
-.SH "SECURITY CONSIDERATIONS"
-.IX Header "SECURITY CONSIDERATIONS"
-In general, separate passwords should be used for \s-1NNTP\s0 wherever
-possible; the \s-1NNTP\s0 protocol itself does not protect passwords from
-casual interception, and many implementations (including this one) do
-not \*(L"lock out\*(R" accounts or otherwise discourage password-guessing
-attacks.  So it is best to ensure that a compromised password has
-minimal effects.
-.PP
-Authentication using the \s-1AUTHINFO\s0 \s-1USER/PASS\s0 commands passes unencrypted
-over the network.  Extreme caution should therefore be used especially
-with system passwords (e.g. \f(CW\*(C`auth: ckpasswd \-s\*(C'\fR).  Passwords can be
-protected by using \s-1NNTP\s0 over \s-1SSL\s0 or through ssh tunnels, and this usage
-can be enforced by a well-considered server configuration that only
-permits certain auth groups to be applied in certain cases.  Here are
-some ideas:
-.IP "\(bu" 4
-To restrict connections on the standard nntp port (119) to use \s-1SSL\s0 for
-some (or all) of the auth groups to match, use the require_ssl:
-parameter.
-.IP "\(bu" 4
-If you consider your local network (but not the internet) secure, have
-some auth groups with a restrictive hosts: parameter; they would go
-above, with ones having global applicability below.
-.IP "\(bu" 4
-Consider running a \f(CW\*(C`nnrpd \-S\*(C'\fR (with \f(CW\*(C`\-D\*(C'\fR, or out of \*(L"super\-server\*(R"
-like \fBinetd\fR) on the \s-1NNTPS\s0 port (563) for clients that support \s-1SSL\s0.  See
-\&\fInnrpd\fR\|(8) for more details about how to configure that.  You
-can use the require_ssl: parameter, or \f(CW\*(C`\-c\*(C'\fR to specify an alternate
-\&\fIreaders.conf\fR if you want a substantially different configuration for
-this case.
-.IP "\(bu" 4
-If you want to restrict an auth group to only match loopback connections
-(for users running newsreaders on localhost or connecting via an ssh
-tunnel), use the localaddress: parameter.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Aidan Cully <aidan@panix.com> for InterNetNews.  Substantially
-expanded by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: readers.conf.5 7895 2008-06-22 17:54:10Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIauth_krb5\fR\|(8), \fIauth_smb\fR\|(8), \fIckpasswd\fR\|(8), \fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInewsfeeds\fR\|(5),
-\&\fInnrpd\fR\|(8), \fIuwildmat\fR\|(3).
diff --git a/doc/man/rnews.1 b/doc/man/rnews.1
deleted file mode 100644 (file)
index 941f1b3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-.\" $Revision: 5909 $
-.TH RNEWS 1
-.SH NAME
-rnews \- receive news from a UUCP connection
-.SH SYNOPSIS
-.B rnews
-[
-.BI \-h " host"
-]
-[
-.B \-N
-]
-[
-.BI \-P " port"
-]
-[
-.BI \-r " remote"
-]
-[
-.BI \-S " remote"
-]
-[
-.B \-U
-]
-[
-.B \-v
-]
-[
-.I input
-]
-.SH DESCRIPTION
-.I Rnews
-reads messages typically queued by a UUCP newsfeed and
-sends them to the InterNetNews server (either ``localhost'', or the
-value defined by the variable 
-.IR <nnrpdposthost\ in\ inn.conf> .
-.PP
-The message is read from the specified input file, or standard input
-if no input is named.
-.PP
-When sent over UUCP, Usenet articles are typically joined in a single
-batch to reduce the UUCP overhead.
-Batches can also be compressed, to reduce the communication time.
-If a message does not start with a number sign (``#'') and an exclamation
-point, then the entire input is taken as a single news article.
-If it does start with with those two characters, then the first line is
-read and interpreted as a batch command.
-.PP
-If the command is ``#! rnews nnn'' where
-.I nnn
-is a number, then the next
-.I nnn
-bytes (starting with the next line) are read as a news article.
-.PP
-If the command is ``#! cunbatch'' then the rest of input is fed to the
-.IR compress (1)
-program with the ``\-d'' flag to uncompress it, and
-the output of this pipe is read as
-.IR rnews 's
-input.
-This is for historical compatibility \(em there is no program named
-.IR cunbatch .
-A compressed batch will start with a ``#! cunbatch'' line, then contain a
-series of articles separated by ``#! rnews nnn'' lines.
-If 
-.I <DO_RNEWSPROGS in include/config.h>
-is defined and the command is any other word, then
-.I rnews
-will try to execute a program with that name in the directory
-.IR <pathbin\ in\ inn.conf>/bin/rnews.libexec .
-
-The batch will be fed into the program's standard input, and the
-standard output will be read back as input into
-.IR rnews .
-If 
-.I <DO_RNEWS_SAVE_BAD in include/config.h> 
-is defined and
-.I rnews
-detects any problems with an article such as a missing header, or
-an unintelligible reply from the server, it will save a copy of the article
-in the
-.I <pathincoming in inn.conf>/bad
-directory.
-.SH OPTIONS
-.TP
-.B \-h
-If the ``\fB\-h\fP'' flag is given, then
-.I rnews
-will log the Message-ID and host via
-.IR syslog (3)
-for each article offered to the server.
-Logging will only be done if the value is not an empty string.
-If ``\fB\-h\fP'' is not set, the environment variable
-.I <_ENV_UUCPHOST in include/paths.h>
-(typically
-.IR $UU_MACHINE )
-will be examined for a similar string.
-.TP
-.B \-N
-Normally, if unpacking the input fails it is re-spooled to
-.I <pathincoming in inn.conf>
-for another attempt later.  If the ``\fB\-N\fP'' flag is used then no such
-re-spooling is done and rnews exits with status value ``9'' to indicate
-this.
-.TP
-.B \-P
-If the ``\fB\-P\fP'' flag is used, then the articles will be sent to the
-specified port on the remote host.
-.TP
-.B \-r
-If the ``\fB\-r\fP'' flag is used, then the articles will be sent to the
-named remote host instead of the default host.
-.TP
-.B \-S
-\&``\fB\-S\fP'' flag is equivalent to ``\fB\-r\fP'' flag.
-.TP
-.B \-U
-If the server is not available, the message is spooled into a new file
-created in the
-.I <pathincoming in inn.conf>
-directory.
-The ``\fB\-U\fP'' flag may be used to send all spooled messages to the
-server once it becomes available again, and can be invoked regularly
-by
-.IR cron (8).
-.TP
-.B \-v
-If the ``\fB\-v\fP'' flag is used, it will print a notice of all errors on the
-standard error, naming the input file (if known) and printing the first
-few characters of the input.
-Errors are always logged through
-.IR syslog (3).
-.SH BUGS
-.I Rnews
-cannot process articles that have embedded ``\e0'' characters in them.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: rnews.1 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5),
-innd(8).
diff --git a/doc/man/sasl.conf.5 b/doc/man/sasl.conf.5
deleted file mode 100644 (file)
index 27ac6a3..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-.\" 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 "SASL.CONF 5"
-.TH SASL.CONF 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-sasl.conf \- SASL Configuration file for nnrpd.
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The file \fIsasl.conf\fR in \fIpathetc\fR specifies Simple Authentication
-and Security Layer (\s-1SASL\s0), defined in \s-1RFC\s0 2222, for nnrpd.
-Now nnrpd implements only Security Layer support, which is an extension
-of \s-1RFC\s0 2595. This means you can get \s-1SSL\s0 or \s-1TLS\s0 encrypted \s-1NNRP\s0 between
-your server and newsreaders. It requires OpenSSL 0.9.3 or newer from
-http://www.openssl.org/; it has been tested with versions 0.9.4 and 0.9.5.
-.SH "INSTALLATION"
-.IX Header "INSTALLATION"
-To use \s-1SSL\s0, a certificate and private key are needed that you can
-create using the openssl binary. 
-Make certain that each keys are owned by your news user, news group,
-and are mode 0640 or 0660.
-.Sh "\s-1EXAMPLE\s0"
-.IX Subsection "EXAMPLE"
-.Vb 4
-\&   openssl req \-new \-x509 \-nodes \-out /usr/local/news/lib/cert.pem\e
-\&    \-days 366 \-keyout /usr/local/news/lib/cert.pem
-\&   chown news:news /usr/local/news/lib/cert.pem
-\&   chmod 640 /usr/local/news/lib/cert.pem
-.Ve
-.PP
-You also can make the keys as the root user with \f(CW\*(C`make cert\*(C'\fR.
-.SH "CONFIGURATION"
-.IX Header "CONFIGURATION"
-Comments begin with a number  sign  (\f(CW\*(C`#\*(C'\fR)  and  continue through the 
-end of the line.  Blank lines and comments are ignored.
-All other lines specify parameters, and should be of the form
-.PP
-.Vb 1
-\&    <option>: <value>
-.Ve
-.PP
-where <option> is the name of the configuration option being set and
-<value> is the value that the configuration option is being set to.
-.PP
-Blank lines and lines beginning with (\f(CW\*(C`#\*(C'\fR) are ignored.
-For boolean options, the values  \f(CW\*(C`yes\*(C'\fR,  \f(CW\*(C`on\*(C'\fR,  \f(CW\*(C`t\*(C'\fR,
-and  \f(CW1\fR turn the option on; the values \f(CW\*(C`no\*(C'\fR, \f(CW\*(C`off\*(C'\fR,
-\&\f(CW\*(C`f\*(C'\fR, and \f(CW0\fR turn the option off.
-.IP "tls_cert_file" 4
-.IX Item "tls_cert_file"
-The path to a file containing the server's certificate.
-.IP "tls_key_file" 4
-.IX Item "tls_key_file"
-The path to a file containing the server's private key.
-.IP "tls_ca_path" 4
-.IX Item "tls_ca_path"
-The path to a directory containing the \s-1CA\s0's certificate.
-.IP "tls_ca_file" 4
-.IX Item "tls_ca_file"
-The path to a file containing the \s-1CA\s0's certificate.
-.SH "TO DO"
-.IX Header "TO DO"
-Implement methods of the authentication protocols of \s-1SASL\s0.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Kenichi \s-1OKADA\s0 <okada@opaopa.org> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinn.conf\fR\|(5), \fIinnd\fR\|(8), \fInnrpd\fR\|(8), \fIreaders.conf\fR\|(5)
diff --git a/doc/man/scanlogs.8 b/doc/man/scanlogs.8
deleted file mode 100644 (file)
index 75cc977..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-.TH SCANLOGS 8
-.SH NAME
-scanlogs \- summarize INN log files.
-.SH SYNOPSIS
-.B scanlogs
-[
-.B norotate
-]
-.SH DESCRIPTION
-.I Scanlogs
-summarizes the information recorded in the INN log files (see
-.IR newslog (5)).
-By default, it also rotates and cleans out the logs.
-It is normally invoked by the
-.IR news.daily (8)
-script.
-.SH KEYWORDS
-.PP
-The following keywords are accepted:
-.TP
-.I norotate
-Using this keyword disables the rotating and cleaning aspect of the log
-processing: the logs files are only scanned for information and no contents
-are altered.
-.PP
-If
-.I scanlogs
-is invoked more than once a day, the ``norotate'' keyword should be used
-to prevent premature log cleaning.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: scanlogs.8 309 1998-01-28 04:08:10Z scrappy $
-.SH "SEE ALSO"
-innd(8),
-newslog(5),
-news.daily(8),
-nnrpd(8).
diff --git a/doc/man/send-nntp.8 b/doc/man/send-nntp.8
deleted file mode 100644 (file)
index 2f09242..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-.TH SEND-UUCP 8
-.SH NAME
-send-nntp, send-ihave \- send Usenet articles to remote site
-.SH SYNOPSIS
-.B send-nntp
-[
-.B \-d
-]
-.B sitename:hostname | sitename
-[
-.B sitename:hostname | sitename ..
-]
-.PP
-.B send-ihave
-[
-.B \-d
-]
-.B sitename:hostname | sitename
-[
-.B sitename:hostname | sitename ..
-]
-.SH DESCRIPTION
-The send-* utilities are scripts that process the batch files written
-by
-.IR innd (8)
-to send Usenet articles to a remote NNTP site.
-.PP
-The sites to be fed may be specified by giving
-.I sitename
-.I hostname
-pairs on the command line.
-.PP
-The
-.I sitename
-is the label the site has in the
-.I newsfeeds
-file, the
-.I hostname
-is the real hostname of the remote site, a FQDN (Fully Qualified Domain Name).
-Normally, the
-.I sitename
-and the
-.I hostname
-are the same, and as such don't have to be specified as sitename:hostname
-pairs but just as a sitename.
-.PP
-.I send-nntp
-starts an innxmit to send the articles to the remote site.
-.PP
-.I send-ihave
-encapsulates the articles in an
-.I ihave
-control message and uses
-.I inews
-to send the articles to a
-.I to.sitename
-pseudo-group. Using
-.I send-ihave
-is discouraged, nobody uses it anymore and even the author of this manpage
-is unsure as to how it actually works or used to work.
-.PP
-.I send-*
-expect that the batchfile for a site is named
-.IR <pathoutgoing\ in\ inn.conf>/sitename .
-To prevent batchfile corruption,
-.IR shlock (1)
-is used to ``lock'' these files.
-.SH OPTIONS
-.TP
-.B "\-d"
-The ``\-d'' flag causes
-.I nntpsend
-to send output to stdout rather than the log file
-.IR <pathlog\ in\ inn.conf>/<program-name>.log .
-.SH NOTES
-You should probably not use send-nntp, but
-.IR innfeed ,
-or if that is not possible,
-.IR nntpsend .
-.PP
-The usual flags for a batch file for send-nntp are ``\fBTf,Wfm\fP''.
-.SH "SEE ALSO"
-newsfeeds(5),
-nntpsend(8)
diff --git a/doc/man/send-uucp.8 b/doc/man/send-uucp.8
deleted file mode 100644 (file)
index 4b64b98..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-.\" 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 "SEND-UUCP 8"
-.TH SEND-UUCP 8 "2008-04-06" "INN 2.4.4" "InterNetNews Documentation"
-.SH "NAME"
-send\-uucp \- Send Usenet articles via UUCP
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBsend-uucp\fR [\fI\s-1SITE\s0\fR ...]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The \fBsend-uucp\fR program processes batch files written by \fIinnd\fR\|(8) to send
-Usenet articles to \s-1UUCP\s0 sites.  It reads a configuration file to control how
-it behaves with various sites.  Normally, it's run periodically out of cron
-to put together batches and send them to remote \s-1UUCP\s0 sites.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-Any arguments provided to the program are interpreted as a list of sites
-specfied in \fIsend\-uucp.cf\fR for which batches should be generated.  If no
-arguments are supplied then batches will be generated for all sites listed
-in that configuration file.
-.SH "CONFIGURATION"
-.IX Header "CONFIGURATION"
-The sites to which articles are to be sent must be configured in the
-configuration file \fIsend\-uucp.cf\fR.  Each site is specified with a line of
-the form:
-.PP
-.Vb 1
-\&    site[:host[:funnel]] [compressor [maxsize [batchtime]]]
-.Ve
-.IP "\fIsite\fR" 4
-.IX Item "site"
-The news site name being configured.  This must match a site name 
-from \fInewsfeeds\fR\|(5).
-.IP "\fIhost\fR" 4
-.IX Item "host"
-The \s-1UUCP\s0 host name to which batches should be sent for this site.
-If omitted, the news site name will be used as the \s-1UUCP\s0 host name.
-.IP "\fIfunnel\fR" 4
-.IX Item "funnel"
-In the case of a site configured as a funnel, \fBsend-uucp\fR needs to flush
-the channel (or exploder) being used as the target of the funnel instead of
-flushing the site.  This is the way to tell \fBsend-uucp\fR the name of the
-channel or exploder to flush for this site.  If not specified, default to
-flushing the site.
-.IP "\fIcompressor\fR" 4
-.IX Item "compressor"
-The compression method to use for batches.  This should be one of compress,
-gzip or none.  Arguments for the compression command may be specified by
-using \f(CW\*(C`_\*(C'\fR instead of spaces. For example, \f(CW\*(C`gzip_\-9\*(C'\fR.  The default value is
-\&\f(CW\*(C`compress\*(C'\fR.
-.IP "\fImaxsize\fR" 4
-.IX Item "maxsize"
-The maximum size of a single batch before compression.  The default value is
-500,000 bytes.
-.IP "\fIbatchtime\fR" 4
-.IX Item "batchtime"
-A comma separated list of hours during which batches should be generated for
-a given site.  When \fBsend-uucp\fR runs, a site will only be processed if the
-current hour matches one of the hours in \fIbatchtime\fR.  The default is no
-limitation on when to generate batches.
-.PP
-Fields are seperated by spaces and only the site name needs to be specified,
-with defaults being used for unspecified values.  If the first character on
-a line is a \f(CW\*(C`#\*(C'\fR then the rest of the line is ignored.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-Here is an example send\-uucp.cf configuration file:
-.PP
-.Vb 8
-\&    zoetermeer      gzip            1048576         5,18,22
-\&    hoofddorp       gzip            1048576         5,18,22
-\&    pa3ebv          gzip            1048576         5,18,22
-\&    drinkel         gzip            1048576         5,6,18,20,22,0,2
-\&    manhole         compress        1048576         5,18,22
-\&    owl             compress        1048576
-\&    able
-\&    pern::MYFUNNEL!
-.Ve
-.PP
-This defines eight \s-1UUCP\s0 sites.  The first four use gzip compression and the
-last three use compress.  The first six use a batch size of 1MB, and the
-last site (able) uses the default of 500,000 bytes.  The zoetermeer,
-hoofddorp, pa3ebv, and manhole sites will only have batches generated for
-them during the hours of 05:00, 18:00, and 22:00, and the drinkel site will
-only have batches generated during those hours and 20:00, 00:00, and 02:00.
-There are no restrictions on when batches will be generated for owl or able.
-.PP
-The pern site is configured as a funnel into \f(CW\*(C`MYFUNNEL!\*(C'\fR.  \fBsend-uucp\fR will
-issue \f(CW\*(C`ctlinnd flush MYFUNNEL!\*(C'\fR instead of \f(CW\*(C`ctlinnd flush pern\*(C'\fR.
-.SH "FILES"
-.IX Header "FILES"
-.IP "\fIpathetc\fR/send\-uucp.cf" 4
-.IX Item "pathetc/send-uucp.cf"
-Configuration file specifying a list of sites to be processed.  
-.SH "NOTES"
-.IX Header "NOTES"
-The usual flags used for a \s-1UUCP\s0 feed in the \fInewsfeeds\fR file are \f(CW\*(C`Tf,Wfb\*(C'\fR.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIinnd\fR\|(8), \fInewsfeeds\fR\|(5), \fIuucp\fR\|(8)
-.SH "AUTHOR"
-.IX Header "AUTHOR"
-This program was originally written by Edvard Tuinder <ed@elm.net> and then
-maintained and extended by Miquel van Smoorenburg <miquels@cistron.nl>.
-Marco d'Itri <md@linux.it> cleaned up the code for inclusion in \s-1INN\s0.  This
-manual page was written by Mark Brown <broonie@sirena.org.uk>.
diff --git a/doc/man/sendinpaths.8 b/doc/man/sendinpaths.8
deleted file mode 100644 (file)
index 0bf9493..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-.\" 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 "SENDINPATHS 8"
-.TH SENDINPATHS 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-sendinpaths \- Send Usenet Path statistics via e\-mail
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBsendinpaths\fR [\fB\-n\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBsendinpaths\fR checks \fIpathlog\fR/path for \fBninpaths\fR dump files, finds
-dump files generated in the past 30 days, makes sure they are valid by
-running \fBninpaths\fR on each one and making sure the exit status is zero,
-and passes them to \fBninpaths\fR to generate a cumulative report.  That
-report is mailed to the e\-mail addresses configured at the beginning of
-this script (by default \*(L"pathsurvey@top1000.org\*(R" and
-\&\*(L"top1000@anthologeek.net\*(R").
-.PP
-When finished, \fBsendinpaths\fR deletes all dump files in \fIpathlog\fR/path
-that are older than 14 days (configurable at the beginning of the script).
-.PP
-For more information on how to set up \fBninpaths\fR, see \fIninpaths\fR\|(8).
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-n\fR" 4
-.IX Item "-n"
-Don't e\-mail the report; instead, just print it to standard output.  Don't
-delete old dump files.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIninpaths\fR\|(8)
-.SH "HISTORY"
-.IX Header "HISTORY"
-\&\fBsendinpaths\fR was written by Olaf Titz <olaf@bigred.inka.de>.
diff --git a/doc/man/shlock.1 b/doc/man/shlock.1
deleted file mode 100644 (file)
index 11bf250..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-.\" $Revision: 5794 $
-.TH SHLOCK 1
-.SH NAME
-shlock \- create lock files for use in shell scripts
-.SH SYNOPSIS
-.B shlock
-.BI \-p " pid"
-.BI \-f " name"
-[
-.B \-b
-]
-[
-.B \-u
-]
-[
-.B \-c
-]
-.SH DESCRIPTION
-.I Shlock
-tries to create a lock file named
-.I name
-and write the process ID
-.I pid
-into it.
-If the file already exists,
-.I shlock
-will read the process ID from the file and test to see if the process
-is currently running.
-If the process exists, then the file will not be created.
-.PP
-.I Shlock
-exits with a zero status if it was able to create the lock file, or
-non-zero if the file refers to currently-active process.
-.SH OPTIONS
-.TP
-.B \-b
-Process IDs are normally read and written in ASCII.
-If the ``\-b'' flag is used, then they will be written as a binary
-.IR int .
-For compatibility with other systems, the ``\-u'' flag is accepted as
-a synonym for ``\-b'' since binary locks are used by many UUCP packages.
-.TP
-.B \-c
-If the ``\-c'' flag is used, then
-.I shlock
-will not create a lock file, but will instead use the file to see if
-the lock is held by another program.
-If the lock is valid, the program will exit with a non-zero status; if
-the lock is not valid (i.e., invoking
-.I shlock
-without the flag would have succeeded), then the program will exit
-with a zero status.
-.SH EXAMPLES
-The following example shows how
-.I shlock
-would be used within a shell script:
-.RS
-.nf
-LOCK=<pathrun in inn.conf>/LOCK.send
-trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-if shlock -p $$ -f ${LOCK} ; then
-    # Do appropriate work
-else
-    echo Locked by `cat ${LOCK}`
-f\&i
-.fi
-.RE
-.SH BUGS
-.I shlock
-assumes that it will not be used in an environment with multiple
-locks/unlocks in a short time (due to a race condition).  That is,
-.I shlock
-is intended for daily or hourly jobs.
-.SH HISTORY
-Written by Rich $alz <rsalz@uunet.uu.net> after a description of HDB UUCP
-locking given by Peter Honeyman.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: shlock.1 5794 2002-10-01 23:31:53Z vinocur $
-.SH "SEE ALSO"
-inn.conf(5)
diff --git a/doc/man/shrinkfile.1 b/doc/man/shrinkfile.1
deleted file mode 100644 (file)
index 8ed35bd..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-.\" $Revision: 5909 $
-.TH SHRINKFILE 1
-.SH NAME
-shrinkfile \- shrink a file on a line boundary
-.SH SYNOPSIS
-.B shrinkfile
-[
-.B \-n
-]
-[
-.BI \-m " maxsize"
-]
-[
-.BI \-s " size"
-]
-[
-.B \-v
-]
-.I file...
-.SH DESCRIPTION
-The
-.I shrinkfile
-program shrinks files to a given 
-.I size
-if the size is larger than
-.IR maxsize ,
-preserving the data at the end of the file.
-Truncation is performed on line boundaries, where a line is a series
-of bytes ending with a newline, ``\en''.
-There is no line length restriction and files may contain any binary data.
-.PP
-Temporary files are created in the
-.I <pathtmp in inn.conf>
-directory.
-The ``TMPDIR'' environment variable may be used to specify a
-different directory.
-.PP
-A newline will be added to any non-empty file that does not end with a newline.
-The maximum file size will not be exceeded by this addition.
-.SH OPTIONS
-.TP
-.B \-s
-By default, 
-.I size
-is assumed to be zero and files are truncated to zero bytes.
-By default,
-.I maxsize
-is the same as 
-.IR size .
-If
-.I maxsize
-is less than
-.IR size ,
-.I maxsize
-is reset to
-.IR size .
-The ``\fB\-s\fP'' flag may be used to change the truncation size.
-Because the program truncates only on line boundaries, the final size
-may be smaller then the specified truncation size.
-The
-.I size
-and
-.I maxsize
-parameter may end with a ``k'', ``m'', or ``g'', indicating
-kilobyte (1024), megabyte (1048576) or gigabyte (1073741824) lengths.
-Uppercase letters are also allowed.
-The maximum file size is 2147483647 bytes.
-.TP
-.B \-v
-If the ``\fB\-v\fP'' flag is used, then
-.I shrinkfile
-will print a status line if a file was shrunk.
-.TP
-.B \-n
-If the ``\fB\-n\fP'' flag is used, then
-.I shrinkfile
-will exit 0 if any file is larger than
-.I maxsize
-and exit 1 otherwise.
-No files will be altered.
-.SH EXAMPLES
-.PP
-Example usage:
-.sp 1
-.RS
-.nf
-shrinkfile -s 4m curds
-shrinkfile -s 1g -v whey
-shrinkfile -s 500k -m 4m -v curds whey
-if shrinkfile -n -s 100m whey; then echo whey is way too big; fi
-.fi
-.RE
-.PP
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.SH "SEE ALSO"
-inn.conf(5)
diff --git a/doc/man/simpleftp.1 b/doc/man/simpleftp.1
deleted file mode 100644 (file)
index 90cf672..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-.\" 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 "SIMPLEFTP 1"
-.TH SIMPLEFTP 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-simpleftp \- Rudimentary FTP client
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBsimpleftp\fR \fIurl\fR [...]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBsimpleftp\fR is a Perl script that provides basic support for
-fetching files with \s-1FTP\s0 in a batch oriented fashion.  It takes one or more
-\&\s-1FTP\s0 URLs on the command line.  The file(s) will be retrieved from the
-remote server and placed in the current directory with the same basename
-as on the remote; e.g., <ftp://ftp.isc.org/pub/usenet/CONFIG/active.gz>
-is stored as \fIactive.gz\fR in the current directory.
-.PP
-The script properly understands usernames, passwords and ports specified
-as follows:
-.PP
-.Vb 1
-\&    ftp://user:password@host:port/path/file
-.Ve
-.SH "BUGS"
-.IX Header "BUGS"
-\&\fBsimpleftp\fR is an extremely poor substitute for more complete programs
-like the freely available \fBwget\fR or \fBncftp\fR utilities.  It was written
-only to provide elementary support in \s-1INN\s0 for non-interactive fetching of
-the files in <ftp://ftp.isc.org/pub/pgpcontrol/> or
-<ftp://ftp.isc.org/pub/usenet/CONFIG/> without requiring
-administrators to install yet another package.  Its shortcomings as a
-general purpose program are too numerous to mention, but one that stands
-out is that downloaded files by \fBsimpleftp\fR override existing files
-with the same name in the local directory.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Tossed off by David C Lawrence <tale@isc.org> for InterNetNews.
-Rewritten to use Net::FTP by Julien Elie <julien@trigofacile.com>.
-.PP
-$Id: simpleftp.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIactsync\fR\|(8).
diff --git a/doc/man/sm.1 b/doc/man/sm.1
deleted file mode 100644 (file)
index 88a3685..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-.\" 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 "SM 1"
-.TH SM 1 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-sm \- Command\-line interface to the INN storage manager
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBsm\fR [\fB\-dHiqRrS\fR] [\fItoken\fR ...]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The \s-1INN\s0 storage manager is the subsystesm that stores and keeps track of
-all of the articles and what storage backend they're in.  All stored
-articles are assigned a storage \s-1API\s0 token.  \fBsm\fR is a command-line
-interface to that storage manager, primarily used to retrieve articles by
-those tokens but also to perform other operations on the storage
-subsystem.
-.PP
-\&\fItoken\fR is the token of an article (the same thing that's returned by
-\&\fBgrephistory\fR or stored in the history file).  It looks something like:
-.PP
-.Vb 1
-\&    @0502000005A4000000010000000000000000@
-.Ve
-.PP
-Any number of tokens can be given on the command line.  If none are, \fBsm\fR
-reads tokens from standard input, one per line.  The default operation is
-to retrieve and write to standard output the corresponding article for
-each token given.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-d\fR, \fB\-r\fR" 4
-.IX Item "-d, -r"
-Rather than retrieving the specified article, remove the article.  This
-will delete the article out of the news spool and it will not subsequently
-be retrievable by any part of \s-1INN\s0.  It's equivalent to \f(CW\*(C`ctlinnd cancel\*(C'\fR
-except it takes a storage \s-1API\s0 token instead of a message \s-1ID\s0.
-.IP "\fB\-H\fR" 4
-.IX Item "-H"
-Retrieve only the header of the article rather than the entire article.
-This option cannot be used with \fB\-d\fR, \fB\-r\fR, \fB\-i\fR, or \fB\-S\fR.
-.IP "\fB\-i\fR" 4
-.IX Item "-i"
-Show the newsgroup name and article number associated with the token
-rather than the article itself.  Note that for crossposted articles, only
-the first newsgroup and article number to which the article is associated
-will be returned.
-.IP "\fB\-q\fR" 4
-.IX Item "-q"
-Suppress all error messages except usage errors.
-.IP "\fB\-R\fR" 4
-.IX Item "-R"
-Display the raw article.  This means that line endings won't be converted
-to native line endings and will be left as \s-1CRLF\s0 sequences, leading periods
-will still be escaped for sending over \s-1NNTP\s0, and the article will end in
-a \s-1CRLF\s0.CRLF sequence.
-.IP "\fB\-S\fR" 4
-.IX Item "-S"
-Write the article to standard output in the format used by rnews spool
-files.  Multiple articles can be written in this format, and the resulting
-output can be fed to rnews (on another system, for example) to inject
-those articles into \s-1INN\s0.  This option cannot be used with \fB\-d\fR, \fB\-r\fR,
-\&\fB\-H\fR, \fB\-i\fR, or \fB\-R\fR.
-.SH "EXIT STATUS"
-.IX Header "EXIT STATUS"
-If all operations were successful, \fBsm\fR exits with status 0.  If an
-operation on any of the provided tokens fails, \fBsm\fR will exit with status
-1, even if the operations on other tokens were successful.  In other
-words, if twenty tokens are fed to \f(CW\*(C`sm \-r\*(C'\fR on stdin, 19 articles were
-successfully removed, but the sixth article couldn't be found, \fBsm\fR will
-still exit with status 1.
-.PP
-This means that if you need to be sure whether a particular operation
-succeeded, you should run sm on one token at a time.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-Rewritten in \s-1POD\s0 by Russ Allbery <rra@stanford.edu>.
-.PP
-$Id: sm.1 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIctlinnd\fR\|(8), \fIgrephistory\fR\|(1), \fIhistory\fR\|(5), \fIrnews\fR\|(1), \fIstorage.conf\fR\|(5).
diff --git a/doc/man/startinnfeed.1 b/doc/man/startinnfeed.1
deleted file mode 100644 (file)
index 80dfefb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-.TH STARTINNFEED 8 "Nov 7, 1997"
-.SH NAME
-startinnfeed \- setuid root program to start innfeed
-.SH SYNOPSIS
-.B startinnfeed
-.RB [innfeed-options]
-.sp
-.B startinnfeed
-.RB imapfeed
-.RB [imapfeed-options]
-.SH DESCRIPTION
-.B Startinnfeed
-sets all resources (files opened, memory usage) to unlimited. It then executes
-innfeed(8) with the options specified.
-
-If the first argument to 
-.B startinnfeed
-is ``\fIimapfeed\fP'' then 
-.B imapfeed 
-will be executed (instead of innfeed(8)) with the remaining argument as
-options.
-.SH HISTORY
-Written by James Brister.
-.SH "SEE ALSO"
-.BR innfeed (8)
diff --git a/doc/man/storage.conf.5 b/doc/man/storage.conf.5
deleted file mode 100644 (file)
index fd47384..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-.\" $Revision: 6124 $
-.TH STORAGE.CONF 5
-.SH NAME
-storage.conf \- configuration file for storage manager
-.SH DESCRIPTION
-The storage manager is a
-unified interface between INN and a variety of different storage method,
-allowing the news administrator to choose between different storage methods
-with different tradeoffs (or even use several at the same time for
-different newsgroups, or articles of different sizes).  The rest of INN
-need not care what type of storage method was used for a given article;
-the storage manager will figure this out automatically when that article
-is retrieved via the storage API.
-.PP
-The
-.I <pathetc in inn.conf>/storage.conf
-file contains the rules to be used in assigning
-articles to different storage methods.
-.PP
-The file consists of a series of storage method entries.
-Blank lines and lines beginning with a number sign (``#'') are ignored.
-The maximum number of characters in each line is 255.
-The order of entries in this file is important, see below.
-.PP
-Each entry specifies a storage method and a set of rules.  Articles that
-match all of the rules of a storage method entry will be stored using that
-storage method; if an article matches multiple storage method entries,
-the first will be used.  Each entry is formatted as follows:
-.RS
-.nf
-
-method <methodname> {
-       class: <storage_class>
-       newsgroups: <wildmat>
-       size: <minsize>[,<maxsize>]
-       expires: <mintime>[,<maxtime>]
-       options: <options>
-       exactmatch: <bool>
-}
-
-.fi
-.RE
-If spaces or tabs are included in a value, that value must be quoted
-with ``"''.
-If either ``#'' or ``"'' are meant to be included verbatim in a value,
-they should be escaped with ``\\''.
-.PP
-<methodname> is the name of a storage method to use for articles that
-match the rules of this entry.  The currently available storage methods
-are 
-\&``timecaf'', ``timehash'', ``cnfs'', ``tradspool'' and ``trash''.
-See the STORAGE METHODS section below for more details.
-.PP
-The meanings of the keys in each entry are as follows:
-.TP
-.B class
-An identifier for this storage method entry.  <storage_class> should be a
-number and should be unique across all of the entries in this file.  It's
-used mainly for specifying expiration times by storage class as described in
-.IR expire.ctl (5).
-.TP
-.B newsgroups
-What newsgroups are stored using this storage method.  <wildmat> is a
-.IR uwildmat (3)
-pattern that is matched against the newsgroups an article is posted to.
-If ``storeonxref'' in inn.conf is ``true'', this pattern will be matched
-against the newsgroup names in the ``Xref'' header; otherwise, it will be
-matched against newsgroup names in the ``Newsgroups'' header (see
-.IR inn.conf (5)
-for discussion of the differences between these possibilities).  Poison
-wildmat expressions (expressions starting with ``@'') are allowed and can
-be used to exclude certain group patterns.  ``!'' cannot be used, however.
-The <wildmat> pattern is matched in order.  There is no default newsgroups
-pattern; if an entry should match all newsgroups, use an explicit
-\&``newsgroups: *''.
-.TP
-.B size
-A range of article sizes (in bytes) that should be stored using this
-storage method.
-If <maxsize> is ``0'' or not given, the upper size of articles is limited
-only by ``maxartsize'' in
-.IR inn.conf .
-The ``size'' field is optional and may be omitted entirely if you want
-articles of any size (that otherwise fulfill the requirements of this
-storage method entry) to be stored in this storage method.
-.TP
-.B expires
-A range of article expiration times that should be stored using this
-storage method.  Be careful; this is less useful than it may appear at
-first.  This is based
-.B only
-on the ``Expires'' header of the article, not on any local expiration
-policies or anything in
-.IR expire.ctl !
-If <mintime> is non-zero, then this entry 
-.B will not match
-any article without an ``Expires'' header.
-This key is therefore only really useful for assigning articles with
-requested longer expire times to a separate storage method.  Articles only
-match if the time until expiration (that is, the amount of time into the
-future that the ``Expires'' header of the article requests that it remain
-around) falls in the interval specified by <mintime> and <maxtime>.  The
-format of these parameters is 0d0h0m0s (days, hours, minutes, and
-seconds into the future).  If <maxtime> is ``0s'' or is not specified,
-there is no upper bound on expire times falling into this entry (note that
-this key has no effect on when the article will actually be expired, only
-on whether or not the article will be stored using this storage method).
-This field is also optional and may be omitted entirely if all articles
-with or without an ``Expires'' header (that otherwise fulfill the
-requirements of this storage method entry) should be stored according to
-it.
-.TP
-.B options
-This key is for passing special options to storage methods that require
-them (currently only ``cnfs'').  See the STORAGE METHODS section below for
-a description of its use.
-.TP
-.B exactmatch
-If this key is set to ``true'', all newsgroups will be examined to see if
-they match newsgroups patterns.  (Normally, any nonzero number of matching
-newsgroups is sufficient, provided no newsgroup matches a poison wildmat as
-described above.)  This is a boolan value and ``true'', ``yes''
-and ``on'' are usable to enable this key.  The case of these values is not
-significant.  The default is false.
-.PP
-If an article matches all of the constraints of an entry, it is stored via
-that storage method and is associated with that <storage_class>.  This
-file is scanned in order and the first matching entry is used to store the
-article.
-.PP
-If an article doesn't match any entry, either by being posted to a
-newsgroup that doesn't match any of the <wildmat> patterns or by being
-outside the size and expires ranges of all entries whose newsgroups
-pattern it does match, the article is not stored and is rejected by
-.IR innd (8).
-When this happens, the error message
-.RS
-.nf
-
-cant store article: no matching entry in storage.conf
-
-.fi
-.RE
-is logged to syslog.  If you want to silently drop articles matching
-certain newsgroup patterns or size or expires ranges, assign them to the
-\&``trash'' storage method rather than having them not match any storage
-method entry.
-.SH STORAGE METHODS
-Currently, there are four storage methods available.  Each method has its
-pros and cons; you can choose any mixture of them as is suitable for your
-environment.  Note that each method has an attribute ``EXPENSIVESTAT'' which
-indicates  whether checking the existence of an article is expensive or not.
-This is used to run
-.IR expireover (8).
-.TP
-.B cnfs
-The ``cnfs'' storage method stores articles in large cyclic buffers (CNFS
-stands for Cyclic News File System).  It's by far the fastest of all
-storage methods (except for ``trash''), since it eliminates the overhead
-of dealing with a file system and creating new files.  Articles are stored
-in CNFS buffers in arrival order, and when the buffer fills, it wraps
-around to the beginning and stores new articles over top of the oldest
-articles in the buffer.  The expire time of articles stored in CNFS
-buffers is therefore entirely determined by how long it takes the buffer
-to wrap around, which depends on how quickly data is being stored in it.
-(This method is therefore said to have self-expire functionality.)
-\&``EXPENSIVESTAT'' is ``false'' for this method.
-CNFS has its own configuration file,
-.IR cycbuff.conf ,
-which describes some subtlties to the basic description given above.
-Storage method entries for the ``cnfs'' storage method must have an
-\&``options'' field specifying the metacycbuff into which articles
-matching that entry should be stored; see
-.IR cycbuff.conf (5)
-for details on metacycbuffs.
-.TP
-.B timecaf
-This method stores multiple articles in one file, whose name is based on
-the article's arrival time and the storage class.  The file name will be
-.IR <patharticles\ in\ inn.conf>/timecaf-nn/bb/aacc.CF ,
-where ``nn'' is the hexadecimal value of <storage_class>, ``bb'' and
-\&``aacc'' are hexadecimal components of the arrival time, and ``CF'' is a
-hardcoded extension.  (The arrival time, in seconds since the epoch, is
-converted to hexadecimal and interpreted as 0xaabbccdd, with ``aa'',
-``bb'', and ``cc'' used to build the path.)  This method does not have
-self-expire functionality (meaning
-.IR expire (8)
-has to run periodically to delete old articles).
-\&``EXPENSIVESTAT'' is ``false'' for this method.
-.TP
-.B timehash
-This method is very similar to ``timecaf'' except that each article is
-stored in a separate file.  The name of the file for a given article will
-be
-.IR <patharticles\ in\ inn.conf>/time-nn/bb/cc/yyyy-aadd ,
-where ``nn'' is the hexadecimal value of <storage_class>, ``yyyy'' is a
-hexadecimal sequence number, and ``bb'', ``cc'', and ``aadd'' are
-components of the arrival time in hexadecimal (the arrival time is
-interpreted as documented above under ``timecaf'').  This method does not
-have self-expire functionality.
-\&``EXPENSIVESTAT'' is ``true'' for this method.
-.TP
-.B tradspool
-Traditional spool, or ``tradspool'', is the traditional news article
-storage format.  Each article is stored in a file named:
-.IR <patharticles\ in\ inn.conf>/news/group/name/nnnnn ,
-where ``news/group/name'' is the name of the newsgroup to which the
-article was posted with each period changed to a slash, and ``nnnnn'' is
-the sequence number of the article in that newsgroup.  For crossposted
-articles, the article is linked into each newsgroup to which it is
-crossposted (using either hard or symbolic links).  This is the way
-versions of INN prior to 2.0 stored all articles, as well as being the
-article storage format used by C News and earlier news systems.
-This method does not have self-expire functionality.
-\&``EXPENSIVESTAT'' is ``true'' for this method.
-.TP
-.B trash
-This method silently discards all articles stored in it.  Its only real
-uses are for testing and for silently discarding articles matching a
-particular storage method entry (for whatever reason).  Articles stored in
-this method take up no disk space and can never be retrieved, so this
-method has self-expire functionality of a sort.
-\&``EXPENSIVESTAT'' is ``false'' for this method.
-.SH EXAMPLE
-The following sample storage.conf file would store all articles posted to
-alt.binaries.* in the ``BINARIES'' CNFS metacycbuff, all articles over
-roughly 50 KB in any other hierarchy in the ``LARGE'' CNFS metacycbuff,
-all other articles in alt.* in one timehash class, and all other articles
-in any newsgroups in a second timehash class, except for the internal.*
-hierarchy which is stored in traditional spool format.
-.RS
-.nf
-
-method tradspool {
-    class: 1
-    newsgroups: internal.*
-}
-
-method cnfs {
-    class: 2
-    newsgroups: alt.binaries.*
-    options: BINARIES
-}
-
-method cnfs {
-    class: 3
-    newsgroups: *
-    size: 50000
-    options: LARGE
-}
-
-method timehash {
-    class: 4
-    newsgroups: alt.*
-}
-
-method timehash {
-    class: 5
-    newsgroups: *
-}
-
-.fi
-.RE
-Notice that the last storage method entry will catch everything.  This is
-a good habit to get into; make sure that you have at least one catch-all
-entry just in case something you didn't expect falls through the cracks.
-Notice also that the special rule for the internal.* hierarchy is first,
-so it will catch even articles crossposted to alt.binaries.* or over 50 KB
-in size.
-.SH HISTORY
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: storage.conf.5 6124 2003-01-14 06:03:29Z rra $
-.SH "SEE ALSO"
-cycbuff.conf(5),
-expire.ctl(5),
-inn.conf(5),
-innd(8),
-newsfeeds(5),
-uwildmat(3).
diff --git a/doc/man/subscriptions.5 b/doc/man/subscriptions.5
deleted file mode 100644 (file)
index c109ed7..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-.\" 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 "SUBSCRIPTIONS 5"
-.TH SUBSCRIPTIONS 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-subscriptions \- Default recommended subscriptions
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-The \fIpathetc\fR/\fIsubscriptions\fR file contains a list of newsgroups that is
-returned by the \s-1NNTP\s0 command \s-1LIST\s0 \s-1SUBSCRIPTIONS\s0.
-.PP
-Clients that support this command and send it the first time they connect
-to a new news server use the returned list to initialize the list of
-subscribed newsgroups.  The \fIsubscriptions\fR file therefore should contain
-groups intented for new users, for testing, or that contain FAQs and other
-useful information for first-time Usenet users.
-.PP
-The syntax of the \fIsubscriptions\fR file is trivial; it is a simple list of
-newsgroup names, one per line.  The order of newsgroups may be
-significant; the news reading client may present the groups in that order
-to the user.
-.SH "EXAMPLE"
-.IX Header "EXAMPLE"
-A typical \fIsubscriptions\fR file may look like:
-.PP
-.Vb 9
-\&    news.announce.newusers
-\&    news.newusers.questions
-\&    local.test
-\&    local.general
-\&    local.talk
-\&    misc.test
-\&    misc.test.moderated
-\&    news.answers
-\&    news.announce.newgroups
-.Ve
-.PP
-This gives the client the FAQs and question newsgroup for new users first,
-then a local newsgroup for testing and various commonly-read local
-discussion groups, followed by the world-wide test groups, all the FAQs,
-and announcements of new world-wide newsgroups.  If there is a local new
-users group, one might want to list it first.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Bettina Fink <laura@hydrophil.de> for InterNetNews.
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fInnrpd\fR\|(8).
diff --git a/doc/man/tally.control.8 b/doc/man/tally.control.8
deleted file mode 100644 (file)
index b10e053..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH TALLY.CONTROL 8
-.SH NAME
-tally.control \- keep track of newsgroup creations and deletions.
-.SH SYNOPSIS
-tally.control
-.SH DECSRIPTION
-tally.control is normally invoked by
-.IR scanlogs (8). 
-It
-reads its standard input, which should be the
-.I newgroup.log
-and
-.I rmgroup.log
-log files.
-It updates the cumulative list of newsgroup creations and deletions,
-.IR control.log .
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: tally.control.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-newslog(5),
-news.daily(8),
-scanlogs(8),
-tally.unwanted(8),
-writelog(8).
diff --git a/doc/man/tdx-util.8 b/doc/man/tdx-util.8
deleted file mode 100644 (file)
index b2ab95b..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-.\" 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 "TDX-UTIL 8"
-.TH TDX-UTIL 8 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-tdx\-util \- Tradindexed overview manipulation utility
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fBtdx-util\fR [\fB\-AFgio\fR] [\fB\-a\fR \fIarticle\fR] [\fB\-n\fR \fInewsgroup\fR]
-[\fB\-p\fR \fIpath\fR] [\fB\-R\fR \fIpath\fR]
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBtdx-util\fR is an administrative interface to the tradindexed overview
-method for \s-1INN\s0.  It only works on tradindexed overview databases, not on
-any other type of \s-1INN\s0 overview.  It allows the administrator to dump
-various information about the internal state of the overview, audit it for
-errors, and rebuild portions of the overview database.
-.PP
-The tradindexed overview method should lock properly and therefore it
-should be safe to run this utility and perform any operation it performs,
-including full repairs or per-group overview rebuilds, while the server is
-running.  However, note that some of the operations performed by this
-utility can take an extended period of time and will hold locks in the
-overview database during that period, which depending on what the server
-is doing may cause the server to stall until \fBtdx-util\fR completes its
-operation.
-.PP
-The dump operations are \fB\-i\fR, which dumps the master index for the
-overview database, \fB\-g\fR, which dumps the index for an individual group,
-and \fB\-o\fR, which dumps the overview information for a particular group
-(including the additional metadata stored in the index).  For \fB\-g\fR and
-\&\fB\-o\fR, the \fB\-n\fR option must also be given to specify a newsgroup to
-operate on.
-.PP
-To audit the entire overview database for problems, use \fB\-A\fR.  Any
-problems found will be reported to standard error.  There is not (yet) a
-corresponding option to correct the errors found.
-.PP
-To rebuild the database for a particular newsgroup, use \fB\-R\fR.  The \fB\-R\fR
-option takes a path to a directory which contains all of the articles for
-that newsgroup, one per file.  The names of the files must be the numbers
-of the articles in that group.  (In other words, this directory must be a
-traditional spool directory for that group.)  The \fB\-n\fR option must also
-be given to specify the newsgroup for which the overview is being rebuilt.
-.PP
-For all operations performed by \fBtdx-util\fR, a different overview database
-than the one specified in \fIinn.conf\fR may be specified using the \fB\-p\fR
-option.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\fB\-A\fR" 4
-.IX Item "-A"
-Audit the entire overview database for problems.  This runs the internal
-consistency checks built into the tradindexed overview implementation,
-checking such things as the validity and reachability of all group index
-entries, the format of the individual overview entries, the correspondance
-of index entries to overview data, and similar such things.  No changes
-will be made to the database, but problems will be reported to standard
-error.
-.IP "\fB\-a\fR \fIarticle\fR" 4
-.IX Item "-a article"
-The article number to act on.  Only useful in combination with the \fB\-o\fR
-option to dump overview information.
-.IP "\fB\-F\fR" 4
-.IX Item "-F"
-Audit the entire overview database for problems, fixing them as they're
-detected where possible. This runs the internal consistency checks built
-into the tradindexed overview implementation, checking such things as the
-validity and reachability of all group index entries, the format of the
-individual overview entries, the correspondance of index entries to
-overview data, and similar such things.  The strategy used when fixing
-problems is to throw away data that's unrecoverable, so be warned that
-using this option may result in inaccessible articles if their overview
-data has been corrupted.
-.Sp
-To see what would be changed by \fB\-F\fR, run \fBtdx-util\fR with \fB\-A\fR first.
-.IP "\fB\-g\fR" 4
-.IX Item "-g"
-Dump the master index of the overview database.  This contains similar
-information to the server active file, such as high and low water marks
-and moderation status, and is the information that nnrpd hands out to
-clients.
-.Sp
-The fields are, in order, the newsgroup name, the high water mark, the low
-water mark, the base article number (the point at which the group index
-begins), the count of articles in the group, the group status flag, the
-time (in seconds since epoch) when that newsgroup was deleted or 0 if it
-hasn't been, and the inode of the index file for that group.
-.IP "\fB\-i\fR" 4
-.IX Item "-i"
-Dump the index of a particular group.  The fields are, in order, the
-article number, the offset of the data for that article in the overview
-data file for that group, the length of the overview data, the time (in
-seconds since epoch) when the article arrived on the server, the time (in
-seconds since epoch) when the article should expire based on its Expires
-header (or 0 if there is no Expires header), and the storage \s-1API\s0 token of
-the article.
-.Sp
-If this option is given, the \fB\-n\fR option must also be given to specify
-the newsgroup on which to act.
-.IP "\fB\-n\fR \fInewsgroup\fR" 4
-.IX Item "-n newsgroup"
-Specify the newsgroup on which to act, required for the \fB\-i\fR, \fB\-o\fR, and
-\&\fB\-R\fR options.
-.IP "\fB\-o\fR" 4
-.IX Item "-o"
-Dump the overview information for a newsgroup, in the same format as it
-would be returned to clients but with one modification.  Appended to the
-end of each entry will be four additional pieces of data:  the article
-number according to the index file for that group, the storage \s-1API\s0 token
-for that article, the arrival date for that article on the server in \s-1RFC\s0
-822 date format, and the expiration date for that article (from the
-Expires header) in \s-1RFC\s0 822 date format if there is any.
-.Sp
-If this option is given, the \fB\-n\fR option must also be given to specify
-the newsgroup on which to act.  By default, all of the overview
-information for that newsgroup is dumped, but the \fB\-a\fR option may be
-given to restrict the dump to the information for a single article.
-.IP "\fB\-p\fR \fIpath\fR" 4
-.IX Item "-p path"
-Act on the overview database rooted in \fIpath\fR, overriding the overview
-path specified in \fIinn.conf\fR.
-.IP "\fB\-R\fR \fIpath\fR" 4
-.IX Item "-R path"
-Rebuild the overview for a given group from the articles stored in
-\&\fIpath\fR.  The articles must be in the form of a traditional spool
-directory; in other words, each article must be in a separate file and the
-name of the file must match the article number of the article.
-.Sp
-If this option is given, the \fB\-n\fR option must also be given to specify
-the newsgroup on which to act.
-.SH "EXAMPLES"
-.IX Header "EXAMPLES"
-Dump the master index for the overview database in \fI/news/overview\fR,
-regardless of the overview path specified in \fIinn.conf\fR:
-.PP
-.Vb 1
-\&    tdx\-util \-i \-p /news/overview
-.Ve
-.PP
-Dump the group index for example.test:
-.PP
-.Vb 1
-\&    tdx\-util \-g \-n example.test
-.Ve
-.PP
-Dump the complete overview information for example.test:
-.PP
-.Vb 1
-\&    tdx\-util \-o \-n example.test
-.Ve
-.PP
-Audit the entire overview database for any problems:
-.PP
-.Vb 1
-\&    tdx\-util \-A
-.Ve
-.PP
-Rebuild the overview information for example.test from a traditional spool
-directory:
-.PP
-.Vb 1
-\&    tdx\-util \-R /news/spool/articles/example/test \-n example.test
-.Ve
-.PP
-The last command may be useful for recovering from a bad crash or
-corrupted overview information for a particular group, if you are also
-using the tradspool article storage method.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-.PP
-$Id: tdx-util.8 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fImakehistory\fR\|(8)
diff --git a/doc/man/tst.3 b/doc/man/tst.3
deleted file mode 100644 (file)
index fd9a977..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-.\" 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 "tst 3"
-.TH tst 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-tst \- ternary search trie functions
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fB#include <inn/tst.h>\fR
-.PP
-\&\fBstruct tst;\fR
-.PP
-\&\fBstruct tst *tst_init(int \fR\fInode_line_width\fR\fB);\fR
-.PP
-\&\fBvoid tst_cleanup(struct tst *\fR\fItst\fR\fB);\fR
-.PP
-\&\fBint tst_insert(struct tst *\fR\fItst\fR\fB, const unsigned char *\fR\fIkey\fR\fB, void *\fR\fIdata\fR\fB, int \fR\fIoption\fR\fB, void **\fR\fIexist_ptr\fR\fB);\fR
-.PP
-\&\fBvoid *tst_search(struct tst *\fR\fItst\fR\fB, const unsigned char *\fR\fIkey\fR\fB);\fR
-.PP
-\&\fBvoid *tst_delete(struct tst *\fR\fItst\fR\fB, const unsigned char *\fR\fIkey\fR\fB);\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBtst_init\fR allocates memory for members of \fIstruct tst\fR, and
-allocates the first \fInode_line_width\fR nodes. A \s-1NULL\s0 pointer is
-returned by \fBtst_init\fR if any part of the memory allocation fails. On
-success, a pointer to a \fIstruct tst\fR is returned.
-.PP
-The value for \fInode_line_width\fR must be chosen very carefully. One
-node is required for every character in the tree. If you choose a
-value that is too small, your application will spend too much time
-calling \fImalloc\fR\|(3) and your node space will be too spread out. Too large
-a value is just a waste of space.
-.PP
-\&\fBtst_cleanup\fR frees all memory allocated to nodes, internal structures,
-as well as \fItst\fR itself.
-.PP
-\&\fBtst_insert\fR inserts the string \fIkey\fR into the tree. Behavior when a
-duplicate key is inserted is controlled by \fIoption\fR. If \fIkey\fR is
-already in the tree then \fB\s-1TST_DUPLICATE_KEY\s0\fR is returned, and the
-data pointer for the existing key is placed in \fIexist_ptr\fR.  If
-\&\fIoption\fR is set to \fB\s-1TST_REPLACE\s0\fR then the existing data pointer for
-the existing key is replaced by \fIdata\fR.  Note that the old data
-pointer will still be placed in \fIexist_ptr\fR.
-.PP
-If a duplicate key is encountered and \fIoption\fR is not set to
-\&\fB\s-1TST_REPLACE\s0\fR then \fB\s-1TST_DUPLICATE_KEY\s0\fR is returned. If \fIkey\fR is
-zero length then \fB\s-1TST_NULL_KEY\s0\fR is returned. A successful insert or
-replace returns \fB\s-1TST_OK\s0\fR. A return value of \fB\s-1TST_ERROR\s0\fR indicates
-that a memory allocation error occurred while trying to grow the node
-free.
-.PP
-Note that the \fIdata\fR argument must never be \fB\s-1NULL\s0\fR. If it is, then
-calls to \fBtst_search\fR will fail for a key that exists because the
-data value was set to \fB\s-1NULL\s0\fR, which is what \fBtst_search\fR returns. If
-you just want a simple existence tree, use the \fBtst\fR pointer as the
-data pointer.
-.PP
-\&\fBtst_search\fR finds the string \fIkey\fR in the tree if it exists and
-returns the data pointer associated with that key.
-.PP
-If \fIkey\fR is not found then \fB\s-1NULL\s0\fR is returned, otherwise the data pointer
-associated with \fIkey\fR is returned.
-.PP
-\&\fBtst_delete\fR deletes the string \fIkey\fR from the tree if it exists and
-returns the data pointer assocaited with that key.
-.PP
-If \fIkey\fR is not found then \fB\s-1NULL\s0\fR is returned, otherwise the data
-pointer associated with \fIkey\fR is returned.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Converted to \s-1POD\s0 from Peter A. Friend's ternary search trie
-documentation by Alex Kiernan <alex.kiernan@thus.net> for InterNetNews
-2.4.0.
-.PP
-$Id: tst.3 7880 2008-06-16 20:37:13Z iulius $
diff --git a/doc/man/uwildmat.3 b/doc/man/uwildmat.3
deleted file mode 100644 (file)
index bbdc88d..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-.\" 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 "uwildmat 3"
-.TH uwildmat 3 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
-.SH "NAME"
-uwildmat, uwildmat_simple, uwildmat_poison \- Perform wildmat matching
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-\&\fB#include <libinn.h>\fR
-.PP
-\&\fBbool uwildmat(const char *\fR\fItext\fR\fB, const char *\fR\fIpattern\fR\fB);\fR
-.PP
-\&\fBbool uwildmat_simple(const char *\fR\fItext\fR\fB, const char *\fR\fIpattern\fR\fB);\fR
-.PP
-\&\fBenum uwildmat uwildmat_poison(const char *\fR\fItext\fR\fB,
-const char *\fR\fIpattern\fR\fB);\fR
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fBuwildmat\fR compares \fItext\fR against the wildmat expression \fIpattern\fR,
-returning true if and only if the expression matches the text.  \f(CW\*(C`@\*(C'\fR has
-no special meaning in \fIpattern\fR when passed to \fBuwildmat\fR.  Both \fItext\fR
-and \fIpattern\fR are assumed to be in the \s-1UTF\-8\s0 character encoding, although
-malformed \s-1UTF\-8\s0 sequences are treated in a way that attempts to be mostly
-compatible with single-octet character sets like \s-1ISO\s0 8859\-1.  (In other
-words, if you try to match \s-1ISO\s0 8859\-1 text with these routines everything
-should work as expected unless the \s-1ISO\s0 8859\-1 text contains valid \s-1UTF\-8\s0
-sequences, which thankfully is somewhat rare.)
-.PP
-\&\fBuwildmat_simple\fR is identical to \fBuwildmat\fR except that neither \f(CW\*(C`!\*(C'\fR
-nor \f(CW\*(C`,\*(C'\fR have any special meaning and \fIpattern\fR is always treated as a
-single pattern.  This function exists solely to support legacy interfaces
-like \s-1NNTP\s0's \s-1XPAT\s0 command, and should be avoided when implementing new
-features.
-.PP
-\&\fBuwildmat_poison\fR works similarly to \fBuwildmat\fR, except that \f(CW\*(C`@\*(C'\fR as the
-first character of one of the patterns in the expression (see below)
-\&\*(L"poisons\*(R" the match if it matches.  \fBuwildmat_poison\fR returns
-\&\fB\s-1UWILDMAT_MATCH\s0\fR if the expression matches the text, \fB\s-1UWILDMAT_FAIL\s0\fR if
-it doesn't, and \fB\s-1UWILDMAT_POISON\s0\fR if the expression doesn't match because
-a poisoned pattern matched the text.  These enumeration constants are
-defined in the \fBlibinn.h\fR header.
-.SH "WILDMAT EXPRESSIONS"
-.IX Header "WILDMAT EXPRESSIONS"
-A wildmat expression follows rules similar to those of shell filename
-wildcards but with some additions and changes.  A wildmat \fIexpression\fR is
-composed of one or more wildmat \fIpatterns\fR separated by commas.  Each
-character in the wildmat pattern matches a literal occurance of that same
-character in the text, with the exception of the following metacharacters:
-.IP "?" 8
-Matches any single character (including a single \s-1UTF\-8\s0 multibyte
-character, so \f(CW\*(C`?\*(C'\fR can match more than one byte).
-.IP "*\&" 8
-Matches any sequence of zero or more characters.
-.IP "\e" 8
-.IX Item ""
-Turns off any special meaning of the following character; the following
-character will match itself in the text.  \f(CW\*(C`\e\*(C'\fR will escape any character,
-including another backslash or a comma that otherwise would separate a
-pattern from the next pattern in an expression.  Note that \f(CW\*(C`\e\*(C'\fR is not
-special inside a character range (no metacharacters are).
-.IP "[...]" 8
-A character set, which matches any single character that falls within that
-set.  The presence of a character between the brackets adds that character
-to the set; for example, \f(CW\*(C`[amv]\*(C'\fR specifies the set containing the
-characters \f(CW\*(C`a\*(C'\fR, \f(CW\*(C`m\*(C'\fR, and \f(CW\*(C`v\*(C'\fR.  A range of characters may be specified
-using \f(CW\*(C`\-\*(C'\fR; for example, \f(CW\*(C`[0\-5abc]\*(C'\fR is equivalent to \f(CW\*(C`[012345abc]\*(C'\fR.  The
-order of characters is as defined in the \s-1UTF\-8\s0 character set, and if the
-start character of such a range falls after the ending character of the
-range in that ranking the results of attempting a match with that pattern
-are undefined.
-.Sp
-In order to include a literal \f(CW\*(C`]\*(C'\fR character in the set, it must be the
-first character of the set (possibly following \f(CW\*(C`^\*(C'\fR); for example, \f(CW\*(C`[]a]\*(C'\fR
-matches either \f(CW\*(C`]\*(C'\fR or \f(CW\*(C`a\*(C'\fR.  To include a literal \f(CW\*(C`\-\*(C'\fR character in the
-set, it must be either the first or the last character of the set.
-Backslashes have no special meaning inside a character set, nor do any
-other of the wildmat metacharacters.
-.IP "[^...]" 8
-A negated character set.  Follows the same rules as a character set above,
-but matches any character \fBnot\fR contained in the set.  So, for example,
-\&\f(CW\*(C`[^]\-]\*(C'\fR matches any character except \f(CW\*(C`]\*(C'\fR and \f(CW\*(C`\-\*(C'\fR.
-.PP
-In addition, \f(CW\*(C`!\*(C'\fR (and possibly \f(CW\*(C`@\*(C'\fR) have special meaning as the first
-character of a pattern; see below.
-.PP
-When matching a wildmat expression against some text, each comma-separated
-pattern is matched in order from left to right.  In order to match, the
-pattern must match the whole text; in regular expression terminology, it's
-implicitly anchored at both the beginning and the end.  For example, the
-pattern \f(CW\*(C`a\*(C'\fR matches only the text \f(CW\*(C`a\*(C'\fR; it doesn't match \f(CW\*(C`ab\*(C'\fR or \f(CW\*(C`ba\*(C'\fR
-or even \f(CW\*(C`aa\*(C'\fR.  If none of the patterns match, the whole expression
-doesn't match.  Otherwise, whether the expression matches is determined
-entirely by the rightmost matching pattern; the expression matches the
-text if and only if the rightmost matching pattern is not negated.
-.PP
-For example, consider the text \f(CW\*(C`news.misc\*(C'\fR.  The expression \f(CW\*(C`*\*(C'\fR matches
-this text, of course, as does \f(CW\*(C`comp.*,news.*\*(C'\fR (because the second pattern
-matches).  \f(CW\*(C`news.*,!news.misc\*(C'\fR does not match this text because both
-patterns match, meaning that the rightmost takes precedence, and the
-rightmost matching pattern is negated.  \f(CW\*(C`news.*,!news.misc,*.misc\*(C'\fR does
-match this text, since the rightmost matching pattern is not negated.
-.PP
-Note that the expression \f(CW\*(C`!news.misc\*(C'\fR can't match anything.  Either the
-pattern doesn't match, in which case no patterns match and the expression
-doesn't match, or the pattern does match, in which case because it's
-negated the expression doesn't match.  \f(CW\*(C`*,!news.misc\*(C'\fR, on the other hand,
-is a useful pattern that matches anything except \f(CW\*(C`news.misc\*(C'\fR.
-.PP
-\&\f(CW\*(C`!\*(C'\fR has significance only as the first character of a pattern; anywhere
-else in the pattern, it matches a literal \f(CW\*(C`!\*(C'\fR in the text like any other
-non\-metacharacter.
-.PP
-If the \fBuwildmat_poison\fR interface is used, then \f(CW\*(C`@\*(C'\fR behaves the same as
-\&\f(CW\*(C`!\*(C'\fR except that if an expression fails to match because the rightmost
-matching pattern began with \f(CW\*(C`@\*(C'\fR, \fB\s-1UWILDMAT_POISON\s0\fR is returned instead of
-\&\fB\s-1UWILDMAT_FAIL\s0\fR.
-.PP
-If the \fBuwildmat_simple\fR interface is used, the matching rules are the
-same as above except that none of \f(CW\*(C`!\*(C'\fR, \f(CW\*(C`@\*(C'\fR, or \f(CW\*(C`,\*(C'\fR have any special
-meaning at all and only match those literal characters.
-.SH "BUGS"
-.IX Header "BUGS"
-All of these functions internally convert the passed arguments to const
-unsigned char pointers.  The only reason why they take regular char
-pointers instead of unsigned char is for the convenience of \s-1INN\s0 and other
-callers that may not be using unsigned char everywhere they should.  In a
-future revision, the public interface should be changed to just take
-unsigned char pointers.
-.SH "HISTORY"
-.IX Header "HISTORY"
-Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> in 1986, and posted to Usenet
-several times since then, most notably in comp.sources.misc in
-March, 1991.
-.PP
-Lars Mathiesen <thorinn@diku.dk> enhanced the multi-asterisk failure
-mode in early 1991.
-.PP
-Rich and Lars increased the efficiency of star patterns and reposted it to
-comp.sources.misc in April, 1991.
-.PP
-Robert Elz <kre@munnari.oz.au> added minus sign and close bracket handling
-in June, 1991.
-.PP
-Russ Allbery <rra@stanford.edu> added support for comma-separated patterns
-and the \f(CW\*(C`!\*(C'\fR and \f(CW\*(C`@\*(C'\fR metacharacters to the core wildmat routines in July,
-2000.  He also added support for \s-1UTF\-8\s0 characters, changed the default
-behavior to assume that both the text and the pattern are in \s-1UTF\-8\s0, and
-largely rewrote this documentation to expand and clarify the description
-of how a wildmat expression matches.
-.PP
-Please note that the interfaces to these functions are named \fBuwildmat\fR
-and the like rather than \fBwildmat\fR to distinguish them from the
-\&\fBwildmat\fR function provided by Rich \f(CW$alz\fR's original implementation.
-While this code is heavily based on Rich's original code, it has
-substantial differences, including the extension to support \s-1UTF\-8\s0
-characters, and has noticable functionality changes.  Any bugs present in
-it aren't Rich's fault.
-.PP
-$Id: uwildmat.3 7880 2008-06-16 20:37:13Z iulius $
-.SH "SEE ALSO"
-.IX Header "SEE ALSO"
-\&\fIgrep\fR\|(1), \fIfnmatch\fR\|(3), \fIregex\fR\|(3), \fIregexp\fR\|(3).
diff --git a/doc/man/writelog.8 b/doc/man/writelog.8
deleted file mode 100644 (file)
index 4d7f706..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-.TH WRITELOG 8
-.SH NAME
-writelog \- add a entry to an INN log file.
-.SH SYNOPSIS
-.B writelog
-.I name
-.I text...
-.SH DESCRIPTION
-.PP
-The
-.I writelog
-script is used to write a log entry or send it as mail.
-The
-.I name
-parameter specifies the name of the log file where the entry should
-be written.
-If it is the word ``mail'' then the entry is mailed to the news administrator,
-.IR <USER\ specified\ with\ \-\-with\-news\-master\ at\ configure> .
-The data that is written or sent consists of the
-.I text
-given on the command line, followed by standard input indented by
-four spaces.
-.IR Shlock (1)
-is used to avoid simultaneous updates to a single log file.
-.SH HISTORY
-Written by Landon Curt Noll <chongo@toad.com> and Rich $alz
-<rsalz@uunet.uu.net> for InterNetNews.
-.de R$
-This is revision \\$3, dated \\$4.
-..
-.R$ $Id: writelog.8 5909 2002-12-03 05:17:18Z vinocur $
-.SH "SEE ALSO"
-innd(8),
-innstat(8),
-news.daily(8),
-newslog(5),
-nnrpd(8),
-scanlogs(8).
diff --git a/doc/pod/Makefile b/doc/pod/Makefile
deleted file mode 100644 (file)
index 2294717..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-##  $Id: Makefile 7458 2005-12-12 00:25:05Z eagle $
-##
-##  This Makefile contains rules to generate the files derived from POD
-##  source.  Normal make commands at the top level of the source tree don't
-##  recurse into this directory.  These targets are only used by
-##  maintainers.
-
-include ../../Makefile.global
-
-TEXT   = ../../HACKING ../../INSTALL ../../NEWS ../../README ../hook-perl \
-       ../hook-python ../external-auth ../checklist
-
-MAN1   = ../man/convdate.1 ../man/fastrm.1 ../man/grephistory.1 \
-       ../man/inews.1 ../man/innconfval.1 ../man/innmail.1 \
-       ../man/pullnews.1 ../man/simpleftp.1 ../man/sm.1
-
-MAN3   = ../man/libauth.3 ../man/libinnhist.3 ../man/list.3 ../man/qio.3 \
-       ../man/tst.3 ../man/uwildmat.3
-
-MAN5   = ../man/active.5 ../man/active.times.5 ../man/control.ctl.5 \
-       ../man/cycbuff.conf.5 ../man/distrib.pats.5 ../man/expire.ctl.5 \
-       ../man/inn.conf.5 ../man/motd.news.5 ../man/newsfeeds.5 ../man/ovdb.5 \
-       ../man/passwd.nntp.5 ../man/radius.conf.5 ../man/readers.conf.5 \
-       ../man/sasl.conf.5 ../man/subscriptions.5
-
-MAN8   = ../man/auth_krb5.8 ../man/auth_smb.8 ../man/ckpasswd.8 \
-       ../man/domain.8 ../man/expireover.8 ../man/ident.8 ../man/innd.8 \
-       ../man/inndf.8 ../man/nnrpd.8 ../man/inndstart.8 ../man/innupgrade.8 \
-       ../man/mailpost.8 ../man/makehistory.8 ../man/ninpaths.8 \
-       ../man/ovdb_init.8 ../man/ovdb_monitor.8 ../man/ovdb_server.8 \
-       ../man/ovdb_stat.8 ../man/radius.8 ../man/rc.news.8 \
-       ../man/sendinpaths.8 ../man/tdx-util.8
-
-ALL    = $(TEXT) $(MAN1) $(MAN3) $(MAN5) $(MAN8)
-
-all: $(ALL)
-
-clean:
-       rm -f $(ALL)
-
-../../HACKING:         hacking.pod             ; $(POD2TEXT) $? > $@
-../../INSTALL:         install.pod             ; $(POD2TEXT) $? > $@
-../../NEWS:            news.pod                ; $(POD2TEXT) $? > $@
-../../README:          readme.pod              ; $(POD2TEXT) $? > $@
-../hook-perl:          hook-perl.pod           ; $(POD2TEXT) $? > $@
-../hook-python:                hook-python.pod         ; $(POD2TEXT) $? > $@
-../external-auth:      external-auth.pod       ; $(POD2TEXT) $? > $@
-../checklist:          checklist.pod           ; $(POD2TEXT) $? > $@
-
-../man/convdate.1:     convdate.pod            ; $(POD2MAN) -s 1 $? > $@
-../man/fastrm.1:       fastrm.pod              ; $(POD2MAN) -s 1 $? > $@
-../man/grephistory.1:  grephistory.pod         ; $(POD2MAN) -s 1 $? > $@
-../man/inews.1:                inews.pod               ; $(POD2MAN) -s 1 $? > $@
-../man/innconfval.1:   innconfval.pod          ; $(POD2MAN) -s 1 $? > $@
-../man/innmail.1:      innmail.pod             ; $(POD2MAN) -s 1 $? > $@
-../man/pullnews.1:     pullnews.pod            ; $(POD2MAN) -s 1 $? > $@
-../man/simpleftp.1:    simpleftp.pod           ; $(POD2MAN) -s 1 $? > $@
-../man/sm.1:           sm.pod                  ; $(POD2MAN) -s 1 $? > $@
-
-../man/libauth.3:      libauth.pod             ; $(POD2MAN) -s 3 $? > $@
-../man/libinnhist.3:   libinnhist.pod          ; $(POD2MAN) -s 3 $? > $@
-../man/list.3:         list.pod                ; $(POD2MAN) -s 3 $? > $@
-../man/qio.3:          qio.pod                 ; $(POD2MAN) -s 3 $? > $@
-../man/tst.3:          tst.pod                 ; $(POD2MAN) -s 3 $? > $@
-../man/uwildmat.3:     uwildmat.pod            ; $(POD2MAN) -s 3 $? > $@
-
-../man/active.5:       active.pod              ; $(POD2MAN) -s 5 $? > $@
-../man/active.times.5: active.times.pod        ; $(POD2MAN) -s 5 $? > $@
-../man/control.ctl.5:  control.ctl.pod         ; $(POD2MAN) -s 5 $? > $@
-../man/cycbuff.conf.5: cycbuff.conf.pod        ; $(POD2MAN) -s 5 $? > $@
-../man/distrib.pats.5: distrib.pats.pod        ; $(POD2MAN) -s 5 $? > $@
-../man/expire.ctl.5:   expire.ctl.pod          ; $(POD2MAN) -s 5 $? > $@
-../man/inn.conf.5:     inn.conf.pod            ; $(POD2MAN) -s 5 $? > $@
-../man/motd.news.5:    motd.news.pod           ; $(POD2MAN) -s 5 $? > $@
-../man/newsfeeds.5:    newsfeeds.pod           ; $(POD2MAN) -s 5 $? > $@
-../man/ovdb.5:         ovdb.pod                ; $(POD2MAN) -s 5 $? > $@
-../man/passwd.nntp.5:  passwd.nntp.pod         ; $(POD2MAN) -s 5 $? > $@
-../man/radius.conf.5:  radius.conf.pod         ; $(POD2MAN) -s 5 $? > $@
-../man/readers.conf.5: readers.conf.pod        ; $(POD2MAN) -s 5 $? > $@
-../man/sasl.conf.5:    sasl.conf.pod           ; $(POD2MAN) -s 5 $? > $@
-../man/subscriptions.5:        subscriptions.pod       ; $(POD2MAN) -s 5 $? > $@
-
-../man/auth_krb5.8:    auth_krb5.pod           ; $(POD2MAN) -s 8 $? > $@
-../man/auth_smb.8:     auth_smb.pod            ; $(POD2MAN) -s 8 $? > $@
-../man/ckpasswd.8:     ckpasswd.pod            ; $(POD2MAN) -s 8 $? > $@
-../man/domain.8:       domain.pod              ; $(POD2MAN) -s 8 $? > $@
-../man/expireover.8:   expireover.pod          ; $(POD2MAN) -s 8 $? > $@
-../man/ident.8:                ident.pod               ; $(POD2MAN) -s 8 $? > $@
-../man/innd.8:         innd.pod                ; $(POD2MAN) -s 8 $? > $@
-../man/inndf.8:                inndf.pod               ; $(POD2MAN) -s 8 $? > $@
-../man/inndstart.8:    inndstart.pod           ; $(POD2MAN) -s 8 $? > $@
-../man/innupgrade.8:   innupgrade.pod          ; $(POD2MAN) -s 8 $? > $@
-../man/mailpost.8:     mailpost.pod            ; $(POD2MAN) -s 8 $? > $@
-../man/makehistory.8:  makehistory.pod         ; $(POD2MAN) -s 8 $? > $@
-../man/ninpaths.8:     ninpaths.pod            ; $(POD2MAN) -s 8 $? > $@
-../man/nnrpd.8:                nnrpd.pod               ; $(POD2MAN) -s 8 $? > $@
-../man/ovdb_init.8:    ovdb_init.pod           ; $(POD2MAN) -s 8 $? > $@
-../man/ovdb_monitor.8: ovdb_monitor.pod        ; $(POD2MAN) -s 8 $? > $@
-../man/ovdb_server.8:  ovdb_server.pod         ; $(POD2MAN) -s 8 $? > $@
-../man/ovdb_stat.8:    ovdb_stat.pod           ; $(POD2MAN) -s 8 $? > $@
-../man/radius.8:       radius.pod              ; $(POD2MAN) -s 8 $? > $@
-../man/rc.news.8:      rc.news.pod             ; $(POD2MAN) -s 8 $? > $@
-../man/sendinpaths.8:  sendinpaths.pod         ; $(POD2MAN) -s 8 $? > $@
-../man/tdx-util.8:     tdx-util.pod            ; $(POD2MAN) -s 8 $? > $@
diff --git a/doc/pod/active.pod b/doc/pod/active.pod
deleted file mode 100644 (file)
index a37acd9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-=head1 NAME
-
-active - List of newsgroups carried by the server
-
-=head1 DESCRIPTION
-
-The file I<pathdb>/active lists the newsgroups carried by INN.  This file
-is generally maintained using ctlinnd(8) to create and remove groups, or
-by letting controlchan(8) do so on the basis of received control messages.
-This file should not be edited directly without throttling B<innd>, and
-must be reloaded using B<ctlinnd> before B<innd> is unthrottled.  Editing
-it directly even with those precautions may make it inconsistent with the
-overview database and won't update F<active.times>, so B<ctlinnd> should
-be used to make modifications whenever possible.
-
-Each newsgroup should be listed only once.  Each line specifies one group.
-The order of groups does not matter.  Within each newsgroup, received
-articles for that group are assigned monotonically increasing numbers as
-unique names.  If an article is posted to newsgroups not mentioned in this
-file, those newsgroups are ignored.
-
-If none of the newsgroups listed in the Newsgroups header of an article
-are present in this file, the article is either rejected (if I<wanttrash>
-is false in F<inn.conf>), or is filed into the newsgroup C<junk> and only
-propagated to sites that receive the C<junk> newsgroup (if I<wanttrash> is
-true).
-
-Each line of this file consists of four fields separated by a space:
-
-    <name> <high> <low> <flag>
-
-The first field is the name of the newsgroup.  The newsgroup C<junk> is
-special, as mentioned above.  The newsgroup C<control> and any newsgroups
-beginning with C<control.> are also special; control messages are filed
-into a control.* newsgroup named after the type of control message if that
-group exists, and otherwise are filed into the newsgroup C<control>
-(without regard to what newsgroups are listed in the Newsgroups header).
-If I<mergetogroups> is set to true in F<inn.conf>, newsgroups that begin
-with C<to.> are also treated specially; see innd(8).
-
-The second field is the highest article number that has been used in that
-newsgroup.  The third field is the lowest article number in the group;
-this number is not guaranteed to be accurate, and should only be taken to
-be a hint.  It is normally updated nightly as part of the expire process;
-see news.daily(8) and look for C<lowmark> or C<renumber> for more details.
-Note that because of article cancellations, there may be gaps in the
-numbering sequence.  If the lowest article number is greater then the
-highest article number, then there are no articles in the newsgroup.  In
-order to make it possible to update an entry in-place without rewriting
-the entire file, the second and third fields are padded out with leading
-zeros to make them a fixed width.
-
-The fourth field contains one of the following flags:
-
-    y         Local postings are allowed.
-    m         The group is moderated and all postings must be approved.
-    n         No local postings are allowed, only articles from peers.
-    j         Articles are filed in the junk group instead.
-    x         No local postings and ignored for articles from peers.
-    =foo.bar  Articles are filed in the group foo.bar instead.
-
-If a newsgroup has the C<j> flag, no articles will be filed in that
-newsgroup, and local postings to that group will be rejected.  If an
-article for that newsgroup is received from a remote site, and it is not
-crossposted to some other valid group, it will be filed into the C<junk>
-newsgroup instead.  This is different than simply not listing the group,
-since the article will still be accepted and can be propagated to other
-sites, and the C<junk> group can be made available to readers if wished.
-
-If the <flag> field begins with an equal sign, the newsgroup is an alias.
-Articles cannot be posted to that newsgroup, but they can be received from
-other sites.  Any articles received from peers for that newsgroup are
-treated as if they were actually posted to the group named after the equal
-sign.  Note that the Newsgroups header of the articles are not modified.
-(Alias groups are typically used during a transition and are typically
-created manually with ctlinnd(8).)  An alias should not point to another
-alias.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: active.pod 6773 2004-05-17 05:48:54Z rra $
-
-=head1 SEE ALSO
-
-active.times(5), controlchan(8), ctlinnd(8), inn.conf(5), innd(8),
-news.daily(8)
-
-=cut
diff --git a/doc/pod/active.times.pod b/doc/pod/active.times.pod
deleted file mode 100644 (file)
index 6172913..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-=head1 NAME
-
-active.times - List of local creation times of newsgroups
-
-=head1 DESCRIPTION
-
-The file I<pathdb>/active.times provides a chronological record of when
-newsgruops were created on the local server.  This file is normally
-updated by B<innd> whenever a newgroup control message is processed or a
-C<ctlinnd newgroup> command is issued, and is used by B<nnrpd> to answer
-NEWGROUPS requests.
-
-Each line consists of three fields:
-
-    <name> <time> <creator>
-
-The first field is the name of the newsgroup.  The second field is the
-time it was created, expressed as the number of seconds since the epoch.
-The third field is the e-mail addrses of the person who created the group,
-as specified in the control message or on the B<ctlinnd> command line, or
-the newsmaster specified at configure time if no creator argument was
-given to B<ctlinnd>.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-POD by Russ Allbery <rra@stanford.edu>
-
-$Id: active.times.pod 6282 2003-04-06 21:50:07Z rra $
-
-=head1 SEE ALSO
-
-active(5), ctlinnd(8), inn.conf(5), innd(8), nnrpd(8)
-
-=cut
diff --git a/doc/pod/auth_krb5.pod b/doc/pod/auth_krb5.pod
deleted file mode 100644 (file)
index adf5f0f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-=head1 NAME
-
-auth_krb5 - nnrpd Kerberos v5 authenticator
-
-=head1 SYNOPSIS
-
-B<auth_krb5> [B<-i> I<instance>]
-
-=head1 DESCRIPTION
-
-This program does authentication for B<nnrpd> against a Kerberos v5 KDC.
-This is NOT real Kerberos authentication using service tickets; instead, a
-username and password is used to attempt to obtain a Kerberos v5 TGT to
-confirm that they are valid.  As such, this authenticator assumes that
-B<nnrpd> has been given the user's username and password, and therefore is
-not as secure as real Kerberos authentication.  It generally should only
-be used with NNTP over SSL to protect the password from sniffing.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-i> I<instance>
-
-If this option is given, I<instance> will be used as the instance of the
-principal received from B<nnrpd> and authentication will be done against
-that principal instead of the base principal.  In other words, a principal
-like C<user>, when passed to B<auth_krb5> invoked with C<-i nntp>, will be
-transformed into C<user/nntp> before attempting Kerberos authentication.
-
-Since giving one's password to B<nnrpd> is not as secure as normal
-Kerberos authentication, this option supports a configuration where all
-users are given a separate instance just for news authentication with its
-own password, so their regular account password isn't exposed via NNTP.
-
-=back
-
-=head1 EXAMPLE
-
-The following readers.conf(5) fragment tells nnrpd to authenticate users
-by attempting to obtain Kerberos v5 TGTs for them, appending an instance
-of C<nntp> to usernames before doing so:
-
-    auth kerberos {
-        auth: "auth_krb5 -i nntp"
-    }
-
-    access kerberos {
-        users: "*/nntp"
-        newsgroups: example.*
-    }
-
-Access is granted to the example.* groups for all users who successfully
-authenticate.
-
-=head1 BUGS
-
-Currently, any username containing realm information (containing C<@>) is
-rejected.  This is to prevent someone from passing in a username
-corresponding to a principal in another realm that they have access to and
-gaining access to the news server via it.  However, this is also something
-that people may wish to do under some circumstances, so there should be a
-better way of handling it (such as, perhaps, a list of acceptable realms
-or a -r flag specifying the realm in which to attempt authentication).
-
-It's not clear the right thing to do when the username passed in contains
-a C</> and B<-i> was also given.  Right now, B<auth_krb5> will create a
-malformed Kerberos principal with multiple instances and attempt to
-authenticate against it, which will fail but perhaps not with the best
-error message.
-
-=head1 HISTORY
-
-Originally written by Christopher P. Lindsey.  This documentation was
-written by Russ Allbery <rra@stanford.edu> based on Christopher's original
-README file.
-
-$Id: auth_krb5.pod 5897 2002-12-03 03:41:06Z rra $
-
-=head1 SEE ALSO
-
-nnrpd(8), readers.conf(5)
-
-The latest version of Christopher's original B<nnrpkrb5auth> may be found
-on his web site at L<http://www.mallorn.com/tools/>.
-
-=cut
diff --git a/doc/pod/auth_smb.pod b/doc/pod/auth_smb.pod
deleted file mode 100644 (file)
index f3cda91..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-=head1 NAME
-
-auth_smb - nnrpd Samba authenticator
-
-=head1 SYNOPSIS
-
-B<auth_smb> B<server> [B<backup_server>] B<domain>
-
-=head1 DESCRIPTION
-
-This program does authentication for B<nnrpd> against an SMB server.  It
-passes the received username and password to B<server> for validation in
-the specified SMB B<domain>.  A backup server may optionally be
-supplied; if it is missing, only B<server> is used.
-
-If authentication is successful, the original username is returned as
-the authentication identity.  Brief errors, including incorrect password
-and failure contacting the server, are logged.
-
-=head1 EXAMPLE
-
-The following readers.conf(5) fragment grants access to users who can
-authenticate against an SMB server:
-
-    auth windows {
-        auth: "auth_smb pdc.example.com bdc.example.com USERS"
-       default-domain: "users.example.com"
-    }
-
-    access internal {
-        users: "*@users.example.com"
-        newsgroups: example.*
-    }
-
-Access is granted to the example.* groups after successful
-authentication.
-
-=head1 BUGS
-
-We should link against an external SMB library rather than maintain one
-within the INN source tree.
-
-=head1 HISTORY
-
-Originally written October 2000 by Krischan Jodies <krischan@jodies.cx>,
-based heavily on pam_smb v1.1.6 by David Airlie <airlied@samba.org>.
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-
-$Id: auth_smb.pod 5988 2002-12-12 23:02:14Z vinocur $
-
-=head1 SEE ALSO
-
-nnrpd(8), readers.conf(5)
-
-=cut
diff --git a/doc/pod/checklist.pod b/doc/pod/checklist.pod
deleted file mode 100644 (file)
index 4c8279a..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-=head1 Introduction
-
-$Id: checklist.pod 5909 2002-12-03 05:17:18Z vinocur $
-
-This is an installation checklist written by Rebecca Ore, intended to be
-the beginning of a different presentation of the information in INSTALL,
-since getting started with installing INN can be complex.  Further
-clarifications, updates, and expansion are welcome.
-
-=head1 Setup
-
-=over 4
-
-=item *
-
-Make sure there is a "news" user (and a "news" group)
-
-=item *
-
-Create a home directory for news (perhaps F</usr/local/news/>) and make
-sure it (and subdirectories) are owned by "news", group "news".
-
-You want to be careful that things in that directory stay owned by
-"news" -- but you can't just C<chown -R news.news> after the install,
-because you may have binaries that are SUID root.  You can do the build
-as any user, because C<make install> will set the permissions
-correctly.  After that point, though, you may want to C<su news> to
-avoid creating any files as root.  (For routine maintenance once INN is
-working, you can generally be root.)
-
-=item *
-
-If necessary, add F<~news/bin> to the news user's path and F<~news/man>
-to the news user's manpath in your shell config files.  (You may want to
-do this, especially the second part, on your regular account; the
-manpages are very useful.)
-
-You can do this now or later, but you will certainly want the manpages
-to help with configuring INN.
-
-For bash, try:
-
-    PATH=~news/bin:$PATH
-    export PATH
-    MANPATH=~news/man:$MANPATH
-    export MANPATH
-
-or csh:
-
-    setenv PATH ~news/bin:$PATH
-    setenv MANPATH ~news/man:$MANPATH
-
-although if you don't already have MANPATH set, the above may give an
-error or override your defaults (making it so you can only read the news
-manpages); if C<echo $MANPATH> does not give some reasonable path,
-you'll need to look up what the default is for your system (such as
-F</usr/man> or F</usr/share/man>).
-
-=back
-
-=head1 Compile
-
-=over 4
-
-=item *
-
-Download the INN tarball and unpack.
-
-=item *
-
-Work out configure options (C<./configure --help> for a list).  If you
-aren't working out of F</usr/local/news>, or want to put some files on a
-different partition, you can set the directories now (or later in
-F<inn.conf> if you change your mind).
-
-You probably want C<--with-perl>.  If you're not using NetBSD with
-cycbuffs or OpenBSD, perhaps C<--with-tagged-hash>.  You might want to
-compile in SSL and Berkeley DB, if your system supports them.
-
-    ./configure --with-perl ...
-    make
-
-    su
-    make install
-
-(If you do the last step as root, all of the ownerships and permissions
-will be correct.)
-
-=back
-
-=head1 Configure
-
-=over 4
-
-=item *
-
-Find F<INSTALL> and open a separate window for it.  A printout is
-probably a good idea -- it's long but very helpful.  Any time the
-instructions below ask you to make a decision, you can probably find
-help in INSTALL.
-
-=item *
-
-Now it's time to work on the files in F<~news/etc/>.  Start with
-F<inn.conf>; you must fill in the default moderators address, your fully
-qualified domain names and path.  Fill in all the blanks.  Change the
-file descriptor limits to something like 500.
-
-=item *
-
-If using cycbuffs (the CNFS storage method), open F<cycbuff.conf> in one
-window and a shell in another to create the cycbuff as described in
-INSTALL.  As you create them, record in cycbuff.conf the paths and
-sizes.  Save paths and sizes in a separate text file on another machine
-in case you ever blow away the wrong file.
-
-Name the metacycbuff, then configure F<storage.conf>.
-
-=item *
-
-In F<storage.conf>, be sure that all sizes of articles can be
-accomodated.  If you want to throw away large articles, do it explicitly
-by using the "trash" storage method.
-
-=item *
-
-The default options in F<expire.ctl> work fine if you have cycbuffs, if
-not, configure to suit.
-
-=item *
-
-Check over F<moderators> and F<control.ctl>.
-
-=item *
-
-Run F<~news/bin/inncheck> and fix anything noted.
-
-Inncheck gives a rough check on the appropriateness of the configuration
-files as you go.  (It's the equivalent of C<perl -cw yourfile.pl> for
-perl scripts.)
-
-Note that inncheck is very conservative about permissions; there's no
-reason most of the config files can't be world-readable if you prefer
-that.
-
-=item *
-
-Import an active file (F<~news/db/active>) and run inncheck again.
-Change where noted (there's a gotcha in the ISC's active list 000000
-000000 (whatever number of zeros) should be 0000000 00000001).
-
-=item *
-
-Create empty initial db files.  Be sure these end up owned by news.
-
-    cd ~news/db
-
-    touch newsgroups
-    touch active.times
-
-    touch history
-    ~news/bin/makedbz -i
-    mv history.n.hash  history.hash
-    mv history.n.index history.index
-    mv history.n.dir   history.dir
-
-    chmod 644 *
-
-=item *
-
-Create the cron jobs and make the changes to your system's
-F<syslog.conf> as noted in INSTALL.  Also create the cron job for
-nntpsend if you've chosen that over innfeed.
-
-Create the log files.
-
-=item *
-
-For the time being, we can see if everything initially works without
-worrying about feeds or reader access.
-
-=back
-
-=head1 Run
-
-=over 4
-
-=item *
-
-Start inn by running ~news/bin/rc.news I<as the news user>.
-
-Check F<~news/log/news.notice> to see if everything went well, also use
-C<ps> to see if innd is running.
-
-C<telnet localhost 119> and you should see either a welcome banner or a
-"no permission to talk" message.  If not, investigate.
-
-=item *
-
-C<man ctlinnd> now; you'll use C<ctlinnd reload> as you complete your
-configuration.
-
-=back
-
-=head1 Feeds
-
-All of this can be done while INN is running.
-
-=over 4
-
-=item *
-
-To get your incoming feeds working, edit F<incoming.conf>.  When done,
-C<ctlinnd reload incoming.conf reason> (where "reason" is some text that
-will show up in the logs, anything will do).
-
-=item *
-
-To get your outgoing feeds working, decide whether to use innfeed or
-nntpsend.  Edit F<newsfeeds> and either F<innfeed.conf> or
-F<nntpsend.ctl>.  
-
-In newsfeeds, if using innfeed, use the option which doens't require you
-to do a separate innfeed configuration unless you know more than I do.
-
-Then C<ctlinnd reload newsfeeds reason>.
-
-=item *
-
-In readers.conf, remember that auth and access can be separated.
-
-Begin with auth.  Your auth for password users could look like this:
-
-    auth "foreignokay" {
-        auth: "ckpasswd -d ~news/db/newsusers"
-        default: "<unauthenticated>"
-    }
-
-There is a perl script in the ckpasswd man page if you want to do
-authentications by password and have the appropriate libraries.  Copy it
-to ~news/bin, name the file something like makepasswd.pl and change the
-internal paths to whatever you're using and wherever you're putting the
-newsusers database.  The standard Apache C<htpasswd> tool also works
-just fine to create INN password files.
-
-Follow with the access stanzas.  Something for people with passwords:
-
-    access "generalpeople" {
-        users: "*"
-        newsgroups: "*,!junk,!control,!control.*"
-    }
-
-And then something like one of the following two, depending on whether
-unauthenticated users get any access:
-
-    access "restrictive" {
-        users: "<unauthenticated>"
-        newsgroups: "!*"
-    }
-
-    access "readonly" {
-        users: "<unauthenticated>"
-        read: "local.*"
-        post: "!*"
-    }
-    
-You don't need to reload anything after modifying F<readers.conf>; every
-time an nnrpd launches it reads its configuration from disk.
-
-=back
-
diff --git a/doc/pod/ckpasswd.pod b/doc/pod/ckpasswd.pod
deleted file mode 100644 (file)
index 4e5b4d5..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-=head1 NAME
-
-ckpasswd - nnrpd password authenticator
-
-=head1 SYNOPSIS
-
-B<ckpasswd> [B<-gs>] [B<-d> I<database>] [B<-f> I<filename>]
-[B<-u> I<username> B<-p> I<password>]
-
-=head1 DESCRIPTION
-
-B<ckpasswd> is the basic password authenticator for nnrpd, suitable for
-being run from an auth stanza in I<readers.conf>.  See readers.conf(5) for
-more information on how to configure an nnrpd authenticator.
-
-B<ckpasswd> accepts a username and password from nnrpd and tells nnrpd(8)
-whether that's the correct password for that username.  By default, when
-given no arguments, it tries to check the password using PAM if support
-for PAM was found when INN was built.  Failing that, it tries to check the
-password against the password field returned by getpwnam(3).  Note that
-these days most systems no longer make real passwords available via
-getpwnam(3) (some still do if and only if the program calling getpwnam(3)
-is running as root).
-
-When using PAM, B<ckpasswd> identifies itself as C<nnrpd>, not as
-C<ckpasswd>, and the PAM configuration must be set up accordingly.  The
-details of PAM configuration are different on different operating systems
-(and even different Linux distributions); see L<EXAMPLES> below for help
-getting started, and look for a pam(7) or pam.conf(4) manual page on your
-system.
-
-When using any method other than PAM, B<ckpasswd> expects all passwords to
-be stored encrypted by the system crypt(3) function and calls crypt(3) on
-the supplied password before comparing it to the expected password.  IF
-you're using a different password hash scheme (like MD5), you must use
-PAM.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d> I<database>
-
-Read passwords from a database (ndbm or dbm format depending on what your
-system has) rather than by using getpwnam(3).  B<ckpasswd> expects
-I<database>.dir and I<database>.pag to exist and to be a database keyed by
-username with the encrypted passwords as the values.
-
-While INN doesn't come with a program intended specifically to create such
-databases, on most systems it's fairly easy to write a Perl script to do
-so.  Something like:
-
-    #!/usr/bin/perl
-    use NDBM_File;
-    use Fcntl;
-    tie (%db, 'NDBM_File', '/path/to/database', O_RDWR|O_CREAT, 0640)
-        or die "Cannot open /path/to/database: $!\n";
-    $| = 1;
-    print "Username: ";
-    my $user = <STDIN>;
-    chomp $user;
-    print "Password: ";
-    my $passwd = <STDIN>;
-    chomp $passwd;
-    my @alphabet = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
-    my $salt = join '', @alphabet[rand 64, rand 64];
-    $db{$user} = crypt ($passwd, $salt);
-    untie %db;
-
-Note that this will echo back the password when typed; there are obvious
-improvements that could be made to this, but it should be a reasonable
-start.  Sometimes a program like this will be available with the name
-B<dbmpasswd>.
-
-This option will not be available on systems without dbm or ndbm
-libraries.
-
-=item B<-f> I<filename>
-
-Read passwords from the given file rather than using getpwnam(3).  The
-file is expected to be formatted like a system password file, at least
-vaguely.  That means each line should look something like:
-
-    username:pdIh9NCNslkq6
-
-(and each line may have an additional colon after the encrypted password
-and additional data; that data will be ignored by B<ckpasswd>).  Lines
-starting with a number sign (`#') are ignored.  INN does not come with a
-utility to create the encrypted passwords, but B<htpasswd> (which comes
-with Apache) can do so and it's a quick job with Perl (see the example
-script under B<-d>).  If using Apache's B<htpasswd> program, be sure to
-give it the B<-d> option so that it will use crypt(3).
-
-=item B<-g>
-
-Attempt to look up system group corresponding to username and return a
-string like "user@group" to be matched against in F<readers.conf>.  This
-option is incompatible with the B<-d> and B<-f> options.
-
-=item B<-p> I<password>
-
-Use I<password> as the password for authentication rather than reading a
-password using the nnrpd authenticator protocol.  This option is useful
-only for testing your authentication system (particularly since it
-involves putting a password on the command line), and does not work when
-B<ckpasswd> is run by B<nnrpd>.  If this option is given, B<-u> must also
-be given.
-
-=item B<-s>
-
-Check passwords against the result of getspnam(3) instead of getpwnam(3).
-This function, on those systems that supports it, reads from /etc/shadow
-or similar more restricted files.  If you want to check passwords supplied
-to nnrpd(8) against system account passwords, you will probably have to
-use this option on most systems.
-
-Most systems require special privileges to call getspnam(3), so in order
-to use this option you may need to make B<ckpasswd> setgid to some group
-(like group "shadow") or even setuid root.  B<ckpasswd> has not been
-specifically audited for such uses!  It is, however, a very small program
-that you should be able to check by hand for security.
-
-This configuration is not recommended if it can be avoided, for serious
-security reasons.  See L<readers.confZ<>(5)/SECURITY CONSIDERATIONS> for
-discussion.
-
-=item B<-u> I<username>
-
-Authenticate as I<username>.  This option is useful only for testing (so
-that you can test your authentication system easily) and does not work
-when B<ckpasswd> is run by B<nnrpd>.  If this option is given, B<-p> must
-also be given.
-
-=back
-
-=head1 EXAMPLES
-
-See readers.conf(5) for examples of nnrpd(8) authentication configuration
-that uses B<ckpasswd> to check passwords.
-
-An example PAM configuration for F</etc/pam.conf> that tells B<ckpasswd>
-to check usernames and passwords against system accounts is:
-
-    nnrpd auth    required pam_unix.so
-    nnrpd account required pam_unix.so
-
-Your system may want you to instead create a file named F<nnrpd> in
-F</etc/pam.d> with lines like:
-
-    auth    required pam_unix.so
-    account required pam_unix.so
-
-This is only the simplest configuration.  You may be able to include
-common shared files, and you may want to stack other modules, either to
-allow different authentication methods or to apply restrictions like lists
-of users who can't authenticate using B<ckpasswd>.  The best guide is the
-documentation for your system and the other PAM configurations you're
-already using.
-
-To test to make sure that B<ckpasswd> is working correctly, you can run it
-manually and then give it the username (prefixed with C<ClientAuthname:>)
-and password (prefixed with C<ClientPassword:>) on standard input.  For
-example:
-
-    (echo 'ClientAuthname: test' ; echo 'ClientPassword: testing') \
-        | ckpasswd -f /path/to/passwd/file
-
-will check a username of C<test> and a password of C<testing> against the
-username and passwords stored in F</path/to/passwd/file>.  On success,
-B<ckpasswd> will print C<User:test> and exit with status 0.  On failure,
-it will print some sort of error message and exit a non-zero status.
-
-=head1 HISTORY
-
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-
-$Id: ckpasswd.pod 7526 2006-08-12 22:31:11Z eagle $
-
-=head1 SEE ALSO
-
-readers.conf(5), nnrpd(8)
-
-Linux users who want to use PAM should read the Linux-PAM System
-Administrator's Guide at
-L<http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_SAG.html>.
-
-=cut
diff --git a/doc/pod/control.ctl.pod b/doc/pod/control.ctl.pod
deleted file mode 100644 (file)
index 87876c8..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-=head1 NAME
-
-control.ctl - Specify handling of Usenet control messages
-
-=head1 DESCRIPTION
-
-F<control.ctl> in I<pathetc> is used to determine what action is taken
-when a control message is received.  It is read by B<controlchan>, which
-is normally invoked as a channel program by B<innd>.  When F<control.ctl>
-is modified, B<controlchan> notices this automatically and reloads it.
-
-Blank lines and lines beginning with a number sign (C<#>) are ignored.
-All other lines should consist of four fields separated by colons:
-
-    <type>:<from>:<newsgroups>:<action>
-
-The first field, <type>, is the type of control message for which this
-line is valid.  It should either be the name of a control message or the
-word C<all> to indicate that it applies to all control messages.
-
-The second field, <from>, is a shell-style pattern that matches the e-mail
-address of the person posting the message (with the address first
-converted to lowercase).  The matching is done with rules equivalent to
-those of the shell's I<case> statement; see sh(1) for more details.
-
-If the control message is a newgroup or rmgroup, the third field,
-<newsgroups>, is a shell-style pattern matching the newsgroup affected by
-the control message.  If the control message is a checkgroups, the third
-field is a shell-style pattern matching the newsgroups that should be
-processed for checking.  If the control message is of any other type, the
-third field is ignored.
-
-The fourth field, <action>, specifies what action to take with control
-messages that match this line.  The following actions are understood:
-
-=over 4
-
-=item B<doit>
-
-The action requested by the control message should be performed.  For
-checkgroups messages, this means that the shell commands that should
-be run will be mailed to the news administrator (the argument to
-B<--with-news-master> given at configure time, C<usenet> by default); for
-other commands, this means that the change will be silently performed.  If
-you always want notification of actions taken, use C<doit=mail> instead (see
-below).
-
-=item B<doifarg>
-
-If the control message has an argument, this is equivalent to B<doit>.  If
-it does not have an argument, this is equivalent to B<mail>.  This is only
-useful for entries for sendsys control messages, allowing a site to
-request its own F<newsfeeds> entry by posting a C<sendsys mysite> control
-message, but not allowing the entire F<newsfeeds> file to be sent.  This
-was intended to partially counter so-called "sendsys bombs," where forged
-sendsys control messages were used to mailbomb people.
-
-Processing sendsys control messages is not recommended even with this
-work-around unless they are authenticated in some fashion.  The risk of
-having news servers turned into anonymous mail bombing services is too
-high.
-
-=item B<doit>=I<file>
-
-The action is performed as in B<doit>, and additionally a log entry is
-written to the specified log file I<file>.  If I<file> is the word
-C<mail>, the log entry is mailed to the news administrator instead.  An
-empty string is equivalent to F</dev/null> and says to log nothing.
-
-If I<file> starts with a slash, it is taken as the absolute filename to
-use for the log file.  Otherwise, the filename is formed by prepending
-I<pathlog> and a slash and appending C<.log>.  In other words, an action
-of C<doit=newgroup> will log to I<pathlog>/newgroup.log.
-
-=item B<drop>
-
-No action is taken and the message is ignored.
-
-=item B<verify-*>
-
-If the action starts with the string C<verify->, as in:
-
-    verify-news.announce.newgroups
-
-then PGP verification of the control message will be done and the user ID
-of the key of the authenticated signer will be checked against the
-expected identity defined by the rest of the string
-(C<news.announce.newgroups> in the above example.  This verification is
-done via B<pgpverify>; see pgpverify(8) for more details.
-
-If no logging is specified (with =I<file> as mentioned below), logging will
-be done the same as with B<doit> as described above.
-
-=item B<verify-*>=B<mail>
-
-PGP verification is done as for the B<verify-*> action described above, and
-notification of successful newgroup and rmgroup control messages and the
-output of checkgroups messages will be mailed to the news administrator.
-(In the case of checkgroups messages, this means that the shell script that
-should be run will be mailed to the administrator.)
-
-=item B<verify-*>=I<file>
-
-PGP verification is done as for the B<verify-*> action described above,
-and a log entry is written to the specified file as described in
-B<doit>=I<file> above.  (In the case of checkgroups messages, this means
-that the shell script output of the checkgroups message will be written to
-that file.)
-
-=item B<log>
-
-A one-line log message is sent to standard error.  B<innd> normally
-directs this to I<pathlog>/errlog.
-
-=item B<log>=I<file>
-
-A log entry is written to the specified log file, which is interpreted as
-in B<doit>=I<file> described above.
-
-=item B<mail>
-
-A mail message is sent to the news administrator without taking any other
-action.
-
-=back
-
-Processing of a checkgroups message will never actually change the
-F<active> file (the list of groups carried by the server).  The difference
-between a B<doit> or B<verify> action and a B<mail> action for a
-checkgroups control message lies only in what e-mail is sent; B<doit> or
-B<verify> will mail the news administrator a shell script to create,
-delete, or modify newsgroups to match the checkgroups message, whereas
-B<mail> will just mail the entire message.  In either case, the news
-administrator will have to take action to implement the checkgroups
-message, and if that mail is ignored, nothing will be changed.
-
-Lines are matched in order and the last matching line in the file will be
-used.
-
-Use of the B<verify> action for processing newgroup, rmgroup, and
-checkgroups messages is STRONGLY recommended.  Abuse of control messages
-is rampant, and authentication via PGP signature is currently the only
-reliable way to be sure that a control message comes from who it claims to
-be from.  Most major hierarchies are now issuing PGP-authenticated control
-messages.
-
-In order to use B<verify> actions, the PGP key ring of the news user must
-be populated with the PGP keys of the hierarchy maintainers whose control
-messages you want to honor.  For more details on PGP-authenticated control
-messages and the URL for downloading the PGP keys of major hierarchies,
-see pgpverify(8).
-
-Control messages of type cancel are handled internally by B<innd> and
-cannot be affected by any of the mechanisms described here.
-
-=head1 EXAMPLE
-
-With the following three lines in F<control.ctl>:
-
-    newgroup:*:*:drop
-    newgroup:group-admin@isc.org:comp.*:verify-news.announce.newgroups
-    newgroup:kre@munnari.oz.au:aus.*:mail
-
-a newgroup coming from C<group-admin@isc.org> will be honored if it is for
-a newsgroup in the comp.* hierarchy and if it has a valid signature
-corresponding to the PGP key with a user ID of C<news.announce.newgroups>.
-If any newgroup claiming to be from C<kre@munnari.oz.au> for a newsgroup
-in the aus.* hierarchy is received, it too will be honored.  All other
-newgroup messages will be ignored.
-
-=head1 WARNINGS
-
-The third argument for a line affecting checkgroups does B<not> affect
-whether the line matches.  It is only used after a matching line is found,
-to filter out which newsgroups listed in the checkgroups will be
-processed.  This means that a line like:
-
-    checkgroups:*:*binaries*:drop
-
-will cause B<all> checkgroups control messages to be dropped unless they
-match a line after this one in F<control.ctl>, not just ignore newsgroups
-containing C<binaries> in the name.  The general rule is to never use C<*>
-in the second field for a line matching checkgroups messages.  There is
-unfortunately no way to do what the author of a line like the above
-probably intended to do (yet).
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: control.ctl.pod 7569 2006-08-30 18:12:53Z eagle $
-
-=head1 SEE ALSO
-
-controlchan(8), inn.conf(5), innd(8), newsfeeds(5), pgpverify(8), sh(1).
-
-=cut
diff --git a/doc/pod/convdate.pod b/doc/pod/convdate.pod
deleted file mode 100644 (file)
index a025c9e..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-=head1 NAME
-
-convdate - Convert time/date strings and numbers
-
-=head1 SYNOPSIS
-
-B<convdate> [B<-dhl>] [B<-c> | B<-n> | B<-s>] [I<date> ...]
-
-=head1 DESCRIPTION
-
-B<convdate> translates the date/time strings given on the command line,
-outputting the results one to a line.  The input can either be a date in
-some format that parsedate(3) can parse or the number of seconds since
-epoch (if B<-c> is given).  The output is either ctime(3) results, the
-number of seconds since epoch, or a Usenet Date: header, depending on the
-options given.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-c>
-
-Each argument is taken to be the number of seconds since epoch (a time_t)
-rather than a date.
-
-=item B<-d>
-
-Output a valid Usenet Date: header instead of the results of ctime(3) for
-each date given on the command line.  This is useful for testing the
-algorithm used to generate Date: headers for local posts.  Normally, the
-date will be in UTC, but see the B<-l> option.
-
-=item B<-h>
-
-Print usage information and exit.
-
-=item B<-l>
-
-Only makes sense in combination with B<-d>.  If given, Date: headers
-generated will use the local time zone instead of UTC.
-
-=item B<-n>
-
-Rather than outputting the results of ctime(3) or a Date: header, output
-each date given as the number of seconds since epoch (a time_t).  This
-option doesn't make sense in combination with B<-d>.
-
-=item B<-s>
-
-Pass each given date to parsedate(3) and print the results of ctime(3) (or
-a Date: header if B<-d> is given).  This is the default behavior.
-
-=back
-
-=head1 EXAMPLES
-
-Note that relative times or times with partial information use the current
-time to fill in the rest of the date, so dates like "12pm" are taken to be
-12pm of the day when convdate is run.  This is a property of parsedate(3);
-see the man page for more information.  Most of these examples are from
-the original man page dating from 1991 and were run in the -0400 time
-zone.
-
-    % convdate 'feb 10 10am'
-    Sun Feb 10 10:00:00 1991
-
-    % convdate 12pm 5/4/90
-    Fri Dec 13 00:00:00 1991
-    Fri May  4 00:00:00 1990
-
-Note that 12pm and 5/4/90 are two *separate* arguments and therefore
-result in two results.  Note also that a date with no time is taken to be
-at midnight.
-
-    % convdate -n 'feb 10 10am' '12pm 5/4/90'
-    666198000
-    641880000
-
-    % convdate -c 666198000
-    Sun Feb 10 10:00:00 1991
-
-ctime(3) results are in the local time zone.  Compare to:
-
-    % convdate -dc 666198000
-    Sun, 10 Feb 1991 15:00:00 +0000 (UTC)
-
-    % env TZ=PST8PDT convdate -dlc 666198000
-    Sun, 10 Feb 1991 07:00:00 -0800 (PST)
-
-    % env TZ=EST5EDT convdate -dlc 666198000
-    Sun, 10 Feb 1991 10:00:00 -0500 (EST)
-
-The system library functions generally use the environment variable TZ to
-determine (or at least override) the local time zone.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net>, rewritten and updated by Russ
-Allbery <rra@stanford.edu> for the B<-d> and B<-l> flags.
-
-$Id: convdate.pod 3362 2000-06-13 02:57:51Z rra $
-
-=head1 SEE ALSO
-
-parsedate(3).
diff --git a/doc/pod/cycbuff.conf.pod b/doc/pod/cycbuff.conf.pod
deleted file mode 100644 (file)
index 837b2d2..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-=head1 NAME
-
-cycbuff.conf - Configuration file for INN CNFS storage method
-
-=head1 DESCRIPTION
-
-This file defines the cyclical buffers that make up the storage pools for
-CNFS (Cyclic News File System).  Some options controlling the behavior of
-the CNFS storage system can also be set here.  F<cycbuff.conf> is required
-if the CNFS (Cyclic News File System) storage method is used.  INN will
-look for it in I<pathetc> (as set in F<inn.conf>).
-
-For information about how to configure INN to use CNFS, see
-storage.conf(5).
-
-Blank lines and lines beginning with a hash sign (C<#>) are ignored.  All
-other lines must be of one of the following forms:
-
-    cycbuffupdate:<interval>
-    refreshinterval:<interval>
-    cycbuff:<name>:<file>:<size>
-    metacycbuff:<name>:<buffer>[,<buffer>,...][:<mode>]
-
-(where items enclosed in [] are optional).  Order is mostly not
-significant, but all I<cycbuff> lines must occur before all I<metacycbuff>
-lines.  Long lines can be continued on the next line by ending the line
-with a backslash (C<\>).
-
-=over 4
-
-=item cycbuffupdate:<interval>
-
-Sets the number of articles are written before the cycbuff header is
-written back to disk to <interval>.  Under most operating systems, the
-header doesn't have to be written to disk for the updated data to be
-available to other processes on the same system that are reading articles
-out of CNFS, but any accesses to the CNFS cycbuffs over NFS will only see
-the data present at the last write of the header.  After a system crash,
-all updates since the last write of the CNFS header may be lost.  The
-default value, if this line is omitted, is 25, meaning that the header is
-written to disk after every 25 articles stored in that cycbuff.
-
-=item refreshinterval:<interval>
-
-Sets the interval (in seconds) between re-reads of the cycbuff header to
-<interval>.  This primarily affects B<nnrpd> and controls the frequency
-with which it updates its knowledge of the current contents of the CNFS
-cycbuffs.  The default value, if this line is omitted, is 30.
-
-=item cycbuff:<name>:<file>:<size>
-
-Configures a particular CNFS cycbuff.  <name> is a symbolic name for the
-buffer, to be used later in a metacycbuff line.  It must be no longer than
-seven characters.  <file> is the full path to the buffer file or block
-device, and must be no longer than 63 characters.  <size> is the length of
-the buffer in kilobytes (1KB is 1024 bytes).  If <file> is not a block
-device, it should be <size> * 1024 bytes long.
-
-=item metacycbuff:<name>:<buffer>[,<buffer>,...][:<mode>]
-
-Specifies a collection of CNFS buffers that make up a single logical
-storage location from the perspective of INN.  Metacycbuffs are referred
-to in F<storage.conf> as storage locations for articles, so in order to
-actually put articles in a cycbuff, it has to be listed as part of some
-metacycbuff which is then referenced in F<storage.conf>.
-
-<name> is the symbolic name of the metacycbuff, referred to in the options
-field of cnfs entries in F<storage.conf>.  <buffer> is the name of a
-cycbuff (the <name> part of a cycbuff line), and any number of cycbuffs
-may be specified, separated by commas.
-
-If there is more than one cycbuff in a metacycbuff, there are two ways
-that INN can distribute articles between the cycbuffs.  The default mode,
-INTERLEAVE, stores the articles in each cycbuff in a round-robin fashion,
-one article per cycbuff in the order listed.  If the cycbuffs are of
-wildly different sizes, this can cause some of them to roll over much
-faster than others, and it may not give the best performance depending on
-your disk layout.  The other storage mode, SEQUENTIAL, instead writes to
-each cycbuff in turn until that cycbuff is full and then moves on to the
-next one, returning to the first and starting a new cycle when the last
-one is full.  To specify a mode rather than leaving it at the default, add
-a colon and the mode (INTERLEAVE or SEQUENTIAL) at the end of the
-metacycbuff line.
-
-=back
-
-B<innd> only reads F<cycbuff.conf> on startup, so if you change anything
-in this file and want B<innd> to pick up the changes, you have to stop and
-restart it.  C<ctlinnd reload all ''> is not sufficient.
-
-When articles are stored, the cycbuff into which they're stored is saved
-as part of the article token.  In order for INN to retrieve articles from
-a cycbuff, that cycbuff must be listed in F<cycbuff.conf>.  However, if
-INN should not write to a cycbuff, it doesn't need to be (and shouldn't
-be) listed in a metacycbuff.
-
-This provides an easy way to retire a cycbuff.  Just remove it from its
-metacycbuff, leaving in the cycbuff line, and restart B<innd> (with, for
-example, C<ctlinnd xexec innd>).  No new articles will be put into the
-cycbuff, but neither will any articles expire from it.  After you no
-longer need the articles in the cycbuff, just remove it entirely from
-F<cycbuff.conf>.  Then all of the articles will appear to have been
-deleted to INN, and the next nightly expire run will clean up any
-remaining references to them.
-
-Adding a new cycbuff just requires creating it (see below), adding a
-cycbuff line, adding it to a metacycbuff, and then restarting B<innd>.
-
-=head1 CREATING CYCBUFFS
-
-When creating a new cycbuff, there are two different methods for creating
-the buffers in which the articles will be stored.
-
-=over 4
-
-=item 1.
-
-Create a large file on top of a regular file system.  The easiest way to
-do this is probably with dd(1), using a command like:
-
-    dd if=/dev/zero of=/path/to/cycbuff bs=1024 count=<size>
-
-where <size> is the size from the cycbuff line in F<cycbuff.conf>.
-F<INSTALL> contains a script that will generate these commands for you
-from your F<cycbuff.conf> file.
-
-This is the simplest method, but has the disadvantage that very large
-files on regular file systems can be fairly slow to access, particularly
-at the end of the file, and INN incurs unnecessary file system overhead
-when accessing the cycbuff.
-
-=item 2.
-
-Use block devices directly.  If your operating system allows you to call
-mmap() on block devices (Solaris and recent versions of Linux do, FreeBSD
-at last report does not), this is the recommended method since you can
-avoid all of the native file system overhead.  Note, however, that each
-cycbuff cannot be larger than 2GB with this method, so if you need a lot
-of spool space, you may have to go back to disk files.
-
-Partition the disk to make each partition equal to or smaller than 2GB.
-If you're using Solaris, set up your partitions to avoid the first
-cylinder of the disk (or otherwise the cycbuff header will overwrite the
-disk partition table and render the cycbuffs inaccessible).  Then, create
-device files for each block device you're going to use.
-
-It's not recommended to use the block device files in F</dev>, since the
-news system doesn't have permission to write to them and changing the
-permissions of the system device files may affect something else.
-Instead, use mknod(1) to create a new set of block devices (in somewhere
-like I<pathspool>/cycbuffs that's only writable by the news user).  To do
-this, run C<ls -Ll> on the devices in F</dev> that correspond to the block
-devices that you want to use.  The major and minor device numbers are in
-the fifth and sixth columns (right before the date), respectively.  Then
-run mknod like:
-
-    mknod <file> b <major> <minor>
-
-where <file> is the path to the device to create (matching the <file> part
-of the cycbuff line) and <major> and <minor> are the major and minor
-device numbers as discovered above.
-
-Here's a short script to do this when given the path to the system device
-file as an argument:
-
-    #!/bin/sh
-    base=`echo "$1" | sed 's%.*/%%'`
-    major=`ls -Ll "$1" | awk '{print $5}' | tr -d ,`
-    minor=`ls -Ll "$1" | awk '{print $6}`
-    mkdir -p /usr/local/news/spool/cycbuffs
-    mknod /usr/local/news/spool/cycbuffs/"$base" b "$major" "$minor"
-    chown news:news /usr/local/news/spool/cycbuffs/"$base"
-    chmod 644 /usr/local/news/spool/cycbuffs/"$base"
-
-Make sure that the created files are owned by the news user and news
-group, as specified at configure time (the default being C<news> for
-both).  Also make sure that the permissions on the devices allow the news
-user to read and write, and if you want other users on the system to be
-able to use B<sm> to retrieve articles, make sure they're world-readable.
-
-=back
-
-Once you have everything configured properly and you start B<innd>, you
-should see messages in F<news.notice> that look like:
-
-    innd: CNFS-sm No magic cookie found for cycbuff ONE, initializing
-
-where ONE will be whatever you called your cycbuff.
-
-=head1 HISTORY
-
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-Rewritten into POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: cycbuff.conf.pod 7860 2008-06-07 12:46:49Z iulius $
-
-=head1 SEE ALSO
-
-ctlinnd(8), innd(8), nnrpd(8), sm(1), storage.conf(5)
-
-=cut
diff --git a/doc/pod/distrib.pats.pod b/doc/pod/distrib.pats.pod
deleted file mode 100644 (file)
index 5071d8c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-=head1 NAME
-
-distrib.pats - Default values for the Distribution header
-
-=head1 DESCRIPTION
-
-The file I<pathetc>/distrib.pats is used by B<nnrpd> to determine the
-default value of the Distribution header.  Blank lines and lines beginning
-with a number sign (C<#>) are ignored.  All other lines consist of three
-fields separated by a colon:
-
-    <weight>:<pattern>:<value>
-
-The first field is the weight to assign to this match.  If a newsgroup
-matches multiple lines, the line with the highest weight is used.  This
-should be an arbitrary integer greater than zero.  The order of lines in
-the file is only important if groups have equal weight (in which case, the
-first matching line will be used).
-
-The second field is either the name of a newsgroup or a uwildmat(3)-style
-pattern to specify a set of newsgroups.
-
-The third field is the value that should be used for the Distribution
-header of a posted article, if this line was picked as the best match and
-no Distribution header was supplied by the user.  It can be an empty
-string, specifying that no Distribution header should be added.
-
-When a post is received by B<nnrpd> that does not already contain a
-Distribution header, each newsgroup to which an article is posted will be
-checked against this file in turn, and the matching line with the highest
-weight will be used as the value of the Distribution header.  If no lines
-match, or if the matching line has an empty string for its third field, no
-header will be added.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: distrib.pats.pod 6282 2003-04-06 21:50:07Z rra $
-
-=head1 SEE ALSO
-
-inn.conf(5), nnrpd(8), uwildmat(3)
-
-=cut
diff --git a/doc/pod/domain.pod b/doc/pod/domain.pod
deleted file mode 100644 (file)
index c98ccef..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-=head1 NAME
-
-domain - nnrpd domain resolver
-
-=head1 SYNOPSIS
-
-B<domain> B<domainname>
-
-=head1 DESCRIPTION
-
-This program can be used in F<readers.conf> to grant access based on the
-subdomain part of the remote hostname.  In particular, it only returns
-success if the remote hostname ends in B<domainname>.  (A leading dot on
-B<domainname> is optional; even without it, the argument must match on
-dot-separated boundaries).  The "username" returned is whatever initial
-part of the remote hostname remains after B<domainname> is removed.  It
-is an error if there is no initial part (that is, if the remote hostname
-is I<exactly> the specified B<domainname>).
-
-=head1 EXAMPLE
-
-The following readers.conf(5) fragment grants access to hosts with
-internal domain names:
-
-    auth internal {
-        res: "domain .internal"
-       default-domain: "example.com"
-    }
-
-    access internal {
-        users: "*@example.com"
-        newsgroups: example.*
-    }
-
-Access is granted to the example.* groups for all connections from hosts
-that resolve to hostnames ending in C<.internal>; a connection from
-"foo.internal" would match access groups as "foo@example.com".
-
-=head1 BUGS
-
-It seems the code does not confirm that the matching part is actually at
-the end of the remote hostname (e.g., "domain: example.com" would match
-the remote host "foo.example.com.org" by ignoring the trailing ".org"
-part).
-
-Does this resolver actually provide any useful functionality not
-available by using wildcards in the readers.conf(5) I<hosts> parameter?
-If so, the example above should reflect this functionality.
-
-=head1 HISTORY
-
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-
-$Id: domain.pod 5988 2002-12-12 23:02:14Z vinocur $
-
-=head1 SEE ALSO
-
-nnrpd(8), readers.conf(5)
-
-=cut
diff --git a/doc/pod/expire.ctl.pod b/doc/pod/expire.ctl.pod
deleted file mode 100644 (file)
index bc89c95..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-=head1 NAME
-
-expire.ctl - Configuration file for article expiration
-
-=head1 DESCRIPTION
-
-The file I<pathetc>/expire.ctl is the default configuration file for
-B<expire> and B<expireover>, which read it at start-up.  It serves two
-purposes:  it defines how long history entries for expired or rejected
-articles are remembered, and it determines how long articles stored on the
-server are retained.
-
-Normally, if all of the storage methods used by the server are
-self-expiring (such as CNFS), all lines except the C</remember/> setting
-(described below) are ignored.  This can be changed with the B<-N> option
-to B<expire> or B<expireover>.
-
-Black lines and lines beginning with a number sign (C<#>) are ignored.
-All other lines should be in one of two formats.  The order of the file is
-significant, and the last matching entry will be used.
-
-The first format specifies how long to keep history entries for articles
-that aren't present in the news spool.  These are articles that have
-either already expired, or articles which the server rejected (when
-I<remembertrash> is set to true in F<inn.conf>).  There should be one and
-only one line in this format, which looks like:
-
-    /remember/:<days>
-
-where <days> is a decimal number that specifies the minimum number of days
-a history record for a given message ID is retained, regardless of whether
-the article is present in the spool.  (History entries for articles still
-present in the spool are always retained.)
-
-The primary reason to retain a record of old articles is in case a peer
-offers old articles that were previously accepted but have already
-expired.  Without a history record for such articles, the server would
-accept the article again and readers would see duplicate articles.
-Articles older than a certain number of days won't be accepted by the
-server at all (see I<artcutoff> in inn.conf(5) and the B<-c> flag in
-innd(8)), and this setting should probably match that time period (10 days
-by default) to ensure that the server never accepts duplicates.
-
-Most of the lines in this file will be in the second format, which
-consists of either four or five colon-separated fields:
-
-    <pattern>:<flag>:<min>:<default>:<max>
-
-if I<groupbaseexpiry> is true in F<inn.conf> (the default), and otherwise:
-
-    <classnum>:<min>:<default>:<max>
-
-All lines must be in the correct format given the current setting of
-I<groupbaseexpiry>, and therefore the two formats cannot co-exist in the
-same file.
-
-Normally, a rule matches a newsgroup through the combination of the
-<pattern> and <flag> fields.  <pattern> is a uwildmat(3)-style pattern,
-specifying the newsgroups to which the line is applied.  Note that the
-last matching entry will be used, so general patterns (such as defaults
-for all groups where <pattern> is C<*>) should appear at the beginning of
-the file before more specific settings.
-
-The <flag> field can be used to further limit newsgroups to which the line
-applies, and should be chosen from the following set:
-
-    M   Only moderated groups
-    U   Only unmoderated groups
-    A   All groups
-    X   Remove the article from all groups it appears in
-
-One of M, U, or A must be specified.  X should be used in combination with
-one of the other letters, not by itself.
-
-An expiration policy is applied to every article in a newsgroup it
-matches.  There is no way to set an expiration policy for articles
-crossposted to groups you don't carry that's different than other articles
-in the same group.  Normally, articles are not completely deleted until
-they expire out of every group to which they were posted, but if an
-article is expired following a rule where <flag> contains X, it is deleted
-out of all newsgroups to which it was posted immediately.
-
-If I<groupbaseexpiry> is instead set to false, there is no <pattern> and
-<flag> field and the above does not apply.  Instead, there is a single
-<classnum> field, which is either a number matching the storage class
-number specified in F<storage.conf> or C<*> to specify a default for all
-storage classes.  All articles stored in a storage class will be expired
-following the instructions in the line with a matching <classnum>, and
-when articles are expired, they're always removed from all groups to which
-they were posted.
-
-The remaining three fields are the same in either format, and are used to
-determine how long an article should be kept.  Each field should be either
-a decimal number of days (fractions like C<8.5> are allowed, but remember
-that articles are only removed when B<expire> or B<expireover> is run,
-normally once a day by B<news.daily>) or the word C<never>.
-
-The middle field, <default>, will be used as the expiration period for
-most articles.  The other two fields, <min> and <max>, only come into
-play if the article requests a particular expiration date with an Expires
-header.  Articles with an Expires header will be expired at the date given
-in that header, subject to the constraints that they will be retained at
-least <min> days and no longer than <max> days.
-
-If <min> is set to C<never>, no article matching that line will ever be
-expired.  If <default> is set to C<never>, no article matching that line
-without an explicit Expires header will ever be expired.  If <max> is
-set to C<never>, Expires headers will be honored no matter how far into
-the future they are.
-
-One should think of the fields as a lower bound, the default, and an upper
-bound.  Since most articles do not have an Expires header, the second
-field is the most important and most commonly applied.
-
-Articles that do not match any expiration rule will not be expired, but
-this is considered an error and will result in a warning.  There should
-always be a default line (a line with a <pattern> of C<*> and <flag> of
-C<A>, or a line with a <classnum> of C<*>), which can explicitly state
-that articles should never expire by default if that's the desired
-configuration.  The default line should generally be the first line of the
-file (except for C</remember/>) so that other expiration rules can
-override it.
-
-It is often useful to honor the Expires header in articles, especially
-those in moderated groups.  To do this, set <min> to zero, <default> to
-whatever normal expiration you wish, and <max> to C<never> or some large
-number, like 365 days for a maximum article life of a year.
-
-To ignore any Expires header, set all three fields to the same value.
-
-=head1 EXAMPLES
-
-When I<groupbaseexpiry> is true (the default):
-
-    # Keep expired article history for 10 days, matching artcutoff.
-    /remember/:10
-
-    # Most articles stay for two weeks, ignoring Expires.
-    *:A:14:14:14
-
-    # Accept Expires headers in moderated groups for up to a year and
-    # retain moderated groups for a bit longer.
-    *:M:1:30:365
-
-    # Keep local groups for a long time and local project groups forever.
-    example.*:A:90:90:90
-    example.project.*:A:never:never:never
-
-When I<groupbaseexpiry> is false, for class-based expiration:
-
-    # Keep expired article history for 10 days, matching artcutoff.
-    /remember/:10
-
-    # Set a default expiration of seven days.
-    *:7:7:7
-
-    # Class 0 is retained for two weeks.
-    0:14:14:14
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Converted to
-POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: expire.ctl.pod 7207 2005-04-11 18:18:40Z rra $
-
-=head1 SEE ALSO
-
-expire(8), expireover(8), inn.conf(5), innd(8), news.daily(8),
-storage.conf(5), uwildmat(3)
-
-=cut
diff --git a/doc/pod/expireover.pod b/doc/pod/expireover.pod
deleted file mode 100644 (file)
index 69c27ae..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-=head1 NAME
-
-expireover - Expire entries from the news overview database
-
-=head1 SYNOPSIS
-
-B<expireover> [B<-ekNpqs>] [B<-f> I<file>] [B<-w> I<offset>]
-[B<-z> I<rmfile>] [B<-Z> I<lowmarkfile>]
-
-=head1 DESCRIPTION
-
-B<expireover> expires old entries from the news overview database.  It
-reads in a list of newsgroups (by default from I<pathdb>/active, but a
-different file can be specified with the B<-f> option) and then removes
-from the overview database mentions of any articles that no longer exist
-in the news spool.
-
-If I<groupbaseexpiry> in I<inn.conf> is true, B<expireover> also removes
-old articles from the news spool according to the expiration rules in
-F<expire.ctl>.  Otherwise it only removes overview entries for articles
-that have already been removed by some other process, and B<-e>, B<-k>,
-B<-N>, B<-p>, B<-q>, B<-w>, and B<-z> are all ignored.
-
-When I<groupbaseexpiry> is set, the default behavior of B<expireover> is
-to remove the article from the spool once it expires out of all of the
-newsgroups to which it was crossposted.  The article is, however, removed
-from the overview database of each newsgroup as soon as it expires out of
-that individual newsgroup.  The effect is that an article crossposted to
-several groups will be removed from the overview database from each group
-one-by-one as its age passes the expiration threshold for that group as
-set in F<expire.ctl>, and then when it expires out of the last newsgroup,
-it will be deleted from the news spool.
-
-Articles that are stored in self-expiring storage backends such as CNFS
-are normally treated differently and not expired until they expire out of
-the backend regardless of F<expire.ctl>.  See B<-N>, however.
-
-By default, B<expireover> purges all overview information for newsgroups
-that have been removed from the server; this behavior is suppressed if
-B<-f> is given.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-e>
-
-Remove articles from the news spool and all overview databases as soon as
-they expire out of any newsgroup to which they are posted, rather than
-retain them until they expire out of all newsgroups.  B<-e> and B<-k>
-cannot be used at the same time.  This flag is ignored if
-I<groupbaseexpiry> is false.
-
-=item B<-f> I<file>
-
-Use I<file> as the newsgroup list instead of I<pathdb>/active.  I<file>
-can be C<-> to indicate standard input.  Using this flag suppresses the
-normal purge of all overview information from newsgroups that have been
-removed from the server.
-
-=item B<-k>
-
-Retain all overview information for an article, as well as the article
-itself, until it expires out of all newsgroups to which it was posted.
-This can cause articles to stick around in a newsgroup for longer than the
-F<expire.ctl> rules indicate, when they're crossposted.  B<-e> and B<-k>
-cannot be used at the same time.  This flag is ignored if
-I<groupbaseexpiry> is false.
-
-=item B<-N>
-
-Apply F<expire.ctl> rules to expire articles even from storage methods
-that have self-expire functionality.  This may remove articles from
-self-expiring storage methods before the articles "naturally" expire.
-This flag is ignored if I<groupbaseexpiry> is false.
-
-=item B<-p>
-
-By default, B<expireover> bases decisions on whether to remove an article
-on the arrival time on the server.  This means that articles may be kept a
-little longer than if the decision were based on the article's posting
-date.  If this option is given, expiration decisions are based on the
-article posting date instead.  This flag is ignored if I<groupbaseexpiry>
-is false.
-
-=item B<-q>
-
-B<expireover> normally prints statistics at the end of the expiration
-process.  B<-q> suppresses this report.  This flag is ignored if
-I<groupbaseexpiry> is false.
-
-=item B<-s>
-
-B<expireover> normally only checks the existence of articles in the news
-spool if querying the storage method for that article to see if it still
-exists is considered "inexpensive."  To always check the existence of all
-articles regardless of how resource-intensive this may be, use the B<-s>
-flag.  See storage.conf(5) for more information about this metric.
-
-=item B<-w> I<offset>
-
-"Warps" time so that B<expireover> thinks that it's running at some time
-other than the current time.  This is occasionally useful to force groups
-to be expired or not expired without changing F<expire.ctl> for the expire
-run.  I<offset> should be a signed floating point number specifying the
-number of days difference from the current time to use as "now."  This
-flag is ignored if I<groupbaseexpiry> is false.
-
-=item B<-z> I<rmfile>
-
-Don't remove articles immediately but instead write the path to the
-article or the token of the article to I<rmfile>, which is suitable input
-for fastrm(1).  This can substantially speed up deletion of expired
-articles for those storage methods where each article is a single file
-(such as tradspool and timehash).  See the description of I<delayrm> in
-news.daily(8) for more details.  This flag is ignored if
-I<groupbaseexpiry> is false.
-
-=item B<-Z> I<lowmarkfile>
-
-Write the lowest article numbers for each newsgroup as it's expired to the
-specified file.  This file is then suitable for C<ctlinnd lowmark>.  See
-ctlinnd(8) for more information.
-
-=back
-
-=head1 EXAMPLES
-
-Normally B<expireover> is invoked from news.daily(8), which handles such
-things as processing the I<rmfile> and I<lowmarkfile> if necessary.
-Sometimes it's convenient to manually expire a particular newsgroup,
-however.  This can be done with a command like:
-
-    echo example.test | expireover -f - -Z /usr/local/news/tmp/lowmark
-    ctlinnd lowmark /usr/local/news/tmp/lowmark
-
-This can be particularly useful if a lot of articles in a particular group
-have expired but the overview information is still present, causing some
-clients to see a lot of "this article may have been cancelled" messages
-when they first enter the newsgroup.
-
-=head1 HISTORY
-
-Written by Rob Robertson <rob@violet.berkeley.edu> and Rich $alz
-<rsalz@uunet.uu.net> (with help from Dave Lawrence <tale@uunet.uu.net>)
-for InterNetNews.
-
-$Id: expireover.pod 5909 2002-12-03 05:17:18Z vinocur $
-
-=head1 SEE ALSO
-
-active(5), ctlinnd(8), expire(8), expire.ctl(5), inn.conf(5),
-news.daily(8).
-
-=cut
diff --git a/doc/pod/external-auth.pod b/doc/pod/external-auth.pod
deleted file mode 100644 (file)
index 189da34..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-=head1 NNRPD External Authentication Support
-
-This is $Revision: 7141 $ dated $Date: 2005-03-17 03:42:46 -0800 (Thu, 17 Mar 2005) $.
-
-A fundamental part of the readers.conf(5)-based authorization mechanism
-is the interface to external authenticator and resolver programs.  This
-interface is documented below.
-
-INN ships with a number of such programs (all written in C, although any
-language can be used).  Code for them can be found in F<authprogs/> of
-the source tree; the authenticators are installed to
-I<pathbin>/auth/passwd, and the resolvers are installed to
-I<pathbin>/auth/resolv.
-
-=head1 Reading information from nnrpd
-
-When nnrpd spawns an external auth program, it passes information on
-standard input as a sequence of "key: value" lines.  Each line ends with
-CRLF, and a line consisting of only "." indicates the end of the input.
-The order of the fields is not significant.  Additional fields not
-mentioned below may be included; this should not be cause for alarm.
-
-(For robustness as well as ease of debugging, it is probably wise to
-accept line endings consisting only of LF, and to treat EOF as
-indicating the end of the input even if "." has not been received.)
-
-Code which reads information in the format discussed below and parses it
-into convenient structures is available authenticators and resolvers
-written in C; see libauth(3) for details.  Use of the libauth library
-will make these programs substantially easier to write and more robust.
-
-=head2 For authenticators
-
-When nnrpd calls an authenticator, the lines it passes are
-
-    ClientAuthname: user\r\n
-    ClientPassword: pass\r\n
-
-where I<user> and I<pass> are the username and password provided by the
-client (e.g. using AUTHINFO).  In addition, nnrpd generally also passes
-the fields mentioned as intended for resolvers; it rare instances this
-data may be useful for authenticators.
-
-=head2 For resolvers
-
-When nnrpd calls a resolver, the lines it passes are
-
-    ClientHost: hostname\r\n
-    ClientIP: IP-address\r\n
-    ClientPort: port\r\n
-    LocalIP: IP-address\r\n
-    LocalPort: port\r\n
-    .\r\n
-
-where I<hostname> indicates a string representing the hostname if
-available, I<IP-address> is a numeric IP address (dotted-quad for IPv4,
-equivalent for IPv6 if appropriate), and I<port> is a numeric port
-number.  (The I<LocalIP> paramter may be useful for determining which
-interface was used for the incoming connection.)
-
-If information is not available, nnrpd will omit the corresponding
-fields.  In particular, this applies to the unusual situation of nnrpd
-not being connected to a socket; TCP-related information is not
-available for standard input.
-
-=head1 Returning information to nnrpd
-
-=head2 Exit status and signals
-
-The external auth program must exit with a status of C<0> to indicate
-success; any other exit status indicates failure.  (The non-zero exit
-value will be logged.)
-
-If the program dies due to catching a signal (for example, a
-segmentation fault occurs), this will be logged and treated as a
-failure.
-
-=head2 Returning a username and domain
-
-If the program succeeds, it must return a username string (optionally
-with a domain appended) by writing to standard output.  The line it
-should write is exactly:
-
-    user:username\r\n
-
-where I<username> is the string that nnrpd should use in matching
-readers.conf access blocks.
-
-There should be no extra spaces in lines sent from the hook to nnrpd;
-C<user:aidan> is read by nnrpd as a different username than C<user:
-aidan>.
-
-=head1 Error messages
-
-As mentioned above, errors can be indicated by a non-zero exit value, or
-termination due to an unhandled signal; both cases are logged by nnrpd.
-However, external auth programs may wish to log error messages
-separately.
-
-Although nnrpd will syslog() anything an external auth program writes to
-standard error, it is generally better to use the F<messages.h>
-functions, such as warn() and die().
-
-Please use the ckpasswd.c program as an example for any authenticators
-you write, and ident.c as an example for any resolvers.
-
-=head1 HISTORY
-
-Written by Aidan Cully for InterNetNews.  This documentation rewritten
-in POD by Jeffrey M. Vinocur <jeff@litech.org>.
-
-=cut
diff --git a/doc/pod/fastrm.pod b/doc/pod/fastrm.pod
deleted file mode 100644 (file)
index 8f99c58..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-=head1 NAME
-
-fastrm - Quickly remove a list of files
-
-=head1 SYNOPSIS
-
-B<fastrm> [B<-de>] [B<-u>|B<-u>I<N>] [B<-s>|B<-s>I<M>] [B<-c>|B<-c>I<I>]
-I<base-directory>
-
-=head1 DESCRIPTION
-
-B<fastrm> reads a list of either file names or storage API tokens, one per
-line, from its standard input and removes them.  Storage API tokens are
-removed via the SMcancel() interface.  B<fastrm> does not delete files
-safely or with an eye to security, but rather cuts every corner it can to
-delete files as fast as it can.  It should therefore never be run on
-publically writable directories, or in any other environment where a
-hostile party may control the directory structure in which it is working.
-
-If a file name is not an absolute path name, it is considered to be
-relative to I<base-directory> as given on the command line.  The
-I<base-directory> parameter must be a simple absolute pathname (it must
-not contain multiple consecutive slashes or references to the special
-directories C<.> or C<..>).
-
-B<fastrm> is designed to be faster than the typical C<| xargs rm> pipeline
-when given a sorted list of file names as input.  For example, B<fastrm>
-will usually chdir(2) into a directory before removing files from it,
-meaning that if its input is sorted, most names passed to unlink(2) will
-be simple names.  This can substantially reduce the operating system
-overhead from directory lookups.
-
-B<fastrm> assumes that its input is valid and that it is safe to call
-unlink(2) on every file name it is given.  As a safety measure, however,
-B<fastrm> when running as root will check with stat(2) that a file name
-doesn't specify a directory before removing it.  (In some operating
-systems, root is allowed to unlink directories, even directories which
-aren't empty, which can cause file system corruption.)
-
-The input to B<fastrm> should always be sorted -- or even better be in the
-order file names are output by find(1) -- if speed is an issue and the
-input isn't solely storage API tokens.  (It deals fine with unsorted
-input, but is unlikely to be any faster in that case than a simple C<xargs
-rm> command.)  Sorting may even slightly speed up the removal of storage
-API tokens due to caching effects, since sorting will tend to keep all of
-the tokens from a particular storage method together.
-
-Various additional optimizations for removing files can be turned on
-and/or tuned with options (see below).  Which options will be most
-effective depends heavily on the underlying structure of the file system,
-the way in which directories are stored and searched, and similar, often
-underdocumented, operating system implementation details.  The more
-sophisticated the underlying operating system and file system, the more
-likely that it will already perform the equivalent of these optimizations
-internally.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d>
-
-Don't remove any files.  Instead, print a list of the files that would be
-removed to standard output.  Each line contains either the current
-directory of B<fastrm> at the time it would do the unlink and the relative
-path name it would pass to unlink(2) as two fields separated by whitespace
-and a C</>, the absolute path name (as a single field) that would be
-passed to unlink(2), or the string C<Token> and the storage API token that
-would be removed.
-
-=item B<-e>
-
-Treat an empty input file as an error.  This is most useful when B<fastrm>
-is last in a pipeline after a preceding sort(1) command, ensuring that
-B<fastrm> will fail if the sort fails.
-
-=item B<-c>I<I>
-
-Controls when B<fastrm> calls chdir(2).  If the number of files to be
-unlinked from a given directory is at least I<I>, then B<fastrm> will
-change to that directory before unlinking those files.  Otherwise, it will
-use either the absolute path names or a path name relative to the current
-directory (whichever is likely more efficient).  The I<I> parameter is
-optional; if just B<-c> is given, B<-c1> is assumed, which will cause
-B<fastrm> to always chdir before calling unlink(2).  The default is
-B<-c3>.  Use B<-c0> to prevent B<fastrm> from ever using chdir(2).
-
-=item B<-s>I<M>
-
-When B<-s> is given and the number of files to remove in a directory is
-greater than I<M>, rather than remove files in the order given, B<fastrm>
-will open the directory and read it, unlinking files in the order that
-they appear in the directory.  On systems with a per-process directory
-cache or that use a linear search to find files in a directory, this
-should make directory lookups faster.  The I<M> parameter is optional; if
-just B<-s> is given, B<-s5> is assumed.
-
-When this option is in effect, B<fastrm> won't attempt to remove files
-that it doesn't see in the directory, possibly significantly speeding it
-up if most of the files to be removed have already been deleted.  However,
-using this option requires B<fastrm> to do more internal work and it also
-assumes that the order of directory listings is stable in the presence of
-calls to unlink(2) between calls to readdir(3).  This may be a dangerous
-assumption with some sophisticated file systems (and in general this
-option is only useful with file systems that use unindexed linear searches
-to find files in directories or when most of the files to be removed have
-already been deleted).
-
-This optimization is off by default.
-
-=item B<-u>I<N>
-
-Specifying this option promises that there are no symbolic links in the
-directory tree from which files are being removed.  This allows B<fastrm>
-to make an additional optimization to its calls to chdir(2), constructing
-a relative path using C<../..> and the like to pass to chdir(2) rather
-than always using absolute paths.  Since this reduces the number of
-directory lookups needed with deeply nested directory structures (such as
-that typically created by traditional news spool storage), it can be a
-significant optimization, but it breaks horribly in the presence of
-symbolic links to directories.
-
-When B<-u> is given, B<fastrm> will use at most I<N> levels of C<..>
-segments to construct paths.  I<N> is optional; if just B<-u> is given,
-B<-u1> is assumed.
-
-This optimization is off by default.
-
-=back
-
-B<fastrm> also accepts B<-a> and B<-r> options, which do nothing at all
-except allow you to say C<fastrm -usa>, C<fastrm -ussr>, or C<fastrm
--user>.  These happen to often be convenient sets of options to use.
-
-=head1 EXIT STATUS
-
-B<fastrm> exits with a status of zero if there were no problems, and an
-exit status of 1 if something went wrong.  Attempting to remove a file
-that does not exist is not considered a problem.
-
-=head1 EXAMPLES
-
-B<fastrm> is typically invoked by INN via expirerm(8) using a command
-like:
-
-    fastrm -e /usr/local/news/spool/articles < expire.list
-
-To enable all optimizations and see the affect on the order of removal
-caused by B<-s>, use:
-
-    fastrm -d -s -e -u ~news/spool/articles < expire.list
-
-If your file system has indexed directory lookups, but you have a deeply
-nested directory structure, you may want to use a set of flags like:
-
-    fastrm -e -u3 ~news/spool/articles < expire.list
-
-to strongly prefer relative paths but not to use readdir(2) to order the
-calls to unlink(2).
-
-You may want to edit expirerm(8) to change the flags passed to B<fastrm>.
-
-=head1 WARNINGS
-
-B<fastrm> cuts corners and does not worry about security, so it does not
-use chdir(2) safely and could be tricked into removing files other than
-those that were intended if run on a specially constructed file tree or a
-file tree that is being modified while it is running.  It should therefore
-never be used with world-writable directories or any other directory that
-might be controlled or modified by an attacker.
-
-=head1 NOTES
-
-B<fastrm> defers opening the storage subsystem or attempting to parse any
-INN configuration files until it encounters a token in the list of files
-to remove.  It's therefore possible to use B<fastrm> outside of INN as a
-general fast file removal program.
-
-=head1 HISTORY
-
-B<fastrm> was originally written by kre@munnari.oz.au.  This manual page
-rewritten in POD by Russ Allbery <rra@stanford.edu> for InterNetNews.
-
-$Id: fastrm.pod 7422 2005-10-09 04:46:53Z eagle $
-
-=head1 SEE ALSO
-
-expirerm(8)
-
-=cut
diff --git a/doc/pod/grephistory.pod b/doc/pod/grephistory.pod
deleted file mode 100644 (file)
index 748e084..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-=head1 NAME
-
-grephistory - Query the INN history database
-
-=head1 SYNOPSIS
-
-B<grephistory> [B<-eilnqsv>] [B<-f> I<db>] [I<message-id>]
-
-=head1 DESCRIPTION
-
-B<grephistory> queries the INN history database for information about the
-specified message ID.  If no flags are given, the program prints the
-storage API token of the corresponding article, or C</dev/null> if the
-article is listed in the history database but not stored on the server.
-If the message ID cannot be found in the database, B<grephistory> will
-print C<grephistory: not found> and exit with a non-zero status.
-
-Be sure to escape any special characters in the message ID from the shell.
-Single quotes are recommended for this purpose since many message IDs
-contain dollar signs.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-e>
-
-Only print the storage token if the article is stored on the system.  (In
-other words, suppress the C</dev/null> or C<not found> output for missing
-or remembered articles.)
-
-=item B<-f> I<db>
-
-Query the history database I<db> rather than the default history database.
-
-=item B<-i>
-
-Rather than expecting a message ID on the command line, B<grephistory>
-will read a list of message IDs on standard input, one per line.  Leading
-and trailing whitespace is ignored, as are any malformed lines.  It will
-print out standard output those message IDs which are not found in the
-history database.  This is used when processing C<ihave> control messages.
-
-=item B<-l>
-
-Display the entire line from the history database, rather than just the
-storage API token.
-
-=item B<-n>
-
-If the message ID is present in the history database but has no storage
-API token, print C</dev/null> and exit successfully.  This can happen if
-an article has been cancelled or expired, but history information has
-still been retained.  This is the default behavior.
-
-=item B<-q>
-
-Don't print any message, but still exit with the appropriate status.
-
-=item B<-s>
-
-Rather than expecting a message ID on the command line, B<grephistory>
-will read a list of message IDs on standard input, one per line.  Leading
-and trailing whitespace is ignored, as are any malformed lines.  It will
-print on standard output the storage API tokens for any articles that are
-still available, one per line.  This flag is used when processing
-C<sendme> control messages.
-
-=item B<-v>
-
-Print out the hash of the message ID for diagnostic purposes, as well as
-any other requested information.  This flag is not useful with B<-s>.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: grephistory.pod 7045 2004-12-19 19:37:45Z rra $
-
-=head1 SEE ALSO
-
-history(5), inn.conf(5)
-
-=cut
diff --git a/doc/pod/hacking.pod b/doc/pod/hacking.pod
deleted file mode 100644 (file)
index db39c0b..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-=head1 Hacking INN
-
-This file is for people who are interested in making modifications to INN.
-Normal users can safely skip reading it.  It is intended primarily as a
-guide, resource, and accumulation of tips for maintainers and
-contributors, and secondarily as documentation of some of INN's internals.
-
-This is $Revision: 7518 $ dated $Date: 2006-04-14 19:52:06 -0700 (Fri, 14 Apr 2006) $.
-
-First of all, if you plan on working on INN source, please start from the
-current development tree.  There may be significant changes from the
-previous full release, so starting from development sources will make it
-considerably easier to integrate your work.  You can get nightly snapshots
-of the current development source from ftp.isc.org in /isc/inn/snapshots
-(the snapshots named inn-CURRENT-*.tar.gz), or you can get the current CVS
-tree by using CVSup (see L<"Using CVSup">).
-
-=head1 Configuring and Portability
-
-All INN code should be written expecting ANSI C and POSIX.  There is no
-need to attempt to support pre-ANSI compilers, and ANSI-only features such
-as <stdarg.h>, string concatenation, #elif, and token pasting may be used
-freely.  So far as possible, INN is written to attempt to be portable to
-any system new enough that someone is likely to want to run a news server
-on it, but whenever possible this portability should be provided by
-checking for standard behavior in configure and supplying replacements for
-standard functions that are missing.
-
-When there is a conflict between ANSI C and C99, INN code should be
-written expecting C99 and autoconf used to patch up the differences.
-
-Try to avoid using #ifdef and the like in the middle of code as much as
-possible.  Instead, try to isolate the necessary portability bits and
-include them in libinn or at least in conditional macros separate from the
-code.  Trying to read code littered with conditional compilation
-directives is much more difficult.
-
-The shell script F<configure> at the top level of the source tree is
-generated by autoconf from F<configure.in>, and F<include/config.h.in> is
-generated by autoheader from F<configure.in> and F<include/acconfig.h>.
-At configure time, configure generates F<include/config.h> and several
-other files based on options it was given and what it discovers about the
-target system.
-
-All modifications to configure should instead be made to F<configure.in>.
-Similarly, modifications to F<include/config.h.in> should instead be made
-to F<include/acconfig.h>.  The autoconf manual (available using info
-autoconf if you have autoconf and the GNU info utilities installed on your
-system) is a valuable reference when making any modifications.
-
-To regenerate configure, just run C<autoconf>.  To regenerate
-F<include/config.h.in>, run:
-
-    autoheader -l include
-
-to tell it where to find acconfig.h.  Please don't include patches to
-either F<configure> or F<include/config.h.in> when sending patches to INN;
-instead, note in your patch that those files must be regenerated.
-
-The generated files are checked into the CVS repository so that people
-working on INN don't have to have autoconf on their system, and to make
-packaging easier.
-
-At the time of this writing, autoconf 2.13 is required.
-
-The supporting files for autoconf are in the F<support> subdirectory,
-including the files F<config.guess> and F<config.sub> to determine the
-system name and and F<ltmain.sh> for libtool support.  The latter file
-comes from the libtool distribution; the canonical version of the former
-two are available from ftp.gnu.org in /gnu/config.  In addition,
-F<m4/libtool.m4> is just a copy of F<libtool.m4> from the libtool
-distribution.  (Using libtool without using automake requires a few odd
-hacks.)  These files used to be on a separate vendor branch so that we
-could make local modifications, but local modifications have not been
-necessary for some time.  Now, new versions can just be checked in like
-any other file modifications.
-
-INN should not compile with libtool by default, only when requested, since
-otherwise normal compilations are quite slow.  (Using libtool is not
-without some cost.)  Basic compilation with libtool works fine as of this
-writing, with both static and shared compiles, but the dependencies aren't
-quite right for make -j using libtool.
-
-=head1 Documentation
-
-INN's documentation is currently somewhat in a state of flux.  The vast
-majority is still in the form of man pages written directly in nroff.
-Some parts of the documentation have been rewritten in POD; that
-documentation can be found in F<doc/pod>.  The canonical source for
-F<README>, F<INSTALL>, F<NEWS>, F<doc/hook-perl>, F<doc/hook-python>, and
-this file are also in POD.
-
-If you're modifying some part of INN's documentation and see that it has a
-POD version in F<doc/pod>, it's preferred if you can make the
-modifications to the POD source and then regenerate the derived files.
-For a quick introduction to POD, see the perlpod(1) man page on your
-system (it should be installed if you have Perl installed).
-
-When writing new documentation, write in whatever format you care to; if
-necessary, we can always convert it to POD or whatever else we want to
-use.  Having the documentation exist in I<some> form is more important
-than what language you write it in.  If you really don't have any
-particular preference, there's a slight preference currently for POD.
-
-If you use POD or regenerate POD documentation, please install something
-close to the latest versions of the POD processing utilities to avoid
-changes to the documentation depending on who generated it last.  You can
-find the latest version on CPAN (ftp.perl.org or another mirror) in
-F<modules/by-module/Pod>.  You'll need PodParser (for versions of Perl
-before 5.6.1; 5.6.1 and later come with a recent enough version) and the
-latest version of podlators.  For versions of Perl earlier than 5.005,
-you'll also need File::Spec in F<modules/by-module/File>.
-
-podlators 1.25 or later will build INN's documentation without significant
-changes from the versions that are checked into the repository.
-
-There are Makefile rules in F<doc/pod/Makefile> to build all of the
-documentation whose master form is POD; if you add additional
-documentation, please add a rule there as well.  Documentation should be
-generated by cd'ing to F<doc/pod> and typing C<make file> where C<file> is
-the relative path to the documentation file.  This will get all of the
-various flags right for pod2text or pod2man.
-
-=head1 Error Handling
-
-INN has a set of generic error handling routines that should be used as
-much as possible so that the same syntax can be used for reporting errors
-everywhere in INN.  The four basic functions are warn, syswarn, die, and
-sysdie; warn prints or logs a warning, and die does the same and then
-exits the current program.  The sys* versions add a colon, a space, and
-the value of strerror(errno) to the end of the message, and should be used
-to report failing system calls.
-
-All of the actual error reporting is done via error handlers, and a
-program can register its own handlers in addition to or instead of the
-default one.  The default error handler (error_log_stderr) prints to
-stderr, prepending the value of error_program_name if it's set to
-something other than NULL.  Three other error handlers are available,
-error_log_syslog_crit, error_log_syslog_err, and error_log_syslog_warning,
-which log the message to syslog at LOG_CRIT, LOG_ERR, or LOG_WARNING
-priority, respectively.
-
-There is a different set of error handlers for warn/syswarn and
-die/sysdie.  To set them, make calls like:
-
-    warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
-    die_set_handlers(2, error_log_stderr, error_log_syslog_err);
-
-The first argument is the number of handlers, and the remaining arguments
-are pointers to functions taking an int (the length of the formatted
-message), a const char * (the format), a va_list (the arguments), and an
-int that's 0 if warn or die was called and equal to the value of errno if
-syswarn or sysdie was called.  The length of the formatted message is
-obtained by calling vsnprintf with the provided format and arguments, and
-therefore is reliable to use as the size of a buffer to malloc to hold the
-result of formatting the message provided that vsnprintf is used to format
-it (warning: the system vsprintf may produce more output under some
-circumstances, so always use vsnprintf).
-
-The error handler can do anything it wishes; each error handler is called
-in the sequence given.  Error handlers shouldn't call warn or die unless
-great caution is taken to prevent infinite recursion.  Also be aware that
-sysdie is called if malloc fails in xmalloc, so if the error handler needs
-to allocate memory, it must not use xmalloc or a related function to do
-so and it shouldn't call die to report failure.  The default syslog
-handlers report memory allocation failure to stderr and exit.
-
-Finally, die and sysdie support an additional handler that's called
-immediate before exiting, takes no arguments, and returns an int which is
-used as the argument for exit.  It can do any necessary global cleanup,
-call abort instead to generate a core dump or the like.
-
-The advantage of using this system everywhere in INN is that library code
-can use warn and die to report errors and each calling program can set up
-the error handlers as appropriate to make sure the errors go to the right
-place.  The default handler is fine for interactive programs; for programs
-that run from interactive scripts, adding something like:
-
-    error_program_name = "program";
-
-to the beginning of main (where program is the name of the program) will
-make it easier to figure out which program the script calls is failing.
-For programs that may also be called non-interactively, like inndstart,
-one may want to set up handlers like:
-
-    warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
-    die_set_handlers(2, error_log_stderr, error_log_syslog_err);
-
-Finally, for daemons and other non-interactive programs, one may want to
-do:
-
-    warn_set_handlers(1, error_log_syslog_warning);
-    die_set_handlers(1, error_log_syslog_err);
-
-to report errors only via syslog.  (Note that if you use syslog error
-handlers, the program should call openlog first thing to make sure they
-are logged with the right facility.)
-
-For historical reasons, error messages that are fatal to the news
-subsystem are logged at the LOG_CRIT priority, and therefore die in innd
-should use error_log_syslog_crit.
-
-=head1 Test Suite
-
-The test suite for INN is located in the tests directory and is just
-getting started.  The test suite consists of a set of programs listed in
-F<tests/TESTS> and the scaffolding in the F<runtests> program.
-
-Adding new tests is very straightforward and very flexible.  Just write a
-program that tests some part of INN, put it in a directory under tests
-named after the part of INN it's testing (all the tests so far are in lib
-because they're testing libinn routines), and have it output first a line
-containing the count of test cases in that file, and then for each test a
-line saying "ok n" or "not ok n" where n is the test case number.  (If a
-test is skipped for some reason, such as a test of an optional feature
-that wasn't compiled into INN, the test program should output
-S<"ok n # skip">.)  Add any rules necessary to build the test to
-tests/Makefile (note that for simplicity it doesn't recurse into
-subdirectories) and make sure it creates an executable ending in F<.t>.
-Then add the name of the test to tests/TESTS, without the .t ending.
-
-One naming convention:  to distinguish more easily between e.g.
-lib/error.c (the implementation) and tests/lib/error-t.c (the test suite),
-we add -t to the end of the test file names.  So tests/lib/error-t.c is
-the source that compiles into an executable tests/lib/error.t which is run
-by putting a line in tests/TESTS of just "lib/error".
-
-Note that tests don't have to be written in C; in fact, lib/xmalloc.t is
-just a shell script (that calls a supporting C program).  Tests can be
-written in shell or Perl (but other languages should be avoided because
-someone who wants to run the test suite may not have it) and just have to
-follow the above output conventions.
-
-Additions to the test suite, no matter how simple, are very welcome.
-
-=head1 Makefiles
-
-All INN makefiles include Makefile.global at the top level, and only that
-makefile is a configure substitution target.  This has the disadvantage
-that configure's normal support for building in a tree outside of the
-source tree doesn't work, but it has the significant advantage of making
-configure run much faster and allowing one to run make in any subdirectory
-and pick up all the definitions and settings from the top level
-configuration.
-
-All INN makefiles should also set $(top) to be the path to the top of the
-build directory (usually relative).  This path is used to find various
-programs like fixscript and libtool so that the same macros (set in
-Makefile.global) can be used all over INN.
-
-The format of INN's makefiles is mostly standardized; the best examples of
-the format are probably F<frontends/Makefile> and F<backends/Makefile>, at
-least for directories with lots of separate programs.  The ALL variable
-holds all the files that should be generated, EXTRA those additional files
-that were generated by configure, and SOURCES the C source files for
-generating tag information.
-
-There are a set of standard installation commands defined in make
-variables by Makefile.global, and these should be used for all file
-installations.  See the comment blocks in Makefile.global.in for
-information on what commands are available and when they should be used.
-There are also variables set for each of the installation directories that
-INN uses, for use in building the list of installed paths to files.
-
-Each subdirectory makefile should have the targets all (the default),
-clean, clobber, install, tags, and profiled.  The tags target generates vi
-tags files, and the profiled target generates a profiling version of the
-programs (although this hasn't been tested much recently).  These rules
-should be present and empty in those directories where they don't apply.
-
-Be sure to test compiling with both static and dynamic libraries and make
-sure that all the libtool support works correctly.  All linking steps, and
-the compile steps for all library source, should be done through
-$(LIBTOOL) (which will be set to empty in Makefile.global if libtool
-support isn't desired).
-
-=head1 Scripts
-
-INN comes with and installs a large number of different scripts, both
-Bourne shell and Perl, and also comes with support for Tcl scripts
-(although it doesn't come with any).  Shell variables containing both
-configure-time information and configuration information from inn.conf are
-set by the innshellvars support libraries, so the only system-specific
-configuration that should have to be done is fixing the right path to the
-interpretor and adding a line to load the appropriate innshellvars.
-
-F<support/fixscript>, built by configure, does this.  It takes a .in file
-and generates the final script (removing the .in) by fixing the path to
-the interpretor on the first line and replacing the second line, whatever
-it is, with code to load the innshellvars appropriate for that
-interpretor.  (If invoked with -i, it just fixes the interpretor path.)
-
-Scripts should use innshellvars (via fixscript) to get the right path and
-the right variables whenever possible, rather than having configure
-substitute values in them.  Any values needed at run-time should instead
-be available from all of the different innshellvars.
-
-See the existing scripts for examples of how this is done.
-
-=head1 Include Files
-
-Include files relevant to all of INN, or relevant to the two libraries
-built as part of INN (the utility libinn library and the libstorage
-library that contains all storage and overview functions) are found in the
-include directory; other include files relevant only to a portion of INN
-are found in the relevant directory.
-
-Practically all INN source files will start with:
-
-    #include "config.h"
-    #include "clibrary.h"
-
-The first picks up all defines generated by autoconf and is necessary for
-types that may not be present on all systems (uid_t, pid_t, size_t,
-int32_t, and the like).  It therefore should be included before any other
-headers that use those types, as well as to get general configuration
-information.
-
-The second is portably equivalent to:
-
-    #include <sys/types.h>
-    #include <stdarg.h>
-    #include <stdio.h>
-    #include <stdlib.h>
-    #include <stddef.h>
-    #include <stdint.h>
-    #include <string.h>
-    #include <unistd.h>
-
-except that it doesn't include headers that are missing on a given system,
-replaces functions not found on the system with the INN equivalents,
-provides macros that INN assumes are available but which weren't found,
-and defines some additional portability things.  Even if this is more
-headers than the source file actually needs, it's generally better to just
-include F<clibrary.h> rather than trying to duplicate the autoconf-driven
-hackery that it does to do things portably.  The primary exception is for
-source files in lib that only define a single function and are used for
-portability; those may want to include only F<config.h> so that they can
-be easily used in other projects that use autoconf.  F<config.h> is a
-fairly standard header name for this purpose.
-
-F<clibrary.h> does also include F<config.h>, but it's somewhat poor form
-to rely on this; it's better to explicitly list the header dependencies
-for the benefit of someone else reading the code.
-
-There are portable wrappers around several header files that have known
-portability traps or that need some fixing up on some platforms.  Look in
-include/portable and familiarize yourself with them and use them where
-appropriate.
-
-Another frequently included header file is F<libinn.h>, which among other
-things defines xmalloc(), xrealloc(), xstrdup(), and xcalloc(), which are
-checked versions of the standard memory allocation routines that terminate
-the program if the memory allocation fails.  These should generally always
-be used instead of the regular C versions.  F<libinn.h> also provides
-various other utility functions that are frequently used.
-
-F<paths.h> includes a wide variety of paths determined at configure time,
-both default paths to various parts of INN and paths to programs.  Don't
-just use the default paths, though, if they're also configurable in
-F<inn.conf>; instead, call ReadInnConf() and use the global innconf
-structure.
-
-Other files in include are interfaces to particular bits of INN library
-functionality or are used for other purposes; see the comments in each
-file.
-
-Eventually, the header files will be separated into installed header files
-and uninstalled header files; the latter are those headers that are used
-only for compiling INN and aren't useful for users of INN's libraries
-(such as clibrary.h).  All of the installed headers will live in
-include/inn and be installed in a subdirectory named inn in the configured
-include directory.  This conversion is still in progress.
-
-When writing header files, remember that C reserves all identifiers
-beginning with two underscores and all identifiers beginning with an
-underscore and a capital letter for the use of the implementation; don't
-use any identifiers with names like that.  Additionally, any identifier
-beginning with an underscore and a lower-case letter is reserved in file
-scope, which means that such identifiers can only be used by INN for the
-name of structure members or function arguments in function prototypes.
-
-Try to pay attention to the impact of a header file on the program
-namespace, particularly for installed header files in include/inn.  All
-symbols defined by a header file should ideally begin with INN_, inn_, or
-some other unique prefix indicating the subsystem that symbol is part of,
-to avoid accidental conflicts with symbols defined by the program that
-uses that header file.
-
-=head1 Coding Style
-
-INN has quite a variety of coding styles intermixed.  As with all
-programs, it's preferrable when making minor modifications to keep the
-coding style of the code you're modifying.  In INN, that will vary by
-file.  (Over time we're trying to standardize on one coding style, so
-changing the region you worked on to fit the general coding style is also
-acceptable).
-
-If you're writing a substantial new piece of code, the prevailing
-"standard" INN coding style appears to be something like the following:
-
-=over 3
-
-=item *
-
-Write in regular ANSI C whenever possible.  Use the normal ANSI and POSIX
-constructs and use autoconf or portability wrappers to fix things up
-beforehand so that the code itself can read like regular ANSI or POSIX
-code.  Code should be written so that it works as expected on a modern
-platform and is fixed up with portability tricks for older platforms, not
-the other way around.  You may assume an ANSI C compiler.
-
-Try to use const wherever appropriate.  Don't use register; modern
-compilers will do as good of a job as you will in choosing what to put
-into a register.  Don't bother with restrict (at least yet).
-
-=item *
-
-Use string handling functions that take counts for the size of the buffer
-whenever possible.  This means using snprintf in preference to sprintf and
-using strlcpy and strlcat in preference to strcpy and strcat.  Also, use
-strlcpy and strlcat instead of strncpy and strncat unless the behavior of
-the latter is specifically required, as it is much easier to audit uses of
-the former than the latter.  (strlcpy is like strncpy except that it
-always nul-terminates and doesn't fill the rest of the buffer with nuls,
-making it more efficient.  strlcat is like strncat except that it always
-nul-terminates and it takes the total size of the buffer as its third
-argument rather than just the amount of space left.)  All of these
-functions are guaranteed to be available; there are replacements in lib
-for systems that don't have them.
-
-=item *
-
-Avoid #ifdef and friends whenever possible.  Particularly avoid using them
-in the middle of code blocks.  Try to hide all portability preprocessor
-magic in header files or in portability code in lib.  When something just
-has to be done two completely different ways depending on the platform or
-compile options or the like, try to abstract that functionality out into a
-generic function and provide two separate implementations using #ifdef;
-then the main code can just call that function.
-
-If you do have to use preprocessor defines, note that if you always define
-them to either 0 or 1 (never use #define without a second argument), you
-can use the preprocessor define in a regular if statement rather than
-using #if or #ifdef.  Make use of this instead of #ifdef when possible,
-since that way the compiler will still syntax-check the other branch for
-you and it makes it far easier to convert the code to use a run-time check
-if necessary.  (Unfortunately, this trick can't be used if one branch may
-call functions unavailable on a particular platform.)
-
-=item *
-
-Avoid uses of fixed-width buffers except in performance-critical code, as
-it's harder to be sure that such code is correct and it tends to be less
-flexible later on.  If you need a reusable, resizable memory buffer, one
-is provided in lib/buffer.c.
-
-=item *
-
-Avoid uses of static variables whenever possible, particularly in
-libraries, because it interferes with making the code re-entrant down the
-road and makes it harder to follow what's going on.  Similarly, avoid
-using global variables whenever possible, and if they are required, try to
-wrap them into structures that could later be changed into arguments to
-the affected functions.
-
-=item *
-
-Roughly BSD style but with four-space indents.  This means no space before
-the parens around function arguments, open brace on the same line as
-if/while/for, and close and open brace on the same line as else).
-
-=item *
-
-Introductory comments for functions or files are generally written as:
-
-    /*
-    **  Introductory comment.
-    */
-
-Other multiline comments in the source are generally written as:
-
-    /* This is a
-       multiline comment. */
-
-Comments before functions saying what they do are nice to have.  In
-general, the RCS/CVS Id tag is on the first line of each source file since
-it's useful to know when a file was last modified.
-
-=item *
-
-Checks for NULL pointers are preferrably written out explicitly; in other
-words, use:
-
-    if (p != NULL)
-
-rather than:
-
-    if (p)
-
-to make it clearer what the code is assuming.
-
-=item *
-
-It's better to always put the body of an if statement on a separate line,
-even if it's only a single line.  In other words, write:
-
-    if (p != NULL)
-        return p;
-
-and not:
-
-    if (p != NULL) return p;
-
-This is in part for a practical reason:  some code coverage analysis tools
-like purecov will count the second example above as a single line and
-won't notice if the condition always evaluates the same way.
-
-=item *
-
-Plain structs make perfectly reasonable abstract data types; it's not
-necessary to typedef the struct to something else.  Structs are actually
-very useful for opaque data structures, since you can predeclare them and
-then manipulate pointers to them without ever having to know what the
-contents look like.  Please try to avoid typedefs except for function
-pointers or other extremely confusing data types, or for data types where
-we really gain some significant data abstraction from hiding the
-underlying data type.  Also avoid using the _t suffix for any type; all
-types ending in _t are reserved by POSIX.  For typedefs of function
-pointer types, a suffix of _func usually works.
-
-This style point is currently widely violated inside of INN itself; INN
-originally made extensive use of typedefs.
-
-=item *
-
-When noting something that should be improved later, add a comment
-containing "FIXME:" so that one can easily grep for such comments.
-
-=back
-
-INN's indentation style roughly corresponds to that produced by GNU indent
-2.2.6 with the following options:
-
-    -bad -bap -nsob -fca -lc78 -cd41 -cp1 -br -ce -cdw -cli0 -ss -npcs
-    -ncs -di1 -nbc -psl -brs -i4 -ci4 -lp -ts8 -nut -ip5 -lps -l78 -bbo
-    -hnl
-
-Unfortunately, indent currently doesn't get everything right (it has
-problems with spacing around struct pointer arguments in functions, wants
-to put in a space between a dereference of a function pointer and the
-arguments to the called function, misidentifies some macro calls as being
-type declarations, and fouls up long but simple case statements).  It
-would be excellent if someday we could just run all of INN's code through
-indent routinely to enforce a consistant coding style, but indent isn't
-quite ready for that.
-
-For users of emacs cc-mode, use the "bsd" style but with:
-
-    (setq c-basic-offset 4)
-
-Finally, if possible, please don't use tabs in source files, since they
-can expand differently in different environments.  In particular, please
-try not to use the mix of tabs and spaces that is the default in emacs.
-If you use emacs to edit INN code, you may want to put:
-
-    ; Use only spaces when indenting or centering, no tabs.
-    (setq-default indent-tabs-mode nil)
-
-in your ~/.emacs file.
-
-Note that this is only a rough guideline and the maintainers aren't style
-nazis; we're more interested in your code contribution than in how you
-write it.
-
-=head1 Using CVSup
-
-If you want to get updated INN source more easily or more quickly than by
-downloading nightly snapshots, or if you want to see the full CVS history,
-you may want to use CVSup to download the source.  CVSup is a client and
-server designed for replicating CVS repositories between sites.
-
-Unfortunately, CVSup is written in Modula-3, so getting a working binary
-can be somewhat difficult.  Binaries are available in the *BSD ports
-collection or (for a wide variety of different platforms) available from
-<ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/binaries/> and its mirrors.
-Alternately, you can get a compiler from <http://m3.polymtl.ca/m3/> (this
-is more actively maintained than the DEC Modula-3 compiler) and the source
-from <ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/>.
-
-After you have the CVSup client, you need to have space to download the
-INN repository and space for CVSup to store its data files.  You also need
-to write a configuration file (a supfile) for CVSup.  The following
-supfile will download the latest versions from the mainline source:
-
-    *default host=inn-cvs.isc.org
-    *default base=<data-location>
-    *default prefix=<download-location>
-    *default release=cvs
-    *default tag=.
-    *default delete use-rel-suffix
-    inn
-
-where <data-location> should be a directory where CVSup can put its data
-files and <download-location> is where the downloaded source will go (it
-will be put into a subdirectory named inn).  If you want to pull down the
-entire CVS repository instead (warning: this is much larger than just the
-latest versions of the source), delete the C<*default tag=.> line.  The
-best way to download the CVS repository is to download it into a portion
-of a locally-created CVS repository, so that then you can perform standard
-CVS operations (like cvs log) against the downloaded repository.  Creating
-your own local CVS repository is outside the scope of this document.
-
-Note that only multiplexed mode is supported (this mode should be the
-default).
-
-For more general information on using CVSup, see the FreeBSD page on it at
-<http://www.freebsd.org/handbook/mirrors-cvsup.html>.
-
-=head1 Making a Release
-
-This is a checklist that INN maintainers should go through when preparing
-a new release of INN.
-
-=over 4
-
-=item 1.
-
-If making a major release, branch the source tree and create a new STABLE
-branch tag.  This branch will be used for minor releases based on that
-major release and can be done a little while before the .0 release of that
-major release.  At the same time as the branch is cut, tag the trunk with
-a STABLE-<version>-branch marker tag so that it's easy to refer to the
-trunk at the time of the branch.
-
-=item 2.
-
-Update doc/pod/news.pod and regenerate NEWS.  Be more detailed for a minor
-release than for a major release.  For a major release, also add
-information on how to upgrade from the last major release, including
-anything special to be aware of.  (Minor releases shouldn't require any
-special care when upgrading.)
-
-=item 3.
-
-Make sure that support/config.sub and support/config.guess are the latest
-versions (from <ftp://ftp.gnu.org/gnu/config/>).  See the instructions in
-L<"Configuring and Portability"> for details on how to update these files.
-
-=item 4.
-
-Make sure that samples/control.ctl is in sync with the master version at
-<ftp://ftp.isc.org/pub/usenet/CONFIG/control.ctl>.
-
-=item 5.
-
-Check out a copy of the release branch.  It's currently necessary to run
-configure to generate Makefile.global.  Then run C<make check-manifest>.
-The only differences should be files that are generated by configure; if
-there are any other differences, fix the MANIFEST.
-
-=item 6.
-
-Run C<make release>.  Note that you need to have a copy of svn2cl from
-<http://ch.tudelft.nl/~arthur/svn2cl/> to do this; at least version 0.7
-is required.  Start the ChangeLog at the time of the previous release.
-(Eventually, the script will be smart enough to do this for you.)
-
-=item 7.
-
-Make the resulting tar file available for testing in a non-listable
-directory on ftp.isc.org and announce its availability on inn-workers.
-Install it on at least one system and make sure that system runs fine for
-at least a few days.  This is also a good time to send out a draft of the
-release announcement to inn-workers for proof-reading.
-
-=item 8.
-
-Generate a diff between this release and the previous release if feasible
-(always for minor releases, possibly not a good idea due to the length of
-the diff for major releases).
-
-=item 9.
-
-Move the release into the public area of the ftp site and update the
-inn.tar.gz link.  Make an MD5 checksum of the release tarball and put it
-on the ftp site as well, and update the inn.tar.gz.md5 link.  Put the diff
-up on the ftp site as well.  Contact the ISC folks to get the release
-PGP-signed.  Possibly move older releases off into the OLD directory.
-
-=item 10.
-
-Announce the new release on inn-announce and in news.software.nntp.
-
-=item 11.
-
-Tag the checked-out tree that was used for generating the release with a
-release tag (INN-<version>).
-
-=item 12.
-
-Bump the revision number in Makefile.global.in.
-
-=back
-
-=head1 References
-
-Some additional references that may be hard to find and may be of use to
-people working on INN:
-
-=over 4
-
-=item <http://www.eyrie.org/~eagle/nntp/>
-
-The home page for the IETF NNTP standardization effort, including links
-to the IETF NNTP working group archives and copies of the latest drafts
-of the new NNTP standard.  The old archived mailing list traffic contains
-a lot of interesting discussion of why NNTP is the way it is.
-
-=item <http://www.imc.org/ietf-usefor/>
-
-The archives for the USEFOR IETF working group, the working group for the
-RFC 1036 replacement (the format of Usenet articles).  Also contains a lot
-of references to other relevant work, such as the RFC 822 replacement
-work.
-
-=item <http://www.mibsoftware.com/userkt/inn/dev/>
-
-Forrest Cavalier provides several tools for following INN development at
-this page and elsewhere in the Usenet RKT.  Under here is a web-accessible
-checked-out copy of the current INN source tree and pointers to how to use
-CVSup.
-
-=item <http://www.sas.com/standards/large.file/>
-
-The standards for large file support on Unix that are being generally
-implemented by vendors.  INN sort of partially uses these, but a good full
-audit of the code to check them should really be done and there are
-occasional problems.
-
-=item <http://v6web.litech.org/ipv6primer/>
-
-A primer on IPv6 with pointers to the appropriate places for more
-technical details as needed, useful when working on IPv6 support in INN.
-
-=back
diff --git a/doc/pod/hook-perl.pod b/doc/pod/hook-perl.pod
deleted file mode 100644 (file)
index a860393..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-=head1 INN Perl Filtering and Authentication Support
-
-This is $Revision: 7860 $ dated $Date: 2008-06-07 05:46:49 -0700 (Sat, 07 Jun 2008) $.
-
-This file documents INN's built-in support for Perl filtering and reader
-authentication.  The code is based very heavily on work by Christophe
-Wolfhugel <wolf@pasteur.fr>, and his work was in turn inspired by the
-existing TCL support.  Please send any bug reports to inn-bugs@isc.org,
-not to Christophe, as the code has been modified heavily since he
-originally wrote it.
-
-The Perl filtering support is described in more detail below.  Basically,
-it allows you to supply a Perl function that is invoked on every article
-received by innd from a peer (the innd filter) or by nnrpd from a reader
-(the nnrpd filter).  This function can decide whether to accept or reject
-the article, and can optionally do other, more complicated processing
-(such as add history entries, cancel articles, spool local posts into a
-holding area, or even modify the headers of locally submitted posts).
-The Perl authentication hooks allow you to replace or supplement the
-readers.conf mechanism used by nnrpd.
-
-For Perl filtering support, you need to have Perl version 5.004 or newer.
-Earlier versions of Perl will fail with a link error at compilation time.
-http://language.perl.com/info/software.html should have the latest Perl
-version.
-
-To enable Perl support, you have to specify B<--with-perl> when you run
-configure.  See F<INSTALL> for more information.
-
-=head1 The innd Perl Filter
-
-When innd starts, it first loads the file _PATH_PERL_STARTUP_INND (defined
-in F<include/paths.h>, by default F<startup_innd.pl>) and then loads the
-file _PATH_PERL_FILTER_INND (also defined in F<include/paths.h>, by
-default F<filter_innd.pl>).  Both of these files must be located in the
-directory specified by pathfilter in F<inn.conf>
-(F</usr/local/news/bin/filter> by default).  The default directory for
-filter code can be specified at configure time by giving the flag
-B<--with-filter-dir> to configure.
-
-INN doesn't care what Perl functions you define in which files.  The only
-thing that's different about the two files is when they're loaded.
-F<startup_innd.pl> is loaded only once, when innd first starts, and is
-never reloaded as long as innd is running.  Any modifications to that file
-won't be noticed by innd; only stopping and restarting innd can cause it
-to be reloaded.
-
-F<filter_innd.pl>, on the other hand, can be reloaded on command (with
-C<ctlinnd reload filter.perl 'reason'>).  Whenever F<filter_innd.pl> is loaded,
-including the first time at innd startup, the Perl function
-filter_before_reload() is called before it's reloaded and the function
-filter_after_reload() is called after it's reloaded (if the functions
-exist).  Additionally, any code in either F<startup_innd.pl> or
-F<filter_innd.pl> at the top level (in other words, not inside a sub { })
-is automatically executed by Perl when the files are loaded.
-
-This allows one to do things like write out filter statistics whenever the
-filter is reloaded, load a cache into memory, flush cached data to disk,
-or other similar operations that should only happen at particular times or
-with manual intervention.  Remember, any code not inside functions in
-F<startup_innd.pl> is executed when that file is loaded, and it's loaded
-only once when innd first starts.  That makes it the ideal place to put
-initialization code that should only run once, or code to load data that
-was preserved on disk across a stop and restart of innd (perhaps using
-filter_mode() -- see below).
-
-As mentioned above, C<ctlinnd reload filter.perl 'reason'> (or C<ctlinnd reload
-all 'reason'>) will cause F<filter_innd.pl> to be reloaded.  If the function
-filter_art() is defined after the file has been reloaded, filtering is
-turned on.  Otherwise, filtering is turned off.  (Note that due to the way
-Perl stores functions, once you've defined filter_art(), you can't
-undefine it just by deleting it from the file and reloading the filter.
-You'll need to replace it with an empty sub.)
-
-The Perl function filter_art() is the heart of a Perl filter.  Whenever an
-article is received from a peer, via either IHAVE or TAKETHIS,
-filter_art() is called if Perl filtering is turned on.  It receives no
-arguments, and should return a single scalar value.  That value should be
-the empty string to indicate that INN should accept the article, or some
-rejection message to indicate that the article should be rejected.
-
-filter_art() has access to a global hash named %hdr, which contains all of
-the standard headers present in the article and their values.  The
-standard headers are:
-
-    Also-Control, Approved, Bytes, Cancel-Key, Cancel-Lock,
-    Content-Base, Content-Disposition, Content-Transfer-Encoding,
-    Content-Type, Control, Date, Date-Received, Distribution, Expires,
-    Face, Followup-To, From, In-Reply-To, Injection-Date, Injection-Info,
-    Keywords, Lines, List-ID, Message-ID, MIME-Version, Newsgroups,
-    NNTP-Posting-Date, NNTP-Posting-Host, Organization, Originator,
-    Path, Posted, Posting-Version, Received, References, Relay-Version,
-    Reply-To, Sender, Subject, Supersedes, User-Agent,
-    X-Auth, X-Canceled-By, X-Cancelled-By, X-Complaints-To, X-Face,
-    X-HTTP-UserAgent, X-HTTP-Via, X-Mailer, X-Modbot, X-Modtrace,
-    X-Newsposter, X-Newsreader, X-No-Archive, X-Original-Message-ID,
-    X-Original-Trace, X-Originating-IP, X-PGP-Key, X-PGP-Sig,
-    X-Poster-Trace, X-Postfilter, X-Proxy-User, X-Submissions-To,
-    X-Trace, X-Usenet-Provider, Xref.
-
-Note that all the above headers are as they arrived, not modified by
-your INN (especially, the Xref: header, if present, is the one of
-the remote site which sent you the article, and not yours).
-
-For example, the Newsgroups: header of the article is accessible
-inside the Perl filter as C<$hdr{'Newsgroups'}>.  In addition,
-C<$hdr{'__BODY__'}> will contain the full body of the article and
-C<$hdr{'__LINES__'}> will contain the number of lines in the body of the
-article.
-
-The contents of the %hdr hash for a typical article may therefore look
-something like this:
-
-    %hdr = (Subject      => 'MAKE MONEY FAST!!', 
-        From         => 'Joe Spamer <him@example.com>',
-        Date         => '10 Sep 1996 15:32:28 UTC',
-        Newsgroups   => 'alt.test',
-        Path         => 'news.example.com!not-for-mail',
-        Organization => 'Spammers Anonymous',
-        Lines        => '5',
-        Distribution => 'usa',
-        'Message-ID' => '<6.20232.842369548@example.com>',
-        __BODY__     => 'Send five dollars to the ISC, c/o ...',
-        __LINES__    => 5
-    );
-
-Note that the value of C<$hdr{Lines}> is the contents of the Lines: header
-of the article and may bear no resemblence to the actual length of the
-article.  C<$hdr{__LINES__}> is the line count calculated by INN, and is
-guaranteed to be accurate.
-
-The %hdr hash should not be modified inside filter_art().  Instead, if any
-of the contents need to be modified temporarily during filtering (smashing
-case, for example), copy them into a seperate variable first and perform
-the modifications on the copy.  Currently, C<$hdr{__BODY__}> is the only
-data that will cause your filter to die if you modify it, but in the
-future other keys may also contain live data.  Modifying live INN data in
-Perl will hopefully only cause a fatal exception in your Perl code that
-disables Perl filtering until you fix it, but it's possible for it to
-cause article munging or even core dumps in INN.  So always, always make a
-copy first.
-
-As mentioned above, if filter_art() returns the empty string (''), the
-article is accepted.  Note that this must be the empty string, not 0 or
-undef.  Otherwise, the article is rejected, and whatever scalar
-filter_art() returns (typically a string) will be taken as the reason why
-the article was rejected.  This reason will be returned to the remote peer
-as well as logged to the news logs.  (innreport, in its nightly report,
-will summarize the number of articles rejected by the Perl filter and
-include a count of how many articles were rejected with each reason
-string.)
-
-One other type of filtering is also supported.  If Perl filtering is
-turned on and the Perl function filter_messageid() is defined, that
-function will be called for each message ID received from a peer (via
-either CHECK or IHAVE).  The function receives a single argument, the
-message ID, and like filter_art() should return an empty string to accept
-the article or an error string to refuse the article.  This function is
-called before any history lookups and for every article offered to innd
-with CHECK or IHAVE (before the actual article is sent).  Accordingly, the
-message ID is the only information it has about the article (the %hdr hash
-will be empty).  This code would sit in a performance-critical hot path in
-a typical server, and therefore should be as fast as possible, but it can
-do things like refuse articles from certain hosts or cancels for already
-rejected articles (if they follow the $alz convention) without having to
-take the network bandwidth hit of accepting the entire article first.
-
-Note that you cannot rely on filter_messageid() being called for every
-incoming article; articles sent via TAKETHIS without an earlier CHECK will
-never pass through filter_messageid() and will only go through
-filter_art().
-
-Finally, whenever ctlinnd throttle, ctlinnd pause, or ctlinnd go is run,
-the Perl function filter_mode() is called if it exists.  It receives no
-arguments and returns no value, but it has access to a global hash %mode
-that contains three values:
-
-    Mode       The current server mode (throttled, paused, or running)
-    NewMode    The new mode the server is going to
-    reason     The reason that was given to ctlinnd
-
-One possible use for this function is to save filter state across a
-restart of innd.  There isn't any Perl function which is called when INN
-shuts down, but using filter_mode() the Perl filter can dump it's state to
-disk whenever INN is throttled.  Then, if the news administrator follows
-the strongly recommended shutdown procedure of throttling the server
-before shutting it down, the filter state will be safely saved to disk and
-can be reloaded when innd restarts (possibly by F<startup_innd.pl>).
-
-The state of the Perl interpretor in which all of these Perl functions run
-is preserved over the lifetime of innd.  In other words, it's permissible for
-the Perl code to create its own global Perl variables, data structures,
-saved state, and the like, and all of that will be available to
-filter_art() and filter_messageid() each time they're called.  The only
-variable INN fiddles with (or pays any attention to at all) is %hdr, which
-is cleared after each call to filter_art().
-
-Perl filtering can be turned off with C<ctlinnd perl n> and back on again
-with C<ctlinnd perl y>.  Perl filtering is turned off automatically if
-loading of the filter fails or if the filter code returns any sort of a
-fatal error (either due to Perl itself or due to a C<die> in the Perl code).
-
-=head1 Supported innd Callbacks
-
-innd makes seven functions available to any of its embedded Perl code.
-Those are:
-
-=over 4
-
-=item INN::addhist(I<messageid>, I<arrival>, I<articledate>, I<expire>, I<paths>)
-
-Adds I<messageid> to the history database.  All of the arguments except
-the first one are optional; the times default to the current time and the
-paths field defaults to the empty string.  (For those unfamiliar with the
-fields of a history(5) database entry, the I<arrival> is normally the time at
-which the server accepts the article, the I<articledate> is from the Date
-header of the article, the I<expire> is from the Expires header of the
-article, and the I<paths> field is the storage API token.  All three times
-as measured as a time_t since the epoch.)  Returns true on success, false
-otherwise.
-
-=item INN::article(I<messageid>)
-
-Returns the full article (as a simple string) identified by I<messageid>,
-or undef if it isn't found.  Each line will end with a simple \n, but
-leading periods may still be doubled if the article is stored in wire
-format.
-
-=item INN::cancel(I<messageid>)
-
-Cancels I<messageid>.  (This is equivalent to C<ctlinnd cancel>; it
-cancels the message on the local server, but doesn't post a cancel message
-or do anything else that affects anything other than the local server.)
-Returns true on success, false otherwise.
-
-=item INN::filesfor(I<messageid>)
-
-Returns the I<paths> field of the history entry for the given
-I<messageid>.  This will be the storage API token for the message.  If
-I<messageid> isn't found in the history database, returns undef.
-
-=item INN::havehist(I<messageid>)
-
-Looks up I<messageid> in the history database and returns true if it's
-found, false otherwise.
-
-=item INN::head(I<messageid>)
-
-Returns the header (as a simple string) of the article identified by
-I<messageid>, or undef if it isn't found.  Each line will end with a
-simple \n (in other words, regardless of the format of article storage,
-the returned string won't be in wire format).
-
-=item INN::newsgroup(I<newsgroup>)
-
-Returns the status of I<newsgroup> (the last field of the active file
-entry for that newsgroup).  See active(5) for a description of the
-possible values and their meanings (the most common are "y" for an
-unmoderated group and "m" for a moderated group).  If I<newsgroup> isn't
-in the active file, returns undef.
-
-=back
-
-These functions can only be used from inside the innd Perl filter; they're
-not available in the nnrpd filter.
-
-=head1 Common Callbacks
-
-The following additional function is available from inside filters
-embedded in innd, and is also available from filters embedded in nnrpd
-(see below):
-
-=over 4
-
-=item INN::syslog(level, message)
-
-Logs a message via syslog(2).  This is quite a bit more reliable and
-portable than trying to use Sys::Syslog from inside the Perl filter.  Only
-the first character of the level argument matters; the valid letters are
-the first letters of ALERT, CRIT, ERR, WARNING, NOTICE, INFO, and DEBUG
-(case-insensitive) and specify the priority at which the message is
-logged.  If a level that doesn't match any of those levels is given, the
-default priority level is LOG_NOTICE.  The second argument is the message
-to log; it will be prefixed by "filter: " and logged to syslog with
-facility LOG_NEWS.
-
-=back
-
-=head1 The nnrpd Posting Filter
-
-Whenever Perl support is needed in nnrpd, it first loads the file
-_PATH_PERL_FILTER_NNRPD (defined in F<include/paths.h>, by default
-F<filter_nnrpd.pl>).  This file must be located in the directory
-specified by pathfilter in F<inn.conf> (F</usr/local/news/bin/filter>
-by default).  The default directory for filter code can be specified
-at configure time by giving the flag B<--with-filter-dir> to
-configure.
-
-If F<filter_nnrpd.pl> loads successfully and defines the Perl function
-filter_post(), Perl filtering is turned on.  Otherwise, it's turned off.
-If filter_post() ever returns a fatal error (either from Perl or from a
-C<die> in the Perl code), Perl filtering is turned off for the life of that
-nnrpd process and any further posts made during that session won't go
-through the filter.
-
-While Perl filtering is on, every article received by nnrpd via the POST
-command is passed to the filter_post() Perl function before it is passed
-to INN (or mailed to the moderator of a moderated newsgroup).  If
-filter_post() returns an empty string (''), the article is accepted and
-normal processing of it continues.  Otherwise, the article is rejected and
-the string returned by filter_post() is returned to the client as the
-error message (with some exceptions; see below).
-
-filter_post() has access to a global hash %hdr, which contains all of the
-headers of the article.  (Unlike the innd Perl filter, %hdr for the nnrpd
-Perl filter contains *all* of the headers, not just the standard ones.  If
-any of the headers are duplicated, though, %hdr will contain only the
-value of the last occurance of the header.  nnrpd will reject the
-article before the filter runs if any of the standard headers are
-duplicated.)  It also has access to the full body of the article in the
-variable $body, and if the poster authenticated via AUTHINFO (or if either
-Perl authentication or a readers.conf authentication method is used and
-produces user information), it has access to the authenticated username of
-the poster in the variable $user.
-
-Unlike the innd Perl filter, the nnrpd Perl filter can modify the %hdr
-hash.  In fact, if the Perl variable $modify_headers is set to true after
-filter_post() returns, the contents of the %hdr hash will be written back
-to the article replacing the original headers.  filter_post() can
-therefore make any modifications it wishes to the headers and those
-modifications will be reflected in the article as it's finally posted.
-The article body cannot be modified in this way; any changes to $body will
-just be ignored.
-
-Be careful when using the ability to modify headers.  filter_post() runs
-after all the normal consistency checks on the headers and after server
-supplied headers (like Message-ID: and Date:) are filled in.  Deleting
-required headers or modifying headers that need to follow a strict format
-can result in nnrpd trying to post nonsense articles (which will probably
-then be rejected by innd).  If $modify_headers is set, I<everything> in
-the %hdr hash is taken to be article headers and added to the article.
-
-If filter_post() returns something other than the empty string, this
-message is normally returned to the client as an error.  There are two
-exceptions:  If the string returned begins with "DROP", the post will be
-silently discarded and success returned to the client.  If the string
-begins with "SPOOL", success is returned to the client, but the post is
-saved in a directory named "spam" under the directory specified by
-pathincoming in F<inn.conf> (in a directory named "spam/mod" if the post
-is to a moderated group).  This is intended to allow manual inspection of
-the suspect messages; if they should be posted, they can be manually moved
-out of the subdirectory to the directory specified by pathincoming in
-F<inn.conf>, where they can be posted by running C<rnews -U>.  If you use
-this functionality, make sure those directories exist.
-
-=head1 Changes to Perl Authentication Support for nnrpd
-
-The old authentication functionality has been combined with the new
-readers.conf mechanism by Erik Klavon <erik@eriq.org>; bug reports
-should however go to inn-bugs@isc.org, not Erik.
-
-The remainder of this section is an introduction to the new mechanism
-(which uses the perl_auth: and perl_access: F<readers.conf> parameters)
-with porting/migration suggestions for people familiar with the old
-mechanism (identifiable by the nnrpperlauth: parameter in F<inn.conf>).
-
-Other people should skip this section.
-
-The perl_auth parameter allows the use of Perl to authenticate a user.
-Scripts (like those from the old mechanism) are listed in F<readers.conf>
-using perl_auth in the same manner other authenticators are using auth:
-
-    perl_auth: "/path/to/script/auth1.pl"
-
-The file given as argument to perl_auth should contain the same
-procedures as before. The global hash %attributes remains the same,
-except for the removal of the "type" entry which is no longer needed
-in this modification and the addition of several new entries (port,
-intipaddr, intport) described below. The return array now only
-contains either two or three elements, the first of which is the NNTP
-return code. The second is an error string which is passed to the
-client if the error code indicates that the authentication attempt has
-failed. This allows a specific error message to be generated by the
-perl script in place of "Authentication failed". An optional third
-return element if present will be used to match the connection with
-the users: parameter in access groups and will also be the username
-logged. If this element is absent, the username supplied by the client
-during authentication will be used as was the previous behavior.
-
-The perl_access parameter (described below) is also new; it allows the
-dynamic generation of an access group for an incoming connection using
-a Perl script.  If a connection matches an auth group which has a
-perl_access parameter, all access groups in readers.conf are ignored;
-instead the procedure described below is used to generate an access group.
-This concept is due to Jeffrey M. Vinocur.
-
-The new functionality should provide all of the existing capabilities
-of the Perl hook, in combination with the flexibility of readers.conf
-and the use of other authentication and resolving programs.  To use
-Perl authentication code that predates the readers.conf mechanism, you
-would need to modify the code slightly (see below for the new
-specification) and supply a simple readers.conf file.  If you don't want
-to modify your code, the samples directory has F<nnrpd_auth_wrapper.pl>
-and F<nnrpd_access_wrapper.pl> which should allow you to use your old
-code without needing to change it.
-
-However, before trying to use your old Perl code, you may want to
-consider replacing it entirely with non-Perl authentication.  (With
-readers.conf and the regular authenticator and resolver programs, much
-of what once required Perl can be done directly.)  Even if the
-functionality is not available directly, you may wish to write a new
-authenticator or resolver (which can be done in whatever language you
-prefer to work in).
-
-
-=head1 Perl Authentication Support for nnrpd
-
-Support for authentication via Perl is provided in nnrpd by the
-inclusion of a perl_auth: parameter in a F<readers.conf> auth
-group. perl_auth: works exactly like the auth: parameter in
-F<readers.conf>, except that it calls the script given as argument using
-the Perl hook rather then treating it as an external program.
-
-If the processing of readers.conf requires that a perl_auth: statement
-be used for authentication, Perl is loaded (if it has yet to be) and
-the file given as argument to the perl_auth: parameter is loaded as
-well. If a Perl function auth_init() is defined by that file, it is called
-immediately after the file is loaded.  It takes no arguments and returns
-nothing.
-
-Provided the file loads without errors, auth_init() (if present) runs
-without fatal errors, and a Perl function authenticate() is defined,
-authenticate() will then be called. authenticate() takes no arguments,
-but it has access to a global hash %attributes which contains
-information about the connection as follows: C<$attributes{hostname}>
-will contain the hostname (or the IP address if it doesn't resolve) of
-the client machine, C<$attributes{ipaddress}> will contain its IP
-address (as a string), C<$attributes{port}> will contain the client
-port (as an integer), C<$attributes{interface}> contains the hostname
-of the interface the client connected on, C<$attributes{intipaddr}>
-contains the IP address (as a string) of the interface the client
-connected on, C<$attributes{intport}> contains the port (as an
-integer) on the interface the client connected on,
-C<$attributes{username}> will contain the provided username and
-C<$attributes{password}> the password.
-
-authenticate() should return a two or three element array.  The first
-element is the NNTP response code to return to the client, the second
-element is an error string which is passed to the client if the
-response code indicates that the authentication attempt has failed. An
-optional third return element if present will be used to match the
-connection with the users: parameter in access groups and will also be
-the username logged. If this element is absent, the username supplied
-by the client during authentication will be used for matching and
-logging.
-
-The NNTP response code should probably be either 281 (authentication
-successful) or 502 (authentication unsuccessful).  If the code
-returned is anything other than 281, nnrpd will print an
-authentication error message and drop the connection and exit.
-
-If authenticate() dies (either due to a Perl error or due to calling die),
-or if it returns anything other than the two or three element array
-described above, an internal error will be reported to the client, the
-exact error will be logged to syslog, and nnrpd will drop the
-connection and exit.
-
-
-=head1 Dynamic Generation of Access Groups
-
-A Perl script may be used to dynamically generate an access group
-which is then used to determine the access rights of the client. This
-occurs whenever the perl_access: is specified in an auth group which
-has successfully matched the client. Only one perl_access:
-statement is allowed in an auth group. This parameter should not be
-mixed with a python_access: statement in the same auth group.
-
-When a perl_access: parameter is encountered, Perl is loaded (if it
-has yet to be) and the file given as argument is loaded as
-well. Provided the file loads without errors, and a Perl function
-access() is defined, access() will then be called. access() takes no
-arguments, but it has access to a global hash %attributes which
-contains information about the connection as follows:
-C<$attributes{hostname}> will contain the hostname (or the IP address
-if it doesn't resolve) of the client machine,
-C<$attributes{ipaddress}> will contain its IP address (as a string),
-C<$attributes{port}> will contain the client port (as an integer),
-C<$attributes{interface}> contains the hostname of the interface the
-client connected on, C<$attributes{intipaddr}> contains the IP address
-(as a string) of the interface the client connected on,
-C<$attributes{intport}> contains the port (as an integer) on the
-interface the client connected on, C<$attributes{username}> will
-contain the provided username and domain (in username@domain form).
-
-access() returns a hash, containing the desired access parameters and
-values.  Here is an untested example showing how to dynamically generate a
-list of newsgroups based on the client's username and domain.
-
-     my %hosts = ( "example.com" => "example.*", "isc.org" => "isc.*" );
-
-     sub access {
-        %return_hash = (
-           "max_rate" => "10000",
-          "addnntppostinghost" => "true",
-     #     ...
-        );
-        if( defined $attributes{username} &&
-            $attributes{username} =~ /.*@(.*)/ )
-        {
-           $return_hash{"virtualhost"} = "true";
-          $return_hash{"path"} = $1;
-           $return_hash{"newsgroups"} = $hosts{$1};
-        } else {
-           $return_hash{"read"} = "*";
-          $return_hash{"post"} = "local.*"
-        }
-        return %return_hash;
-     }
-
-Note that both the keys and values are quoted strings. These values
-are to be returned to a C program and must be quoted strings. For
-values containing one or more spaces, it is not necessary to include
-extra quotes inside the string.
-
-While you may include the users: parameter in a dynamically generated
-access group, some care should be taken (unless your pattern is just
-* which is equivalent to leaving the parameter out). The group created
-with the values returned from the Perl script is the only one
-considered when nnrpd attempts to find an access group matching the
-connection. If a users: parameter is included and it doesn't match the
-connection, then the client will be denied access since there are no
-other access groups which could match the connection.
-
-If access() dies (either due to a Perl error or due to calling die),
-or if it returns anything other than a hash as described
-above, an internal error will be reported to the client, the exact error
-will be logged to syslog, and nnrpd will drop the connection and exit.
-
-=head1 Notes on Writing Embedded Perl
-
-All Perl evaluation is done inside an implicit eval block, so calling die
-in Perl code will not kill the innd or nnrpd process.  Neither will Perl
-errors (such as syntax errors).  However, such errors will have negative
-effects (fatal errors in the innd or nnrpd filter will cause filtering to
-be disabled, and fatal errors in the nnrpd authentication code will cause
-the client connection to be terminated).
-
-Calling exit directly, however, *will* kill the innd or nnrpd process, so
-don't do that.  Similarly, you probably don't want to call fork (or any
-other function that results in a fork such as system, IPC::Open3::open3(),
-or any use of backticks) since there are possibly unflushed buffers that
-could get flushed twice, lots of open state that may not get closed
-properly, and innumerable other potential problems.  In general, be aware
-that all Perl code is running inside a large and complicated C program,
-and Perl code that impacts the process as a whole is best avoided.
-
-You can use print and warn inside Perl code to send output to STDOUT or
-STDERR, but you probably shouldn't.  Instead, open a log file and print to
-it instead (or, in the innd filter, use INN::syslog() to write messages
-via syslog like the rest of INN).  If you write to STDOUT or STDERR, where
-that data will go depends on where the filter is running; inside innd, it
-will go to the news log or the errlog, and inside nnrpd it will probably
-go nowhere but could go to the client.  The nnrpd filter takes some steps
-to try to keep output from going across the network connection to the
-client (which would probably result in a very confused client), but best
-not to take the chance.
-
-For similar reasons, try to make your Perl code -w clean, since Perl
-warnings are written to STDERR.  (INN won't run your code under -w, but
-better safe than sorry, and some versions of Perl have some mandatory
-warnings you can't turn off.)
-
-You *can* use modules in your Perl code, just like you would in an
-ordinary Perl script.  You can even use modules that dynamically load C
-code.  Just make sure that none of the modules you use go off behind your
-back to do any of the things above that are best avoided.
-
-Whenever you make any modifications to the Perl code, and particularly
-before starting INN or reloading filter.perl with new code, you should run
-perl -wc on the file.  This will at least make sure you don't have any
-glaring syntax errors.  Remember, if there are errors in your code,
-filtering will be disabled, which could mean that posts you really wanted
-to reject will leak through and authentication of readers may be totally
-broken.
-
-The samples directory has example F<startup_innd.pl>, F<filter_innd.pl>,
-F<filter_nnrpd.pl>, and F<nnrpd_auth.pl> files that contain some
-simplistic examples.  Look them over as a starting point when writing your
-own.
-
-=head1 Available Packages
-
-This is an unofficial list of known filtering packages at the time of
-publication.  This is not an endorsement of these filters by the ISC or
-the INN developers, but is included as assistance in locating packages
-which make use of this filter mechanism.
-
-  CleanFeed               Jeremy Nixon <jeremy@exit109.com>
-  <URL:http://www.exit109.com/~jeremy/news/cleanfeed.html>
-        A spam filter catching excessive multi-posting and a host of
-        other things.  Uses filter_innd.pl exclusively, requires the MD5
-        Perl module.  Probably the most popular and widely-used Perl
-        filter around.
-
-  Usenet II Filter        Edward S. Marshall <emarshal@xnet.com>
-  <URL:http://www.xnet.com/~emarshal/inn/filter_nnrpd.pl>
-        Checks for "soundness" according to Usenet II guidelines in the
-        net.* hierarchy.  Designed to use filter_nnrpd.pl.
-
-  News Gizmo              Aidan Cully <aidan@panix.com>
-  <URL:http://www.panix.com/gizmo/>
-        A posting filter for helping a site enforce Usenet-II soundness,
-        and for quotaing the number of messages any user can post to
-        Usenet daily.
diff --git a/doc/pod/hook-python.pod b/doc/pod/hook-python.pod
deleted file mode 100644 (file)
index da59948..0000000
+++ /dev/null
@@ -1,657 +0,0 @@
-=head1 INN Python Filtering and Authentication Support
-
-This file documents INN's built-in optional support for Python article
-filtering.  It is patterned after the Perl and (now obsolete) TCL hooks
-previously added by Bob Heiney and Christophe Wolfhugel.
-
-For this filter to work successfully, you will need to have at least
-S<Python 1.5.2> installed.  You can obtain it from L<http://www.python.org/>.
-
-The B<innd> Python interface and the original Python filtering documentation
-were written by Greg Andruk (nee Fluffy) <gerglery@usa.net>.  The Python
-authentication and authorization support for B<nnrpd> as well as the original
-documentation for it were written by Ilya Etingof <ilya@glas.net> in
-December 1999.
-
-=head1 Installation
-
-Once you have built and installed Python, you can cause INN to use it by
-adding the B<--with-python> switch to your C<configure> command.  You will
-need to have all the headers and libraries required for embedding Python
-into INN; they can be found in Python development packages, which include
-header files and static libraries.
-
-You will then be able to use Python authentication, dynamic access group
-generation and dynamic access control support in B<nnrpd> along with
-filtering support in B<innd>.
-
-See the ctlinnd(8) manual page to learn how to enable, disable and reload
-Python filters on a running server (especially C<ctlinnd mode>,
-C<ctlinnd python y|n> and C<ctlinnd reload filter.python 'reason'>).
-
-Also, see the F<filter_innd.py>, F<nnrpd_auth.py>, F<nnrpd_access.py>
-and F<nnrpd_dynamic.py> samples in your filters directory for
-a demonstration of how to get all this working.
-
-=head1 Writing an B<innd> Filter
-
-=head2 Introduction
-
-You need to create a F<filter_innd.py> module in INN's filter directory
-(see the I<pathfilter> setting in F<inn.conf>).  A heavily-commented sample
-is provided; you can use it as a template for your own filter.  There is
-also an F<INN.py> module there which is not actually used by INN; it is
-there so you can test your module interactively.
-
-First, define a class containing the methods you want to provide to B<innd>.
-Methods B<innd> will use if present are:
-
-=over 4
-
-=item __init__(I<self>)
-
-Not explicitly called by B<innd>, but will run whenever the filter module is
-(re)loaded.  This is a good place to initialize constants or pick up where
-C<filter_before_reload> or C<filter_close> left off.
-
-=item filter_before_reload(I<self>)
-
-This will execute any time a C<ctlinnd reload all 'reason'> or C<ctlinnd reload
-filter.python 'reason'> command is issued.  You can use it to save statistics or
-reports for use after reloading.
-
-=item filter_close(I<self>)
-
-This will run when a C<ctlinnd shutdown 'reason'> command is received.
-
-=item filter_art(I<self>, I<art>)
-
-I<art> is a dictionary containing an article's headers and body.  This method
-is called every time B<innd> receives an article.  The following can be
-defined:
-
-    Also-Control, Approved, Bytes, Cancel-Key, Cancel-Lock,
-    Content-Base, Content-Disposition, Content-Transfer-Encoding,
-    Content-Type, Control, Date, Date-Received, Distribution, Expires,
-    Face, Followup-To, From, In-Reply-To, Injection-Date, Injection-Info,
-    Keywords, Lines, List-ID, Message-ID, MIME-Version, Newsgroups,
-    NNTP-Posting-Date, NNTP-Posting-Host, Organization, Originator,
-    Path, Posted, Posting-Version, Received, References, Relay-Version,
-    Reply-To, Sender, Subject, Supersedes, User-Agent,
-    X-Auth, X-Canceled-By, X-Cancelled-By, X-Complaints-To, X-Face,
-    X-HTTP-UserAgent, X-HTTP-Via, X-Mailer, X-Modbot, X-Modtrace,
-    X-Newsposter, X-Newsreader, X-No-Archive, X-Original-Message-ID,
-    X-Original-Trace, X-Originating-IP, X-PGP-Key, X-PGP-Sig,
-    X-Poster-Trace, X-Postfilter, X-Proxy-User, X-Submissions-To,
-    X-Trace, X-Usenet-Provider, Xref, __BODY__, __LINES__.
-
-Note that all the above values are as they arrived, not modified
-by your INN (especially, the Xref: header, if present, is the one
-of the remote site which sent you the article, and not yours).
-
-These values will be buffer objects holding the contents of the
-same named article headers, except for the special C<__BODY__> and C<__LINES__>
-items.  Items not present in the article will contain C<None>.
-
-C<art('__BODY__')> is a buffer object containing the article's entire body, and
-C<art('__LINES__')> is an int holding B<innd>'s reckoning of the number of lines
-in the article.  All the other elements will be buffers with the contents
-of the same-named article headers.
-
-The Newsgroups: header of the article is accessible inside the Python
-filter as C<art['Newsgroups']>.
-
-If you want to accept an article, return C<None> or an empty string.  To
-reject, return a non-empty string.  The rejection strings will be shown to
-local clients and your peers, so keep that in mind when phrasing your
-rejection responses.
-
-=item filter_messageid(I<self>, I<msgid>)
-
-I<msgid> is a buffer object containing the ID of an article being offered by
-IHAVE or CHECK.  Like with C<filter_art>, the message will be refused if
-you return a non-empty string.  If you use this feature, keep it light
-because it is called at a rather busy place in B<innd>'s main loop.  Also, do
-not rely on this function alone to reject by ID; you should repeat the
-tests in C<filter_art> to catch articles sent with TAKETHIS but no CHECK.
-
-=item filter_mode(I<self>, I<oldmode>, I<newmode>, I<reason>)
-
-When the operator issues a B<ctlinnd> C<pause>, C<throttle>, C<go>, C<shutdown>
-or C<xexec> command, this function can be used to do something sensible in accordance
-with the state change.  Stamp a log file, save your state on throttle,
-etc.  I<oldmode> and I<newmode> will be strings containing one of the values in
-(C<running>, C<throttled>, C<paused>, C<shutdown>, C<unknown>).  I<oldmode> is
-the state B<innd> was in before B<ctlinnd> was run, I<newmode> is the state B<innd>
-will be in after the command finishes.  I<reason> is the comment string
-provided on the B<ctlinnd> command line.
-
-=back
-
-=head2 How to Use these Methods with B<innd>
-
-To register your methods with B<innd>, you need to create an instance of your
-class, import the built-in INN module, and pass the instance to
-C<INN.set_filter_hook>.  For example:
-
-    class Filter:
-        def filter_art(self, art):
-            ...
-            blah blah
-            ...
-
-        def filter_messageid(self, id):
-            ...
-            yadda yadda
-            ...
-
-    import INN
-    myfilter = Filter()
-    INN.set_filter_hook(myfilter)
-
-When writing and testing your Python filter, don't be afraid to make use
-of C<try:>/C<except:> and the provided C<INN.syslog> function.  stdout and stderr
-will be disabled, so your filter will die silently otherwise.
-
-Also, remember to try importing your module interactively before loading
-it, to ensure there are no obvious errors.  One typo can ruin your whole
-filter.  A dummy F<INN.py> module is provided to facilitate testing outside
-the server.  To test, change into your filter directory and use a command
-like:
-
-    python -ic 'import INN, filter_innd'
-
-You can define as many or few of the methods listed above as you want in
-your filter class (it is fine to define more methods for your own use; B<innd>
-will not be using them but your filter can).  If you I<do> define the above
-methods, GET THE PARAMETER COUNTS RIGHT.  There are checks in B<innd> to see
-whether the methods exist and are callable, but if you define one and get the
-parameter counts wrong, B<innd> WILL DIE.  You have been warned.  Be careful
-with your return values, too.  The C<filter_art> and C<filter_messageid>
-methods have to return strings, or C<None>.  If you return something like an
-int, B<innd> will I<not> be happy.
-
-=head2 A Note regarding Buffer Objects
-
-Buffer objects are cousins of strings, new in S<Python 1.5.2>.  Using buffer
-objects may take some getting used to, but we can create buffers much faster
-and with less memory than strings.
-
-For most of the operations you will perform in filters (like C<re.search>,
-C<string.find>, C<md5.digest>) you can treat buffers just like strings, but
-there are a few important differences you should know about:
-
-    # Make a string and two buffers.
-    s = "abc"
-    b = buffer("def")
-    bs = buffer("abc")
-
-    s == bs          # - This is false because the types differ...
-    buffer(s) == bs  # - ...but this is true, the types now agree.
-    s == str(bs)     # - This is also true, but buffer() is faster.
-    s[:2] == bs[:2]  # - True.  Buffer slices are strings.
-
-    # While most string methods will take either a buffer or a string,
-    # string.join (in the string module) insists on using only strings.
-    import string
-    string.join([str(b), s], '.')  # Returns 'def.abc'.
-    '.'.join([str(b), s])          # Returns 'def.abc' too.
-    '.'.join([b, s])               # This raises a TypeError.
-
-    e = s + b                      # This raises a TypeError, but...
-
-    # ...these two both return the string 'abcdef'.  The first one
-    # is faster -- choose buffer() over str() whenever you can.
-    e = buffer(s) + b
-    f = s + str(b)
-
-    g = b + '>'                    # This is legal, returns the string 'def>'.
-
-=head2 Functions Supplied by the Built-in B<innd> Module
-
-Besides C<INN.set_filter_hook> which is used to register your methods
-with B<innd> as it has already been explained above, the following functions
-are available from Python scripts:
-
-=over 4
-
-=item addhist(I<message-id>)
-
-=item article(I<message-id>)
-
-=item cancel(I<message-id>)
-
-=item havehist(I<message-id>)
-
-=item hashstring(I<string>)
-
-=item head(I<message-id>)
-
-=item newsgroup(I<groupname>)
-
-=item syslog(I<level>, I<message>)
-
-=back
-
-Therefore, not only can B<innd> use Python, but your filter can use some of
-B<innd>'s features too.  Here is some sample Python code to show what you get
-with the previously listed functions.
-
-    import INN
-
-    # Python's native syslog module isn't compiled in by default,
-    # so the INN module provides a replacement.  The first parameter
-    # tells the Unix syslogger what severity to use; you can
-    # abbreviate down to one letter and it's case insensitive.
-    # Available levels are (in increasing levels of seriousness)
-    # Debug, Info, Notice, Warning, Err, Crit, and Alert.  (If you
-    # provide any other string, it will be defaulted to Notice.)  The
-    # second parameter is the message text.  The syslog entries will
-    # go to the same log files innd itself uses, with a 'python:'
-    # prefix.
-    syslog('warning', 'I will not buy this record.  It is scratched.')
-    animals = 'eels'
-    vehicle = 'hovercraft'
-    syslog('N', 'My %s is full of %s.' % (vehicle, animals))
-
-    # Let's cancel an article!  This only deletes the message on the
-    # local server; it doesn't send out a control message or anything
-    # scary like that.  Returns 1 if successful, else 0.
-    if INN.cancel('<meow$123.456@solvangpastries.edu>'):
-        cancelled = "yup"
-    else:
-        cancelled = "nope"
-
-    # Check if a given message is in history.  This doesn't
-    # necessarily mean the article is on your spool; cancelled and
-    # expired articles hang around in history for a while, and
-    # rejected articles will be in there if you have enabled
-    # remembertrash in inn.conf.  Returns 1 if found, else 0.
-    if INN.havehist('<z456$789.abc@isc.org>'):
-        comment = "*yawn* I've already seen this article."
-    else:
-        comment = 'Mmm, fresh news.'
-
-    # Here we are running a local spam filter, so why eat all those
-    # cancels?  We can add fake entries to history so they'll get
-    # refused.  Returns 1 on success, 0 on failure.
-    cancelled_id = buffer('<meow$123.456@isc.org>')
-    if INN.addhist("<cancel." + cancelled_id[1:]):
-        thought = "Eat my dust, roadkill!"
-    else:
-        thought = "Darn, someone beat me to it."
-
-    # We can look at the header or all of an article already on spool,
-    # too.  Might be useful for long-memory despamming or
-    # authentication things.  Each is returned (if present) as a
-    # string object; otherwise you'll end up with an empty string.
-    artbody = INN.article('<foo$bar.baz@bungmunch.edu>')
-    artheader = INN.head('<foo$bar.baz@bungmunch.edu>')
-
-    # As we can compute a hash digest for a string, we can obtain one
-    # for artbody.  It might be of help to detect spam.
-    digest = INN.hashstring(artbody)
-
-    # Finally, do you want to see if a given newsgroup is moderated or
-    # whatever?  INN.newsgroup returns the last field of a group's
-    # entry in active as a string.
-    froupflag = INN.newsgroup('alt.fan.karl-malden.nose')
-    if froupflag == '':
-        moderated = 'no such newsgroup'
-    elif froupflag == 'y':
-        moderated = "nope"
-    elif froupflag == 'm':
-        moderated = "yep"
-    else:
-        moderated = "something else"
-
-=head1 Writing an B<nnrpd> Filter
-
-=head2 Changes to Python Authentication and Access Control Support for B<nnrpd>
-
-The old authentication and access control functionality has been
-combined with the new F<readers.conf> mechanism by Erik Klavon
-<erik@eriq.org>; bug reports should however go to <inn-bugs@isc.org>,
-not Erik.
-
-The remainder of this section is an introduction to the new mechanism
-(which uses the I<python_auth>, I<python_access>, and I<python_dynamic>
-F<readers.conf> parameters) with porting/migration suggestions for
-people familiar with the old mechanism (identifiable by the now
-deprecated I<nnrpperlauth> parameter in F<inn.conf>).
-
-Other people should skip this section.
-
-The I<python_auth> parameter allows the use of Python to authenticate a
-user.  Authentication scripts (like those from the old mechanism) are
-listed in F<readers.conf> using I<python_auth> in the same manner other
-authenticators are using I<auth>:
-
-    python_auth: "nnrpd_auth"
-
-It uses the script named F<nnrpd_auth.py> (note that C<.py> is not present
-in the I<python_auth> value).
-
-Scripts should be placed as before in the filter directory (see the
-I<pathfilter> setting in F<inn.conf>).  The new hook method C<authen_init>
-takes no arguments and its return value is ignored; its purpose is to
-provide a means for authentication specific initialization.  The hook
-method C<authen_close> is the more specific analogue to the old C<close>
-method.  These two method hooks are not required, contrary to
-C<authenticate>, the main method.
-
-The argument dictionary passed to C<authenticate> remains the same,
-except for the removal of the I<type> entry which is no longer needed
-in this modification and the addition of several new entries (I<port>,
-I<intipaddr>, I<intport>) described below.  The return tuple now only
-contains either two or three elements, the first of which is the NNTP
-response code.  The second is an error string which is passed to the
-client if the response code indicates that the authentication attempt
-has failed.  This allows a specific error message to be generated by
-the Python script in place of the generic message C<Authentication
-failed>.  An optional third return element, if present, will be used to
-match the connection with the I<user> parameter in access groups and
-will also be the username logged.  If this element is absent, the
-username supplied by the client during authentication will be used, as
-was the previous behaviour.
-
-The I<python_access> parameter (described below) is new; it allows the
-dynamic generation of an access group of an incoming connection using
-a Python script.  If a connection matches an auth group which has a
-I<python_access> parameter, all access groups in F<readers.conf> are
-ignored; instead the procedure described below is used to generate an
-access group.  This concept is due to Jeffrey S<M. Vinocur> and you can
-add this line to F<readers.conf> in order to use the F<nnrpd_access.py>
-Python script in I<pathfilter>:
-
-    python_access: "nnrpd_access"
-
-In the old implementation, the authorization method allowed for access
-control on a per-group basis.  That functionality is preserved in the
-new implementation by the inclusion of the I<python_dynamic> parameter in
-F<readers.conf>.  The only change is the corresponding method name of
-C<dynamic> as opposed to C<authorize>.  Additionally, the associated
-optional housekeeping methods C<dynamic_init> and C<dynamic_close>
-may be implemented if needed.  In order to use F<nnrpd_dynamic.py> in
-I<pathfilter>, you can add this line to F<readers.conf>:
-
-    python_dynamic: "nnrpd_dynamic"
-
-This new implementation should provide all of the previous
-capabilities of the Python hooks, in combination with the flexibility
-of F<readers.conf> and the use of other authentication and resolving
-programs (including the Perl hooks!).  To use Python code that predates
-the new mechanism, you would need to modify the code slightly (see
-below for the new specification) and supply a simple F<readers.conf>
-file.  If you do not want to modify your code, the sample directory has
-F<nnrpd_auth_wrapper.py>, F<nnrpd_access_wrapper.py> and
-F<nnrpd_dynamic_wrapper.py> which should allow you to use your old
-code without needing to change it.
-
-However, before trying to use your old Python code, you may want to
-consider replacing it entirely with non-Python authentication.  (With
-F<readers.conf> and the regular authenticator and resolver programs, much
-of what once required Python can be done directly.)  Even if the
-functionality is not available directly, you may wish to write a new
-authenticator or resolver (which can be done in whatever language you
-prefer).
-
-=head2 Python Authentication Support for B<nnrpd>
-
-Support for authentication via Python is provided in B<nnrpd> by the
-inclusion of a I<python_auth> parameter in a F<readers.conf> auth
-group.  I<python_auth> works exactly like the I<auth> parameter in
-F<readers.conf>, except that it calls the script given as argument
-using the Python hook rather then treating it as an external
-program.  Multiple, mixed use of I<python_auth> with other I<auth>
-statements including I<perl_auth> is permitted.  Each I<auth> statement
-will be tried in the order they appear in the auth group until either
-one succeeds or all are exhausted.
-
-If the processing of F<readers.conf> requires that a I<python_auth>
-statement be used for authentication, Python is loaded (if it has yet
-to be) and the file given as argument to the I<python_auth> parameter is
-loaded as well (do not include the C<.py> extension of this file in
-the value of I<python_auth>).  If a Python object with a method
-C<authen_init> is hooked in during the loading of that file, then
-that method is called immediately after the file is loaded.  If no
-errors have occurred, the method C<authenticate> is called.  Depending
-on the NNTP response code returned by C<authenticate>, the authentication
-hook either succeeds or fails, after which the processing of the
-auth group continues as usual.  When the connection with the client
-is closed, the method C<authen_close> is called if it exists.
-
-=head2 Dynamic Generation of Access Groups
-
-A Python script may be used to dynamically generate an access group
-which is then used to determine the access rights of the client.  This
-occurs whenever the I<python_access> parameter is specified in an auth group
-which has successfully matched the client.  Only one I<python_access>
-statement is allowed in an auth group.  This parameter should not be
-mixed with a I<perl_access> statement in the same auth group.
-
-When a I<python_access> parameter is encountered, Python is loaded (if
-it has yet to be) and the file given as argument is loaded as well (do not
-include the C<.py> extension of this file in the value of I<python_access>).
-If a Python object with a method C<access_init> is hooked in during the
-loading of that file, then that method is called immediately after the
-file is loaded.  If no errors have occurred, the method C<access> is
-called.  The dictionary returned by C<access> is used to generate an
-access group that is then used to determine the access rights of the
-client.  When the connection with the client is closed, the method
-C<access_close> is called, if it exists.
-
-While you may include the I<users> parameter in a dynamically generated
-access group, some care should be taken (unless your pattern is just
-C<*> which is equivalent to leaving the parameter out).  The group created
-with the values returned from the Python script is the only one
-considered when B<nnrpd> attempts to find an access group matching the
-connection.  If a I<users> parameter is included and it does not match the
-connection, then the client will be denied access since there are no
-other access groups which could match the connection.
-
-=head2 Dynamic Access Control
-
-If you need to have access control rules applied immediately without
-having to restart all the B<nnrpd> processes, you may apply access
-control on a per newsgroup basis using the Python dynamic hooks (as
-opposed to F<readers.conf>, which does the same on per user
-basis).  These hooks are activated through the inclusion of the
-I<python_dynamic> parameter in a F<readers.conf> auth group.  Only one
-I<python_dynamic> statement is allowed in an auth group.
-
-When a I<python_dynamic> parameter is encountered, Python is loaded (if
-it has yet to be) and the file given as argument is loaded as well (do not
-include the C<.py> extension of this file in the value of I<python_dynamic>).
-If a Python object with a method C<dynamic_init> is hooked in during the
-loading of that file, then that method is called immediately after the
-file is loaded.  Every time a reader asks B<nnrpd> to read or post an
-article, the Python method C<dynamic> is invoked before proceeding with
-the requested operation.  Based on the value returned by C<dynamic>, the
-operation is either permitted or denied.  When the connection with the
-client is closed, the method C<access_close> is called if it exists.
-
-=head2 Writing a Python B<nnrpd> Authentication Module
-
-You need to create a F<nnrpd_auth.py> module in INN's filter directory
-(see the I<pathfilter> setting in F<inn.conf>) where you should define a
-class holding certain methods depending on which hooks you want to use.
-
-Note that you will have to use different Python scripts for authentication
-and access:  the values of I<python_auth>, I<python_access> and I<python_dynamic>
-have to be distinct for your scripts to work.
-
-The following methods are known to B<nnrpd>:
-
-=over 4
-
-=item __init__(I<self>)
-
-Not explicitly called by B<nnrpd>, but will run whenever the auth module is
-loaded.  Use this method to initialize any general variables or open
-a common database connection.  This method may be omitted.
-
-=item authen_init(I<self>)
-
-Initialization function specific to authentication.  This method may be
-omitted.
-
-=item authenticate(I<self>, I<attributes>)
-
-Called when a I<python_auth> statement is reached in the processing of
-F<readers.conf>.  Connection attributes are passed in the I<attributes>
-dictionary.  Returns a response code, an error string, and an optional
-string to be used in place of the client-supplied username (both for
-logging and for matching the connection with an access group).
-
-=item authen_close(I<self>)
-
-This method is invoked on B<nnrpd> termination.  You can use it to save
-state information or close a database connection.  This method may be omitted.
-
-=item access_init(I<self>)
-
-Initialization function specific to generation of an access group.  This
-method may be omitted.
-
-=item access(I<self>, I<attributes>)
-
-Called when a I<python_access> statement is reached in the processing of
-F<readers.conf>.  Connection attributes are passed in the I<attributes>
-dictionary.  Returns a dictionary of values representing statements to
-be included in an access group.
-
-=item access_close(I<self>)
-
-This method is invoked on B<nnrpd> termination.  You can use it to save
-state information or close a database connection.  This method may be omitted.
-
-=item dynamic_init(I<self>)
-
-Initialization function specific to dynamic access control.  This
-method may be omitted.
-
-=item dynamic(I<self>, I<attributes>)
-
-Called when a client requests a newsgroup, an article or attempts to
-post.  Connection attributes are passed in the I<attributes> dictionary.
-Returns C<None> to grant access, or a non-empty string (which will be
-reported back to the client) otherwise.
-
-=item dynamic_close(I<self>)
-
-This method is invoked on B<nnrpd> termination.  You can use it to save
-state information or close a database connection.  This method may be omitted.
-
-=back
-
-=head2 The I<attributes> Dictionary
-
-The keys and associated values of the I<attributes> dictionary are
-described below.
-
-=over 4
-
-=item I<type>
-
-C<read> or C<post> values specify the authentication type; only valid
-for the C<dynamic> method.
-
-=item I<hostname>
-
-It is the resolved hostname (or IP address if resolution fails) of
-the connected reader.
-
-=item I<ipaddress>
-
-The IP address of the connected reader.
-
-=item I<port>
-
-The port of the connected reader.
-
-=item I<interface>
-
-The hostname of the local endpoint of the NNTP connection.
-
-=item I<intipaddr>
-
-The IP address of the local endpoint of the NNTP connection.
-
-=item I<intport>
-
-The port of the local endpoint of the NNTP connection.
-
-=item I<user>
-
-The username as passed with AUTHINFO command, or C<None> if not
-applicable.
-
-=item I<pass>
-
-The password as passed with AUTHINFO command, or C<None> if not
-applicable.
-
-=item I<newsgroup>
-
-The name of the newsgroup to which the reader requests read or post access;
-only valid for the C<dynamic> method.
-
-=back
-
-All the above values are buffer objects (see the notes above on what
-buffer objects are).
-
-=head2 How to Use these Methods with B<nnrpd>
-
-To register your methods with B<nnrpd>, you need to create an instance of
-your class, import the built-in B<nnrpd> module, and pass the instance to
-C<nnrpd.set_auth_hook>.  For example:
-
-    class AUTH:
-        def authen_init(self):
-            ...
-            blah blah
-            ...
-
-        def authenticate(self, attributes):
-            ...
-            yadda yadda
-            ...
-
-    import nnrpd
-    myauth = AUTH()
-    nnrpd.set_auth_hook(myauth)
-
-When writing and testing your Python filter, don't be afraid to make use
-of C<try:>/C<except:> and the provided C<nnrpd.syslog> function.  stdout and stderr
-will be disabled, so your filter will die silently otherwise.
-
-Also, remember to try importing your module interactively before loading
-it, to ensure there are no obvious errors.  One typo can ruin your whole
-filter.  A dummy F<nnrpd.py> module is provided to facilitate testing outside
-the server.  It is not actually used by B<nnrpd> but provides the same set
-of functions as built-in B<nnrpd> module. This stub module may be used
-when debugging your own module.  To test, change into your filter directory
-and use a command like:
-
-    python -ic 'import nnrpd, nnrpd_auth'
-
-=head2 Functions Supplied by the Built-in B<nnrpd> Module
-
-Besides C<nnrpd.set_auth_hook> used to pass a reference to the instance
-of authentication and authorization class to B<nnrpd>, the B<nnrpd> built-in
-module exports the following function:
-
-=over 4
-
-=item syslog(I<level>, I<message>)
-
-It is intended to be a replacement for a Python native syslog.  It works
-like C<INN.syslog>, seen above.
-
-=back
-
-$Id: hook-python.pod 7926 2008-06-29 08:27:41Z iulius $
-
-=cut
diff --git a/doc/pod/ident.pod b/doc/pod/ident.pod
deleted file mode 100644 (file)
index e9d6250..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-=head1 NAME
-
-ident - nnrpd ident resolver
-
-=head1 SYNOPSIS
-
-B<ident> [B<-p> I<port>] [B<-t>]
-
-=head1 DESCRIPTION
-
-This program attempts to resolve usernames for B<nnrpd> by using the
-ident protocol to query the remote host.  It contacts the remote host
-using either IPv4 or IPv6 depending on which protocol was used for the
-incoming NNTP connection.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-p> I<port>
-
-If this option is given, attempt to contact identd on the specified
-remote port (which can be a numeric or symbolic specification).
-Non-numeric values will be looked up using getservbyname(3).  The
-default value is the result of C<getservbyname("ident")> if available,
-or port 113 otherwise.
-
-=item B<-t>
-
-If this option is given, the identity returned will never have a domain
-part.  That is, if the remote server returns a result containing an C<@>
-character, B<ident> truncates the response at the C<@>.  This is useful
-to allow the I<default-domain> parameter in F<reaers.conf> to override
-the domain supplied by the remote host (particularly if the supplied
-domain part is an unqualified local machine name rather than a full
-domain name).
-
-=back
-
-=head1 EXAMPLE
-
-The following readers.conf(5) fragment tells nnrpd to trust ident
-information for hosts on a local network, but to replace the domain
-returned from the ident query:
-
-    auth LAN {
-       hosts: "192.168/16"
-        res: "ident -t"
-       default-domain: "internal.example.com"
-    }
-
-    access LAN {
-        users: "*@internal.example.com"
-        newsgroups: example.*
-    }
-
-Access is granted to the example.* groups for all users on the local
-network whose machines respond to ident queries.
-
-=head1 HISTORY
-
-This documentation was written by Jeffrey M. Vinocur <jeff@litech.org>.
-
-$Id: ident.pod 5988 2002-12-12 23:02:14Z vinocur $
-
-=head1 SEE ALSO
-
-nnrpd(8), readers.conf(5)
-
-=cut
diff --git a/doc/pod/inews.pod b/doc/pod/inews.pod
deleted file mode 100644 (file)
index 8c8176d..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-=head1 NAME
-
-inews - Post a Usenet article to the local news server
-
-=head1 SYNOPSIS
-
-B<inews> [B<-ADhNORSVW>] [B<-acdeFfnortwx> I<value>] [B<-p> I<port>] [I<file>]
-
-=head1 DESCRIPTION
-
-B<inews> reads a Usenet news article, perhaps with headers, from I<file>
-or standard input if no file is given.  It adds some headers and performs
-some consistency checks.  If the article does not meet those checks, the
-article is rejected.  If it passes the checks, B<inews> sends the article
-to the local news server as specified in F<inn.conf>.
-
-By default, if a file named F<.signature> exists in the home directory of
-the posting user, it is appended to the post, preceeded by a line that
-contains only C<-- >.  Signatures are not allowed to be more than four
-lines long.
-
-Cancel messages can only be posted with B<inews> if the sender of the
-cancel message matches the sender of the original message being
-cancelled.  The same check is also applied to Supersedes.  Sender in this
-case means the contents of the Sender header if present, otherwise the
-From header.
-
-Control messages other than cancel messages are only allowed if B<inews>
-is being run by the news user or by a user in the news group and if the
-control message is recognized.  If the article contains a Distribution
-header with a distribution that matches one of the bad distribution
-patterns in F<inn/options.h> (anything containing a period by default),
-the message will be rejected.  The message will also be rejected if
-I<checkincludedtext> is true in F<inn.conf>, it contains more quoted text
-than original text, and it is over 40 lines long.
-
-If not provided, the Path header of an article is constructed as follows:
-The basic Path header will be "not-for-mail".  If I<pathhost> is specified
-in F<inn.conf>, it will be added to the beginning Path.  Otherwise, if
-I<server> is specified, the full domain of the local host will be added to
-the beginning of the Path.  Then, if B<-x> was given, its value will be
-added to the beginning of the Path.
-
-If posting fails, a copy of the failed post will be saved in a file named
-F<dead.article> in the home directory of the user running B<inews>.
-B<inews> exits with a non-zero status if posting failed or with a zero
-status if posting was successful.
-
-=head1 OPTIONS
-
-Most of the options to B<inews> take a single value and set the
-corresponding header in the message that is posted.  If the value is more
-than one word or contains any shell metacharacters, it must be quoted to
-protect it from the shell.  Here are all the options that set header
-fields and the corresponding header:
-
-    -a  Approved
-    -c  Control
-    -d  Distribution
-    -e  Expires
-    -F  References
-    -f  From
-    -n  Newsgroups
-    -o  Organization
-    -r  Reply-To
-    -t  Subject
-    -w  Followup-To
-    -x  Path prefix
-
-The B<-x> argument will be added to the beginning of the normal Path
-header; it will not replace it.
-
-=over 4
-
-=item B<-A>, B<-V>, B<-W>
-
-Accepted for compatibility with C News.  These options have no affect.
-
-=item B<-D>, B<-N>
-
-Perform the consistency checks and add headers where appropriate, but then
-print the article to standard output rather than sending it to the server.
-B<-N> is accepted as as synonym for compatibility with C News.
-
-=item B<-h>
-
-Normally, this flag should always be given.  It indicates that the article
-consists of headers, a blank line, and then the message body.  If it is
-omitted, the input is taken to be just the body of the message, and any
-desired headers have to be specified with command-line options as
-described above.
-
-=item B<-O>
-
-By default, an Organization header will be added if none is present in the
-article.  To prevent adding the default (from I<organization> in
-F<inn.conf>), use this flag.
-
-=item B<-p> I<port>
-
-Connect to the specified port on the server rather than to the default
-(port 119).
-
-=item B<-R>
-
-Reject all control messages.
-
-=item B<-S>
-
-Do not attempt to append F<~/.signature> to the message, even if it
-exists.
-
-=back
-
-=head1 NOTES
-
-If the NNTP server requests authentication, B<inews> will try to read
-F<passwd.nntp> to get the username and password to use and will therefore
-need read access to that file.  This is typically done by making that file
-group-readable and adding all users who should be able to use B<inews> to
-post to that server to the appropriate group.
-
-B<inews> used to do even more than it does now, and all of the remaining
-checks that are not dependent on the user running B<inews> should probably
-be removed in favor of letting the news server handle them.
-
-Since INN's B<inews> uses F<inn.conf> and some other corners of an INN
-installation, it's not very appropriate as a general stand-alone B<inews>
-program for general use on a system that's not running a news server.
-Other, more suitable versions of B<inews> are available as part of various
-Unix news clients or by themselves.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Rewritten in
-POD by Russ Allbery <rra@stanford.edu>.
-
-=head1 SEE ALSO
-
-inn.conf(5), rnews(1)
-
-=cut
diff --git a/doc/pod/inn.conf.pod b/doc/pod/inn.conf.pod
deleted file mode 100644 (file)
index 3145595..0000000
+++ /dev/null
@@ -1,1273 +0,0 @@
-=head1 NAME
-
-inn.conf - Configuration data for InterNetNews programs
-
-=head1 DESCRIPTION
-
-F<inn.conf> in I<pathetc> 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 INNCONF environment variable, if set,
-specifies an alternate path to F<inn.conf>.
-
-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, F<inn.conf> cannot be reloaded
-dynamically using ctlinnd(8); innd(8) must be stopped and restarted for
-relevant changes to F<inn.conf> to take effect (C<ctlinnd xexec innd> is
-the fastest way to do this.)
-
-Blank lines and lines starting with a number sign (C<#>) are ignored.  All
-other lines specify parameters, and should be of the following form:
-
-    <name>: <value>
-
-(Any amount of whitespace can be put after the colon and is optional.)  If
-the value contains embedded whitespace or any of the characers C<[]<>"\:>,
-it must be enclosed in double quotes ("").  A backslash (C<\>) can be used
-to escape quotes and backslashes inside double quotes.  <name> is
-case-sensitive; C<server> is not the same as C<Server> or C<SERVER>.
-(F<inn.conf> parameters are generally all in lowercase.)
-
-If <name> occurs more than once in the file, the first value is used.
-Some parameters specified in the file may be overridden by environment
-variables.  Most parameters have default values if not specified in
-F<inn.conf>; those defaults are noted in the description of each
-parameter.
-
-Many parameters take a boolean value.  For all such parameters, the value
-may be specified as C<true>, C<yes>, or C<on> to turn it on and may be any
-of C<false>, C<no>, or C<off> to turn it off.  The case of these values is
-significant.
-
-This documentation is extremely long and organized as a reference manual
-rather than as a tutorial.  If this is your first exposure to INN and
-these parameters, it would be better to start by reading other man pages
-and referring to this one only when an F<inn.conf> parameter is explicitly
-mentioned.  Those parameters which need to be changed when setting up a
-new server are discussed in F<INSTALL>.
-
-=head1 PARAMETERS
-
-=head2 General Settings
-
-These parameters are used by a wide variety of different components of
-INN.
-
-=over 4
-
-=item I<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 GetFQDN() routine in libinn(3) cannot get the fully-qualified
-domain name by using either the gethostname(3) or gethostbyname(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 I<virtualhost> and I<domain> in
-L<readers.conf>.  The default value is unset.
-
-=item I<innflags>
-
-The flags to pass to innd on startup.  See innd(8) for details on the
-possible flags.  The default value is unset.
-
-=item I<mailcmd>
-
-The path to the program to be used for mailing reports and control
-messages.  The default is I<pathbin>/innmail.  This should not normally
-need to be changed.
-
-=item I<mta>
-
-The command to use when mailing postings to moderators and for the use of
-innmail(1).  The message, with headers and an added To: header, will be
-piped into this program.  The string C<%s>, if present, will be replaced
-by the e-mail address of the moderator.  It's strongly recommended for
-this command to include C<%s> 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 F<inn.conf> or a
-fatal error message will be logged via syslog.
-
-For most systems, C</usr/lib/sendmail -oi -oem %s> (adjusted for the
-correct path to sendmail) is a good choice.
-
-=item I<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 F<inn.conf> or INN will
-not start.  A good value to use is the fully-qualified hostname of the
-system.
-
-=item I<server>
-
-The name of the default NNTP server.  If I<nnrpdposthost> is not set and
-UNIX domain sockets are not supported, nnrpd(8) tries to hand off
-locally-posted articles through an INET domain socket to this server.
-actsync(8), nntpget(8), and getlist(8) also use this value as the default
-server to connect to.  In the latter cases, the value of the NNTPSERVER
-environment variable, if it exists, overrides this.  The default value is
-unset.
-
-=back
-
-=head2 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.
-
-=over 4
-
-=item I<artcutoff>
-
-Articles older than this number of days are dropped.  This setting should
-probably match the setting on the C</remember/> line in F<expire.ctl>.
-The default value is C<10>.
-
-=item I<bindaddress>
-
-Which IP address innd(8) should bind itself to.  This must be in
-dotted-quad format (nnn.nnn.nnn.nnn).  If set to C<all> or not set, innd
-defaults to listening on all interfaces.  The value of the
-INND_BIND_ADDRESS environment variable, if set, overrides this setting.
-The default value is unset.
-
-=item I<bindaddress6>
-
-Like I<bindaddress> but for IPv6 sockets. If only one of the I<bindaddress>
-and I<bindaddress6> 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
-I<getaddrinfo(3)> function.  The value of the INND_BIND_ADDRESS6, if set,
-overrides this setting.  The default value is unset.
-
-Note that you will generally need to put double quotes ("") around this
-value if you set it, since IPv6 addresses contain colons.
-
-=item I<hiscachesize>
-
-If set to a value other than C<0>, 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 C<256>; systems with only one incoming feed should probably leave
-this at C<0>.  The default value is C<0>.
-
-=item I<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 F<newsfeeds>.  This is a boolean value and the default is false.
-
-=item I<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.
-
-This setting is ignored unless the timecaf storage method is used.
-
-=item I<linecountfuzz>
-
-If set to something other than C<0>, 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 C<5>, which is the standard maximum signature length
-plus one (some injection software calculates the Lines: header before
-adding the signature).  The default value is C<0>, which tells INN not to
-check the Lines: header of incoming articles.
-
-=item I<maxartsize>
-
-The maximum size of article (headers and body) that will be accepted by
-the server, in bytes.  A value of C<0> allows any size of article, but
-note that B<innd> will crash if system memory is exceeded.  The default
-value is C<1000000> (approximately 1 MB).  See also I<localmaxartsize>.
-
-=item I<maxconnections>
-
-The maximum number of incoming NNTP connections innd(8) will accept.  The
-default value is C<50>.
-
-=item I<pathalias>
-
-If set, this value is prepended to the Path: header of accepted posts
-(before I<pathhost>) 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.
-
-=item I<pathcluster>
-
-If set, this value is appended to the Path: header of accepted posts
-(after I<pathhost>) 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.
-
-Note that the Path: header reads right to left, so appended means inserted
-at the leftmost side of the Path: header.
-
-=item I<pgpverify>
-
-Whether to enable PGP 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.
-
-=item I<port>
-
-What TCP port innd(8) should listen on.  The default value is C<119>, the
-standard NNTP port.
-
-=item I<refusecybercancels>
-
-Whether to refuse all articles whose message IDs start with
-C<E<lt>cancel.>.  This message ID convention is widely followed by spam
-cancellers, so the vast majority of such articles will be cancels of spam.
-This check, if enabled, is done before the history check and the message
-ID is not written to the history file.  This is a boolean value and the
-default is false.
-
-This is a somewhat messy, inefficient, and inexact way of refusing spam
-cancels.  A much better way is to ask all of your upstream peers to not
-send to you any articles with C<cyberspam> in the Path: header (usually
-accomplished by having them mark C<cyberspam> as an alias for your machine
-in their feed configuration).  The filtering enabled by this parameter is
-hard-coded; general filtering of message IDs can be done via the embedded
-filtering support.
-
-=item I<remembertrash>
-
-By default, innd(8) records rejected articles in history so that, if
-offered the same article again, it can be refused before it is sent.  If
-you wish to disable this behavior, set this to false.  This can cause a
-substantial increase in the amount of bandwidth consumed by incoming news
-if you have several peers and reject a lot of articles, so be careful with
-it.  Even if this is set to true, INN won't log some rejected articles to
-history if there's reason to believe the article might be accepted if
-offered by a different peer, so there is usually no reason to set this to
-false (although doing so can decrease the size of the history file).  This
-is a boolean value and the default is true.
-
-=item I<sourceaddress>
-
-Which local IP address to bind to for outgoing NNTP sockets (used by
-innxmit(8) among other programs, but I<not> innfeed(8) -- see
-I<bindaddress> in innfeed.conf(5) for that).  This must be in dotted-quad
-format (nnn.nnn.nnn.nnn).  If set to C<all> or not set, the operating
-system will choose the source IP address for outgoing connections.  The
-default value is unset.
-
-=item I<sourceaddress6>
-
-Like I<sourceaddress> but for IPv6 sockets.
-
-=item I<verifycancels>
-
-Set this to true to enable a simplistic check on all cancel messages,
-attempting to verify (by simple header comparison) that the cancel message
-is from the same person as the original post.  This can't be done if the
-cancel arrives before the article does, and is extremely easy to spoof.
-While this check may once have served a purpose, it's now essentially
-security via obscurity, commonly avoided by abusers, and probably not
-useful.  This is a boolean value, and the default is false.
-
-=item I<wanttrash>
-
-Set this to true if you want to file articles posted to unknown newsgroups
-(newsgroups not in the F<active> file) into the C<junk> newsgroup rather
-than rejecting them.  This is sometimes useful for a transit news server
-that needs to propagate articles in all newsgroups regardless if they're
-carried locally.  This is a boolean value and the default is false.
-
-=item I<wipcheck>
-
-If INN is offered an article by a peer on one channel, it will return
-deferral responses (code 436) to all other offers of that article for this
-many seconds.  (After this long, if the peer that offered the article
-still hasn't sent it, it will be accepted from other channels.)  The
-default value is C<5> and probably doesn't need to be changed.
-
-=item I<wipexpire>
-
-How long, in seconds, to keep track of message IDs offered on a channel
-before expiring articles that still haven't been sent.  The default value
-is C<10> and probably doesn't need to be changed.
-
-=item I<dontrejectfiltered>
-
-Normally innd(8) rejects incoming articles when directed to do so by any
-enabled article filters (Perl, Python, and TCL).  However, this parameter
-causes such articles I<not> to be rejected; instead filtering can be
-applied on outbound articles.  If this parameter is set, all articles will
-be accepted on the local machine, but articles rejected by the filter will
-I<not> be fed to any peers specified in F<newsfeeds> with the C<Af> flag.
-
-=back
-
-=head2 Article Storage
-
-These parameters affect how articles are stored on disk.
-
-=over 4
-
-=item I<cnfscheckfudgesize>
-
-If set to a value other than C<0>, the claimed size of articles in CNFS
-cycbuffs is checked against I<maxartsize> plus this value, and if larger,
-the CNFS cycbuff is considered corrupt.  This can be useful as a sanity
-check after a system crash, but be careful using this parameter if you
-have changed I<maxartsize> recently.  The default value is C<0>.
-
-=item I<enableoverview>
-
-Whether to write out overview data for articles.  If set to false, INN
-will run much faster, but reading news from the system will be impossible
-(the server will be for news transit only).  If this option is set to
-true, I<ovmethod> must also be set.  This is a boolean value and the
-default is true.
-
-=item I<groupbaseexpiry>
-
-Whether to enable newsgroup-based expiry.  If set to false, article expiry
-is done based on storage class of storing method.  If set to true (and
-overview information is available), expiry is done by newsgroup name.
-This affects the format of F<expire.ctl>.  This is a boolean value and the
-default is true.
-
-=item I<mergetogroups>
-
-Whether to file all postings to C<to.*> groups in the pseudonewsgroup
-C<to>.  If this is set to true, the newsgroup C<to> must exist in the
-F<active> file or INN will not start.  (See the discussion of C<to.>
-groups in innd(8) under CONTROL MESSAGES.)  This is a boolean value and
-the default is false.
-
-=item I<overcachesize>
-
-How many cache slots to reserve for open overview files.  If INN is
-writing overview files (see I<enableoverview>), I<ovmethod> is set to
-C<tradindexed>, and this is set to a value other than C<0>, INN will keep
-around and open that many recently written-to overview files in case more
-articles come in for those newsgroups.  Every overview cache slot consumes
-two file descriptors, so be careful not to set this value too high.  You
-may be able to use the C<limit> command to see how many open file
-descriptors your operating system allows.  innd(8) also uses an open file
-descriptor for each incoming feed and outgoing channel or batch file, and
-if it runs out of open file descriptors it may throttle and stop accepting
-new news.  The default value is C<15> (which is probably way too low if
-you have a large number of file descriptors available).
-
-This setting is ignored unless I<ovmethod> is set to C<tradindexed>.
-
-=item I<ovgrouppat>
-
-If set, restricts the overview data stored by INN to only the newsgroups
-matching this comma-separated list of wildmat expressions.  Newsgroups not
-matching this setting may not be readable, and if I<groupbaseexpiry> is
-set to true and the storage method for these newsgroups does not have
-self-expire functionality, storing overview data will fail.
-The default is unset.
-
-=item I<ovmethod>
-
-Which overview storage method to use.  Currently supported values are
-C<tradindexed>, C<buffindexed>, and C<ovdb>.  There is no default value;
-this parameter must be set if I<enableoverview> is true (the default).
-
-=over 4
-
-=item C<buffindexed>
-
-Stores overview data and index information into buffers, which are
-preconfigured files defined in F<buffinedexed.conf>.  C<buffindexed> never
-consumes additional disk space beyond that allocated to these buffers.
-
-=item C<tradindexed>
-
-Uses two files per newsgroup, one containing the overview data and one
-containing the index.  Fast for readers, but slow to write to.
-
-=item C<ovdb>
-
-Stores data into a Berkeley DB database.  See the ovdb(5) man page.
-
-=back
-
-=item I<hismethod>
-
-Which history storage method to use.  The only currently supported
-value is C<hisv6>.  There is no default value; this parameter must
-be set.
-
-=over 4
-
-=item C<hisv6>
-
-Stores history data in the INN history v6 format:  history(5) text
-file and a number of dbz(3) database files; this may be in true history
-v6 format, or tagged hash format, depending on the build
-options.  Separation of these two is a project which has not yet been
-undertaken.
-
-=back
-
-=item I<storeonxref>
-
-If set to true, articles will be stored based on the newsgroup names in
-the Xref: header rather than in the Newsgroups: header.  This affects what
-the patterns in F<storage.conf> apply to.  The primary interesting effect
-of setting this to true is to enable filing of all control messages
-according to what storage class the control pseudogroups are filed in
-rather than according to the newsgroups the control messages are posted
-to.  This is a boolean value and the default is true.
-
-=item I<useoverchan>
-
-Whether to innd(8) should create overview data internally through
-libstorage(3).  If set to false, innd creates overview data by itself.  If
-set to true, innd does not create; instead overview data must be created
-by overchan(8) from an appropriate entry in F<newsfeeds>.  Setting to true
-may be useful, if innd cannot keep up with incoming feed and the
-bottleneck is creation of overview data within innd.  This is a boolean
-value and the default is false.
-
-=item I<wireformat>
-
-Only used with the tradspool storage method, this says whether to write
-articles in wire format.  Wire format means storing articles with C<\r\n> at
-the end of each line and with periods at the beginning of lines doubled,
-the article format required by the NNTP protocol.  Articles stored in this
-format are suitable for sending directly to a network connection without
-requiring conversion, and therefore setting this to true can make the
-server more efficient.  The primary reason not to set this is if you have
-old existing software that looks around in the spool and doesn't
-understand how to read wire format.  Storage methods other than tradspool
-always store articles in wire format.  This is a boolean value and the
-default is false.
-
-=item I<xrefslave>
-
-Whether to act as the slave of another server.  If set, INN attempts to
-duplicate exactly the article numbering of the server feeding it by
-looking at the Xref: header of incoming articles and assigning the same
-article numbers to articles as was noted in the Xref: header from the
-upstream server.  The result is that clients should be able to point at
-either server interchangeably (using some load balancing scheme, for
-example) and see the same internal article numbering.  Servers with this
-parameter set should generally only have one upstream feed, and should
-always have I<nnrpdposthost> set to hand locally posted articles off to
-the master server.  The upstream should be careful to always feed articles
-in order (innfeed(8) can have problems with this in the event of a
-backlog).  This is a boolean value and the default is false.
-
-=item I<nfswriter>
-
-For servers writing articles, determine whether the article spool is
-on NFS storage.  If set, INN attempts to flush articles to the spool
-in a more timely manner, rather than relying on the operating system
-to flush things such as the CNFS article bitmaps.  You should only set
-this parameter if you are attempting to use a shared NFS spool on a
-machine acting as a single writer within a cluster.  This is a boolean
-value and the default is false.
-
-=item I<nfsreader>
-
-For servers reading articles, determine whether the article spool is
-on NFS storage.  If set, INN will attempt to force articles and
-overviews to be read directly from the NFS spool rather than from
-cached copies.  You should only set this parameter if you are
-attempting to use a shared NFS spool on a machine acting a reader a
-cluster.  This is a boolean value and the default is false.
-
-=item I<nfsreaderdelay>
-
-For servers reading articles, determine whether the article spool is
-on NFS storage.  If I<nfsreader> is set, INN will use the value of
-I<nfsreaderdelay> to delay the apparent arrival time of articles to
-clients by this amount; this value should be tuned based on the NFS
-cache timeouts locally.  This default is 60 (1 minute).
-
-=item I<msgidcachesize>
-
-How many cache slots to reserve for Message ID to storage token
-translations.  When serving overview data to clients (NEWNEWS, XOVER
-etc.), nnrpd(8) can cache the storage token associated with a Message
-ID and save the cost of looking it up in the history file; for some
-configurations setting this parameter can save more than 90% of the
-wall clock time for a session.  The default value is 10000.
-
-=item I<tradindexedmmap>
-
-Whether to attempt to mmap() tradindexed overviews articles.  Setting
-this to true will give better performance on most systems, but some
-systems have problems with mmap().  If this is set to false, overviews
-will be read into memory before being sent to readers.  This is a
-boolean value and the default is true.
-
-=back
-
-=head2 Reading
-
-These parameters affect the behavior of INN for readers.  Most of them are
-used by nnrpd(8).  There are some special sets of settings that are broken
-out separately after the initial alphabetized list.
-
-=over 4
-
-=item I<allownewnews>
-
-Whether to allow use of the NEWNEWS command by clients.  This command used
-to put a heavy load on the server in older versions of INN, but is now
-reasonably efficient, at least if only one newsgroup is specified by the
-client.  This is a boolean value and the default is true.  If you use the
-I<access> parameter in F<readers.conf>, be sure to read about the way it
-overrides I<allownewnews>.
-
-=item I<articlemmap>
-
-Whether to attempt to mmap() articles.  Setting this to true will give
-better performance on most systems, but some systems have problems with
-mmap().  If this is set to false, articles will be read into memory before
-being sent to readers.  This is a boolean value and the default is false.
-
-=item I<clienttimeout>
-
-How long (in seconds) a client connection can be idle before it exits.
-When setting this parameter, be aware that some newsreaders use the same
-connection for reading and posting and don't deal well with the connection
-timing out while a post is being composed.  If the system isn't having a
-problem with too many long-lived connections, it may be a good idea to
-increase this value to C<3600> (an hour).  The default value is C<600>
-(ten minutes).
-
-=item I<initialtimeout>
-
-How long (in seconds) B<nnrpd> will wait for the first command from a
-reader connection before dropping the connection.  This is a defensive
-timeout intended to protect the news server from badly behaved reader
-clients that open and abandon a multitude of connections without every
-closing them.  The default value is C<10> (ten seconds), which may need to
-be increased if many clients connect via slow network links.
-
-=item I<nnrpdcheckart>
-
-Whether B<nnrpd> should check the existence of an article before listing
-it as present in response to an NNTP command.  The primary use of this
-setting is to prevent nnrpd from returning information about articles
-which are no longer present on the server but which still have overview
-data available.  Checking the existence of articles before returning
-overview information slows down the overview commands, but reduces the
-number of "article is missing" errors seen by the client.  This is a
-boolean value and the default is true.
-
-=item I<nnrpperlauth>
-
-This parameter is now obsolete; see "Changes to Perl Authentication
-Support for nnrpd" in F<doc/hook-perl>.
-
-=item I<nnrppythonauth>
-
-This parameter is now obsolete; see "Changes to Python Authentication and
-Access Control Support for nnrpd" in F<doc/hook-python>.
-
-=item I<noreader>
-
-Normally, innd(8) will fork a copy of nnrpd(8) for all incoming
-connections from hosts not listed in F<incoming.conf>.  If this parameter
-is set to true, those connections will instead be rejected with a 502
-error code.  This should be set to true for a transit-only server that
-doesn't support readers, or if nnrpd is running in daemon mode or being
-started out of inetd.  This is a boolean value and the default is false.
-
-=item I<readerswhenstopped>
-
-Whether to allow readers to connect even if the server is paused or
-throttled.  This is only applicable if nnrpd(8) is spawned from innd(8)
-rather than run out of inetd or in daemon mode.  This is a boolean value
-and the default is false.
-
-=item I<readertrack>
-
-Whether to enable the tracking system for client behavior.  Tracked
-information is recorded to I<pathlog>/tracklogs/log-ID, where ID is
-determined by nnrpd's PID and launch time.)  Currently the information
-recorded includes initial connection and posting; only information about
-clients listed in F<nnrpd.track> is recorded.  This is a boolean value and
-the default is false.
-
-=item I<nnrpdflags>
-
-When nnrpd(8) is spawned from innd(8), these flags are passed as
-arguments to the nnrpd process.  This setting does not affect instances
-of nnrpd that are started in daemon mode, or instances that are started
-via another listener process such as inetd(8) or xinetd(8).  Shell
-quoting and metacharacters are not supported.  This is a string value
-and the default is unset.
-
-=item I<nnrpdloadlimit>
-
-If set to a value other than C<0>, connections to nnrpd will be refused
-if the system load average is higher than this value.  The default value
-is C<16>.
-
-=back
-
-INN has optional support for generating keyword information automatically
-from article body text and putting that information in overview for the
-use of clients that know to look for it.  The following parameters control
-that feature.
-
-This may be too slow if you're taking a substantial feed, and probably
-will not be useful for the average news reader; enabling this is not
-recommended unless you have some specific intention to take advantage of
-it.
-
-=over 4
-
-=item I<keywords>
-
-Whether the keyword generation support should be enabled.  This is a
-boolean value and the default is false.
-
-FIXME: Currently, support for keyword generation is configured into INN
-semi-randomly (based on whether configure found the regex library); it
-should be an option to configure and that option should be mentioned here.
-
-=item I<keyartlimit>
-
-Articles larger than this value in bytes will not have keywords generated
-for them (since it would take too long to do so).  The default value is
-C<100000> (approximately 100 KB).
-
-=item I<keylimit>
-
-Maximum number of bytes allocated for keyword data.  If there are more
-keywords than will fit into this many bytes when separated by commas, the
-rest are discarded.  The default value is C<512>.
-
-=item I<keymaxwords>
-
-Maximum number of keywords that will be generated for an article.  (The
-keyword generation code will attempt to discard "noise" words, so the
-number of keywords actually writen into the overview will usually be
-smaller than this even if the maximum number of keywords is found.)  The
-default value is C<250>.
-
-=back
-
-=head2 Posting
-
-These parameters are only used by nnrpd(8), inews(1), and other programs
-that accept or generate postings.  There are some special sets of settings
-that are broken out separately after the initial alphabetized list.
-
-=over 4
-
-=item I<addnntppostingdate>
-
-Whether to add an NNTP-Posting-Date: header to all local posts.  This is a
-boolean value and the default is true.  Note that INN either does not add
-this header or adds the name or IP address of the client.  There is no
-intrinsic support for obfuscating the name of the client.  That has to be
-done with a user-written Perl filter, if desired.
-
-=item I<addnntppostinghost>
-
-Whether to add an NNTP-Posting-Host: header to all local posts giving the
-FQDN or IP address of the system from which the post was received.  This
-is a boolean value and the default is true.
-
-=item I<checkincludedtext>
-
-Whether to check local postings for the ratio of new to quoted text and
-reject them if that ratio is under 50%.  Included text is recognized by
-looking for lines beginning with C<E<gt>>, C<|>, or C<:>.  This is a
-boolean value and the default is false.
-
-=item I<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 C<usenet>, doesn't contain C<@>, the
-address will consist of the newsmaster, a C<@>, and the value of
-I<fromhost>.)
-
-=item I<fromhost>
-
-Contains a domain used to construct e-mail addresses.  The address of the
-local news administrator will be given as <user>@I<fromhost>, where <user>
-is the newsmaster user set at compile time (C<usenet> by default).  This
-setting will also be used by mailpost(8) to fully qualify addresses and by
-inews(1) to generate the Sender: header (and From: header if missing).
-The value of the FROMHOST environment variable, if set, overrides this
-setting.  The default is the fully-qualified domain name of the local
-host.
-
-=item I<localmaxartsize>
-
-The maximum article size (in bytes) for locally posted articles.  Articles
-larger than this will be rejected.  A value of C<0> allows any size of
-article, but note that B<nnrpd> and B<innd> will crash if system memory is
-exceeded.  See also I<maxartsize>, which applies to all articles including
-those posted locally.  The default value is C<1000000> (approximately 1
-MB).
-
-=item I<moderatormailer>
-
-The address to which to send submissions for moderated groups.  It is only
-used if the F<moderators> 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 F<moderators> file.  In most cases,
-C<%s@moderators.isc.org> is a good value for this parameter (C<%s> is
-expanded into a form of the newsgroup name).  See moderators(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 F<moderators> file, the posting will be rejected
-with an error.
-
-=item I<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 F<readers.conf>.  If the assigned
-identity does not include an C<@>, 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.
-
-=item I<nnrpdposthost>
-
-If set, nnrpd(8) and rnews(1) will pass all locally posted articles to the
-specified host rather than trying to inject them locally.  See also
-I<nnrpdpostport>.  This should always be set if I<xrefslave> is true.  The
-default value is unset.
-
-=item I<nnrpdpostport>
-
-The port on the remote server to connect to to post when I<nnrpdposthost>
-is used.  The default value is C<119>.
-
-=item I<organization>
-
-What to put in the Organization: header if it is left blank by the poster.
-The value of the ORGANIZATION environment variable, if set, overrides this
-setting.  The default is unset, which tells INN not to insert an
-Organization: header.
-
-=item I<spoolfirst>
-
-If true, nnrpd(8) will spool new articles rather than attempting to send
-them to innd(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; C<rnews -U> must be run periodically to take the
-spooled articles and post them.  This is a boolean value and the default
-is false.
-
-=item I<strippostcc>
-
-Whether to strip To:, Cc:, and Bcc: headers out of all local posts via
-nnrpd(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.  INN now protects against this abuse in other ways
-provided I<mta> is set to a command that includes C<%s> and honors it, so
-this is generally no longer needed.  This is a boolean value and the
-default is false.
-
-=back
-
-nnrpd(8) has support for controlling high-volume posters via an
-exponential backoff algorithm, as configured by the following parameters.
-
-Exponential posting backoff works as follows:  News clients are indexed by
-IP address (or username, see I<backoffauth> below).  Each time a post is
-received from an IP 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, nnrpd(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.
-
-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 I<backoffpostfast>, the new
-sleep time will be 1 + (previous sleep time * I<backoffk>).  If this
-difference is less than I<backoffpostslow> but greater than
-I<backoffpostfast>, then the new sleep time will equal the previous sleep
-time.  If this difference is greater than I<backoffpostslow>, the new
-sleep time is zero and posting backoff is deactivated for this poster.
-
-Exponential posting backoff will not be enabled unless I<backoffdb> is set
-and I<backoffpostfast> and I<backoffpostslow> are set to something other
-than their default values.
-
-Here are the parameters that control exponential posting backoff:
-
-=over 4
-
-=item I<backoffauth>
-
-Whether to index posting backoffs by user rather than by source IP
-address.  You must be using authentication in nnrpd(8) for a value of true
-to have any meaning.  This is a boolean value and the default is false.
-
-=item I<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.
-
-=item I<backoffk>
-
-The amount to multiply the previous sleep time by if the user is still
-posting too quickly.  A value of C<2> will double the sleep time for each
-excessive post.  The default value is C<1>.
-
-=item I<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 C<0>.
-
-=item I<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/I<backoffpostslow> posts per day.  The default value is C<1>.
-
-=item I<backofftrigger>
-
-This many postings are allowed before the backoff algorithm is triggered.
-The default value is C<10000>.
-
-=back
-
-=head2 Monitoring
-
-These parameters control the behavior of innwatch(8), the program that
-monitors INN and informs the news administrator if anything goes wrong
-with it.
-
-=over 4
-
-=item I<doinnwatch>
-
-Whether to start innwatch(8) from rc.news.  This is a boolean value, and
-the default is true.
-
-=item I<innwatchbatchspace>
-
-Free space in I<pathoutgoing>, in inndf(8) output units (normally
-kilobytes), at which innd(8) will be throttled by innwatch(8), assuming a
-default F<innwatch.ctl>.  The default value is C<800>.
-
-=item I<innwatchlibspace>
-
-Free space in I<pathdb>, in inndf(8) output units (normally kilobytes), at
-which innd(8) will be throttled by innwatch(8), assuming a default
-F<innwatch.ctl>.  The default value is C<25000>.
-
-=item I<innwatchloload>
-
-Load average times 100 at which innd(8) will be restarted by innwatch(8)
-(undoing a previous pause or throttle), assuming a default
-F<innwatch.ctl>.  The default value is C<1000> (that is, a load average of
-10.00).
-
-=item I<innwatchhiload>
-
-Load average times 100 at which innd(8) will be throttled by innwatch(8),
-assuming a default F<innwatch.ctl>.  The default value is C<2000> (that
-is, a load average of 20.00).
-
-=item I<innwatchpauseload>
-
-Load average times 100 at which innd(8) will be paused by innwatch(8),
-assuming a default F<innwatch.ctl>.  The default value is C<1500> (that
-is, a load average of 15.00).
-
-=item I<innwatchsleeptime>
-
-How long (in seconds) innwatch(8) will sleep between each check of INN.
-The default value is C<600>.
-
-=item I<innwatchspoolnodes>
-
-Free inodes in I<patharticles> at which innd(8) will be throttled by
-innwatch(8), assuming a default F<innwatch.ctl>.  The default value is
-C<200>.
-
-=item I<innwatchspoolspace>
-
-Free space in I<patharticles> and I<pathoverview>, in inndf(8) output
-units (normally kilobytes), at which innd(8) will be throttled by
-innwatch(8), assuming a default F<innwatch.ctl>.  The default value is
-C<8000>.
-
-=back
-
-=head2 Logging
-
-These parameters control what information INN logs.
-
-=over 4
-
-=item I<docnfsstat>
-
-Whether to start cnfsstat(8) when innd(8) is started.  cnfsstat will log
-the status of all CNFS cycbuffs to syslog on a periodic basis (frequency
-is the default for C<cnfsstat -l>, currently 600 seconds).  This is a
-boolean value and the default is false.
-
-=item I<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.
-
-=item I<logcancelcomm>
-
-Set this to true to log C<ctlinnd cancel> commands to syslog.  This is a
-boolean value and the default is false.
-
-=item I<logcycles>
-
-How many old logs scanlogs(8) keeps.  scanlogs(8) is generally run by
-news.daily(8) and will archive compressed copies of this many days worth
-of old logs.  The default value is C<3>.
-
-=item I<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 F<newsfeeds> flags; see newsfeeds(5) for more
-information.  This is a boolean value and the default is true.
-
-=item I<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 newsrequeue(8).  This is a boolean value and
-the default is true.
-
-=item I<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.
-
-=item I<nntpactsync>
-
-How many articles to process on an incoming channel before logging the
-activity.  The default value is C<200>.
-
-FIXME: This is a rather unintuitive name for this parameter.
-
-=item I<nntplinklog>
-
-Whether to put the storage API token for accepted articles (used by
-nntplink) in the article log.  This is a boolean value and the default is
-false.
-
-=item I<stathist>
-
-Where to write history statistics for analysis with
-F<contrib/stathist.pl>; this can be modified with ctlinnd(8) while innd is
-running.  Logging does not occur unless a path is given, and there is no
-default value.
-
-=item I<status>
-
-How frequently (in seconds) innd(8) should write out a status report.  The
-report is written to I<pathhttp>/inn_status.html.  If this is set to C<0> or
-C<false>, status reporting is disabled.  The default value is C<0>.
-
-=item I<timer>
-
-How frequently (in seconds) innd(8) should report performance timings to
-syslog.  If this is set to C<0>, performance timing is disabled.  Enabling
-this is highly recommended, and innreport(8) can produce a nice summary of
-the timings.  If set to C<0>, performance timings in nnrpd(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 C<0>.
-
-=back
-
-=head2 System Tuning
-
-The following parameters can be modified to tune the low-level operation
-of INN.  In general, you shouldn't need to modify any of them except
-possibly I<rlimitnofile> unless the server is having difficulty.
-
-=over 4
-
-=item I<badiocount>
-
-How many read or write failures until a channel is put to sleep or
-closed.  The default value is C<5>.
-
-=item I<blockbackoff>
-
-Each time an attempted write returns EAGAIN or EWOULDBLOCK, innd(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 C<2> or C<3>,
-since then when the channel fills INN will try again in a couple of
-seconds rather than waiting two minutes.  The default value is C<120>.
-
-=item I<chaninacttime>
-
-The time (in seconds) to wait between noticing inactive channels.  The
-default value is C<600>.
-
-=item I<chanretrytime>
-
-How many seconds to wait before a channel restarts.  The default value is
-C<300>.
-
-=item I<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
-NNTP data.  Increasing this value may improve performance, but it should
-not be increased on Systems with insufficient memory.  Permitted values
-are between C<0> and C<1048576> (out of range values are treated as
-C<1048576>) and the default value is C<8192>.  
-
-=item I<icdsynccount>
-
-How many article writes between updating the active and history files.
-The default value is C<10>.
-
-=item I<keepmmappedthreshold>
-
-When using buffindexed, retrieving overview data (that is, responding to
-XOVER 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 I<keepmmappedthreshold> (in KB), buffindexed mmap's just
-one overview block (8 KB).  This parameter is specific to buffindexed
-overview storage method.  The default value is C<1024> (1 MB).
-
-=item I<maxcmdreadsize>
-
-If set to anything other than C<0>, maximum buffer size (in bytes) for
-reading NNTP 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 innd(8) spending a long time on each channel and keeping other channels
-waiting.  The default value is BUFSIZ defined in stdio.h (C<1024> in most
-environments, see setbuf(3)).
-
-=item I<maxforks>
-
-How many times to attempt a fork(2) before giving up.  The default value
-is C<10>.
-
-=item I<nicekids>
-
-If set to anything other than C<0>, all child processes of innd(8) will
-have this nice(2) value.  This is usually used to give all child processes
-of innd(8) a lower priority (higher nice value) so that innd(8) can get
-the lion's share of the CPU when it needs it.  The default value is C<4>.
-
-=item I<nicenewnews>
-
-If set to anything greater than C<0>, all nnrpd(8) processes that receive
-and process a NEWNEWS command will nice(2) themselves to this value
-(giving other nnrpd processes a higher priority).  The default value is
-C<0>.  Note that this value will be ignored if set to a lower value than
-I<nicennrpd> (or I<nicekids> if nnrpd(8) is spawned from innd(8)).
-
-=item I<nicennrpd>
-
-If set to anything greater than C<0>, all nnrpd(8) processes will nice(1)
-themselves to this value.  This gives other news processes a higher
-priority and can help overchan(8) keep up with incoming news (if that's
-the object, be sure overchan(8) isn't also set to a lower priority via
-I<nicekids>).  The default value is C<0>, which will cause nnrpd(8)
-processes spawned from innd(8) to use the value of I<nicekids>, while
-nnrpd(8) run as a daemon will use the system default priority.  Note that
-for nnrpd(8) processes spawned from innd(8), this value will be ignored if
-set to a value lower than I<nicekids>.
-
-=item I<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 I<badiocount>.  The
-default value is C<300>.
-
-=item I<peertimeout>
-
-How long (in seconds) an innd(8) incoming channel may be inactive before
-innd closes it.  The default value is C<3600> (an hour).
-
-=item I<rlimitnofile>
-
-The maximum number of file descriptors that innd(8) or innfeed(8) can have
-open at once.  If innd(8) or innfeed(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 innd(8) and the number of outgoing streams for innfeed(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 C<-1>.  Setting it to
-C<256> on Solaris systems is highly recommended.
-
-=back
-
-=head2 Paths and File Names
-
-=over 4
-
-=item I<patharchive>
-
-Where to store archived news.  The default value is I<pathspool>/archive.
-
-=item I<patharticles>
-
-The path to where the news articles are stored (for storage methods other
-than CNFS).  The default value is I<pathspool>/articles.
-
-=item I<pathbin>
-
-The path to the news binaries.  The default value is I<pathnews>/bin.
-
-=item I<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 C<.pl>, as it can
-potentially be a severe security risk.  The default value is
-I<pathbin>/control.
-
-=item I<pathdb>
-
-The path to the database files used and updated by the server (currently,
-F<active>, F<active.times>, F<history> and its indices, and
-F<newsgroups>).  The default value is I<pathnews>/db.
-
-=item I<pathetc>
-
-The path to the news configuration files.  The default value is
-I<pathnews>/etc.
-
-=item I<pathfilter>
-
-The path to the Perl, Tcl, and Python filters.  The default value is
-I<pathbin>/filter.
-
-=item I<pathhttp>
-
-Where any HTML 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 I<pathlog>.
-
-=item I<pathincoming>
-
-Location where incoming batched news is stored.  The default value is
-I<pathspool>/incoming.
-
-=item I<pathlog>
-
-Where the news log files are written.  The default value is
-I<pathnews>/log.
-
-=item I<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 F<inn.conf>
-or INN will refuse to start.
-
-=item I<pathoutgoing>
-
-Default location for outgoing feed files.  The default value is
-I<pathspool>/outgoing.
-
-=item I<pathoverview>
-
-The path to news overview files.  The default value is
-I<pathspool>/overview.
-
-=item I<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 innd(8).  This directory and the control sockets in it should be
-protected from unprivileged users other than the news user.  The default
-value is I<pathnews>/run.
-
-=item I<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 innfeed(8).  The default value is I<pathnews>/spool.
-
-=item I<pathtmp>
-
-Where INN puts temporary files.  For security reasons, this is not the
-same as the system temporary files directory (INN 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
-I<pathnews>/tmp.
-
-=back
-
-=head1 EXAMPLE
-
-Here is a very minimalist example that only sets those parameters that are
-required.
-
-    mta:                /usr/lib/sendmail -oi -oem %s
-    ovmethod:           tradindexed
-    pathhost:           news.example.com
-    pathnews:           /usr/local/news
-    hismethod:          hisv6
-
-For a more comprehensive example, see the sample F<inn.conf> distributed
-with INN and installed as a starting point; it contains all of the default
-values for reference.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews and since
-modified, updated, and reorganized by innumerable other people.
-
-$Id: inn.conf.pod 7751 2008-04-06 14:35:40Z iulius $
-
-=head1 SEE ALSO
-
-inews(1), innd(8), innwatch(8), nnrpd(8), rnews(1).
-
-Nearly every program in INN uses this file to one degree or another.  The
-above are just the major and most frequently mentioned ones.
diff --git a/doc/pod/innconfval.pod b/doc/pod/innconfval.pod
deleted file mode 100644 (file)
index c73d6e7..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-=head1 NAME
-
-innconfval - Get configuration parameters from inn.conf
-
-=head1 SYNOPSIS
-
-B<innconfval> [B<-pstv>] [B<-i> I<file>] [I<parameter> ...]
-
-B<innconfval> B<-C> [B<-i> I<file>]
-
-=head1 DESCRIPTION
-
-B<innconfval> normally prints the values of the parameters specified on
-the command line.  By default, it just prints the parameter values, but if
-B<-p>, B<-s>, or B<-t> are given, it instead prints the parameter and
-value in the form of a variable assignment in Perl, Bourne shell, or Tcl
-respectively.  If no parameters are specifically requested, B<innconfval>
-prints out all parameter values (this isn't particularly useful unless one
-of B<-p>, B<-s>, or B<-t> were specified).
-
-All parameters are taken from F<inn.conf> except for I<version>, which is
-always the version string of INN.
-
-If given the B<-C> option, B<innconfval> instead checks F<inn.conf>,
-reporting any problems found to standard error.  B<innconfval> will exit
-with status 0 if no problems are found and with status 1 otherwise.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-C>
-
-Check F<inn.conf> rather than printing out the values of parameters.
-
-=item B<-i> I<file>
-
-Use I<file> as the source configuration file rather than F<inn.conf>.
-I<file> must be a valid F<inn.conf> file and will be parsed the same as
-F<inn.conf> would be.
-
-=item B<-p>
-
-Print out parameters as Perl assignment statements.  The variable name
-will be the same as the F<inn.conf> parameter, and string values will be
-enclosed in single quotes with appropriate escaping.  Boolean values will
-be mapped to C<true> or C<false>, and string parameters that are set to
-NULL will be mapped to empty strings.
-
-=item B<-s>
-
-Print out parameters as Bourne shell assignment statements.  The variable
-name will be the F<inn.conf> parameter name in all capitals, and all
-variables will be exported.  String values will be enclosed in single
-quotes with appropriate escaping, and boolean values will be mapped to
-C<true> or C<false>.  String parameters that are set to NULL will be
-mapped to empty strings.
-
-=item B<-t>
-
-Print out parameters as Tcl assignment statements.  The variable name will
-be the same as the F<inn.conf> parameter name but with C<inn_> prepended,
-and string variables will be escaped appropriately.  Boolean values will
-be mapped to C<true> or C<false> and string parameters that are set to
-NULL will be mapped to empty strings.
-
-=item B<-v>
-
-Print INN's version.  This is equivalent to C<innconfval version>.
-
-=back
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-
-$Id: innconfval.pod 5962 2002-12-08 19:52:13Z rra $
-
-=head1 SEE ALSO
-
-inn.conf(5)
-
-=cut
diff --git a/doc/pod/innd.pod b/doc/pod/innd.pod
deleted file mode 100644 (file)
index f79323c..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-=head1 NAME
-
-innd - InterNetNews daemon
-
-=head1 SYNOPSIS
-
-B<innd> [B<-aCdfNrsu>] [B<-c> I<days>] [B<-H> I<count>] [B<-i> I<count>]
-[B<-I> I<address>] [B<-l> I<size>] [B<-m> I<mode>] [B<-n> I<flag>]
-[B<-o> I<count>] [B<-p> I<fd>] [B<-P> I<port>] [B<-t> I<timeout>]
-[B<-T> I<count>] [B<-X> I<seconds>]
-
-=head1 DESCRIPTION
-
-B<innd>, the InterNetNews daemon, handles all incoming NNTP feeds,
-coordinates the storage, retransmission, and overview generation for all
-accepted articles, and manages the active(5) and history(5) databases.  It
-handles incoming connections on the NNTP port, and also creates and
-listens to a local Unix-domain stream socket in order to receive articles
-from local processes such as nnrpd(8) and rnews(1).
-
-As the master daemon, B<innd> should generally be started at boot and be
-always running.  It listens to a Unix-domain datagram socket for commands
-to control its activites, commands that can be sent using ctlinnd(8).  The
-current status of B<innd> can be obtained by running C<ctlinnd mode>, or
-for more detailed output, innstat(8).
-
-B<innd> can be in one of three operating modes:  running, paused, or
-throttled.  Running is the normal mode; when the server is throttled, it
-closes connections and rejects new ones.  Paused is like a temporary
-throttle, suspending B<innd>'s activities but not causing the server to
-shut down existing connections.  The mode is normally changed via
-ctlinnd(8), either by various automated processes (such as nightly article
-expiration) or manually by the news administrator, but B<innd> will also
-throttle itself if it encounters ENOSPC errors in writing data or an
-excessive number of I/O errors (among other problems).
-
-B<innd> normally takes care of spawning nnrpd(8) to handle connections
-from news reading clients, but it can be run on a separate port from
-nnrpd(8) so that feed connections and news reading connections are handled
-separately (this can often be faster).  Normally, B<innd> listens on port
-119, the assigned port for NNTP; if it is desireable to run B<innd> and
-nnrpd(8) on separate ports, it's recommended that nnrpd(8) be given port
-119 (since many news reading clients connect only to that port) and that
-port 433 be used for B<innd>.
-
-The primary configuration files that control B<innd>'s activities are
-F<incoming.conf>, which specifies what remote sites B<innd> will accept
-connections from, F<newsfeeds>, which specifies what is to be done with
-incoming articles besides storing them, and F<inn.conf>, which sets a wide
-variety of configuration parameters.  Some parameters in inn.conf(5) can
-also be set with command-line flags; for these, the command-line flags
-take precedence if used.
-
-B<innd> should normally not run directly.  It must run as the news user or
-all sorts of file ownership problems may result, and normally the port it
-listens on (119 or 433) is privileged and must be opened by root.
-Instead, B<innd> should normally be started via inndstart(8), a small
-setuid-root program that opens the appropriate port, cleans up the
-environment, changes to the news user, and then runs B<innd>, passing
-along any command-line arguments.
-
-To use IPv6, B<innd> must be started by B<inndstart>.
-
-=head1 OPTIONS
-
-For the options below that override F<inn.conf> settings, see inn.conf(5)
-for the default values if neither the F<inn.conf> setting nor the
-command-line option is given.
-
-=over 4
-
-=item B<-a>
-
-By default, if a host connects to B<innd> but is not listed in
-F<incoming.conf>, the connection is handed off to B<nnrpd> (or rejected if
-I<noreader> is set in F<inn.conf>).  If B<-a> is given, F<incoming.conf>
-is ignored and any host can connect and transfer articles.  This flag
-should never be used with an accessible server connected to Usenet; it
-would open the server up for all sorts of abuse.
-
-=item B<-c> I<days>
-
-B<innd> normally rejects any article that is older (in days) than the
-value of I<artcutoff> in F<inn.conf>.  This option, if given, overrides
-the value of that setting.  If I<days> is 0, this check is suppressed and
-B<innd> will accept articles regardless of how old they are.
-
-=item B<-C>
-
-This flag tells B<innd> to accept and propagate but not actually process
-cancel or supersede messages.  This is intended for sites concerned about
-abuse of cancels, or that wish to use another cancel mechanism with
-stronger authentication.
-
-=item B<-d>, B<-f>
-
-B<innd> normally puts itself into the background, points its standard
-output and error to log files, and disassociates itself from the
-terminal.  Using B<-d> prevents all of this, resulting in log messages
-being written to standard output; this is generally useful only for
-debugging.  Using B<-f> prevents the backgrounding and disassociation but
-still redirects output; it may be useful if you want to monitor B<innd>
-with a program that would be confused by forks.
-
-=item B<-H> I<count>, B<-T> I<count>, B<-X> I<seconds>
-
-These flags control the number of connections per minute that are allowed.
-This code is meant to protect your server from newsreader clients that
-make too many connections per minute (and therefore these flags are
-probably only useful when B<innd> is spawning B<nnrpd>).  You probably
-should not use these options unless you're having problems.  The table
-used for this check is fixed at 128 entries and is used as a ring; the
-size was chosen to make calculating the index easy and to be fairly sure
-that it won't run out of space.  In practice, it is unlikely that even
-half the table will be used at any given moment.
-
-The B<-H> flag limits the number of times a host is allowed to connect to
-the server per the time interval given by B<-X>.  The default is C<2>.
-
-The B<-T> flag limits the total number of incoming connections per the
-time interval given by B<-X>.  The maximum value is C<128>, and the
-default is C<60>.
-
-=item B<-i> I<count>
-
-B<innd> normally allows a maximum number of concurrent NNTP connections
-given by the value of I<maxconnections> in F<inn.conf>.  This option, if
-given, overrides the value of that setting.  If I<count> is C<0>, this
-check is suppressed.
-
-=item B<-I> I<address>
-
-Normally if B<innd> itself binds to a port, it lets the operating system
-pick the source IP address (unless I<bindaddress> is set in F<inn.conf>).
-If this option is given, it specifies the IP address that INN should bind
-as.  This is only relevant for servers with multiple local IP addresses.
-The IP address must be in dotted quad (C<nnn.nnn.nnn.nnn>) format.
-
-This option is rarely useful since B<innd> should not be binding to a
-port itself.  Instead, use inndstart(8) and its analgous B<-I> option.
-
-=item B<-l> I<size>
-
-B<innd> normally rejects any article larger than the value of
-I<maxartsize> in F<inn.conf>.  This option, if given, overrides the value
-of that setting and specifies a maximum article size of I<size>.  If
-I<size> is C<0>, this check is suppressed.
-
-=item B<-m> I<mode>
-
-Normally B<innd> starts in the C<running> mode.  If this option is given,
-it specifies what mode B<innd> should start in.  I<mode> should begin with
-one of C<g>, C<p>, or C<t>, and the starting mode will be set to
-C<running>, C<paused>, or C<throttled>, respectively, based on that
-initial letter.  (C<g> is short for C<go>.)
-
-=item B<-N>
-
-If this option is given, any filters (Perl, Tcl, or Python) are disabled
-before B<innd> starts (normally, filters default to being enabled).  The
-filters can be enabled after B<innd> has started with ctlinnd(8).
-
-=item B<-n> I<flag>
-
-Whether B<innd> allows (and hands off to B<nnrpd>) reader connections
-while paused or throttled is normally determined by the value of
-I<readerswhenstopped> in F<inn.conf>).  This option, if given, overrides
-that value.  If I<flag> is C<n>, B<innd> will not allow readers if it is
-paused or throttled.  If I<flag> is C<y>, readers will be allowed
-regardless of B<innd>'s operating mode.
-
-=item B<-o> I<count>
-
-This flag limits the number of file descriptors that are available for
-outgoing file feeds.  The default is the number of available file
-descriptors minus some reserved for internal use (which could potentially
-starve B<innd> of descriptors to use for accepting new connections).  If
-B<innd> has more file feeds than I<count>, some of them will be buffered
-and only written out periodically.
-
-Normally you never need to use this option, since the number of outgoing
-feeds is fixed, being the number of file feeds configured in F<newsfeeds>,
-and is generally small (particularly given that innfeed(8) is now used for
-most outgoing feeds at large sites).
-
-=item B<-p> I<fd>
-
-If this flag is given, B<innd> expects the file descriptor given by I<fd>
-to already be open and bound to the appropriate local port and to be
-suitable for listening to for incoming connections.  This is how
-B<inndstart> tells B<innd> which open file descriptor is the network
-connection.  If this flag is not given, B<innd> will attempt to open its
-network socket itself.  B<inndstart> always passes this flag to B<innd>.
-
-=item B<-P> I<port>
-
-The port B<innd> should listen on is normally given by the value of
-I<port> in F<inn.conf>.  This option, if given, overrides that value and
-specifies the port that B<innd> should bind to.  This option is rarely
-useful since B<innd> normally does not bind itself; instead the analgous
-B<-P> option to inndstart(8) should be used.  Since B<innd> should never
-be run as root, I<port> has to be a non-privileged port (one larger than
-1024).
-
-=item B<-r>
-
-Instructs B<innd> to renumber the F<active> file after starting, just as
-if a C<ctlinnd renumber> command were sent.
-
-=item B<-s>
-
-Just check the syntax of the F<newsfeeds> file and exit.  B<innd> will
-exit with a non-zero status if any errors are found; the actual errors
-will be reported via syslog(3).
-
-=item B<-t> I<seconds>
-
-Normally, B<innd> will flush any changes to history and the active file
-after 300 seconds of inactivity.  This option changes that timeout to
-I<seconds>.
-
-=item B<-u>
-
-The news log (the trace information for every article accepted by B<innd>)
-is normally buffered.  This option changes the log to be unbuffered.
-
-=back
-
-=head1 CONTROL MESSAGES
-
-Arriving articles that have a Control: header are called "control
-messages".  Except for cancel messages, these messages are handled by
-controlchan(8) via a feed set up in F<newsfeeds>.
-
-(Cancel messages update the history database, so they must be handled
-internally; the cost of syncing, locking, then unlocking would be too high
-given the number of cancel messages that are received.  Note that if an
-article is cancelled before it is received by the news server, it will
-be rejected when it arrives since the history database has been updated;
-it is useful for rejecting spam before it arrives.)
-
-The distribution of control messages is different than that of standard
-articles.  Control messages are normally filed into the pseudo-newsgroup
-named C<control> regardless of which newsgroup they were actually posted
-to.  If, however, a C<control.>I<command> newsgroup exists that matches
-the control command, the control message will be filed into that group
-instead.  For example, a newgroup control message will be filed in
-C<control.newgroup> if that group exists; otherwise, it will be filed in
-C<control>.
-
-If you want to specifically feed all control messages to a given site
-regardless of whether the control messages would affect the newsgroups
-you're feeding that site, you can put the appropriate control newsgroup in
-the subscription list.  For example, to feed all cancel messages to a
-given remote site (normally a bad idea), add C<control.cancel> to its
-subscription list.  Normally it's best to exclude the control newsgroups
-from feeds to keep from sending your peers more control messages than they
-care about.  That's why the F<newsfeeds> pattern C<!control,!control.*>
-is as often as not specified (adding this pattern do not prevent control
-messages which affect the newsgroups fed to a site from being sent to it).
-
-checkgroups, newgroup and rmgroup control messages receive additional special
-treatment.  If one of these control messages is approved and posted to the
-newsgroup being created or removed (or to the admin group to which the
-checkgroups is posted), the message will be sent to all sites
-whose subscription patterns would cause them to receive articles posted to
-that group.  For example, if a newgroup control message for a nonexistent
-newsgroup C<news.admin.meow> is received, it will be sent to any site
-whose subscription pattern would cause it to receive C<news.admin.meow> if
-that newsgroup existed (such as a pattern of C<news.admin.*>).  For this
-reason, it is correct to post newgroup messages to the newsgroup that the
-control message would create.  It is I<not> generally correct to crosspost
-newgroup messages to some "well-propagated" newsgroup; not only will this
-not actually improve their propagation to sites that want such control
-messages, but it will also cause sites that do not want those control
-messages to receive them.  Therefore, assuming that a newgroup control
-message is sent to the group C<news.admin.meow> (specified in the
-Newsgroups: header) in order to create the group C<news.admin.meow>,
-the sites with the following subscription patterns will receive it:
-
-    *,@news.*
-    news.*
-    news.*,!control,!control.*
-    control,control.*
-
-but the sites with the following subscription patterns will not receive it:
-
-    *,@news.*,!control,!control.*
-    comp.*,@news.*
-
-If a control message is posted to a group whose name ends with the four
-characters C<.ctl>, this suffix is stripped off and the control message is
-propagated as if it were posted to the base group.  For example, a cancel
-message posted to C<news.admin.ctl> will be sent to all sites that
-subscribe to C<control.cancel> (or C<control> if that newsgroup doesn't
-exist) or C<news.admin>.  This behavior is present for historical
-compatibility reasons and should be considered obsolete; support for the
-C<.ctl> suffix may be removed in a future version of INN.
-
-Finally, articles posted to newsgroups beginning with C<to.> are treated
-specially.  Provided that either that newsgroup exists in the F<active> file
-or I<mergetogroups> is set in F<inn.conf>, the remainder of the newsgroup
-is taken to be a site name, as configured in F<newsfeeds>, and the article
-is sent to that site.  If I<mergetogroups> is set, the article will be
-filed in the group named C<to> (which must exist in the F<active> file).  For
-example, with I<mergetogroups> set, an article posted to C<to.uunet> will
-be filed in C<to> and sent to the site C<uunet>.
-
-=head1 PROTOCOL DIFFERENCES
-
-B<innd> implements the NNTP commands defined in RFC 977, with the
-following differences:
-
-=over 4
-
-=item 1.
-
-The LIST command may be followed by an optional ACTIVE, ACTIVE.TIMES, or
-NEWSGROUPS.  There is only basic support for LIST in B<innd> since feeding
-peers normally don't need it; see nnrpd(8) for full support.
-
-=item 2.
-
-The AUTHINFO USER and AUTHINFO PASS commands are implemented, although the
-authentication is currently limited to matching a password for a given
-peer specified in F<incoming.conf>.  These are based on the reference Unix
-implementation.
-
-=item 3.
-
-A new command, MODE READER, is implemented.  This command will cause the
-server to pass the connection to B<nnrpd>.
-
-=item 4.
-
-The streaming extension (MODE STREAM, CHECK, and TAKETHIS) is fully
-supported.
-
-=item 5.
-
-A batch transfer command, XBATCH I<byte-count>, is provided.  This command
-will read I<byte-count> bytes and store them for later processing by
-rnews(1) (which must be run separately, probably from cron).  See
-innxbatch(8) and F<backends/sendxbatches> for more details on this
-extension.
-
-=item 6.
-
-B<innd> implements a limited subset of the protocol useful for
-transferring news.  The only other commands implemented are HEAD, HELP,
-IHAVE, STAT, and QUIT.  The remaining commands are mostly only useful for
-readers and are implemented by nnrpd(8).
-
-=back
-
-=head1 HEADER MODIFICATIONS
-
-B<innd> modifies as few article headers as possible, although it could be
-better in this area.
-
-Empty headers and headers that consist of nothing but whitespace are
-dropped.
-
-The local site's name (as set with the I<pathhost> parameter in
-F<inn.conf>) and an exclamation point are prepended to the Path: header,
-provided the first site name in the Path: header is different from the
-local one.  In addition, I<pathalias> and I<pathcluster> may be similarly
-respectively prepended and appended to the Path: header; see inn.conf(5)
-for the details.
-
-The Xref: header is removed and a new one created.
-
-A Lines: header will be added if the article was missing one.
-
-B<innd> does not rewrite incorrect headers.  For example, it will not
-replace an incorrect Lines header, though it may reject such an article
-depending on the value of I<linecountfuzz> in F<inn.conf>.
-
-=head1 CANCEL FEEDS
-
-In order to efficiently apply a large number of local cancels (such as
-from processing NoCeMs or from some other external source), INN supports a
-special feed mode available only to connections to the local Unix domain
-socket (not to connections to any network sockets).
-
-To enter this mode, connect to the Unix domain socket (I<pathrun>/nntpin)
-and send the command MODE CANCEL.  The response will have code C<284>.
-Every subsequent line sent on that connection should consist of a single
-message ID.  An attempt will be made to cancel that message ID, and the
-server will reply C<289> for success or C<484> for failure.  (Failure can
-occur, for example, if the server is paused or throttled, or the
-Message-ID is corrupt.  Failure does I<not> occur if the article to be
-cancelled does not exist.)
-
-=head1 LOGGING
-
-B<innd> reports all incoming articles in its log file (I<pathlog>/news).
-This is a text file with a variable number of space-separated fields in
-one of the following formats:
-
-    mon dd hh:mm:ss.mmm + feed <message-id> site ...
-    mon dd hh:mm:ss.mmm j feed <message-id> site ...
-    mon dd hh:mm:ss.mmm c feed <message-id> Cancelling <message-id>
-    mon dd hh:mm:ss.mmm - feed <message-id> reason
-    mon dd hh:mm:ss.mmm ? feed <message-id> reason
-
-There may also be hostname and/or size fields after the message ID
-depending on the settings of I<nntplinklog> and I<logartsize> in
-F<inn.conf>.
-
-The first three fields are the date and time to millisecond resolution.
-The fifth field is the site that sent the article (based on the Path
-header) and the sixth field is the article's message ID; they will be a
-question mark if the information is not available.
-
-The fourth field indicates whether the article was accepted or not.  If it
-is a plus sign, then the article was accepted.  If it is the letter C<j>
-then the article was accepted, but all of the newsgroups to which the
-article was posted were set to mode C<j> in the active file (or not listed
-in the active file and I<wanttrash> was set in F<inn.conf>) so the article
-was filed into the C<junk> newsgroup.  In both of these cases, the article
-has been accepted and the C<site ...> field contains the space-separated
-list of sites to which the article is being sent.
-
-If the fourth field is the letter C<c>, then a cancel message was accepted
-before the original article arrived, and a history entry for the cancelled
-message was created so that B<innd> will reject that message if it arrives
-later.
-
-If the fourth field is a minus sign, then the article was rejected.  The
-reasons for rejection generated by B<innd> include:
-
-    "%s" header too long
-    "%s" wants to cancel <%s> by "%s"
-    Article exceeds local limit of %s bytes
-    Article posted in the future -- "%s"
-    Bad "%s" header
-    Can't write history
-    Duplicate
-    Duplicate "%s" header
-    EOF in headers
-    Linecount %s != %s +- %s
-    Missing %s header
-    No body
-    No colon-space in "%s" header
-    No space
-    Space before colon in "%s" header
-    Too old -- "%s"
-    Unapproved for "%s"
-    Unwanted newsgroup "%s"
-    Unwanted distribution "%s"
-    Whitespace in "Newsgroups" header -- "%s"
-
-where C<%s>, above, is replaced by more specific information.  (The Perl,
-Python, andr Tcl filters, if used, may reject articles with other
-reasons.)
-
-If the fourth field is the letter C<?>, the article contains strange
-strings, such as CR without LF or LF without CR.  (These characters should
-never occur in isolation, only together as CRLF to indicate the end of a
-line.)  This log message is just informational, to give an idea of how
-widespread such articles are; B<innd> does not reject such articles.
-
-Note that when I<wanttrash> is set to true in F<inn.conf> and an article
-is received that isn't posted to any valid newsgroups, it will be accepted
-and logged with two lines, a C<j> line and a minus sign line.
-
-B<innd> also makes extensive reports through syslog(3).  The first word of
-the log message will be the name of the site if the entry is site-specific
-(such as a "connected" message).  The first word will be C<SERVER> if the
-message relates to the server itself, such as when a read error occurs.
-
-If the second word is the four letters C<cant>, then an error is being
-reported.  (The absence of an apostrophe is intentional; it makes it
-easier to grep from the command line and easier to find error messages in
-FAQs using a search engine.)  In this case, the next two words generally
-name the system call or library routine that failed and the object upon
-which the action was being performed.  The rest of the line may contain
-other information.
-
-In other cases, the second word attempts to summarize what change has been
-made, while the rest of the line gives more specific information.  The
-word C<internal> generally indicates an internal logic error.
-
-=head1 SIGNALS
-
-B<innd> will catch SIGTERM and SIGHUP and shut down.  If B<-d> is used,
-SIGINT will also be caught and will result in an orderly shutdown.
-
-B<innd> will catch the SIGUSR1 signal and recreate the control channel
-used by ctlinnd(8).
-
-=head1 BUGS
-
-B<innd> normally attempts to strip IP options from incoming connections,
-since it uses IP-based authentication and source routing can confuse that.
-However, this doesn't work on all systems, and it doesn't work at all in
-the presence of IPv6 support (and is disabled in that case).  Hence, if
-using B<innd> with IPv6 support, make sure that your kernel or router
-disables source routing.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
-
-$Id: innd.pod 7748 2008-04-06 13:49:56Z iulius $
-
-=head1 SEE ALSO
-
-active(5), ctlinnd(8), dbz(3), history(5), incoming.conf(5), inn.conf(5),
-newsfeeds(5), nnrpd(8), rnews(1), syslog(3).
-
-=cut
diff --git a/doc/pod/inndf.pod b/doc/pod/inndf.pod
deleted file mode 100644 (file)
index f0d1004..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-=head1 NAME
-
-inndf - Report free disk, inodes, and overview information
-
-=head1 SYNOPSIS
-
-B<inndf> [B<-Fhi>] [B<-f> I<filename>] I<directory> [I<directory> ...]
-
-B<inndf> B<-n>
-
-B<inndf> B<-o>
-
-=head1 DESCRIPTION
-
-B<inndf> was originally a replacement for C<df | awk> in innwatch.ctl(5)
-and innstat(8), and now also reports various other usage information about
-INN's storage that df(1) doesn't understand.  B<inndf> doesn't sync, forks
-less, and is generally less complicated than df(1).
-
-Its default behavior is to report free kilobytes (not disk blocks), or
-free inodes if B<-i> is used, in the file systems holding the directories
-given on the command line.  (A kilobyte in this case is 1024 bytes.)  If
-only one directory is given, the output will be a simple number; if more
-than one directory is given, the output will be formatted for human
-readability.
-
-If I<enableoverview> is set to true in F<inn.conf>, B<inndf> can also be
-used to get information about the overview database.  With the B<-n>
-option, it reports a count of the total number of overview records stored.
-With B<-o>, it reports the percentage of space used in the overview
-database (for those overview methods where this is meaningful data).
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-f> I<filename>
-
-I<filename> should contain a list of directories to use in addition to
-those given by the arguments, one per line.  Blank lines and anything
-after C<#> on any line are ignored.
-
-=item B<-F>
-
-Like B<-f> execpt that the filename is I<pathetc>/filesystems and it is
-not an error if this file doesn't exist.  (This option is used primarily
-by such things as innstat(8), so that the news administrator can add
-additional file systems to check to I<pathetc>/filesystems without having
-to modify the script.)
-
-=item B<-h>
-
-Print a usage message and exit.
-
-=item B<-i>
-
-Report the number of free inodes rather than the amount of free disk
-space.
-
-=item B<-n>
-
-Report the total number of records in the overview database.  Note that
-crossposted articles will have one overview record for each newsgroup
-they're posted to.
-
-=item B<-o>
-
-Report the percentage usage of the overview database space.  This is only
-meaningful for overview methods that pre-allocate a certain amount of
-space rather than grow to accomodate more records.  Currently, this flag
-is only useful for the buffindexed overview method.
-
-=back
-
-=head1 EXAMPLES
-
-Print the free kilobytes in /news/spool as a simple number:
-
-    inndf /news/spool
-
-Report the free inodes in /usr/local/news and /news/spool in a format
-designed for human readability:
-
-    inndf -i /usr/local/news /news/spool
-
-The same, but also add in all file systems in I<pathetc>/filesystems:
-
-    inndf -i -F /usr/local/news /news/spool
-
-Print out the number of overview records and the percentage space used by
-a buffindexed overview database:
-
-    inndf -no
-
-=head1 HISTORY
-
-B<inndf> was written by Ian Dickinson <idickins@fore.com>.  This manual
-page was written by Swa Frantzen <Swa.Frantzen@belgium.eu.net>.  Thanks
-also to the following folks for ports, patches, and comments:
-
-    Mahesh Ramachandran <rr@eel.ufl.edu>
-    Chuck Swiger <chuck@its.com>
-    Sang-yong Suh <sysuh@kigam.re.kr>
-    Brad Dickey <bdickey@haverford.edu>
-    Taso N. Devetzis <devetzis@snet.net>
-    Wei-Yeh Lee <weiyeh@columbia.edu>
-    Jeff Garzik <jeff.garzik@spinne.com>
-
-and to all the other folks I met and worked with during my 10 years as a
-newsadmin.
-
-Katsuhiro Kondou added the B<-n> and B<-o> options.  Russ Allbery added
-reporting of percentage free disk space.  Support for B<-f> and B<-F> was
-added by Fabien Tassin <fta@sofaraway.org>.
-
-=head1 SEE ALSO
-
-df(1), innwatch.ctl(5), innstat(8).
-
-=cut
diff --git a/doc/pod/inndstart.pod b/doc/pod/inndstart.pod
deleted file mode 100644 (file)
index 84265ea..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-=head1 NAME
-
-inndstart - Start innd
-
-=head1 SYNOPSIS
-
-B<inndstart> [B<-P> I<port>] [B<-I> I<address>] [I<innd-options>]
-
-=head1 DESCRIPTION
-
-The purpose of B<inndstart> is to raise system file descriptor limits,
-open the privileged news transfer port, and then start innd(8), passing it
-the open file descriptor for the news port.  B<inndstart> is used since
-only privileged programs can perform those two operations and since
-B<innd> should not run with elevated privileges.  It is installed setuid
-root and drops privileges to the news user (as set at configure time)
-before running B<innd>.
-
-Normally there is no need to run B<inndstart> directly.  Instead, run
-rc.news(8) as the news user, and it will handle running B<inndstart>
-appropriately for you.
-
-Since B<inndstart> is setuid root, it is extremely restrictive about who
-can run it and what it is willing to do.  See L<"SECURITY"> for the full
-details.
-
-B<inndstart> can only be run by the news user; if run by any other user,
-it will abort.  It will also only bind to ports 119, 433, or a port number
-given at configure time with B<--with-innd-port> among those ports below
-1024, although it can bind to any port above 1024.  This is to prevent
-various security exploits possible by binding to arbitrary privileged
-ports.
-
-Before running B<innd>, B<inndstart> cleans out the environment and sets
-only those environment variables listed in L<"ENVIRONMENT">.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-P> I<port>
-
-Bind to I<port> instead of whatever is specified by I<port> in
-F<inn.conf>.  Note that this is subject to the constraints mentioned
-above.
-
-=item B<-I> I<address>
-
-Bind as I<address> instead of whatever is specified by I<bindaddress> in
-F<inn.conf>.  The default behavior is to bind to INADDR_ANY, and that's
-what's desired almost all the time.  This option, and the F<inn.conf>
-parameter, may be useful if the machine has multiple interface cards and
-B<innd> should only be listening on a particular one.
-
-=back
-
-All other options given on the command line are passed verbatim to
-B<innd>.  In addition, B<inndstart> will give the B<-p> option to B<innd>,
-specifying the file descriptor of the open network socket.
-
-=head1 SECURITY
-
-B<inndstart> is setuid root, and therefore an expected point of attack.
-It has therefore been carefully written with security in mind.  In a
-normal INN installation, it is installed setuid root and executable only
-by users in the news group.
-
-Ideally, everything about B<inndstart>'s operations would be hard-coded so
-that it could not be modified.  Fighting against this desire, however, is
-the ideal that as much of INN's operation as possible should be
-configurable at run-time using F<inn.conf>, and the news system should be
-able to an alternate inn.conf by setting INNCONF to the path to that file
-before starting any programs.  The configuration data therefore can't be
-trusted.
-
-The security model used is:
-
-=over 2
-
-=item *
-
-B<inndstart> can only be executed by the news user and news group, as
-determined at configure time and compiled into B<inndstart> as constants.
-Similarly, B<inndstart> will always setuid() and setgid() to those users
-before running B<innd>.  This is to prevent a user other than news but in
-the news group from using B<inndstart> to leverage that access into access
-to the news account.
-
-=item *
-
-As mentioned above, B<inndstart> will only bind to a very limited subset
-of ports below 1024.  There are various attacks that can be performed
-using random low-numbered ports, including exploits of the rsh(1) family
-of commands on some systems.
-
-=item *
-
-B<inndstart> does as little as possible as root, dropping privileges
-before performing any operations that do not require elevated privileges.
-
-=back
-
-This program therefore gives the news user the ability to revoke system
-file descriptor limits and bind to the news port, and nothing else.
-
-=head1 DIAGNOSTICS
-
-B<inndstart> may log the following messages to syslog and print them to
-stderr.
-
-=over 4
-
-=item can't bind: %s
-
-(Fatal) Unable to bind to the designated port.  This usually means that
-something else is already running on the news port.  Check with
-netstat(8) and make sure that inetd(8) doesn't think it's running a
-service on the same port you're trying to run B<innd> on.
-
-=item can't bind to restricted port %d
-
-(Fatal) B<inndstart> was told to bind to a low numbered port (under 1024)
-other than 119, 433, or a port number given at configure time.  This is
-not allowed for security reasons.  If you're running B<innd> on a port
-other than 119 or 433, you need to give the --with-innd-port flag to
-C<configure> when you compile INN.
-
-=item can't exec %s: %s
-
-(Fatal) B<inndstart> was unable to execute B<innd>.  Make sure that
-I<pathbin> is set correctly in inn.conf and that B<innd> is located in
-that directory and is executable by the news user.
-
-=item can't getgrnam(%s)
-
-(Fatal) Unable to determine the GID for the compiled-in news group.
-Perhaps the news group is not listed in F</etc/group>.
-
-=item can't getpwnam(%s)
-
-(Fatal) Unable to determine the UID for the compiled-in news user.
-Perhaps the news user is not listed in F</etc/passwd>.
-
-=item can't open socket: %s
-
-(Fatal) Something went wrong in creating the network socket.  Chances are
-your system is out of resources of some kind.
-
-=item can't set file descriptor limit to %d: %s
-
-(Warning) Unable to set the system file descriptor limit to the specified
-value; the limit was left unchanged.  Perhaps that value is too high for
-your system.  Try changing I<rlimitnofile> in F<inn.conf> to a smaller
-value.
-
-=item can't set SO_REUSEADDR: %s
-
-(Warning) B<inndstart> attempts to set SO_REUSEADDR using setsockopt(2) so
-that if B<innd> exits, it can be restarted again immediately without
-waiting for the port to time out.  For some reason, this failed, and that
-option was not set on the port.
-
-=item can't seteuid to %d: %s
-
-(Fatal) Unable to change the effective UID.  If B<inndstart> has the
-correct permissions (setuid root) and seteuid to root (UID 0) is failing,
-this may mean that your system has seteuid(2) but doesn't have support for
-POSIX saved UIDs.  If this is the case, please report this to the INN
-maintainers.
-
-=item can't setgid to %d: %s
-
-(Fatal) Dropping privileges to the news group failed for some reason.
-
-=item can't setgroups (is inndstart setuid root?): %s
-
-(Warning) Dropping all supplemental groups except the news group failed
-for some reason, and the process group membership was left unchanged.
-This almost always indicates that B<inndstart> isn't setuid root as it has
-to be to do what it does.  Make sure that B<inndstart> is setuid root,
-owned by group news, and mode 4710.
-
-=item can't setuid to %d: %s
-
-(Fatal) Dropping privileges to the news user failed for some reason.
-
-=item invalid address %s
-
-(Fatal) B<-I> was specified on the command line, but the argument wasn't a
-valid address.  Addresses must be given as numeric IP addresses.
-
-=item invalid bindaddress in inn.conf (%s)
-
-(Fatal) The I<bindaddress> specified in F<inn.conf> could not be converted
-to an IP address.  See inn.conf(5) for more information about valid
-values.
-
-=item invalid port %s (must be a number)
-
-(Fatal) B<-P> was specified on the command line, but the argument wasn't a
-valid port.  Ports must be port numbers; service names are not allowed.
-
-=item missing address after -I
-
-(Fatal) B<-I> was given on the command line, but no address was given
-after the option.
-
-=item missing port after -P
-
-(Fatal) B<-P> was given on the command line, but no port was given after
-the option.
-
-=item must be run by user %s (%d), not %d
-
-(Fatal) Someone other than the news user attempted to run B<inndstart>.
-B<inndstart> may only be run by the news user for security reasons.
-
-=back
-
-=head1 EXAMPLES
-
-Normally, B<inndstart> is never run directly.  However, a simple way to
-just restart B<innd> (if it is not running) without running any other
-auxilliary programs or performing any of the other checks done by
-rc.news(8) is to just run:
-
-    inndstart
-
-as the news user.
-
-To start B<innd> on port 433, passing it the C<-c21> option, use:
-
-    inndstart -P433 -c21
-
-=head1 ENVIRONMENT
-
-One environment variable affects the operation of B<inndstart> itself:
-
-=over 8
-
-=item INNCONF
-
-The full path to the inn.conf(5) file to read, rather than the default.
-This can be used to run multiple copies of INN on the same machine with
-different settings.
-
-=back
-
-When executing B<innd>, B<inndstart> cleans out the entire environmnent
-and sets only the following variables:
-
-=over 8
-
-=item BIND_INADDR
-
-Passed verbatim from B<inndstart>'s environment.  This is used by various
-programs to override the I<bindaddress> parameter in F<inn.conf> and
-therefore must be in B<innd>'s environment for programs like innfeed(8).
-
-=item HOME
-
-Set to I<pathnews> from F<inn.conf>.
-
-=item LOGNAME
-
-Set to the news master, as determined at configure time.
-
-=item PATH
-
-Set to I<pathbin> from F<inn.conf>, I<pathetc> from F<inn.conf>, and then
-F</bin>, F</usr/bin>, and F</usr/ucb> in that order.
-
-=item SHELL
-
-Set to the path to the system Bourne shell as determined by configure
-(probably F</bin/sh>).
-
-=item TMPDIR
-
-Set to I<pathtmp> from inn.conf.
-
-=item TZ
-
-Passed verbatim from B<inndstart>'s environment.
-
-=item USER
-
-Set to the news master, as determined at configure time.
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item inn.conf
-
-Read for I<pathnews>, I<pathbin>, I<pathtmp>, I<rlimitnofile>,
-I<bindaddress>, and I<port>.
-
-=item I<pathbin>/innd
-
-The binary that is executed as B<innd> and passed the open network socket.
-
-=back
-
-=head1 HISTORY
-
-Written by Russ Allbery E<lt>rra@stanford.eduE<gt> for InterNetNews.
-
-$Id: inndstart.pod 5909 2002-12-03 05:17:18Z vinocur $
-
-=head1 SEE ALSO
-
-inn.conf(5), innd(8)
-
-=cut
diff --git a/doc/pod/innmail.pod b/doc/pod/innmail.pod
deleted file mode 100644 (file)
index a858eec..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-=head1 NAME
-
-innmail - Simple mail-sending program
-
-=head1 SYNOPSIS
-
-B<innmail> [B<-h>] [B<-s> I<subject>] I<address> [I<address> ...]
-
-=head1 DESCRIPTION
-
-B<innmail> is a Perl script intended to provide the non-interactive
-mail-sending functionality of mail(1) while avoiding nasty security
-problems.  It takes the body of a mail message on standard input and sends
-it to the specified addresses by invoking the value of I<mta> in
-F<inn.conf>.
-
-At least one address (formatted for the MTA specified in F<inn.conf>, if it
-matters) is required.  B<innmail> will sanitize the addresses so that they
-contain only alphanumerics and the symbols C<@>, C<.>, C<->, C<+>, C<_>,
-and C<%>.
-
-B<innmail> was written to be suitable for the I<mailcmd> setting in
-F<inn.conf>.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>
-
-Gives usage information.
-
-=item B<-s> I<subject>
-
-Sets the Subject: header of the message.  A warning is issued if this
-option is omitted.
-
-=back
-
-=head1 EXAMPLES
-
-This sends a one-line message to the local user C<joe>:
-
-    echo "A one-line message." | innmail -s "Simple message" joe
-
-B<innmail> by default is used by INN for sending nightly reports and
-control message reports.
-
-=head1 BUGS
-
-B<innmail> fails on addresses that begin with C<->, although one might
-hope that the news server will not need to contact any such addresses.
-
-There are many "correct" addresses that will be silently modified by the
-sanitization process.  A news administrator should be careful to use
-particularly sane addresses if they may be passed to B<innmail>.
-
-=head1 HISTORY
-
-B<innmail> was written by James Brister <brister@vix.com> for
-InterNetNews.  This manual page was originally written by Jeffrey
-M. Vinocur.
-
-=head1 SEE ALSO
-
-inn.conf(5), mail(1).
-
-=cut
diff --git a/doc/pod/innupgrade.pod b/doc/pod/innupgrade.pod
deleted file mode 100644 (file)
index 656f05b..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-=head1 NAME
-
-innupgrade - Upgrade INN configuration files
-
-=head1 SYNOPSIS
-
-B<innupgrade> I<directory>
-
-B<innupgrade> [B<-t> I<type>] B<-f> I<file>
-
-=head1 DESCRIPTION
-
-B<innupgrade> is intended to be run during a major upgrade of INN to fix
-the configuration files with any required changes.  If given a directory,
-it will scan that directory for any files that it has updates defined for,
-try to perform those updates, and replace the files with updated versions
-if applying the updates resulted in any changes.  The old versions of the
-files will be saved with a C<.OLD> extension.
-
-If the B<-f> flag is used, only that file will be updated.  If the file
-name doesn't match the standard file name of an INN configuration file,
-the optional B<-t> flag may be given to specify the type.  See
-L<"EXAMPLES"> for an example of this.
-
-Currently, B<innupgrade> knows how to apply the following updates:
-
-=over 2
-
-=item *
-
-F<inn.conf>:  Quote values with whitespace and comment out keys with no
-values, required for the change in configuration parsers introduced in INN
-2.4.  The new format is not backward compatible with the previous parser,
-since the previous parser will include the double-quotes in the value of
-the parameter.
-
-=back
-
-Normally, B<innupgrade> should be run on the I<pathetc> directory after
-any upgrade of INN other than a patch release (any upgrade that changes
-the first or second version numbers).  This may occur automatically during
-the upgrade process.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-f> I<file>
-
-Only act on I<file> rather than working on an entire directory.
-
-=item B<-t> I<type>
-
-For a file specified with B<-f>, parse it and upgrade it as if it were
-named I<type>.  Used for upgrading files with the same syntax as normal
-INN configuration files but with different names.  Only makes sense in
-combination with B<-f>.
-
-=back
-
-=head1 EXAMPLES
-
-Upgrade any configuration files found in F</usr/local/news/etc>:
-
-    innupgrade /usr/local/news/etc
-
-Upgrade only F</news/etc/inn.conf>:
-
-    innupgrade -f /news/etc/inn.conf
-
-Upgrade a file named F<inn-special.conf> that should have the same syntax
-as F<inn.conf>:
-
-    innupgrade -t inn.conf -f inn-special.conf
-
-Any upgrade rules that apply to F<inn.conf> will be applied to the
-alternate file.
-
-=head1 HISTORY
-
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-
-$Id: innupgrade.pod 5909 2002-12-03 05:17:18Z vinocur $
-
-=cut
diff --git a/doc/pod/install.pod b/doc/pod/install.pod
deleted file mode 100644 (file)
index 3beb412..0000000
+++ /dev/null
@@ -1,1560 +0,0 @@
-=head1 Welcome to INN 2.4!
-
-Please read this document thoroughly before trying to install INN.  You'll
-be glad you did.
-
-If you are upgrading from a major release of INN prior to 2.3, it is
-recommended that you make copies of your old configuration files and use
-them as guides for doing a clean installation and configuration of 2.4.
-Many config files have changed, some have been added, and some have been
-removed.  You'll find it much easier to start with a fresh install than to
-try to update your old installation.  This is particularly true if you're
-upgrading from a version of INN prior to 2.0.
-
-If you are upgrading from INN 2.3 or later, you may be able to just update
-the binaries, scripts, and man pages by running:
-
-    make update
-
-after building INN and then comparing the new sample configuration files
-with your current ones to see if anything has changed.  If you take this
-route, the old binaries, scripts, and man pages will be saved with an
-extension of C<.OLD> so that you can easily back out.  Be sure to
-configure INN with the same options that you used previously if you take
-this approach (in particular, INN compiled with B<--enable-largefiles>
-can't read the data structures written by INN compiled without that flag,
-and vice versa).  If you don't remember what options you used but you have
-your old build tree, look at the comments at the beginning of
-F<config.status>.
-
-If you made ckpasswd setuid root so that you could use system passwords,
-you'll have to do that again after make update.  (It's much better to use
-PAM instead if you can.)
-
-If you use C<make update> to upgrade from INN 2.3, also look at the new
-sample configuration files in F<samples> to see if there are new options
-of interest to you.  In particular, F<control.ctl> has been updated and
-F<inn.conf> has various new options.
-
-For more information about recent changes, see F<NEWS>.
-
-=head1 Supported Systems
-
-As much as possible, INN is written in portable C and should work on any
-Unix platform.  It does, however, make extensive use of mmap(2) and
-certain other constructs that may be poorly or incompletely implemented,
-particularly on very old operating systems.
-
-INN has been confirmed to work on the following operating systems:
-
-    AIX 4.3
-    FreeBSD 2.2.x and up
-    HP-UX 10.20 and up
-    Linux 2.x (tested with libc 5.4, glibc 2.0 and up)
-    Mac OS X 10.2 and up
-    NetBSD 1.6 and up
-    OpenBSD 2.8 and up
-    SCO 5.0.4 (tested with gcc 2.8.1, cc)
-    Solaris 2.5.x and up
-    UnixWare 7.1
-    UX/4800 R11 and up
-
-If you have gotten INN working on an operating system other than the ones
-listed above, please let us know at <inn-bugs@isc.org>.
-
-=head1 Before You Begin
-
-INN requires several other packages be installed in order to be fully
-functional (or in some cases, to work at all):
-
-=over 2
-
-=item *
-
-In order to build INN, you will need a C compiler that understands ANSI C.
-If you are trying to install INN on an operating system that doesn't have
-an ANSI C compiler (such as SunOS), installing gcc is recommended.  You
-can get it from <ftp://ftp.gnu.org/gnu/gcc/> or its mirrors.  INN is
-tested with gcc more thoroughly than with any other compiler, so even if
-you have another compiler available, you may wish to use gcc instead.
-
-=item *
-
-Currently, in order to build INN, you will need an implementation of yacc.
-GNU bison (from <ftp://ftp.gnu.org/gnu/bison/> or its mirrors) will work
-fine.  We hope to remove this requirement in the future.
-
-=item *
-
-INN requires at least Perl 5.004_03 to build and to run several
-subsystems.  INN is tested primarily with newer versions of Perl, so it's
-generally recommended that you install the latest stable distribution of
-Perl before compiling INN.  For instructions on obtaining and installing
-Perl, see <http://www.perl.com/pub/language/info/software.html>.  Note
-that you may need to use the same compiler and options (particularly
-largefile support) for Perl and INN.
-
-If you're using a version of Perl prior to 5.6.0, you may need to make
-sure that the Perl versions of your system header files have been
-generated in order for Sys::Syslog to work properly (used by various
-utility programs, including controlchan).  To do this, run the following
-two commands:
-
-    # cd /usr/include
-    # h2ph * sys/*
-
-An even better approach is to install Perl 5.6.1 or later, which have a
-fixed version of Sys::Syslog that doesn't require this (as well as many
-other improvements over earlier versions of Perl).
-
-=item *
-
-The INN Makefiles use the syntax C<include FILE>, rather than the syntax
-expected by some BSDish systems of C<.include E<lt>FILEE<gt>>.  If your
-system expects the latter syntax, the recommended solution is to install
-GNU make from <ftp://ftp.gnu.org/make/>.  You may have GNU make already
-installed as gmake, in which case using gmake rather than make to build
-INN should be sufficient.
-
-=item *
-
-If you want to enable support for authenticated control messages (this is
-not required, but is highly recommended for systems carrying public Usenet
-hierarchies) then you will need to install some version of PGP.  The
-recommended version is GnuPG, since it's actively developed, supports
-OpenPGP, is freely available and free to use for any purpose (in the US
-and elsewhere), and (as of version 1.0.4 at least) supports the RSA
-signatures used by most current control message senders.
-
-Alternately, you can install PGP from <http://www.pgp.com/> or one of the
-international versions of it.  Be warned, however, that the licensing
-restrictions on PGP inside the United States are extremely unclear; it's
-possible that if you are installing INN for a company in the U.S., even if
-the news server is not part of the business of that company, you would
-need to purchase a commercial license for PGP.  For an educational or
-non-profit organization, this shouldn't be a problem.
-
-=item *
-
-If you want to use either the Python embedded hooks, you'll need to have a
-suitable versions of Python installed.  See F<doc/hook-python> for more
-information.
-
-=item *
-
-Many of INN's optional features require other packages (primarily
-libraries) be installed.  If you wish to use any of these optional
-features, you will need to install those packages first.  Here is a table
-of configure options enabling optional features and the software and
-versions you'll need:
-
-    --with-perl         Perl 5.004_03 or higher, 5.6.1+ recommended
-    --with-python       Python 1.5.2 or higher
-    --with-berkeleydb   BerkeleyDB 2.0 or higher, 4.2+ recommended
-    --with-openssl      OpenSSL 0.9.6 or higher
-    --with-sasl         SASL 2.x or higher
-    --with-kerberos     MIT Kerberos v5 1.2.x or higher
-
-If any of these libraries (other than Perl or Python) are built shared and
-installed in locations where your system doesn't search for shared
-libraries by default, you may need to encode the paths to those shared
-libraries in the INN binaries.  For more information on shared library
-paths, see:
-
-    <http://www.eyrie.org/~eagle/notes/rpath.html>
-
-For most systems, setting the environment variable LD_RUN_PATH to a
-colon-separated list of additional directories in which to look for shared
-libraries before building INN will be sufficient.
-
-=back
-
-=head1 Unpacking the Distribution
-
-Released versions of INN are available from ftp.isc.org in F</isc/inn>.
-New major releases will be announed on <inn-announce@isc.org> (see
-F<README>) when they're made.
-
-If you want more a more cutting-edge version, you can obtain current
-snapshots from from ftp.isc.org in directory F</isc/inn/snapshots>.  These
-are snapshots of the INN CVS tree taken daily; there are two snapshots
-made each night (one of the current development branch, and one of the
-stable branch consisting of bug fixes to the previous major release).
-They are stored in date format; in other words the snapshots from April
-6th, 2000, would be named F<inn-CURRENT-20000406.tar.gz> and
-F<inn-STABLE-20000406.tar.gz>.  Choose the newest file of whichever branch
-you prefer.  (Note that the downloading, configuring, and compiling steps
-can be done while logged in as any user.)
-
-The distribution is in gzip compressed tar archive format.  To extract it,
-execute:
-
-    gunzip -c <inn-src-file> | tar -xf -
-
-Extracting the source distribution will create a directory named
-F<< inn-<version> >> or F<< inn-<BRANCH>-<date> >> where the source
-resides.
-
-=head1 Installing INN
-
-Before beginning installation, you should make sure that there is a user
-on your system named C<news>, and that this user's primary group is set to
-a group called C<news>.  You can change these with the B<--with-news-user>
-and B<--with-news-group> options to configure (see below).  The home
-directory of this user should be set to the directory under which you wish
-to install INN (F</usr/local/news> is the default and is a good choice).
-INN will install itself as this user and group.  You can change these if
-you want, but these are the defaults and it's easier to stick with them on
-a new installation.
-
-By default, INN sends reports to the user C<usenet>.  This account isn't
-used for any other purposes.  You can change it with the
-B<--with-news-master> option to configure (see below).
-
-WARNING: By default, INN installs various configuration files as
-group-writeable, and in general INN is not hardened from a security
-standpoint against an attack by someone who is already in the news group.
-In general, you should consider membership in the news group as equivalent
-to access to the news account.  You should not rely on being able to keep
-anyone with access to the news GID from converting that into access to the
-news UID.  The recommended configuration is to have the only member of the
-group C<news> be the user C<news>.
-
-Installing INN so that all of its files are under a single directory tree,
-rather than scattering binaries, libraries, and man pages throughout the
-file system, is strongly recommended.  It helps keep everything involved
-in the operation of INN together as a unit and will make the installation
-instructions easier to follow.
-
-As a side note, whenever doing anything with a running news server, first
-log in as this user.  That way, you can ensure that all files created by
-any commands you run are created with the right ownership to be readable
-by the server.  Particularly avoid doing anything in the news spool itself
-as root, and make sure you fix the ownership of any created files if you
-have to.  INN doesn't like files in the news spool owned by a user other
-than the news user.  However, since certain binaries need to be setuid
-root, indiscriminate use of C<chown news> is not the solution.  (If you
-don't like to log in to system accounts, careful use of C<chmod g+s> on
-directories and a umask of C<002> or C<007> may suffice.)
-
-INN uses GNU autoconf and a generated configure script to make
-configuration rather painless.  Unless you have a rather abnormal setup,
-configure should be able to completely configure INN for your system.  If
-you want to change the defaults, you can invoke the configure script with
-one or more command line options.  Type:
-
-    ./configure --help
-
-for a full list of supported options.  Some of the most commonly used
-options are:
-
-=over 4
-
-=item B<--prefix>=PATH
-
-Sets the installation prefix for INN.  The default is F</usr/local/news>.
-All of INN's programs and support files will be installed under this
-directory.  This should match the home directory of your news user (it
-will make installation and maintenance easier).  It is not recommended to
-set this to F</usr>; if you decide to do that anyway, make sure to point
-INN's temporary directory at a directory that isn't world-writeable (see
-B<--with-tmp-dir> below).
-
-=item B<--with-db-dir>=PATH
-
-Sets the prefix for INN database files.  The default is F<PREFIX/db>,
-where PREFIX is F</usr/local/news> unless overridden with the option
-above.  The history and active files will be stored in this directory, and
-writes to those files are an appreciable percentage of INN's disk
-activity.  The history file can also be quite large (requiring up to 2 GB
-or more during nightly expire), so this is a common portion of INN to move
-to a different file system.
-
-=item B<--with-spool-dir>=PATH
-
-Sets the prefix for the news spool (when using any storage method other
-than CNFS) and the overview spool.  The default is F<PREFIX/spool>.  This
-is another common portion of INN to move to a different file system (often
-F</news>).
-
-=item B<--with-tmp-dir>=PATH
-
-Sets the directory in which INN will create temporary files.  This should
-under no circumstances be the same as the system temporary directory or
-otherwise be set to a world-writeable directory, since INN doesn't take
-care to avoid symlink attacks and other security problems possible with a
-world-writeable directory.  This directory should be reserved for the
-exclusive use of INN and only writeable by the news user.  Usage is
-generally light, so this is unlikely to need a separate partition.
-
-It's also possible to set the paths for most other sections of the INN
-installation independently; see C<./configure --help> and look for the
-B<--with-*-dir>=PATH options.
-
-=item B<--enable-largefiles>
-
-Enables large file support.  This is not enabled by default, even on
-platforms that support it, because it changes the format of INN's on-disk
-databases (making it difficult to upgrade an earlier INN installation) and
-can significantly increase the size of some of the history database files.
-Large file support is not necessary unless your history database is so
-large that it exceeds 2 GB or you want to use CNFS buffers larger than 2
-GB.
-
-The history, tradindexed and buffindexed overview, CNFS, and timecaf
-databases written by an INN built with this option are incompatible with
-those written by an INN without this option.
-
-=item B<--enable-tagged-hash>
-
-Use tagged hash table for the history database.  The tagged hash format
-uses much less memory but is somewhat slower.  This option is recommended
-if you have less than 256 MB of RAM on your news server.  If you install
-INN without tagged hash (the default) and expire takes an excessive amount
-of time, you should make sure the RAM in your system satisfies the
-following formula:
-
-    ram > 10 * tablesize
-
-          ram:  Amount of system RAM (in bytes)
-    tablesize:  3rd field on the 1st line of history.dir (bytes)
-
-If you don't have at least that much RAM, try rebuilding INN with tagged
-hash enabled.
-
-NOTE: B<--enable-largefiles> cannot be used with B<--enable-tagged-hash>.
-
-=item B<--with-perl>
-
-Enables support for embedded Perl, allowing you to install filter scripts
-written in Perl.  Highly recommended, because many really good spam
-filters are written in Perl.  See F<doc/hook-perl> for all the details.
-
-Even if you do not use this option, INN still requires Perl as mentioned
-above.
-
-=item B<--with-python>
-
-Enables support for Python, allowing you to install filter and
-authentication scripts written in Python.  You will need Python 1.5.2 or
-later installed on your system to enable this option.  See
-F<doc/hook-python> for all the details.  Note that there is an
-incompatibility between INN and Python 2.0 when Python is compiled with
-cycle garbage collection; this problem was reported fixed in Python 2.1a1.
-
-=item B<--with-innd-port>=PORT
-
-By default, inndstart(8) refuses to bind to any port under 1024 other than
-119 and 433 for security reasons (to prevent attacks on rsh(1)-based
-commands and replacing standard system daemons).  If you want to run innd
-on a different port under 1024, you'll need to tell configure what port
-you intend to use.  (You'll also still need to set the port number in
-F<inn.conf> or give it to inndstart on the command line.)
-
-=item B<--with-syslog-facility>=FACILITY
-
-Specifies the syslog facility that INN programs should log to.  The
-default is LOG_NEWS unless configure detects that your system doesn't
-understand that facility, in which case it uses LOG_LOCAL1.  This flag
-overrides the automatic detection.  Be sure to specify a facility not used
-by anything else on your system (one of LOG_LOCAL0 through LOG_LOCAL7, for
-example).
-
-=item B<--enable-libtool>
-
-INN has optional support for libtool to generate shared versions of INN's
-libraries.  This can significantly decrease the size of the various
-binaries that come with a complete INN installation.  You can also choose
-to use libtool even when only building static libraries; a libtool build
-may be somewhat more portable on weird systems.  libtool builds aren't the
-default because they take somewhat longer.  See C<./configure --help> for
-the various available options related to libtool builds.
-
-Please note that INN's shared library interface is not stable and may
-change drastically in future releases.  For this reason, it's also not
-properly versioned and won't be until some degree of stability is
-guaranteed, and the relevant header files are not installed.  Only INN
-should use INN's shared libraries, and you should only use the shared
-libraries corresponding to the version of INN that you're installing.
-
-Also, when updating an existing version of INN, INN tries to save backup
-copies of all files so that you can revert to the previous installed
-version.  Unfortunately, when using shared libraries, this confuses
-ldconfig on some systems (such as Linux) and the symbolic links for the
-libraries may point to the .OLD versions.  If this happens, you can either
-fix the links by hand or remove the .OLD versions and re-run ldconfig.
-
-=item B<--enable-uucp-rnews>
-
-If this option is given to configure, rnews will be installed setuid news,
-owned by group uucp, and mode 4550.  This will allow the UUCP subsystem
-to run rnews to process UUCP batches of news articles.  Prior to INN 2.3,
-installing rnews setuid news was standard; since most sites no longer use
-UUCP, it is no longer the default as of INN 2.3 and must be requested at
-configure time.  You probably don't want to use this option unless your
-server accepts UUCP news batches.
-
-=item B<--enable-setgid-inews>
-
-If this option is given to configure, inews will be installed setgid news
-and world-executable so that non-privileged users on the news server
-machine can use inews to post articles locally (somewhat faster than
-opening a new network connection).  For standalone news servers, by far
-the most common configuration now, there's no need to use this option;
-even if you have regular login accounts on your news server, INN's inews
-can post fine via a network connection to your running news server and
-doesn't need to use the local socket (which is what setgid enables it to
-do).  Installing inews setgid was the default prior to INN 2.3.
-
-=item B<--with-berkeleydb=PATH>
-
-Enables support for Berkeley DB (2.x or 3.x), which means that it will
-then be possible to use the ovdb overview method if you wish.  Enabling
-this configure option doesn't mean you'll be required to use ovdb, but it
-does require that Berkeley DB be installed on your system (including the
-header files, not just the runtime libraries).  If a path is given, it
-sets the installed directory of Berkeley DB (configure will search for it
-in some standard locations, but if you have it installed elsewhere, you
-may need this option).
-
-=item B<--with-openssl=PATH>
-
-Enables support for SSL for news reading, which means it will be possible
-to have SSL or TLS encrypted NNTP connections between your server and
-newsreaders.  This option requires OpenSSL be installed on your system
-(including the header files, not just the runtime libraries).  If a path
-is given, it sets the installed directory of OpenSSL.  After compiling and
-installing INN with this option, you'll still need to make a certificate
-and private key to use SSL.  See below for details on how to do that.
-
-=item B<--enable-ipv6>
-
-Enables support for IPv6 in innd, innfeed, nnrpd, and several of the
-supporting programs.  This option should be considered developmental at
-present.  For more information see F<doc/IPv6-info> (and if you have any
-particularly good or bad news to report, please let us know at
-<inn-bugs@isc.org>).
-
-=back
-
-For the most common installation, a standalone news server, a suggested
-set of options is:
-
-    ./configure --with-perl
-
-provided that you have the necessary version of Perl installed.
-(Compiling with an embedded Perl interpretor will allow you to use one of
-the available excellent spam filters if you so choose.)
-
-If the configure program runs successfully, then you are ready to build
-the distribution.  From the root of the INN source tree, type:
-
-    make
-
-At this point you can step away from the computer for a little while and
-have a quick snack while INN compiles.  On a decently fast system it
-should only take five or ten minutes at the most to build.
-
-Once the build has completed successfully, you are ready to install INN
-into its final home.  Type:
-
-    make install
-
-You will need to run this command as root so that INN can create the
-directories it needs, change ownerships (if you did not compile as the
-news user) and install a couple of setuid wrapper programs needed to raise
-resource limits and allow innd to bind to ports under 1024.  This step
-will install INN under the install directory (F</usr/local/news>, unless
-you specified something else to the configure script).
-
-If you are configuring SSL support for newsreaders, you must make a
-certificate and private key at least once.  Type:
-
-    make cert
-
-as root in order to do this.
-
-You are now ready for the really fun part:  configuring your copy of INN!
-
-=head1 Choosing an Article Storage Format
-
-The first thing to decide is how INN should store articles on your system.
-There are four different methods for you to choose from, each of which has
-its own advantages and disadvantages.  INN can support all four at the
-same time, so you can store certain newsgroups in one method and other
-newsgroups in another method.
-
-The supported storage formats are:
-
-=over 4
-
-=item tradspool
-
-This is the storage method used by all versions of INN previous to 2.0.
-Articles are stored as individual text files whose names are the same as
-the article number.  The articles are divided up into directories based on
-the newsgroup name.  For example, article 12345 in news.software.nntp
-would be stored as F<news/software/nntp/12345> relative to the root of the
-article spool.
-
-Advantages:  Widely used and well-understood storage mechanism, can read
-article spools written by older versions of INN, compatible with all
-third-party INN add-ons, provides easy and direct access to the articles
-stored on your server and makes writing programs that fiddle with the news
-spool very easy, and gives you fine control over article retention times.
-
-Disadvantages:  Takes a very fast file system and I/O system to keep up
-with current Usenet traffic volumes due to file system overhead.  Groups
-with heavy traffic tend to create a bottleneck because of inefficiencies
-in storing large numbers of article files in a single directory.  Requires
-a nightly expire program to delete old articles out of the news spool, a
-process that can slow down the server for several hours or more.
-
-=item timehash
-
-Articles are stored as individual files as in tradspool, but are divided
-into directories based on the arrival time to ensure that no single
-directory contains so many files as to cause a bottleneck.
-
-Advantages:  Heavy traffic groups do not cause bottlenecks, and fine
-control of article retention time is still possible.
-
-Disadvantages:  The ability to easily find all articles in a given
-newsgroup and manually fiddle with the article spool is lost, and INN
-still suffers from speed degredation due to file system overhead (creating
-and deleting individual files is a slow operation).
-
-=item timecaf
-
-Similar to timehash, articles are stored by arrival time, but instead of
-writing a separate file for each article, multiple articles are put in the
-same file.
-
-Advantages:  Roughly four times faster than timehash for article writes,
-since much of the file system overhead is bypassed, while still retaining
-the same fine control over article retention time.
-
-Disadvantages:  Even worse than timehash, and similar to cnfs (below),
-using this method means giving up all but the most careful manually
-fiddling with your article spool.  As one of the newer and least widely
-used storage types, timecaf has not been as thoroughly tested as the other
-methods.
-
-=item cnfs
-
-CNFS stores articles sequentially in pre-configured buffer files.  When
-the end of the buffer is reached, new articles are stored from the
-beginning of the buffer, overwriting older articles.
-
-Advantages:  Blazingly fast because no file creations or deletions are
-necessary to store an article.  Unlike all other storage methods, does not
-require manual article expiration; old articles are deleted to make room
-for new ones when the buffers get too full.  Also, with CNFS your server
-will never throttle itself due to a full spool disk, and groups are
-restricted to just the buffer files you give them so that they can never
-use more than the amount of disk space you allocate to them.
-
-Disadvantages:  Article retention times are more difficult to control
-because old articles are overwritten automatically.  Attacks on Usenet,
-such as flooding or massive amounts of spam, can result in wanted articles
-expiring much faster than you intended (with no warning).
-
-=back
-
-Some general recommendations:  If you are installing a transit news server
-(one that just accepts news and sends it out again to other servers and
-doesn't support any readers), use CNFS exclusively and don't worry about
-any of the other storage methods.  Otherwise, put high-volume groups and
-groups whose articles you don't need to keep around very long (binaries
-groups, *.jobs*, news.lists.filters, etc.) in CNFS buffers, and use
-timehash, timecaf, or tradspool (if you have a fast I/O subsystem or need
-to be able to go through the spool manually) for everything else.  You'll
-probably find it most convenient to keep special hierarchies like local
-hierarchies and hierarchies that should never expire in tradspool.
-
-If your news server will be supporting readers, you'll also need to choose
-an overview storage mechanism (by setting I<ovmethod> in F<inn.conf>).
-There are three overview mechanisms to choose from:  tradindexed,
-buffindexed, and ovdb.  tradindexed is very fast for readers, but it has
-to update two files for each incoming article and can be quite slow to
-write.  buffindexed can keep up with a large feed more easily, since it
-uses large buffers to store all overview information, but it's somewhat
-slower for readers (although not as slow as the unified overview in INN
-2.2).  ovdb stores overview data in a Berkeley DB database; it's fast and
-very robust, but requires more disk space.  See the ovdb(5) man page for
-more information on it.
-
-Note that ovdb has not been as widely tested as the other overview
-mechanisms and should be considered experimental.  tradindexed is the best
-tested and most widely used of the overview implementations.
-
-If buffindexed is chosen, you will need to create the buffers for it to
-use (very similar to creating CNFS buffers) and list the available buffers
-in F<buffindexed.conf>.  See buffindexed.conf(5) for more information.
-
-=head1 Configuring INN
-
-All documentation from this point on assumes that you have set up the news
-user on your system as suggested in L<Installing INN> so that the root of
-your INN installation is F<~news/>.  If you've moved things around by
-using options with C<configure>, you'll need to adjust the instructions to
-account for that.
-
-All of INN's configuration files are located in F<~news/etc>.  Unless
-noted otherwise, any files referred to below are in this directory.  When
-you first install INN, a sample of each file (containing lots of comments)
-is installed in F<~news/etc>; refer to these for concrete examples of
-everything discussed in this section.
-
-All of INN's configuration files, all of the programs that come with it,
-and some of its library routines have documentation in the form of man
-pages.  These man pages were installed in F<~news/man> as part of the INN
-installation process and are the most complete reference to how INN works.
-You're strongly encouraged to refer to the man pages frequently while
-configuring INN, and for quick reference afterwards.  Any detailed
-questions about individual configuration files or the behavior of specific
-programs should be answered in them.  You may want to add F<~news/man> to
-your MANPATH environment variable; otherwise, you may have to use a
-command like:
-
-    man -M ~news/man inn.conf
-
-to see the inn.conf(5) man page (for example).
-
-Before we begin, it is worth mentioning the wildmat pattern matching
-syntax used in many configuration files.  These are simple wildcard
-matches using the asterisk (C<*>) as the wildcard character, much like the
-simple wildcard expansion used by Unix shells.
-
-In many cases, wildmat patterns can be specified in a comma-separated list
-to indicate a list of newsgroups.  When used in this fashion, each pattern
-is checked in turn to see if it matches, and the last pattern in the line
-that matches the group name is used.  Patterns beginning with C<!> mean to
-exclude groups matching that pattern.  For example:
-
-    *, !comp.*, comp.os.*
-
-In this case, we're saying we match everything (C<*>), except that we
-don't match anything under comp (C<!comp.*>), unless it is actually under
-the comp.os hierarchy (C<comp.os.*>).  This is because non-comp groups
-will match only the first pattern (so we want them), comp.os groups will
-match all three patterns (so we want them too, because the third pattern
-counts in this case), and all other comp groups will match the first and
-second patterns and will be excluded by the second pattern.
-
-Some uses of wildmat patterns also support "poison" patterns (patterns
-starting with C<@>).  These patterns behave just like C<!> patterns when
-checked against a single newsgroup name.  Where they become special is for
-articles crossposted to multiple newsgroups; normally, such an article
-will be considered to match a pattern if any of the newsgroups it is
-posted to matches the pattern.  If any newsgroup the article is posted to
-matches an expression beginning with C<@>, however, that article will not
-match the pattern even if other newsgroups to which it was posted match
-other expressions.
-
-See uwildmat(3) for full details on wildmat patterns.
-
-In all INN configuration files, blank lines and lines beginning with a
-C<#> symbol are considered comments and are ignored.  Be careful, not all
-files permit comments to begin in the middle of the line.
-
-=head2 inn.conf
-
-The first, and most important file is F<inn.conf>.  This file is organized
-as a series of parameter-value pairs, one per line.  The parameter is
-first, followed by a colon and one or more whitespace characters, and then
-the value itself.  For some parameters the value is a string or a number;
-for others it is true or false.  (True values can be written as C<yes>,
-C<true>, or C<on>, whichever you prefer.  Similarly, false values can be
-written as C<no>, C<false>, or C<off>.)
-
-F<inn.conf> contains dozens of changeable parameters (see inn.conf(5) for
-full details), but only a few really need to be edited during normal
-operation:
-
-=over 4
-
-=item allownewnews
-
-If set to true then INN will support the NEWNEWS command for news readers.
-While this can be an expensive operation, its speed has been improved
-considerably as of INN 2.3 and it's probably safe to turn on without
-risking excessive server load.  The default is true.  (Note that the
-I<access:> setting in F<readers.conf> overrides this value; see
-readers.conf(5) for more details.)
-
-=item complaints
-
-Used to set the value of the X-Complaints-To: header, which is added to
-all articles posted locally.  The usual value would be something like
-C<abuse@example.com> or C<postmaster@example.com>.  If not specified, the
-newsmaster email address will be used.
-
-=item hiscachesize
-
-The amount of memory (in kilobytes) to allocate for a cache of recently
-used history file entries.  Setting this to 0 disables history caching.
-History caching can greatly increase the number of articles per second
-that your server is capable of processing.  A value of C<256> is a good
-default choice.
-
-=item logipaddr
-
-If set to true (the default), INN will log the IP address (or hostname, if
-the host is listed in F<incoming.conf> with a hostname) of the remote host
-from which it received an article.  If set to false, the trailing Path:
-header entry is logged instead.  If you are using controlchan (see below)
-and need to process ihave/sendme control messages (this is very, very
-unlikely, so if you don't know what this means, don't worry about it),
-make sure you set this to false, since controlchan needs a site name, not
-an IP address.
-
-=item organization
-
-Set this to the name of your organization as you want it to appear in the
-Organization: header of all articles posted locally and not already
-containing that header.  This will be overridden by the value of the
-ORGANIZATION environment variable (if it exists).  If neither this
-parameter nor the environment variable or set, no Organization: header
-will be added to posts which lack one.
-
-=item pathhost
-
-This is the name of your news server as you wish it to appear in the Path:
-header of all postings which travel through your server (this includes
-local posts and incoming posts that you forward out to other sites).  If
-this parameter is unspecified, the fully-qualified domain name (FQDN) of
-the machine will be used instead.  Please use the FQDN of your server or
-an alias for your server unless you have a very good reason not to; a
-future version of the news RFCs may require this.
-
-=item rlimitnofile
-
-If set to a non-negative value (the default is C<-1>), INN (both innd and
-innfeed) will try to raise the maximum number of open file descriptors to
-this value when it starts.  This may be needed if you have lots of
-incoming and outgoing feeds.  Note that the maximum value for this setting
-is very operating-system-dependent, and you may have to reconfigure your
-system (possibly even recompile your kernel) to increase it.  See L<File
-Descriptor Limits> for complete details.
-
-=back
-
-There are tons of other possible settings; you may want to read through
-inn.conf(5) to get a feel for your options.  Don't worry if you don't
-understand the purpose of most of them right now.  Some of the settings
-are only needed for very obscure things, and with more experience running
-your news server the rest will make more sense.
-
-=head2 newsfeeds
-
-F<newsfeeds> determines how incoming articles are redistributed to your
-peers and to other INN processes.  F<newsfeeds> is very versatile and
-contains dozens of options; we will touch on just the basics here.
-The manpage contains more detailed information.
-
-F<newsfeeds> is organized as a series of feed entries.  Each feed entry is
-composed of four fields separated by colons.  Entries may span multiple
-lines by using a backslash (C<\>) to indicate that the next line is a
-continuation of the current line.  (Note that comments don't interact with
-backslashes in the way you might expect.  A commented-out line ending in a
-backslash will still be considered continued on the next line, possibly
-resulting in more commented out than you intended or bizarre syntax
-errors.  In general, it's best to avoid commenting out lines in the middle
-of continuation lines.)
-
-The first field in an entry is the name of the feed.  It must be unique,
-and for feeds to other news servers it is usually set to the actual
-hostname of the remote server (this makes things easier).  The name can
-optionally be followed by a slash and a comma-separated exclude list.  If
-the feed name or any of the names in the exclude list appear in the Path
-line of an article, then that article will not be forwarded to the feed as
-it is assumed that it has passed through that site once already.  The
-exclude list is useful when a news server's hostname is not the same as
-what it puts in the Path header of its articles, or when you don't want a
-feed to receive articles from a certain source.
-
-The second field specifies a set of desired newsgroups and distribution
-lists, given as newsgroup-pattern/distribution-list.  The distribution
-list is not described here; see newsfeeds(5) for information (it's not
-used that frequently in practice).  The newsgroup pattern is a
-wildmat-style pattern list as described above (supporting C<@>).
-
-The third field is a comma-separated list of flags that determine both the
-type of feed entry and sets certain parameters for the entry.  See
-newsfeeds(5) for information on the flag settings; you can do a surprising
-amount with them.  The three most common patterns, and the ones mainly
-used for outgoing news feeds to other sites, are C<Tf,Wnm> (to write out a
-batch file of articles to be sent, suitable for processing by nntpsend and
-innxmit), C<Tm> (to send the article to a funnel feed, used with innfeed),
-and C<Tc,Wnm*> (to collect a funnel feed and send it via a channel feed to
-an external program, used to send articles to innfeed).
-
-The fourth field is a multi-purpose parameter whose meaning depends on the
-settings of the flags in the third field.  To get a feel for it using the
-examples above, for file feeds (C<Tf>) it's the name of the file to write,
-for funnel feeds (C<Tm>) it's the name of the feed entry to funnel into,
-and for channel feeds (C<Tc>) it's the name of the program to run and feed
-references to articles.
-
-Now that you have a rough idea of the file layout, we'll begin to add the
-actual feed entries.  First, we'll set up the special ME entry.  This entry
-is required and serves two purposes:  the newsgroup pattern specified here
-is prepended to the newsgroup list of all other feeds, and the
-distribution pattern for this entry determines what distributions (from
-the Distribution: header of incoming articles) are accepted from remote
-sites by your server.  The example in the sample newsfeeds file is a good
-starting point.  If you are going to create a local hierarchy that should
-not be distributed off of your system, it may be useful to exclude it from
-the default subscription pattern, but default subscription patterns are
-somewhat difficult to use right so you may want to just exclude it
-specifically from every feed instead.
-
-The ME entry tends to confuse a lot of people, so this point is worth
-repeating:  the newsgroup patterns set the default subscription for
-I<outgoing> feeds, and the distribution patterns set the acceptable
-Distribution: header entries for I<incoming> articles.  This is confusing
-enough that it may change in later versions of INN.
-
-There are two basic ways to feed articles to remote sites.  The most
-common for large sites and particularly for transit news servers is
-innfeed(8), which sends articles to remote sites in real time (the article
-goes out to all peers that are supposed to receive it immediately after
-your server accepts it).  For smaller sites, particularly sites where the
-only outgoing messages will be locally posted articles, it's more common
-to batch outgoing articles and send them every ten minutes or so from cron
-using nntpsend(8) and innxmit(8).  Batching gives you more control and
-tends to be extremely stable and reliable, but it's much slower and can't
-handle high volume very well.
-
-Batching outgoing posts is easy to set up; for each peer, add an entry to
-newsfeeds that looks like:
-
-    remote.example.com/news.example.com\
-        :<newsgroups>\
-        :Tf,Wnm:
-
-where <newsgroups> is the wildmat pattern for the newsgroups that site
-wants.  In this example, the actual name of the remote site is
-"remote.example.com", but it puts "news.example.com" in the Path: header.
-If the remote site puts its actual hostname in the Path: header, you won't
-need the C</news.example.com> part.
-
-This entry will cause innd to write out a file in F<~news/spool/outgoing>
-named F<remote.example.com> and containing the Message-ID and storage
-token of each message to send to that site.  (The storage token is INN's
-internal pointer to where an article is stored; to retrieve an article
-given its storage token, use sm(8)).  F<innxmit> knows how to read files
-of this format and send those articles to the remote site.  For
-information on setting it up to run periodically, see L<Setting Up the
-Cron Jobs> below.  You will also need to set up a config file for
-F<nntpsend>; see the man page for nntpsend.ctl(5) for more information.
-
-If instead you want to use F<innfeed> to send outgoing messages
-(recommended for sites with more than a couple of peers), you need some
-slightly more complex magic.  You still set up a separate entry for each
-of your peers, but rather than writing out batch files, they all "funnel"
-into a special innfeed entry.  That special entry collects all of the
-separate funnel feeds and sends the data through a special sort of feed to
-an external program (F<innfeed> in this case); this is a "channel" feed.
-
-First, the special channel feed entry for F<innfeed> that will collect all
-the funnel feeds:
-
-    innfeed!\
-        :!*\
-        :Tc,Wnm*:/usr/local/news/bin/startinnfeed -y
-
-(adjust the path to startinnfeed(1) if you installed it elsewhere).  Note
-that we don't feed this entry any articles directly (its newsgroup pattern
-is C<!*>).  Note also that the name of this entry ends in an exclamation
-point.  This is a standard convention for all special feeds; since the
-delimiter for the Path: header is C<!>, no site name containing that
-character can ever match the name of a real site.
-
-Next, set up entries for each remote site to which you will be feeding
-articles.  All of these entries should be of the form:
-
-    remote.example.com/news.example.com\
-        :<newsgroups>\
-        :Tm:innfeed!
-
-specifying that they funnel into the C<innfeed!> feed.  As in the previous
-example for batching, "remote.example.com" is the actual name of the
-remote peer, "news.example.com" is what it puts in the Path: header (if
-different than the actual name of the server), and <newsgroups> is the
-wildmat pattern of newsgroups to be sent.
-
-As an alternative to NNTP, INN may also feed news out to an IMAP server,
-by using imapfeed(8), which is almost identical to F<innfeed>.  The
-F<startinnfeed> process can be told to start F<imapfeed> instead of
-F<innfeed>.  The feed entry for this is as follows:
-
-    imapfeed!\
-        :!*\
-        :Tc,Wnm*,S16384:/usr/local/news/bin/startinnfeed imapfeed
-
-And set up entries for each remote site like:
-
-    remote.example.com/news.example.com\
-        :<newsgroups>\
-        :Tm:imapfeed!
-
-For more information on F<imapfeed>, look at the
-F<innfeed/imap_connection.c>.  For more information on IMAP in general,
-see RFC 2060.
-
-Finally, there is a special entry for controlchan(8), which processes
-newsgroup control messages, that should always be in F<newsfeeds> unless
-you never want to honor any control messages.  This entry should look
-like:
-
-    controlchan!\
-        :!*,control,control.*,!control.cancel\
-        :Tc,Wnsm:/usr/local/news/bin/controlchan
-
-(modified for the actual path to F<controlchan> if you put it somewhere
-else).  See L<Processing Control Messages> for more details.
-
-For those of you upgrading from earlier versions of INN, note that the
-functionality of overchan(8) and F<crosspost> is now incorporated into INN
-and neither of those programs is necessary.  Unfortunately, F<crosspost>
-currently will not work even with the tradspool storage method.  You can
-still use F<overchan> if you make sure to set I<useoverchan> to true in
-F<inn.conf> so that innd doesn't write overview data itself, but be
-careful:  innd may accept articles faster than overchan can process the
-data.
-
-=head2 incoming.conf
-
-F<incoming.conf> file specifies which machines are permitted to connect to
-your host and feed it articles.  Remote servers you peer with should be
-listed here.  Connections from hosts not listed in this file will (if you
-don't allow readers) be rejected or (if you allow readers) be handed off
-to nnrpd and checked against the access restrictions in F<readers.conf>.
-
-Start with the sample F<incoming.conf> and, for each remote peer, add an
-entry like:
-
-    peer remote.example.com { }
-
-This uses the default parameters for that feed and allows incoming
-connections from a machine named "remote.example.com".  If that peer could
-be connecting from several different machines, instead use an entry like:
-
-     peer remote.example.com {
-        hostname: "remote.example.com, news.example.com"
-     }
-
-This will allow either "remote.example.com" or "news.example.com" to feed
-articles to you.  (In general, you should add new peer lines for each
-separate remote site you peer with, and list multiple host names using the
-I<hostname> key if one particular remote site uses multiple servers.)
-
-You can restrict the newsgroups a remote site is allowed to send you,
-using the same sort of pattern that newsfeeds(5) uses.  For example, if
-you want to prevent "example.com" hosts from sending you any articles in
-the C<local.*> hierarchy (even if they're crossposted to other groups),
-change the above to:
-
-    peer remote.example.com {
-        patterns: "*, @local.*"
-        hostname: "remote.example.com, news.example.com"
-    }
-
-Note, however, that restricting what a remote side can send you will
-I<not> reduce your incoming bandwidth usage.  The remote site will still
-send you the entire article; INN will just reject it rather than saving it
-to disk.  To reduce bandwidth, you have to contact your peers and ask them
-not to send you the traffic you don't want.
-
-There are various other things you can set, including the maximum number
-of connections the remote host will be allowed.  See incoming.conf(5) for
-all the details.
-
-Note for those familiar with older versions of INN:  this file replaces
-the old F<hosts.nntp> configuration file.
-
-=head2 cycbuff.conf
-
-F<cycbuff.conf> is only required if CNFS is used.  If you aren't using
-CNFS, skip this section.
-
-CNFS stores articles in logical objects called I<metacycbuffs>.  Each
-metacycbuff is in turn composed of one or more physical buffers called
-I<cycbuffs>.  As articles are written to the metacycbuff, each article is
-written to the next cycbuff in the list in a round-robin fashion (unless
-C<sequential> mode is specified, in which case each cycbuff is filled
-before moving on to the next).  This is so that you can distribute the
-individual cycbuffs across multiple physical disks and balance the load
-between them.
-
-There are two ways to create your cycbuffs:
-
-=over 4
-
-=item 1.
-
-Use a block device directly.  This will probably give you the most speed
-since it avoids the file system overhead of large files, but it requires
-your OS support mmap(2) on a block device.  Solaris supports this, as do
-late Linux 2.4 kernels.  FreeBSD does not at last report.  Also on many
-PC-based Unixes it is difficult to create more than eight partitions,
-which may limit your options.
-
-=item 2.
-
-Use a real file on a filesystem.  This will probably be a bit slower than
-using a block device directly, but it should work on any Unix system.
-
-=back
-
-If you're having doubts, use option #2; it's easier to set up and should
-work regardless of your operating system.
-
-Now you need to decide on the sizes of your cycbuffs and metacycbuffs.
-You'll probably want to separate the heavy-traffic groups
-(C<alt.binaries.*> and maybe a few other things like C<*.jobs*> and
-C<news.lists.filters>) into their own metacycbuff so that they don't
-overrun the server and push out articles on the more useful groups.  If
-you have any local groups that you want to stay around for a while then
-you should put them in their own metacycbuff as well, so that they don't
-get pushed out by other traffic.  (Or you might store them in one of the
-other storage methods, such as tradspool.)
-   
-For each metacycbuff, you now need to determine how many cycbuffs will
-make up the metacycbuff, the size of those cycbuffs, and where they will
-be stored.  Some OSes do not support files larger than 2 GB, which will
-limit the size you can make a single cycbuff, but you can still combine
-many cycbuffs into each metacycbuff.  Older versions of Linux are known to
-have this limitation; FreeBSD does not.  Some OSes that support large
-files don't support direct access to block devices for large partitions
-(Solaris prior to Solaris 7, or not running in 64-bit mode, is in this
-category); on those OSes, if you want cycbuffs over 2 GB, you'll have to
-use regular files.  If in doubt, keep your cycbuffs smaller than 2 GB.
-Also, when laying out your cycbuffs, you will want to try to arrange them
-across as many physical disks as possible (or use a striped disk array and
-put them all on that).
-
-In order to use any cycbuff larger than 2 GB, you need to build INN with
-the B<--enable-largefiles> option.  See L<Installing INN> for more
-information and some caveats.
-
-For each cycbuff you will be creating, add a line to F<cycbuff.conf> like
-the following:
-
-    cycbuff:NAME:/path/to/buffer:SIZE
-
-NAME must be unique and must be at most seven characters long.  Something
-simple like "BUFF00", "BUFF01", etc. is a decent choice, or you may want
-to use something that includes the SCSI target and slice number of the
-partition.  SIZE is the buffer size in kilobytes (if you're trying to stay
-under 2 GB, keep your sizes below C<2097152>).
-
-Now, you need to tell INN how to group your cycbuffs into metacycbuffs.
-This is similar to creating cycbuff entries:
-
-    metacycbuff:BUFFNAME:CYCBUFF,CYCBUFF,CYCBUFF
-
-BUFFNAME is the name of the metacycbuff and must be unique and at most
-eight characters long.  These should be a bit more meaningful than the
-cycbuff names since they will be used in other config files as well.  Try
-to name them after what will be stored in them; for example, if this
-metacycbuff will hold alt.binaries postings, "BINARIES" would be a good
-choice.  The last part of the entry is a comma-separated list of all of
-the cycbuffs that should be used to build this metacycbuff.  Each cycbuff
-should only appear in one metacycbuff line, and all metacycbuff lines must
-occur after all cycbuff lines in the file.
-
-If you want INN to fill each cycbuff before moving on to the next one
-rather than writing to them round-robin, add C<:SEQUENTIAL> to the end of
-the metacycbuff line.  This may give noticeably better performance when
-using multiple cycbuffs on the same spindle (such as partitions or slices
-of a larger disk), but will probably give worse performance if your
-cycbuffs are spread out across a lot of spindles.
-
-By default, CNFS data is flushed to disk every 25 articles.  If you're
-running a small server with a light article load, this could mean losing
-quite a few articles in a crash.  You can change this interval by adding a
-cycbuffupdate line to your F<cycbuff.conf> file; see cycbuff.conf(5) for
-more details.
-
-Finally, you have to create the cycbuffs.  See L<Creating the Article
-Spool> for more information on how to do that.
-
-=head2 storage.conf
-
-F<storage.conf> determines where incoming articles will be stored (what
-storage method, and in the case of CNFS, what metacycbuff).  Each entry in
-the file defines a storage class for articles.  The first matching storage
-class is used to store the article; if no storage class matches, INN will
-reject that article.  (This is almost never what you want, so make sure
-this file ends in a catch-all entry that will match everything.)
-
-A storage class definition looks like this:
-
-    method <methodname> {
-        newsgroups: <wildmat>
-        class: <storage_class>
-        size: <minsize>[,<maxsize>]
-        expires: <mintime>[,<maxtime>]
-        options: <options>
-    }
-
-<methodname> is the name of the storage method to use to store articles in
-this class ("cnfs", "timehash", "timecaf", "tradspool", or the special
-method "trash" that accepts the article and throws it away).
-
-The first parameter is a wildmat pattern in the same format used by the
-newsfeeds(5) file, and determines what newsgroups are accepted by this
-storage class.
-
-The second parameter is a unique number identifying this storage class and
-should be between 0 and 255.  It can be used to control article
-expiration, and for timehash and timecaf will set the top-level directory
-in which articles accepted by this storage class are stored.  The easiest
-way to deal with this parameter is to just number all storage classes in
-F<storage.conf> sequentially.  The assignment of a particular number to a
-storage class is arbitrary but I<permanent> (since it is used in storage
-tokens).
-
-The third parameter can be used to accept only articles in a certain size
-range into this storage class.  A <maxsize> of C<0> (or a missing
-<maxsize>) means no upper limit (and of course a <minsize> of C<0> would
-mean no lower limit, because all articles are more than zero bytes long).
-If you don't want to limit the size of articles accepted by this storage
-class, leave this parameter out entirely.
-
-The fourth parameter you probably don't want to use; it lets you assign
-storage classes based on the Expires: header of incoming articles.  The
-exact details are in storage.conf(5).  It's very easy to use this
-parameter incorrectly; leave it out entirely unless you've read the man
-page and know what you're doing.
-
-The fifth parameter is the options parameter.  Currently only CNFS uses
-this field; it should contain the name of the metacycbuff used to store
-articles in this storage class.
-
-If you're using CNFS exclusively, just create one storage class for each
-metacycbuff that you have defined in F<cycbuff.conf> and set the
-newsgroups pattern according to what newsgroups should be stored in that
-buffer.
-
-If you're using timehash or timecaf, the storage class IDs are used to
-store articles in separate directory trees, which you can take advantage
-of to put particular storage classes on different disks.  Also, currently
-storage class is the only way to specify expiration time, so you will need
-to divide up your newsgroups based on how long you want to retain articles
-in those groups and create a storage class for each such collection of
-newsgroups.  Make note of the storage class IDs you assign as they will be
-needed when you edit F<expire.ctl> a bit later.
-
-=head2 expire.ctl
-
-F<expire.ctl> sets the expiration policy for articles stored on the
-server.  Be careful, since the default configuration will expire most
-articles after 10 days; in most circumstances this deletion is
-I<permanent>, so read this whole section carefully if you want to keep
-local hierarchies forever.  (See archive(8) for a way to automate backups
-of important articles.)
-
-Only one entry is required for all storage classes; it looks like:
-
-    /remember/:10
-
-This entry says how long to keep the Message-IDs for articles that have
-already expired in the history file so that the server doesn't accept them
-again.  Occasionally, fairly old articles will get regurgitated somewhere
-and offered to you again, so even after you've expired articles from your
-spool, you want to keep them around in your history file for a little
-while to ensure you don't get duplicates.
-
-INN will reject any articles more than a certain number of days old (the
-I<artcutoff> parameter in F<inn.conf>, defaulting to C<10>); the number on
-the C</remember/> line should match that.
-
-CNFS makes no further use of F<expire.ctl>, since articles stored in CNFS
-buffers expire automatically when the buffer runs out of free space (but
-see the C<-N> option in expireover(8) if you really want to expire them
-earlier).  For other storage methods, there are two different syntaxes of
-this file, depending on I<groupbaseexpiry> in F<inn.conf>.  If it is set
-to false, F<expire.ctl> takes entries of the form:
-
-    <storage_class>:<keep>:<default>:<purge>
-
-<storage_class> is the number assigned to a storage class in
-F<storage.conf>.  <default> is the number of days to keep normal articles
-in that storage class (decimal values are allowed).  For articles that
-don't have an Expires: header, those are the only two values that matter.
-For articles with an Expires: header, the other two values come into play;
-the date given in the Expires: header of an article will be honored,
-subject to the contraints set by <keep> and <purge>.  All articles in this
-storage class will be kept for at least <keep> days, regardless of their
-Expires: headers, and all articles in this storage class will be expired
-after <purge> days, even if their Expires: headers specify a longer life.
-
-All three of these fields can also contain the special keyword C<never>.
-If <default> is C<never>, only articles with explicit Expires: headers
-will ever be expired.  If <keep> is C<never>, articles with explicit
-Expires: headers will be kept forever.  Setting <purge> to C<never> says
-to honor Expires: headers even if they specify dates far into the future.
-(Note that if <keep> is set to C<never>, all articles with Expires:
-headers are kept forever and the value of <purge> is not used.)
-
-If the value of C<groupbaseexpiry> is true, F<expire.ctl> takes entries of
-the form:
-
-    <wildmat>:<flag>:<keep>:<default>:<purge>
-
-<wildmat> is a wildmat expression (C<!> and C<@> not permitted, and only a
-single expression, not a comma-separated set of them).  Each expiration
-line applies to groups matching the wildmat expression.  <flag> is C<M>
-for moderated groups, C<U> for unmoderated groups, and C<A> for groups
-with any moderation status; the line only matches groups with the
-indicated expiration status.  All of the other fields have the same
-meaning as above.
-
-=head2 readers.conf
-
-Provided that I<noreader> is set to false in F<inn.conf>, any connection
-from a host that doesn't match an entry in F<incoming.conf> (as well as
-any connection from a host that does match such an entry, but has issued a
-MODE READER command) will be handed off to nnrpd(8), the part of INN that
-supports newsreading clients.  nnrpd uses F<readers.conf> to determine
-whether a given connection is allowed to read news, and if so what
-newsgroups the client can read and post to.
-
-There are a variety of fairly complicated things that one can do with
-F<readers.conf>, things like run external authentication programs that can
-query RADIUS servers.  See readers.conf(5) and the example file for all
-the gory details.  Here's an example of probably the simplest reasonable
-configuration, one that only allows clients in the example.com domain to
-read from the server and allows any host in that domain to read and post
-to all groups:
-
-    auth "example.com" {
-        hosts: "example.com, *.example.com"
-        default: "<user>"
-        default-domain: "example.com"
-    }
-
-    access "all" {
-        users: "*@example.com"
-        newsgroups: "*"
-    }
-
-If you're running a server for one particular domain, want to allow all
-hosts within that domain to read and post to any group on the server, and
-want to deny access to anyone outside that domain, just use the above and
-change C<example.com> in the above to your domain and you're all set.
-Lots of examples of more complicated things are in the sample file.
-
-=head1 Creating the Article Spool (CNFS only)
-
-If you are using actual files as your CNFS buffers, you will need to
-pre-create those files, ensuring they're the right size.  The easiest way
-to do this is with dd.  For each cycbuff in F<cycbuff.conf>, create the
-buffer with the following commands (as the news user):
-
-    dd if=/dev/zero of=/path/to/buffer bs=1k count=BUFFERSIZE
-    chmod 664 /path/to/buffer
-
-Substitute the correct path to the buffer and the size of the buffer as
-specified in F<cycbuff.conf>.  This will create a zero-filled file of the
-correct size; it may take a while, so be prepared to wait.
-
-Here's a command that will print out the dd(1) commands that you should
-run:
-
-    awk -F: \
-    '/^cy/ { printf "dd if=/dev/zero of=%s bs=1k count=%s\n", $3, $4 }' \
-    ~news/etc/cycbuff.conf
-
-If you are using block devices, you don't technically have to do anything
-at all (since INN is capable of using the devices in F</dev>), but you
-probably want to create special device files for those devices somewhere
-for INN's private use.  It s more convenient to keep all of INN's stuff
-together, but more importantly, the device files used by INN really should
-be owned by the news user and group, and you may not want to do that with
-the files in F</dev>.
-
-To create the device files for INN, use mknod(8) with a type of C<b>,
-getting the major and minor device numbers from the existing devices in
-F</dev>.  There's a small shell script in cycbuff.conf(5) that may help
-with this.  Make sure to create the device files in the location INN
-expects them (specified in F<cycbuff.conf>).
-
-Solaris users please note:  on Solaris, do not use block devices that
-include the first cylinder of the disk.  Solaris doesn't protect the
-superblock from being overwritten by an application writing to block
-devices and includes it in the first cylinder of the disk, so unless you
-use a slice that starts with cylinder 1 instead of 0, INN will invalidate
-the partition table when it tries to initialize the cycbuff and all
-further accesses will fail until you repartition.
-
-=head1 Creating the Database Files
-
-At this point, you need to set up the news database directory
-(F<~news/db>).  This directory will hold the active(5) file (the list of
-newsgroups you carry), the active.times(5) file (the creator and creation
-time of newsgroups created since the server was initialized), the
-newsgroups(5) file (descriptions for all the newsgroups you carry), and
-the history(5) file (a record of every article the server currently has or
-has seen in the past few days, used to decide whether to accept or refuse
-new incoming messages).
-
-Before starting to work on this, make sure you're logged on as the news
-user, since all of these files need to be owned by that user.  This is a
-good policy to always follow; if you are doing any maintenance work on
-your news server, log on as the news user.  Don't do maintenance work as
-root.  Also make sure that F<~news/bin> is in the default path of the news
-user (and while you're at it, make sure F<~news/man> is in the default
-MANPATH) so that you can run INN maintenance commands without having to
-type the full path.
-
-If you already have a server set up (if you're upgrading, or setting up a
-new server based on an existing server), copy F<active> and F<newsgroups>
-from that server into F<~news/db>.  Otherwise, you'll need to figure out
-what newsgroups you want to carry and create new active and newsgroups
-files for them.  If you plan to carry a full feed, or something close to
-that, go to <ftp://ftp.isc.org/pub/usenet/CONFIG/> and download F<active>
-and F<newsgroups> from there; that will start you off with reasonably
-complete files.  If you plan to only carry a small set of groups, the
-default minimal F<active> file installed by INN is a good place to start;
-you can create additional groups after the server is running by using
-C<ctlinnd newgroup>.  (Another option is to use actsync(8) to synchronize
-your newsgroup list to that of another server.)
-
-C<control> and C<junk> must exist as newsgroups in your active file for
-INN to start, and creating pseudogroups for the major types of control
-messages is strongly encouraged for all servers that aren't standalone.
-If you don't want these groups to be visible to clients, do I<not> delete
-them; simply hide them in F<readers.conf>.  C<to> must also exist as a
-newsgroup if you have mergetogroups set in F<inn.conf>.
-
-Next, you need to create an empty history database.  To do this, type:
-
-    cd ~news/db
-    touch history
-    makedbz -i
-
-When it finishes, rename the files it created to remove the C<.n> in the
-file names and then make sure the file permissions are correct on all the
-files you've just created:
-
-    chmod 644 *
-
-Your news database files are now ready to go.
-
-=head1 Configuring syslog
-
-While some logs are handled internally, INN also logs a wide variety of
-information via syslog.  INN's nightly report programs know how to roll
-and summarize those syslog log files, but when you first install INN you
-need to set them up.
-
-If your system understands the C<news> syslog facility, INN will use it;
-otherwise, it will log to C<local1>.  Nearly every modern system has a
-C<news> syslog facility so you can safely assume that yours does, but if
-in doubt take a look at the output from running C<configure>.  You should
-see a line that looks like:
-
-    checking log level for news... LOG_NEWS
-
-If that says LOG_LOCAL1 instead, change the below instructions to use
-C<local1> instead of C<news>.
-
-Edit F</etc/syslog.conf> on your system and add lines that look like the
-following:
-
-    news.crit           /usr/local/news/log/news.crit
-    news.err            /usr/local/news/log/news.err
-    news.notice         /usr/local/news/log/news.notice
-
-(Change the path names as necessary if you installed INN in a different
-location than F</usr/local/news>.)  These lines I<must> be tab-delimited,
-so don't copy and paste from these instructions.  Type it in by hand and
-make sure you use a tab, or you'll get mysterious failures.  You'll also
-want to make sure that news log messages don't fill your other log files
-(INN generates a lot of log traffic); so for every entry in
-F</etc/syslog.conf> that starts with C<*>, add C<;news.none> to the end of
-the first column.  For example, if you have a line like:
-
-    *.err               /dev/console
-
-change it to:
-
-    *.err;news.none     /dev/console
-
-(You can choose not to do this for the higher priority log messages, if
-you want to make sure they go to your normal high-priority log files as
-well as INN's.  Don't bother with anything lower priority than C<crit>,
-though.  C<news.err> isn't interesting enough to want to see all the
-time.)  Now, make sure that the news log files exist; syslog generally
-won't create files automatically.  Enter the following commands:
-
-    touch /usr/local/news/log/news.crit
-    touch /usr/local/news/log/news.err
-    touch /usr/local/news/log/news.notice
-    chown news /usr/local/news/log/news.*
-    chgrp news /usr/local/news/log/news.*
-
-(again adjusting the paths if necessary for your installation).  Finally,
-send a HUP signal to syslogd to make it re-read its configuration file.
-
-=head1 Setting Up the Cron Jobs
-
-INN requires a special cron job to be set up on your system to run
-news.daily(8) which performs daily server maintenance tasks such as
-article expiration and the processing and rotation of the server logs.
-Since it will slow the server down while it is running, it should be run
-during periods of low server usage, such as in the middle of the night.
-To run it at 3am, for example, add the following entry to the news user's
-crontab file:
-
-    0 3 * * * /usr/local/news/bin/news.daily expireover lowmark
-
-or, if your system does not have per-user crontabs, put the following line
-into your system crontab instead:
-
-    0 3 * * * su -c "/usr/local/news/bin/news.daily expireover lowmark" news
-
-If you're using any non-CNFS storage methods, add C<delayrm> to the above
-option list for news.daily.
-
-The news user obviously must be able to run cron jobs.  On Solaris, this
-means that it must have a valid F</etc/shadow> entry and must not be
-locked (although it may be a non-login account).  There may be similar
-restrictions with other operating systems.
-
-If you use the batching method to send news, also set up a cron job to run
-nntpsend(8) every ten minutes.  nntpsend will run innxmit for all
-non-empty pending batch files to send pending news to your peers.  That
-cron entry should look something like:
-
-    0,10,20,30,40,50 * * * * /usr/local/news/bin/nntpsend
-
-The pathnames and user ID used above are the installation defaults; change
-them to match your installation if you used something other than the
-defaults.
-
-The parameters passed to news.daily in the above example are the most
-common (and usually the most efficient) ones to use.  More information on
-what these parameters do can be found in the news.daily(8) man page.
-
-=head1 File Descriptor Limits
-
-INN likes to use a lot of file descriptors, particularly if you have a lot
-of peers.  Depending on what your system defaults are, you may need to
-make sure the default limit is increased for INN (particularly for innd
-and innfeed).  This is vital on Solaris, which defaults (at least as of
-2.6) to an absurdly low limit of 64 file descriptors per process.
-
-One way to increase the number of file descriptors is to set
-I<rlimitnofile> in F<inn.conf> to a higher value.  This will cause both
-startinnfeed and inndstart (the setuid root wrapper scripts that start
-innfeed and innd, respectively) to increase the file descriptor limits
-before they run the regular INN programs.  Note, however, that INN won't
-be able to increase the limits above the hard limits set by your operating
-system; on some systems, that hard limit is normally 256 file descriptors
-(Linux, for example).  On others, like Solaris, it's 1024.  Increasing the
-limit beyond that value may require serious system configuration work.
-(On some operating systems, it requires patching and recompiling the
-kernel.  On Solaris it can be changed in F</etc/system>, but for 2.6 or
-earlier the limit cannot be increased beyond 1024 without breaking
-select(2) and thereby breaking all of INN.  For current versions of Linux,
-you may be able to change the maximum by writing to
-F</proc/sys/fs/file-max>.)
-
-256 file descriptors will probably be enough for all but the largest
-sites.  There is no harm in setting the limits higher than you actually
-need (provided they're set to something lower than or equal to your system
-hard limit).  C<256> is therefore a reasonable value to try.
-
-If you're installing INN on a Solaris system, particularly if you're
-installing it on a dedicated news server machine, it may be easier to just
-increase the default file descriptor limit across the board for all
-processes.  You can do that by putting the line:
-
-    set rlim_fd_cur = 256
-
-in F</etc/system> and rebooting.  You can increase it all the way to
-C<1024> (and may need to if you have a particularly large site), but that
-can cause RPC and some stdio applications to break.  It therefore probably
-isn't a good idea on a machine that isn't dedicated to INN.
-
-=head1 Starting and Stopping the System
-
-INN is started via the shell script F<rc.news>.  This must be run as the
-news user and not as root.  To start INN on system boot, you therefore
-want to put something like:
-
-    su - news -c /usr/local/news/bin/rc.news
-
-in the system boot scripts.  If innd is stopped or killed, you can restart
-it by running rc.news by hand as the news user.
-
-The rc.news script may also be used to shut down INN, with the C<stop>
-option:
-
-    su - news -c '/usr/local/news/bin/rc.news stop'
-
-In the F<contrib> directory of this source tree is a sample init script
-for people using System V-style init.d directories.
-
-=head1 Processing Newsgroup Control Messages
-
-Control messages are specially-formatted messages that tell news servers
-to take various actions.  Cancels (commands to delete messages) are
-handled internally by INN, and all other control messages are processed by
-controlchan.  controlchan should be run out of F<newsfeeds> if you want
-your news server to process any control messages; see L<Configuring INN>
-for specific instructions.
-
-The actions of controlchan are determined by F<control.ctl>, which lists
-who can perform what actions.  The primary control messages to be
-concerned with are C<newgroup> (to create a newsgroup), C<rmgroup> (to
-remove a newsgroup), and C<checkgroups> (to compare the list of groups
-carried in a hierarchy to a canonical list).  INN comes with a
-F<control.ctl> file that processes control messages in most major public
-hierarchies; if you don't want to act on all those control messages, you
-should remove from that file all entries for hierarchies you don't want to
-carry.
-
-You can tell INN to just authenticate control messages based on the From
-header of the message, but this is obviously perilous and control messages
-are widely forged.  Many hierarchies sign all of their control messages
-with PGP, allowing news servers to verify their authenticity, and checking
-those signatures for hierarchies that use them is highly recommended.
-controlchan knows how to do this (using pgpverify) without additional
-configuration, but you do have to provide it with a public key ring
-containing the public keys of all of the hierarchy administrators whose
-control messages you want to check.
-
-INN expects the public key ring to either be in the default location for a
-PGP public key ring for the news user (generally ~news/.gnupg for GnuPG
-and ~news/.pgp for old PGP implementations), or in pathetc/pgp
-(/usr/local/news/etc/pgp by default).  The latter is the recommended path.
-To add a key to that key ring, use:
-
-    gpg --import --homedir=/usr/local/news/etc/pgp <file>
-
-where <file> is a file containing the hierarchy key.  Change the homedir
-setting to point to pathetc/pgp if you have INN installed in a non-default
-location.  If you're using the old-style PGP program, an equivalent
-command is:
-
-    env PGPPATH=/usr/local/news/etc/pgp pgp <file>
-
-You can safely answer "no" to questions about whether you want to sign,
-trust, or certify keys.
-
-The URLs from which you can get hierarchy keys are noted in comments in
-F<control.ctl>.  L<ftp://ftp.isc.org/pub/pgpcontrol/PGPKEYS> tries to
-collect the major hierarchy keys.
-
-If you are using GnuPG, please note that the first user ID on the key will
-be the one that's used by INN for verification and must match the key
-listed in F<control.ctl>.  If a hierarchy key has multiple user IDs, you
-may have to remove all the user IDs except the one that matches the
-F<control.ctl> entry using C<gpg --edit-key> and the C<delkey> command.
diff --git a/doc/pod/libauth.pod b/doc/pod/libauth.pod
deleted file mode 100644 (file)
index f31cddf..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-=head1 NAME
-
-libauth - routines for writing nnrpd resolvers and authenticators
-
-=head1 SYNOPSIS
-
-    #include "libauth.h"
-
-    struct res_info {
-        struct sockaddr *client;
-        struct sockaddr *local;
-        char *clienthostname;
-    };
-
-    struct auth_info {
-        char *username;
-        char *password;
-    };
-
-    struct auth_info *get_auth_info(FILE *);
-    struct res_info  *get_res_info (FILE *);
-
-    void free_auth_info(struct auth_info*);
-    void free_res_info (struct res_info*);
-
-=head1 DESCRIPTION
-
-These functions provide a convenient C frontend to the nnrpd external
-authentication interface documented in F<doc/external-auth>.  Use of
-this library is B<not> required; in particular, external resolvers and
-authenticators written in languages other than C will need to implement
-the necessary functionality themselves.
-
-The get_auth_info() and get_res_info() functions allocate sufficient
-memory for a B<struct auth_info> or B<struct res_info> and any necessary
-fields, and return a pointer to the struct with the fields filled in
-from information supplied by nnrpd (the B<FILE*> parameter generally
-should be C<stdin>).  Both functions return NULL on error.  The caller
-is responsible for deallocating the memory by using the functions below.
-
-The string fields of both structs are straightforward.  The B<client>
-and B<local> fields of B<struct res_info> actually point to instances of
-B<struct sockaddr_in> (or B<struct sockaddr_in6> if IPv6 support is
-compiled in).
-
-The free_auth_info() and free_res_info() functions free the struct
-passed in as argument and all necessary fields.
-
-=head1 BUGS
-
-In many cases, nnrpd provides more information than is normally useful
-(for example, even when calling an authenticator, the resolver
-information is often provided.)  On the other hand, in certain cases it
-provides less information than might be expected (for example, if nnrpd
-is reading from stdin rather than a socket).  The implementation is
-capable of handling at least the first of these issues, but that
-functionality is not exposed in the interface.
-
-At present, F<libauth.h> and its implementation are located in
-F<authprogs/>; perhaps they should be moved to F<include/> and F<lib/>,
-respectively?
-
-=head1 HISTORY
-
-Written by Jeffrey M. Vinocur <jeff@litech.org> for InterNetNews.
-
-$Id: libauth.pod 5988 2002-12-12 23:02:14Z vinocur $
-
-=head1 SEE ALSO
-
-nnrpd(8), readers.conf(5), F<doc/external-auth>
-
-=cut
diff --git a/doc/pod/libinnhist.pod b/doc/pod/libinnhist.pod
deleted file mode 100644 (file)
index 8df364f..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-=head1 NAME
-
-his - routines for managing INN history
-
-=head1 SYNOPSIS
-
-B<#include E<lt>inn/history.hE<gt>>
-
-B<struct history;>
-
-B<struct histstats {>
-B<    int hitpos;>
-B<    int hitneg;>
-B<    int misses;>
-B<    int dne;>
-B<};>
-
-B<#define HIS_RDONLY ...>
-B<#define HIS_RDWR ...>
-B<#define HIS_CREAT ...>
-B<#define HIS_ONDISK ...>
-B<#define HIS_INCORE ...>
-B<#define HIS_MMAP ...>
-
-B<enum {>
-B<    HISCTLG_PATH,>
-B<    HISCTLS_PATH,>
-B<    HISCTLS_SYNCCOUNT,>
-B<    HISCTLS_NPAIRS,>
-B<    HISCTLS_IGNOREOLD,>
-B<    HISCTLS_STATINTERVAL>
-B<};>
-
-B<struct history *HISopen(const char *>I<path>B<, const char *>I<method>B<, int >I<flags>B<);>
-
-B<bool HISclose(struct history *>I<history>B<);>
-
-B<bool HISsync(struct history *>I<history>B<);>
-
-B<void HISsetcache(struct history *>I<history>B<, size_t >I<size>B<);>
-
-B<bool HISlookup(struct history *>I<history>B<, const char *>I<key>B<, time_t *>I<arrived>B<, time_t *>I<posted>B<, time_t *>I<expires>B<, TOKEN *>I<token>B<);>
-
-B<bool HIScheck(struct history *>I<history>B<, const char *>I<key>B<);>
-
-B<bool HISwrite(struct history *>I<history>B<, const char *>I<key>B<, time_t >I<arrived>B<, time_t >I<posted>B<, time_t >I<expires>B<, const TOKEN *>I<token>B<);>
-
-B<bool HISremember(struct history *>I<history>B<, const char *>I<key>B<, time_t >I<arrived>B<);>
-
-B<bool HISreplace(struct history *>I<history>B<, const char *>I<key>B<, time_t >I<arrived>B<, time_t >I<posted>B<, time_t >I<expires>B<, const TOKEN *>I<token>B<);>
-
-B<bool HISexpire(struct history *>I<history>B<, const char *>I<path>B<, const char *>I<reason>B<, bool >I<writing>B<, void *>I<cookie>B<, time_t >I<threshold>B<, bool (*>I<exists>B<)(void *cookie, time_t arrived, time_t posted, time_t expires, const TOKEN *token));>
-
-B<bool HISwalk(struct history *>I<history>B<, const char *>I<reason>B<, void *>I<cookie>B<, bool (*>I<callback>B<)(void *cookie, time_t arrived, time_t posted, time_t expires, const TOKEN *token));>
-
-B<struct histstats HISstats(struct history *>I<history>B<);>
-
-B<const char *HISerror(struct history *>I<history>B<);>
-
-B<bool HISctl(struct history *>I<history>B<, int >I<request>B<, void *>I<val>B<);>
-
-=head1 DESCRIPTION
-
-These functions provide provide access to the INN history
-database. They maintain key/value pairs in an opaque database whilst
-providing for expiry of outdated information.
-
-The history structure is an opaque handle returned from HISopen.
-
-The B<HISopen> function opens the history file designated by I<path>
-using the mode I<flags> using the specified I<method>. I<flags> may be
-B<HIS_RDONLY> to indicate that read-only access to the history
-database is desired, or B<HIS_RDWR> for read/write access. History
-methods are defined at build time; the history method currently
-available is "hisv6". On success a newly initialised history handle is
-returned, or B<NULL> on failure.
-
-B<HIS_ONDISK>, B<HIS_INCORE> and B<HIS_MMAP> may be logically ORed
-into I<flags> to provide a hint to the underlying history manager as
-to how it should handle its data files; B<HIS_ONDISK> indicates that
-the caller would like as much of the data to be kept on disk (and out
-of memory), B<HIS_INCORE> indicates that the data files should be kept
-in main memory where possible and B<HIS_MMAP> that the files should be
-mmap()ed into the processes address space. B<HIS_INCORE> is typically
-used where a mass rebuild of the history database is being performed;
-the underlying history manager may assume that the caller will call
-B<HISsync>() to sync the data files to disk.
-
-The B<HIS_CREAT> flag indicates that the history database should be
-initialised as new; if any options which affect creation of the
-database need to be set an anonymous history handle should be created
-by calling B<HISopen> with I<path> set to B<NULL>, any options set
-using B<HISctl>, then the database opened by calling B<HISctl> with
-B<HISCTLS_PATH>.
-
-The B<HISclose> function closes the handle I<history> and deallocates
-any resources associated with it. It returns B<false> on failure or
-B<true> on success.
-
-The B<HISsync> function synchronises any outstanding transactions
-associated with I<history> to disk.
-
-B<HISsetcache> associates a cache used for speeding up HIScheck with
-I<history>. The cache will occupy approximately I<size> bytes.
-
-B<HISlookup> retrieves a token from I<history> based on the passed
-I<key> (normally the Message-ID). If no entry with an associated token
-can be found, B<HISlookup> will return B<false>. If a token is found
-I<arrived>, I<expires>, and I<posted> are filled in with the message
-arrival, expiry, and posting times respectively (or zero, if the time
-component is not available), in addition to I<token> being set to the
-retrieved token and a function return value of B<true>. Any of
-arrived, expires, posted, or token may be B<NULL> in which case that
-component is not returned to the caller, without affecting the return
-value.
-
-B<HIScheck> checks the database I<history> for I<key> (normally the
-Message-ID); if I<key> has previously been set via B<HISwrite>,
-B<HIScheck> returns B<true>, else B<false>.
-
-B<HISwrite> writes a new entry to the database I<history> associated
-with I<key>. I<arrived>, I<posted>, and I<expired> specify the arrival,
-posting, and expiry time respectively; I<posted> and I<expired> may be
-specifed as <= 0 in which case that component shall be treated as
-absent in the database. I<token> is associated with the specified
-I<key>. B<HISwrite> returns B<true> on success, or B<false> on
-failure. The behaviour when I<key> is not unique with respect to the
-existing entries in I<history> is unspecified.
-
-B<HISremember> writes a new entry to the database I<history>
-associated with I<key>, merely remembering that this I<key> has been
-seen, together with its arrival time I<arrived>. B<HISremember>
-returns B<true> on success, or B<false> on failure. The behaviour when
-I<key> is not unique with respect to the existing entries in
-I<history> is unspecified.
-
-B<HISreplace> replaces an existing entry in the database I<history>,
-associated with I<key>. I<arrived>, I<posted>, I<expired> specify the
-arrival, posting and expiry time respectively; I<posted> and
-I<expired> may be specifed as <= 0 in which case that component shall
-be treated as absent in the database. I<token> is associated with the
-specified I<key>; if B<NULL> then the history database merely
-remembers that this I<key> has been seen, together with its arrival
-time. B<HISreplace> returns B<true> on success, or B<false> on
-failure.
-
-B<HISexpire> expires the history database associated with I<history>,
-creating a new, replacement, database in the same location if I<path>
-is B<NULL>, or in I<path> if not B<NULL>; if I<path> is not B<NULL>
-then the replacement of the old history database with the new one is
-assumed to be performed out of band by the caller. The I<writing> flag
-is normally passed as B<true>, if you wish to inhibit writing of the
-new database (and so merely see the callbacks), I<writing> may be set
-B<false>.
-
-If the underlying history mechanism needs to pause the server, the
-I<reason> string is used as the argument to the `ctlinnd pause'
-command, and as such the server should be reserved by the caller prior
-to calling B<HISexpire>; if the caller wishes to inhibit pausing of
-the server, passing B<NULL> will achieve this. If I<reason> is not
-B<NULL>, then on successful return from B<HISexpire> the server will
-be left paused and the caller should unpause it.
-
-The history database is scanned and entries with an associated storage
-token are passed to the discrimination function I<exists>.
-
-If I<exists>() returns B<false> it indicates that stored entity
-associated with token is no longer available (or no longer required),
-and therefore the associated history entry may be expired once it
-meets the I<threshold> constraint. If I<exists>() returns B<true> the
-entry is kept as-is in the newly expired history database.
-
-The I<exists> function is passed the arrival, posting and expiry
-times, in addition to the token associated with the entry. Note that
-posting and/or expiry may be zero, but that the token will never be
-B<NULL> (such entries are handled solely via the threshold
-mechanism). The storage token passed to the discrimination function
-may updated if required (for example, as might be needed by a
-hierachical storage management implementation).
-
-Entries in the database with an arrival time less than I<threshold>
-with no token associated with them are deleted from the database.
-
-The parameter I<cookie> is passed to the discrimination function, and
-may be used for any purpose required by the caller.
-
-If the discrimination function attempts to access the underlying
-database (for read or write) during the callback, the behaviour is
-unspecified.
-
-B<HISwalk> provides an iteration function for the specified I<history>
-database. For every entry in the history database, I<callback> is
-invoked, passing the I<cookie>, arrival, posting, and expiry times, in
-addition to the token associated with the entry. If the I<callback>()
-returns B<false> the iteration is aborted and B<HISwalk> returns
-B<false> to the caller.
-
-To process the entire database in the presence of a running server,
-I<reason> may be passed; if this argument is not B<NULL>, it is used
-as an an argument to the `ctlinnd (reserve|pause|go)' commands. If
-I<reason> is B<NULL> and the server is running, the behaviour of
-B<HISwalk> is undefined.
-
-If the callback function attempts to access the underlying database
-during the callback, the behaviour is unspecified.
-
-B<HISstats> returns statistics on the history cache mechanism; given a
-handle I<history>, the return value is a I<struct histstats>
-detailing:
-
-=over 4
-
-=item C<hitpos>
-
-The number of times an item was found directly in the cache and known
-to exist in the underlying history manager.
-
-=item C<hitneg>
-
-The number of times an item was found directly in the cache and known
-not to exist in the underlying history manager.
-
-=item C<misses>
-
-The number of times an item was not found directly in the cache, but
-on retrieval from the underlying history manager was found to exist.
-
-=item C<dne>
-
-The number of times an item was not found directly in the cache, but
-on retrieval from the underlying history manager was found not to exist.
-
-=back
-
-Note that the history cache is only checked by B<HIScheck> and only
-affected by B<HIScheck>, B<HISwrite>, B<HISremember> and
-B<HISreplace>. Following a call to B<HISstats> the history statistics
-associated with I<history> are cleared.
-
-B<HISerror> returns a string describing the most recent error
-associated with I<history>; the format and content of these strings is
-history manager dependent. Note that on setting an error, the history
-API will call the B<warn> function from libinn(3).
-
-B<HISctl> provides a control interface to the underlying history
-manager. The I<request> argument determines the type of the request
-and the meaning of the I<val> argument. The values for I<request> are:
-
-=over 4
-
-=item C<HISCTLG_PATH> (const char **)
-
-Get the base file path which the history handle represents. I<val>
-should be a pointer to a location of type B<const char *>.  The
-result must not later be passed to free(3).
-
-
-=item C<HISCTLS_PATH> (const char *)
-
-Set the base file path which this history handle should use; typically
-this is used after an anonymous handle has been created using
-B<HISopen(NULL, ...)>. I<val> should be a value of type B<const char
-*> and will be copied before being stored internally.
-
-=item C<HISCTLS_SYNCCOUNT> (size_t *)
-
-Set an upper bound on how many history operations may be pending in
-core before being synced to permanent storage; B<0> indicates
-unlimited. I<val> should be a pointer to a value of type B<size_t> and
-will not be modified by the call.
-
-=item C<HISCTLS_NPAIRS> (size_t *)
-
-Set a hint to the to the underlying history manager as to how many
-entries there are expected to be in the history database; B<0>
-indicates that an automatic or default sizing should be made. I<val>
-should be a pointer to a value of type B<size_t> and will not be
-modified by the call.
-
-=item C<HISCTLS_IGNOREOLD> (bool *)
-
-Instruct the underlying history manager to ignore existing database
-when creating new ones; typically this option may be set to B<true> if
-the administrator believes that the existing history database is
-corrupt and that ignoring it may help. I<val> should be a pointer to a
-value of type B<bool> and will not be modified by the call.
-
-=item C<HISCTLS_STATINTERVAL> (time_t *)
-
-For the history v6 and tagged hash managers, set the interval, in
-seconds, between stat(2)s of the history files checking for replaced
-files (as happens during expire); this option is typically used by
-nnrpd(8) like applications. I<val> should be a pointer to a value of
-type B<time_t> and will not be modified by the call.
-
-=head1 HISTORY
-
-Written by Alex Kiernan <alexk@demon.net> for InterNetNews 2.4.0.
-
-$Id: libinnhist.pod 5909 2002-12-03 05:17:18Z vinocur $
diff --git a/doc/pod/list.pod b/doc/pod/list.pod
deleted file mode 100644 (file)
index 6b9f631..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-=head1 NAME
-
-list - list routines
-
-=head1 SYNOPSIS
-
-B<#include E<lt>inn/list.hE<gt>>
-
-struct node {
-    struct node *succ;
-    struct node *pred;
-};
-
-struct list {
-    struct node *head;
-    struct node *tail;
-    struct node *tailpred;
-};
-
-B<void list_new(struct list *>I<list>B<);>
-
-B<struct node *list_addhead(struct list *>I<list>B<, struct node *>I<node>B<);>
-
-B<struct node *list_addtail(struct list *>I<list>B<, struct node *>I<node>B<);>
-
-B<struct node *list_head(struct list *>I<list>B<);>
-
-B<struct node *list_tail(struct list *>I<list>B<);>
-
-B<struct node *list_succ(struct node *>I<node>B<);>
-
-B<struct node *list_pred(struct node *>I<node>B<);>
-
-B<struct node *list_remhead(struct list *>I<list>B<);>
-
-B<struct node *list_remtail(struct list *>I<list>B<);>
-
-B<struct node *list_remove(struct node *>I<node>B<);>
-
-B<struct node *list_insert(struct list *>I<list>B<, struct node *>I<node>B<, struct node *>I<pred>B<);>
-
-B<bool list_isempty(struct list *>I<list>B<);>
-
-=head1 DESCRIPTION
-
-B<list_new> initialises the list header I<list> so as to create an
-empty list.
-
-B<list_addhead> adds I<node> to the head of I<list>, returning the node
-just added.
-
-B<list_addtail> adds I<node> to the tail of I<list>, returning the node
-just added.
-
-B<list_head> returns a pointer to the the node at the head of I<list>
-or B<NULL> if the list is empty.
-
-B<list_tail> returns a pointer to the the node at the tail of I<list>
-or B<NULL> if the list is empty.
-
-B<list_succ> returns the next (successor) node on the list after
-I<node> or B<NULL> if I<node> was the final node.
-
-B<list_pred> returns the previous (predecessor) node on the list before
-I<node> or B<NULL> if I<node> was the first node.
-
-B<list_remhead> removes the first node from I<list> and returns it to
-the caller. If the list is empty B<NULL> is returned.
-
-B<list_remtail> removes the last node from I<list> and returns it to
-the caller. If the list is empty B<NULL> is returned.
-
-B<list_remove> removes I<node> from the list it is on and returns it
-to the caller.
-
-B<list_insert> inserts I<node> onto I<list> after the node I<pred>. If
-I<pred> is B<NULL> then I<node> is added to the head of I<list>.
-
-=head1 HISTORY
-
-Written by Alex Kiernan <alex.kiernan@thus.net> for InterNetNews 2.4.0.
-
-$Id: list.pod 6168 2003-01-21 06:27:32Z alexk $
diff --git a/doc/pod/mailpost.pod b/doc/pod/mailpost.pod
deleted file mode 100644 (file)
index af35829..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-=head1 NAME
-
-mailpost - Feed an e-mail message into a newsgroup
-
-=head1 SYNOPSIS
-
-B<mailpost> [B<-hn>] [B<-a> I<addr>] [B<-b> I<database>] [B<-c> I<wait-time>]
-[B<-d> I<distribution>] [B<-f> I<addr>] [B<-m> I<mailing-list>]
-[B<-o> I<output-command>] [B<-p> I<port>] [B<-r> I<addr>]
-[B<-x> I<header>[B<:>I<header>...]] I<newsgroups>
-
-=head1 DESCRIPTION
-
-The B<mailpost> program reads a properly formatted e-mail message from stdin
-and feeds it to B<inews> for posting to a news server.  I<newsgroups> is a
-whitespace-separated list of group names to which to post the article
-(at least one newsgroup must be specified).
-
-Before feeding the article to B<inews>, it checks that the article has not
-been seen before, and it changes some headers (cleans up some address
-headers, removes X-Trace: and X-Complaints-To:, and puts C<X-> in front
-of unknown headers).
-
-If the article has been seen before (B<mailpost> records the Message-ID of
-each article it handles), then the article will be silently dropped.  Other
-errors will cause the article to be mailed to the newsmaster (selected
-at configure time and defaulting to C<usenet>).
-
-Normally, B<mailpost> is run by sendmail(8) via an alias entry:
-
-    local-mail-wreck-bikes: "|<pathbin in inn.conf>/mailpost
-        -b /var/tmp -d local local.mail.rec.bicycles.racing"
-
-Instead of F</var/tmp>, the mail spool directory can be specified,
-or any other directory where the B<mailpost> process has write access.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a> I<addr>
-
-If the B<-a> flag is used, the value given is added to the article 
-as an Approved: header.
-
-=item B<-b> I<database>
-
-If the B<-b> flag is used, then it defines the location of the database 
-used to store the Message-IDs of articles sent on.  This is to prevent articles
-looping around if a news-to-mail gateway sends them back here.  This option may
-be required if the B<mailpost> process does not have write access to the news
-temporary directory.  The default value is I<pathtmp> as set in F<inn.conf>.
-
-=item B<-c> I<wait-time>
-
-The B<-c> flag indicates a length of time to sleep before posting.  If
-duplicate messages are received in this interval (by any instance of
-B<mailpost> using the same database), the article is only posted once, but
-with Newsgroups: header modified to crosspost the article to all indicated
-groups.  The units for I<wait-time> are seconds; a reasonable value may be
-anywhere from tens to hundreds of seconds, or even higher, depending on how
-long mail can be delayed on its way to your system.
-
-=item B<-d> I<distribution>
-
-If the B<-d> flag is used, the value given is added to the article as a
-Distribution: header.
-
-=item B<-f> I<addr>
-
-The B<-f> flag is a synonym for the B<-r> flag.
-
-=item B<-h>
-
-Print usage information and exit.
-
-=item B<-m> I<mailing-list>
-
-If the B<-m> flag is used, the value given is added to the article in a 
-Mailing-List: header, if such a header doesn't already exist.
-
-=item B<-n>
-
-If the B<-n> flag is used, neither an article is posted nor a mail is sent
-in case an error occurs.  Everything is written to the standard output.
-
-=item B<-o> I<output-command>
-
-Specifies the program to which the resulting article processed by B<mailpost>
-should be sent.  For debugging purpose, C<-o cat> can be used.  The default
-value is C<inews -S -h>.
-
-=item B<-p> I<port>
-
-Specifies the port on which B<nnrpd> is listening, used for article posting.
-If given, B<-p> is passed along to B<inews>.
-
-=item B<-r> I<addr>
-
-A heuristic is used to determine a reasonable value for the Path: header.
-The B<-r> flag indicates what to use if no other value can be determined.
-
-=item B<-x> I<header>[B<:>I<header>...]
-
-A colon-separated list of additional headers which should be treated as
-known headers; these headers will be passed through to B<inews> without
-having C<X-> prepended.
-
-Known headers are:
-
-    Approved
-    Content-*
-    Date
-    Distribution
-    From
-    Mailing-List
-    Message-ID
-    MIME-*
-    References
-    Return-Path
-    Sender
-    Subject
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item I<pathbin>/mailpost
-
-The Perl script itself used to feed an e-mail message to a newsgroup.
-
-=item I<pathtmp>/mailpost-msgid.dir and I<pathtmp>/mailpost-msgid.pag
-
-The default database files which record previously seen Message-IDs.
-
-=back
-
-=head1 HISTORY
-
-Written by Paul Vixie long ago and then hacked up by James Brister for INN 
-integration.
-
-$Id: mailpost.pod 7795 2008-04-26 08:28:08Z iulius $
-
-=head1 SEE ALSO
-
-active(5), inews(1), inn.conf(5), nnrpd(8), uwildmat(3).
-
-=cut
-
diff --git a/doc/pod/makehistory.pod b/doc/pod/makehistory.pod
deleted file mode 100644 (file)
index 7775fb9..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-=head1 NAME
-
-makehistory - Initialize or rebuild INN history database
-
-=head1 SYNOPSIS
-
-B<makehistory> [B<-abeFIOx>] [B<-f> I<filename>] [B<-l> I<count>]
-[B<-T> I<tmpdir>] [B<-s> I<size>]
-
-=head1 DESCRIPTION
-
-B<makehistory> rebuilds the history(5) text file, which contains a list of
-Message-IDs of articles already seen by the server.  It can also be used
-to rebuild the overview database.  Note that the dbz(3) indexes for the
-history file are rebuilt by makedbz(8), not by B<makehistory> as in
-earlier versions of INN.
-
-The default location of the history text file is I<pathdb>/history; to
-specify an alternate location, use the B<-f> flag.
-
-By default, B<makehistory> will scan the entire spool, using the storage
-manager, and write a history line for every article.  To also generate
-overview information, use the B<-O> flag.
-
-WARNING: If you're trying to rebuild the overview database, be sure to
-stop innd(8) and delete or zero out the existing database before you start
-for the best results.  An overview rebuild should not be done while the
-server is running.  Unless the existing overview is deleted, you may end
-up with problems like out-of-order overview entries, excessively large
-overview buffers, and the like.
-
-If I<ovmethod> in F<inn.conf> is C<ovdb>, you must have the ovdb processes
-running while rebuilding overview.  ovdb needs them available while
-writing overview entries.  You can start them by hand separate from the
-rest of the server by running B<ovdb_init>; see ovdb_init(8) for more
-details.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a>
-
-Append to the history file rather than generating a new one.  If you
-append to the main history file, make sure innd(8) is throttled or not
-running, or you can corrupt the history.
-
-=item B<-b>
-
-Delete any messages found in the spool that do not have valid Message-ID
-headers in them.
-
-=item B<-e>
-
-Compute Bytes headers which is used for overview data.  This option is valid
-only if B<-O> flag is specified and F<overview.fmt> includes C<Bytes:>.
-
-=item B<-f> I<filename>
-
-Rather than writing directly to I<pathdb>/history, instead write to
-I<filename>.
-
-=item B<-F>
-
-Fork a separate process to flush overview data to disk rather than doing
-it directly.  The advantage of this is that it allows B<makehistory> to
-continue to collect more data from the spool while the first batch of data
-is being written to the overview database.  The disadvantage is that up to
-twice as much temporary disk space will be used for the generated overview
-data.  This option only makes sense in combination with B<-O>.  With
-C<buffindexed>, the C<overchan> program is invoked to write overview.
-
-=item B<-I>
-
-Don't store overview data for articles numbered lower than the lowest
-article number in F<active>.  This is useful if there are for whatever
-reason old articles on disk that shouldn't be available to readers or put
-into the overview database.
-
-=item B<-l> I<count>
-
-This option specifies how many articles to process before writing the
-accumulated overview information out to the overview database.  The
-default is C<10000>.  Since overview write performance is faster with
-sorted data, each "batch" gets sorted.  Increasing the batch size
-with this option may further improve write performance, at the cost
-of longer sort times.  Also, temporary space will be needed to store
-the overview batches.  At a rough estimate, about 300 * I<count> bytes
-of temporary space will be required (not counting temp files created
-by sort(1)).  See the description of the B<-T> option for how to
-specify the temporary storage location.  This option has no effect
-with C<buffindexed>, because C<buffindexed> does not need sorted
-overview and no batching is done.
-
-=item B<-s> I<size>
-
-Size the history database for approximately I<size> pairs.  Accurately
-specifying the size is an optimization that will create a more
-efficient database.  (The size should be the estimated eventual size
-of the F<history> file, typically the size of the old file, in lines.)
-
-=item B<-O>
-
-Create the overview database as well as the history file.  Overview
-information is only required if the server supports readers; it is not
-needed for a transit-only server (see I<enableoverview> in inn.conf(5)).
-If you are using the C<buffindexed> overview storage method, erase all of
-your overview buffers before running B<makehistory> with B<-O>.
-
-=item B<-T> I<tmpdir>
-
-If B<-O> is given, B<makehistory> needs a location to write temporary
-overview data.  By default, it uses I<pathtmp>, set in F<inn.conf>, but if
-this option is given, the provided I<tmpdir> is used instead.  This is
-also used for temporary files created by sort(1) (which is invoked in the
-process of writing overview information since sorted overview information
-writes faster).  By default, sort usually uses your system temporary
-directory; see the sort(1) man page on your system to be sure.
-
-=item B<-x>
-
-If this option is given, B<makehistory> won't write out history file
-entries.  This is useful mostly for building overview without generating
-a new history file.
-
-=back
-
-=head1 EXAMPLES
-
-Here's a typical example of rebuilding the entire history and overview
-database, removing broken articles in the news spool.  This uses the
-default temporary file locations and should be done while innd isn't
-running (or is throttled).
-
-    makehistory -b -f history.n -O -l 30000 -I
-
-This will rebuild the overview (if using C<buffindexed>, erase the
-existing overview buffers before running this command) and leave a new
-history file as C<history.n> in I<pathdb>.  To preserve all of the history
-entries from the old history file that correspond to rejected articles or
-expired articles, follow the above command with:
-
-    cd /usr/local/news/db
-    awk 'NF == 2 { print }' < history >> history.n
-
-(replacing the path with your I<pathdb>, if it isn't the default).  Then
-look over the new history file for problems and run:
-
-    makedbz -s `wc -l < history` -f history.n
-
-Then rename all of the files matching C<history.n.*> to C<history.*>,
-replacing the current history database and indexes.  After that, it's safe
-to unthrottle innd.
-
-For a simpler example:
-
-    makehistory -b -f history.n -I -O
-
-will scan the spool, removing broken articles and generating history and
-overview entries for articles missing from history.
-
-To just rebuild overview:
-
-    makehistory -O -x -F
-
-=head1 FILES
-
-=over 4
-
-=item inn.conf
-
-Read for I<pathdb>, I<pathtmp>, and other settings.
-
-=item I<pathdb>/history
-
-This is the default output file for B<makehistory>.
-
-=item I<pathtmp>
-
-Where temporary files are written unless B<-T> is given.
-
-=back
-
-=head1 HISTORY
-
-Originally written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews and
-updated by various other people since.
-
-$Id: makehistory.pod 6400 2003-07-12 19:26:58Z rra $
-
-=head1 SEE ALSO
-
-dbz(3), active(5), history(5), inn.conf(5), ctlinnd(8), innd(8),
-makedbz(8), ovdb_init(8), overview.fmt(5).
-
-=cut
diff --git a/doc/pod/motd.news.pod b/doc/pod/motd.news.pod
deleted file mode 100644 (file)
index c52fe7a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-=head1 NAME
-
-motd.news - Message of the day information for readers
-
-=head1 DESCRIPTION
-
-This file, found in I<pathetc>/motd.news, contains local information for
-news readers in a free-form format.  The entire file is returned verbatim
-to any client that issues the LIST MOTD command.  This might be used for
-new information, notification of upcoming downtime, or similar purposes.
-
-Be aware that use of the LIST MOTD command is not widespread and most news
-clients will never ask for this file.
-
-If this file is missing, it is not an error.  The server will just send
-the client an empty response.
-
-=head1 HISTORY
-
-Rewritten in POD by Russ Allbery <rra@stanford.edu> for InterNetNews.
-
-$Id: motd.news.pod 6574 2003-12-27 06:25:05Z rra $
-
-=head1 SEE ALSO
-
-inn.conf(5)
diff --git a/doc/pod/news.pod b/doc/pod/news.pod
deleted file mode 100644 (file)
index 39166bf..0000000
+++ /dev/null
@@ -1,1200 +0,0 @@
-=head1 Changes in 2.4.5
-
-=over 2
-
-=item *
-
-Fixed the "alarm signal" around C<SSL_read> in B<nnrpd>:  it allows
-a proper disconnection of news clients which were previously hanging
-when posting an article through a SSL connection.  Moreover, the
-I<clienttimeout> parameter now works on SSL connections.  Thanks to
-Matija Nalis for the patch.
-
-=item *
-
-SO_KEEPALIVE is now implemented for SSL TCP connections on systems
-which support it, allowing system detection and closing the dead
-TCP SSL connections automatically after system-specified time.  Thanks
-to Matija Nalis for the patch.
-
-=item *
-
-Fixed a segmentation fault when an article of a size greater than remaining
-stack is retrieved via SSL.  Thanks to Chris Caputo for this patch.
-
-=item *
-
-Fixed a few segfaults and bugs which affected both Python B<innd> and B<nnrpd>
-hooks.  They no longer check the existence of methods not used by the hooked
-script.  An issue with Python exception handling was also fixed, as well as
-a segfault fixed by Russ Allbery which happened whenever one closes and then
-reopens Python in the same process.  Julien Elie also fixed a bug when reloading
-Python filters (they were not always correctly reloaded) and a segfault when
-generating access groups with embedded Python filters for B<nnrpd>.
-Many thanks to David Hlacik for its bug reports.
-
-=item *
-
-The F<nnrpd.py> stub file in order to test Python B<nnrpd> hooks, as
-mentioned in their documentation, is now installed; only F<INN.py> was
-previously installed in I<pathfilter>.  Also fixed a bug in F<INN.py>
-and add missing methods to it.
-
-=item *
-
-Fixed a long-standing bug in B<innreport> which prevented it from
-correctly reporting B<nnrpd> and B<innfeed> log messages.
-
-=item *
-
-Fixed a hang in Perl hooks on (at least) HP/PA since S<Perl 5.10>.
-
-=item *
-
-Fixed a compilation problem on some platforms because of AF_INET6 which
-was not inside a HAVE_INET6 block in B<innfeed>.
-
-=item *
-
-Fixed a bug in B<innfeed> which contained thrice the same IPs for each
-peer; it unnecessarily slowed the peer IP rotation for B<innfeed>.  Thanks,
-S<D. Stussy>, for having seen that.  Miquel van Smoorenburg provided the patch.
-
-=item *
-
-A new I<heavily> improved version of B<pullnews> is shipped with this
-INN release.  This new version is provided by Geraint Edwards.  He added
-no more than S<16 flags>, fixed some bugs and integrated the B<backupfeed>
-contrib script by Kai Henningsen, adding again S<6 other> flags.  A
-long-standing but very minor bug in the B<-g> option was especially fixed
-and items from the to-do list implemented.  Many thanks again to Geraint Edwards.
-
-=item *
-
-New headers are accessible through Perl and Python B<innd> filtering
-hooks.  You will find the exact list in the INN Python Filtering and
-Authentication Hooks documentation (F<doc/hook-python>) and in Python
-samples.  Thanks to Matija Nalis for this addition of new useful headers.
-
-=item *
-
-New samples for Python B<nnrpd> hooks are shipped with INN:  F<nnrpd_access.py>
-for access control and F<nnrpd_dynamic.py> for dynamic access control.  The
-F<nnrpd_auth.py> script is now only used for authorization control.  See the
-F<readers.conf> man page for more information (especially the I<python_auth>,
-I<python_access> and I<python_dynamic> parameters).  The documention about
-INN Python Filtering and Authentication Hooks has also been improved by
-Julien Elie.
-
-=back
-
-=head1 Changes in 2.4.4
-
-=over 2
-
-=item *
-
-Fixed incomplete checking of packet sizes in the B<ctlinnd> interface in
-the no-Unix-domain-sockets case.  This is a potential buffer overflow in
-dead code since basically all systems INN builds on support Unix domain
-sockets these days.  Also track the buffer size more correctly in the
-client side of this interface for the Unix domain socket case.
-
-=item *
-
-Group blocks in F<incoming.conf> are now correctly parsed and no longer
-cause segfaults when loading this file.
-
-=item *
-
-Fixed a problem with B<innfeed> continuously segfaulting on amd64 hardware
-(and possibly on lots of 64-bit platforms).  Many thanks to Ollivier Robert
-for his patch and also to Kai Gallasch for having reported the problem and
-provided the FreeBSD server to debug it.
-
-=item *
-
-B<scanlogs> now rotates B<innfeed>'s log file, which prevents B<innfeed>
-from silently dying when its log file reaches S<2 GB>.
-
-=item *
-
-S<Perl 5.10> support has been added to INN thanks to Jakub Bogusz.
-
-=item *
-
-Some news clients hang when posting an article through a SSL connection:
-it seems that B<nnrpd>'s SSL routines make it wrongly wait for data
-completion.  In order to fix the problem, the select() wait is now
-just bypassed.  However, the IDLE timer stat is currently not collected
-for such connections.  Thanks to Kachun Lee for this workaround.
-
-=item *
-
-Fixed a bug in the display of the used compressor (C<cunbatch> was used
-if arguments were passed to B<gzip> or B<bzip2>).
-
-=item *
-
-Fixed a bug in B<mailpost> and B<pullnews> which prevented useful error
-messages to be seen.  Also add the B<-x> flag to B<pullnews> in order
-to insert Xref: headers in articles which lack one.
-
-=item *
-
-If compiling with S<Berkeley DB>, use its ndbm compatibility layer for
-B<ckpasswd> in preference to searching for a traditional dbm library.
-INN also supports S<Berkeley DB 4.4>, 4.5 and 4.6 thanks to Marco d'Itri.
-
-=item *
-
-B<ovdb_init> now properly closes stdin/out/err when it becomes a daemon.
-The issue was reported by Viktor Pilpenok and fixed by Marco d'Itri.
-
-=item *
-
-Added support for Diablo quickhash and hashfeed algorithms.
-It allows to distribute the messages among several peers (new B<Q> flag
-for F<newsfeeds>).  Thanks to Miquel van Smoorenburg for this
-implementation in INN.
-
-=item *
-
-B<innd> now listen on separate sockets for IPv4 and IPv6 connections
-if the IPV6_V6ONLY socket option is available.  There might also be
-operating systems that still have separate IPv4 and IPv6 TCP implementations,
-and advanced features like TCP SACK might not be available on v6 sockets.
-Thanks to Miquel van Smoorenburg for this patch.
-
-=item *
-
-The two configuration options I<bindaddress> and I<bindaddress6> can now
-be set on a per-peer basis for B<innfeed>.  Setting I<bindaddress6>
-to C<none> tells B<innfeed> to never attempt an IPv6 connection to that
-host.  Thanks to Miquel van Smoorenburg for this patch.
-
-=item *
-
-Added a I<nnrpdflags> parameter to F<inn.conf> (modeled on the concept of
-I<innflags>) to permit passing of command line arguments to instances of
-B<nnrpd> spawned from B<innd>.
-
-=item *
-
-A new F<inn.conf> parameter called I<pathcluster> has been added:
-it allows to append a common name to the Path: header
-on all incoming articles.  I<pathhost> and I<pathalias> (if set)
-are still appended to the path as usual, but I<pathcluster>
-is always appended as the last element (e.g. on the leftmost
-side of the Path: header).  Thanks to Miquel van Smoorenburg for
-this feature.
-
-=item *
-
-B<simpleftp> has been rewritten to use C<Net::FTP>.  Indeed, F<ftp.pl>
-is no longer shipped with S<Perl 5> and the script did not work.
-
-=item *
-
-B<perl-nocem> will now check for a timeout and re-open the socket
-if required.  Additionally, B<perl-nocem> will switch to
-cancel_ctlinnd in case cancel_nntp fails after sending
-the Message-ID.  Thanks to Christoph Biedl for the patch.  A more
-detailed documentation has also been written for perl-nocem(8).
-
-=item *
-
-The RADIUS configuration is now wrapped in a C<server {}> block in
-F<radius.conf>.
-
-=item *
-
-Checkgroups when there is nothing to change no longer result in sending
-a blank mail to administrators.  Besides, no mail is sent by B<controlchan>
-for the creation of a newsgroup when the action is C<no change>.
-
-=item *
-
-Checkgroups are now properly propagated even though the news server
-does not carry the groups they are posted to.
-
-=item *
-
-B<controlchan> and B<docheckgroups> now handle wire format messages
-so that articles from the spool can be directly fed to them.
-
-=item *
-
-Newgroup control messages for existing groups now change their description.
-If a mail is sent to administrators, it reminds them to update their
-F<newsgroups> file.  It also warns when there are missing or obsolete
-descriptions.  Furthermore, the F<newsgroups> file is now written prettier
-(from one to three tabulations between the name of the group and its
-short description) and to.* groups cannot be created.
-
-=item *
-
-The sample F<control.ctl> file has been extensively updated.
-
-=item *
-
-Fixed empty LISTGROUP replies which were not terminated.  Thanks to
-David Canzi for the patch.
-
-=item *
-
-In response to a LIST [file] command, if the file does not exist,
-we assume it is not maintained and return C<503> instead of C<215> and
-an empty file.  Moreover, capability to LIST ACTIVE.TIMES for a wildmat
-pattern as its third argument has been added in order to select wanted
-newsgroups.
-
-=item *
-
-B<inews> now tries to authenticate if it does not receive a C<200> return
-code after MODE READER.  Indeed, it might be able to post even with
-a C<201> return code and also with another codes like C<440> or C<480>.
-
-=item *
-
-If creating a new F<history> file, set the ownership and mode appropriately.
-B<inncheck> also expects fewer things to be private to the news user.  Most
-of the configuration files will never contain private information like
-passwords.
-
-=item *
-
-Other minor bug fixes and documentation improvements.
-
-=back
-
-=head1 Changes in 2.4.3
-
-=over 2
-
-=item *
-
-Previous versions of INN had an optimization for handling XHDR Newsgroups
-that used the Xref: header from overview.  While this does make the command
-much faster, it doesn't produce accurate results and breaks the NNTP
-protocol, so this optimization has been removed.
-
-=item *
-
-Fixed a bug in B<innd> that allowed it to accept articles with duplicated
-headers if the header occurred an odd number of times.  Modified the
-programs for rebuilding overview to use the last Xref: header if there
-are multiple ones to avoid problems with spools that contain such invalid
-articles.
-
-=item *
-
-Fixed yet another problem with verifying that a user has permissions to
-approve posts to a moderated group.  Thanks, Jens Schlegel.
-
-=item *
-
-Increase the send and receive buffer on the Unix domain socket used by
-B<ctlinnd>.  This should allow longer replies (particularly for B<innstat>) on
-platforms with very low default Unix domain socket buffer sizes.
-
-=item *
-
-B<rnews>'s handling of articles with nul characters, NNTP errors, header
-problems, and deferrals has been significantly improved.
-
-=item *
-
-Thomas Parmelan added support to B<send-uucp> for specifying the funnel or
-exploder site to flush for feeds managed through one and fixed a problem
-with picking up old stranded work files.
-
-=item *
-
-Many other more minor bug fixes, optimization improvements, and
-documentation fixes.
-
-=back
-
-=head1 Changes in 2.4.2
-
-=over 2
-
-=item *
-
-INN is now licensed under a less restrictive license (about as minimally
-restrictive as possible shy of public domain), and the clause similar to
-the old BSD advertising clause has been dropped.
-
-=item *
-
-C<make install> and C<make update> now always install the newly built binaries,
-rather than only installing them if the modification times are newer.
-This is the behavior that people expect.  C<make install> now also
-automatically builds a new (empty) history database if one doesn't already
-exist.
-
-=item *
-
-The embedded Tcl filter code has been disabled (and will be removed
-entirely in the next major release of INN).  It hasn't worked for some
-time and causes B<innd> crashes if compiled in (even if not used).  If
-someone wants to step forward and maintain it, I recommend starting from
-scratch and emulating the Perl and Python filters.
-
-=item *
-
-B<ctlinnd> should now successfully handle messages from INN up to the maximum
-allowable packet size in the protocol, fixing problems sites with many
-active peers were having with B<innstat> output.
-
-=item *
-
-Overview generation has been fixed in both B<makehistory> and B<innd> to follow
-the rules in the latest NNTP draft rather than just replacing special
-characters with spaces.  This means that the unfolding of folded header
-lines will not introduce additional, incorrect whitespace in the overview
-data.
-
-=item *
-
-B<nnrpd> now uniformly responds with a C<480> or C<502> status code to attempts
-to read a newsgroup to which the user does not have access, depending on
-whether the user has authenticated.  Previously, it returned a C<411> status
-code, claiming the group didn't exist, which confuses the reactive
-authentication capability of news readers.
-
-=item *
-
-If a user is not authorized to approve articles (using the C<A> I<access>
-control in F<readers.conf>), articles that include Approved: headers will be
-rejected even if posted to unmoderated groups.  Some other site may
-consider that group to be moderated.
-
-=item *
-
-The configuration parser used for F<readers.conf> and others now correctly
-handles C<#> inside quoted strings and is more robust against unmatched
-double quotes.
-
-=item *
-
-Messages mailed to moderators had two spaces after the colons in the
-headers, rather than one.  This bug has been fixed.
-
-=item *
-
-A bug that could cause heap corruption and random crashes in B<innd> if INN
-were compiled with Python support has been fixed.
-
-=item *
-
-Some problems with B<innd>'s tracking of article size and enforcement of the
-configured maximum article size have been fixed.
-
-=item *
-
-B<pgpverify> will now correctly verify signatures generated by GnuPG and
-better supports GnuPG as the PGP implementation.
-
-=item *
-
-INN's code should now be more 64-bit clean in its handling of size_t,
-pointer differences, and casting of pointers, correcting problems that
-showed up on 64-bit platforms like AMD64.
-
-=item *
-
-Improved the error reporting in the history database code, in B<inews>, in
-B<controlchan>, and in B<expire>.
-
-=item *
-
-Many other, more minor bugs have also been fixed.
-
-=back
-
-=head1 Changes in 2.4.1
-
-=over 2
-
-=item *
-
-SECURITY:  Handle the special filing of control messages into per-type
-newsgroups more robustly.  This closes a potentially exploitable buffer
-overflow.  Thanks to Dan Riley for his excellent bug report.
-
-=item *
-
-Fixed article handling in B<innd> so that articles without a Path: header
-(arising from peers sending malformatted articles or injecting
-malformatted articles through rnews) would not cause B<innd> to crash.  (This
-was not exploitable.)
-
-=item *
-
-Fixed a serious bug in XPAT handling, thanks to Tommy van Leeuwen.
-
-=item *
-
-C<configure> now looks for B<sendmail> only in F</usr/sbin> and F</usr/lib>, not on
-the user's path.  This should reduce the need for B<--with-sendmail> if your
-preferred sendmail is in a standard location.
-
-=item *
-
-The robustness of the tradindexed overview method has been further
-increased, handling more edge cases arising from corrupted databases and
-oddly-named newsgroups.
-
-=item *
-
-B<innd> now never decreases the high water mark of a newsgroup when
-renumbering, which should help ameliorate overview and F<active> file
-synchronization problems.
-
-=item *
-
-Do not close and reopen the F<history> file on B<ctlinnd> reload when the server
-is paused or throttled.  This was breaking B<ctlinnd> reload all during a
-server pause.
-
-=item *
-
-Various minor portability and compilation issues fixed.  Substantial
-numbers of compiler warnings have been cleaned up, thanks largely to work
-by Ilya Kovalenko.
-
-=item *
-
-Multiple other more minor bugs have been fixed.
-
-=item *
-
-Documentation and man pages have been clarified and updated.
-
-=back
-
-=head1 Upgrading from 2.3 to 2.4
-
-The F<inn.conf> parser has changed between S<INN 2.3> and 2.4.  Due to that
-change, options in F<inn.conf> that contain whitespace or a few other
-special characters must be quoted with double quotes, and empty parameters
-(parameters with no value) are not allowed.  S<INN 2.4> comes with a script,
-B<innupgrade>, run automatically during C<make update>, that will attempt
-to fix any problems that it finds with your F<inn.conf> file, saving the
-original as F<inn.conf.OLD>.
-
-This change is the beginning of standardization of parsing and syntax
-across all of INN's configuration files.
-
-The history subsystem now has a standard API that allows other backends to
-be used.  Because of this, you now need to specify the history method in
-F<inn.conf>.  Adding:
-
-    hismethod: hisv6
-
-will tell INN to use the same history backend as was used in previous
-versions.  B<innupgrade> should take care of this for you.
-
-ovdb is known to have some locking and timing issues related to how B<nnrpd>
-shuts down (or fails to shut down) the overview databases.  If you have
-stability problems with ovdb, try setting I<readserver> to C<true> in
-F<ovdb.conf>.  This will funnel all ovdb reads through a single process
-with a cleaner interface to the underlying S<Berkeley DB> database.
-
-If you use Perl authentication for B<nnrpd> (if I<nnrpdperlauth> in
-F<inn.conf> is C<true>), there have been major changes.  See "Changes to
-Perl Authentication Support for nnrpd" in F<doc/hook-perl> for details.
-
-Similarly, if you use Python authentication for B<nnrpd> (if
-I<nnrpdpythonauth> in F<inn.conf> is C<true>), there have been major changes.
-See "Changes to Python Authentication and Access Control Support for
-nnrpd" in F<doc/hook-python> for details.
-
-If you use B<send-uucp>, it has been completely rewritten and now takes a
-configuration file to specify its behavior.  See its man page for more
-information.  If you use B<sendbatch>, it is no longer included in INN
-since the new B<send-uucp> can handle all of the same functionality.
-
-The wildmat API has been renamed (to uwildmat and friends; see uwildmat(3)
-for the interfaces) to distinguish it from Rich $alz's original version,
-since it now supports UTF-8.  This may require changes in other software
-packages that link against INN's libraries.
-
-If you are upgrading from a version prior to S<INN 2.3>, see L<Upgrading
-from 2.2 to 2.3>.
-
-=head1 Changes in 2.4.0
-
-=over 2
-
-=item *
-
-IPv6 support has been added, disabled by default.  If you have IPv6
-connectivity, build with B<--enable-ipv6> to try it.  There are no known
-bugs, but please report any problems you find (or even successes, if you
-use an unusual platform).  There are a few changes of interest; further
-information is available in F<doc/IPv6-info>.
-
-=item *
-
-The tradindexed overview method has been completely rewritten and should
-be considerably more robust in the face of system crashes.  A new utility,
-B<tdx-util>, is provided to examine the contents of the overview database,
-repair inconsistencies, and rebuild the overview for particular groups
-from a tradspool news spool.  See tdx-util(8) for more details.
-
-=item *
-
-The Perl and Python authentication hooks for readers have been extensively
-overhauled and integrated better with F<readers.conf>.  See the Changes
-sections in F<doc/hook-perl> and F<doc/hook-python> for more details.
-
-=item *
-
-B<nnrpd> now optionally supports article injection via IHAVE, see
-readers.conf(5).  Any articles injected this way must have Date, From,
-Message-ID, Newsgroups, Path, and Subject headers.  X-Trace and
-X-Complaints-To headers will be added if the appropriate options are set
-in F<readers.conf>, but other headers will not be modified/inserted (e.g.
-NNTP-Posting-Host, NNTP-Posting-Date, Organization, Lines, Cc, Bcc, and To
-headers).
-
-=item *
-
-B<nnrpd> now handles arbitrarily long lines in POST and IHAVE; administrators
-who want to limit the length of lines in locally posted articles will need
-to add this to their local filters instead.
-
-=item *
-
-B<nnrpd> no longer handles the poorly-specified S<RFC 977> optional fourth
-argument to the NEWGROUPS command specifying the "distributions" that the
-command was supposed to apply to.
-
-Clients that use that argument will break.  There are not believed to be
-any such clients, and it's easy enough to just filter the returned list of
-newsgroups (which is generally fairly short) to achieve the same results.
-
-=item *
-
-B<nnrpd> no longer accepts UTC as a synonym for GMT for NEWGROUPS or NEWNEWS.
-This usage was never portable, and was rejected by the NNTP working group.
-It is being removed now in the hope that it will be caught before anyone
-starts to rely on it.
-
-=item *
-
-B<innfeed> supports a new peer parameter, I<backlog-feed-first>, that if set
-to C<true> feeds any backlog to a peer before new articles, see
-innfeed.conf(5).  When used in combination with I<max-connections> set to C<1>,
-this can be used to enforce in-order delivery of messages to a peer that
-is doing Xref slaving, avoiding cases where a higher-numbered message is
-received before a lower-numbered message in the same group.
-
-=item *
-
-Several other, more minor protocol issues have been fixed:  connections
-rejected due to the connection rate limiting in B<innd> receive C<400> replies
-instead of C<504> or C<505>, and ARTICLE without an argument will always either
-retrieve the current article or return a C<423> error, never advance the
-current article number to the next valid article.
-
-See F<doc/compliance-nntp> for all of the known issues with INN's
-compliance with the current NNTP draft.
-
-=item *
-
-All accesses to the F<history> file for all parts of INN now go through a
-generic API like the storage and overview subsystems do.  This will
-eventually allow new history implementations to be dropped in without
-affecting the rest of INN, and will significantly improve the
-encapsulation of the history subsystem.  See the libinnhist(3) man page
-for the details of the interface.
-
-=item *
-
-INN now uses a new parser for the F<inn.conf> file.  This means that
-parameters containing whitespace or other special characters must now be
-quoted; see inn.conf(5).  It fixes the long-standing bug that certain
-values must be included in F<inn.conf> even if using the defaults for the
-use of shell or Perl scripts, and it will serve as the basis for
-standardizing and cleaning up the configuration file parsing in other
-parts of INN.  B<innupgrade> is run during C<make update> and should convert
-an existing F<inn.conf> file for you.
-
-=item *
-
-B<send-uucp> has been replaced by a completely rewritten version from
-Marco d'Itri, Edvard Tuinder, and Miquel van Smoorenburg, which uses a
-configuration file that specifies batch sizes, compression methods, and
-hours during which batches should be generated.  The old B<sendbatch>
-script has been retired, since B<send-uucp> can now handle everything
-that it did.
-
-=item *
-
-Two C<configure> options have changed names:  B<--with-tmp-path> is now
-B<--with-tmp-dir>, and B<--with-largefiles> is now B<--enable-largefiles>, to
-improve consistency and better match the C<autoconf> option guidelines.
-
-=item *
-
-Variables can now be used in the F<newsfeeds> file to make it easier to
-specify many similar feeds or feed patterns.  See the newsfeeds(5) man
-page for details.
-
-=item *
-
-Local connections to INN support a new special mode, MODE CANCEL, that
-allows efficient batch cancellation of messages.  This is intended to be
-the preferred interface for external spam and abuse filters like NoCeM.
-See "CANCEL FEEDS" in innd(8) for details.
-
-=item *
-
-Two new options, I<nfsreader> and I<nfswriter>, have been added to
-F<inn.conf> to aid in building NFS based shared reader/writer platforms.
-On the writer server configure I<nfswriter> to C<true> and on all of the readers
-configure I<nfsreader> to C<true>; these options add calls to force data out to
-the NFS server and force it to be read directly from the NFS server at the
-appropriate moments.  Note that it has only been tested on S<Solaris 8>,
-using CNFS as the storage mechanism and tradindexed as the overview
-method.
-
-=item *
-
-A new option, I<tradindexedmmap>, has been added to F<inn.conf>.  If set
-to C<true> (the default), then the tradindexed overview method will use
-mmap() to access its overview data (in 2.3 you couldn't control this; it
-always used mmap).
-
-=item *
-
-Thanks to code contributed by CMU, B<innfeed> can now feed an IMAP server as
-well as other NNTP servers.  See the man page for innfeed(8) for more
-information.
-
-=item *
-
-An authenticator, B<auth_smb>, that checks a username and password against
-a remote Samba server is now included.  See auth_smb(8) for details.
-
-=item *
-
-The wildmat functions in INN now support UTF-8, in a way that should allow
-them to still work with most simple 8-bit character sets in widespread
-use.  As part of this change, some additional wildmat interfaces are now
-available and the names have changed (to uwildmat, where C<u> is for
-Unicode).  See uwildmat(3) for the details.
-
-=item *
-
-The interface between external authenticators and B<nnrpd> is now properly
-documented, in F<doc/external-auth>.  A library implementing this
-interface in C is provided, which should make it easier to write
-additional authenticators resolvers.  See libauth(3) for details, and any
-of the existing programs in F<authprogs/> for examples.
-
-=item *
-
-Most (if not all) of the temporary file creation in INN now uses functions
-that create temporary files properly and safely.
-
-=back
-
-=head1 Changes in 2.3.5
-
-=over 2
-
-=item *
-
-Clients using POST are no longer permitted to provide an Injector-Info:
-header.
-
-=item *
-
-Fixed a bug causing posts with Followup-To: set to a moderated group to be
-rejected if the posting user didn't have permission to approve postings.
-
-=item *
-
-Fixed bugs in B<inncheck> with setuid rnews or setgid inews, in I<innconfval>
-with F<inn.conf> parameters containing shell metacharacters but no spaces,
-and in F<parsedate.y> with some versions of B<yacc>.  Fixed a variety of
-size-related printf format warnings (e.g., C<%d> vs. C<%ld>) thanks to the work
-of Winfried Szukalski.
-
-=back
-
-=head1 Changes in 2.3.4
-
-=over 2
-
-=item *
-
-LIST ACTIVE no longer returns data when given a single group argument if
-the client is not authorized to read that group.
-
-=item *
-
-XHDR and XPAT weren't correctly parsing article headers, resulting in
-searches for the header "newsgroup" matching the header "newsgroups".
-
-=item *
-
-Made CNFS more robust against crashes by actually syncing the cycbuff
-headers to disk as was originally intended.  Fixed a memory leak in the
-tradspool code.
-
-=item *
-
-Two bugs in B<pgpverify> when using GnuPG were fixed:  it now correctly checks
-for B<gpgv> (rather than B<pgp>) when told to use GnuPG and expects the keyring
-to be F<pubring.gpg> (not F<pubring.pgp>).
-
-=item *
-
-Substantial updates to the sample provided F<control.ctl> file.
-
-=item *
-
-Compilation fixes with S<Perl 5.8.0>, S<Berkeley DB 4.x>, current versions of
-Linux (including with large file support), and Tru64.  B<inndf> fixes for
-ReiserFS.
-
-=item *
-
-Various bugs in the header handling in B<nnrpd> have been fixed, including
-hangs when using virtual domains and improper processing of folded headers
-under certain circumstances.
-
-=item *
-
-Other minor bug fixes and documentation improvements.
-
-=back
-
-=head1 Changes in 2.3.3
-
-=over 2
-
-=item *
-
-B<pgpverify> now supports using GnuPG to check signatures (rather than PGP)
-without the B<pgpgpg> wrapper.  GnuPG can check both old-style RSA signatures
-and new OpenPGP signatures and is recommended over S<PGP 2.6>.  If you have
-GnuPG installed, B<pgpverify> will use it rather than PGP, which means that
-you may have to create a new key ring for GnuPG to use to verify signatures
-if you were previously using PGP.
-
-=item *
-
-Users can no longer post articles containing Approved: headers to
-moderated groups by default; they must be specifically given that
-permission with the I<access> parameter in F<readers.conf>.  See the man page
-for more details.
-
-=item *
-
-Two bugs in repacking overview index files and a reliability bug with
-writing overview data were all fixed in the tradindexed overview method,
-hopefully making it somewhat more reliable, particularly for B<makehistory>.
-
-=item *
-
-If F<rc.news.local> exists in the INN binary directory, it will be run with
-the start or stop argument whenever B<rc.news> is run.  This is available
-as a hook for local startup and shutdown code.
-
-=item *
-
-The default history table hash sizes were increased because a too-small
-value can cause serious performance problems (whereas a too-large hash
-just wastes a bit of disk space).
-
-=item *
-
-The sample F<control.ctl> file has been extensively updated.
-
-=item *
-
-Wildmat exclusions (C<@> and C<!>) should now work properly in F<storage.conf>
-newsgroup patterns.
-
-=item *
-
-The implementation of the B<-w> flag for B<expireover> was fixed; previously,
-the value given to B<-w> to change B<expireover>'s notion of the current time
-was scaled by too much.
-
-=item *
-
-Various other more minor bug fixes, standards compliance fixes, and
-documentation improvements.
-
-=back
-
-=head1 Changes in 2.3.2
-
-=over 2
-
-=item *
-
-B<innxmit> can again handle regular filenames as input as well as storage API
-tokens (allowing it to be used to import an old traditional spool).
-
-=item *
-
-Several problems with tagged-hash history files have been fixed thanks to
-the debugging efforts of Andrew Gierth and Sang-yong Suh.
-
-=item *
-
-A very long-standing (since S<INN 1.0>!) NNTP protocol bug in B<nnrpd> was
-fixed.  The response to an ARTICLE command retrieving a message by Message-ID
-should have the Message-ID as the third word of the response, not the
-fourth.  Fixing this is reported to I<possibly> cause problems with some
-Netscape browsers, but other news servers correctly follow the protocol.
-
-=item *
-
-Some serious performance problems with expiration of tradspool should now
-be at least somewhat alleviated.  tradspool and timehash now know how to
-output file names for removal rather than tokens, and B<fastrm>'s ability to
-remove regular files has been restored.  This should bring expiration
-times for tradspool back to within a factor of two of pre-storage-API
-expiration times.
-
-=item *
-
-Added a sample F<subscriptions> file and documentation for it and B<innmail>.
-
-=back
-
-=head1 Changes in 2.3.1
-
-=over 2
-
-=item *
-
-B<inews> no longer downloads the F<active> file, no longer tries to send
-postings to moderated groups to the moderator directly, and in general
-duplicates less of the functionality of B<nnrpd>, instead letting B<nnrpd>
-handle it.  This fixes the problem of B<inews> not working properly for users
-other than news without being setgid.
-
-=item *
-
-Added a man page for B<ckpasswd>.
-
-=item *
-
-A serious bug in the embedded Perl authentication hooks was fixed, thanks
-to Jan Rychter.
-
-=item *
-
-The annoying compilation problem with embedded Perl filtering on Linux
-systems without libgdbm installed should be fixed.
-
-=item *
-
-INN now complains loudly at C<configure> time if the configured path for
-temporary files is world-writeable, since this configuration can be a
-security hole.
-
-=item *
-
-Many other varied bug fixes and documentation fixes of all sorts.
-
-=back
-
-=head1 Upgrading from 2.2 to 2.3
-
-There may be additional things to watch out for not listed here; if you
-run across any, please let <inn-bugs@isc.org> know about them.
-
-Simply doing a C<make update> is not sufficient to upgrade; the history and
-overview information will also have to be regenerated, since the formats
-of both files have changed between 2.2 and 2.3.  Regardless of whether you
-were using the storage API or traditional spool under 2.2, you'll need to
-rebuild your overview and history files.  You will also need to add a
-F<storage.conf> file, if you weren't using the storage API under S<INN 2.2>.  A
-good default F<storage.conf> file for 2.2 users would be:
-
-    method tradspool {
-        newsgroups: *
-        class: 0
-    }
-
-Create this F<storage.conf> file before rebuilding history or overview.
-
-If you want to allow readers, or if you want to expire based on newsgroup
-name, you need to tell INN to generate overview data and pick an overview
-method by setting I<ovmethod> in F<inn.conf>.  See F<INSTALL> and inn.conf(5)
-for more details.
-
-The code that generates the dbz index files has been split into a separate
-program, B<makedbz>.  B<makehistory> still generates the base F<history> file
-and the overview information, but some of its options have been changed.
-To rebuild the history and overview files, use something like:
-
-    makehistory -b -f history.n -O -T /usr/local/news/tmp -l 600000
-
-(change the F</usr/local/news/tmp> path to some directory that has plenty of
-temporary space, and leave off B<-O> if you're running a transit-only server
-and don't intend to expire based on group name, and therefore don't need
-overview.)  Or if your overview is buffindexed, use:
-
-    makehistory -b -f history.n -O -F
-
-Both will generate a new history file as F<history.n> and rebuild overview
-at the same time.  If you want to preseve a record of expired Message-IDs
-in the history file, run:
-
-    awk 'NF==2 { print; }' < history >> history.n
-
-to append them to the new history file you created above.  Look over the
-new history file and make sure it looks right, then generate the new index
-files and move them into place:
-
-    makedbz -s `wc -l < history.n` -f history.n
-    mv history.n history
-    mv history.n.dir history.dir
-    mv history.n.hash history.hash
-    mv history.n.index history.index
-
-(Rather than F<.hash> and F<.index> files, you may have a F<.pag> file if you're
-using tagged hash.)
-
-For reader machines, F<nnrp.access> has been replaced by F<readers.conf>.
-There currently isn't a program to convert between the old format and the
-new format (if you'd like to contribute one, it would be welcomed
-gratefully).  The new file is unfortunately considerably more complex as
-a result of its new capabilities; please carefully read the example
-F<readers.conf> provided and the man page when setting up your initial
-configuration.  The provided commented-out examples cover the most common
-installation (IP-based authentication for all machines on the local
-network).
-
-INN makes extensive use of mmap(2) for the new overview mechanisms, so at
-the present time NFS-mounting the spool and overview on multiple reader
-machines from one central server probably isn't feasible in this version.
-mmap tends to interact poorly with NFS (at the least, NFS clients won't
-see updates to the mapped files in situations where they should).  (The
-preferred way to fix this would, rather than backing out the use of mmap
-or making it optional, to add support for Diablo-style header feeds and
-pull-on-demand of articles from a master server.)
-
-The flags for B<overchan> have changed, plus you probably don't want to
-run B<overchan> at all any more.  Letting B<innd> write overview data itself
-results in somewhat slower performance, but is more reliable and has a
-better failure mode under high loads.  Writing overview data directly is
-the default, so in a normal upgrade from 2.2 to 2.3 you'll want to comment
-out or remove your B<overchan> entry in F<newsfeeds> and set I<useoverchan> to
-C<false> in F<inn.conf>.
-
-B<crosspost> is no longer installed, and no longer works (even with
-traditional spool).  If you have an entry for B<crosspost> in F<newsfeeds>,
-remove it.
-
-If you're importing a traditional spool from a pre-storage API INN server,
-it's strongly recommended that you use NNTP to feed the articles to your
-new server rather than trying to build overview and history directly from
-the old spool.  It's more reliable and ensures that everything gets put
-into the right place.  The easiest way to do this is to generate, on your
-old server, a list of all of your existing article files and then feed
-that list to B<innxmit>.  Further details can be found in the FAQ at
-L<http://www.eyrie.org/~eagle/faqs/inn.html>.
-
-If you are using a version of Cleanfeed that still has a line in it like:
-
-    $lines = $hdr{'__BODY__'} =~ tr/\n/\n/;
-
-you will need to change this line to:
-
-    $lines = $hdr{'__LINES__'};
-
-to work with S<INN 2.3> or later.  This is due to an internal optimization of
-the interface to embedded filters that's new in S<INN 2.3>.
-
-=head1 Changes in 2.3.0
-
-=over 2
-
-=item *
-
-New F<readers.conf> file (replaces F<nnrp.access>) which allows more
-flexible specification of access restrictions.  Included in the sample
-implementations is a RADIUS-based authenticator.
-
-=item *
-
-Unified overview has been replaced with an overview API, and there are now
-three separate overview implementations to choose from.  One (tradindexed)
-is very like traditional overview but uses an additional index file.  The
-second (buffindexed) uses large buffers rather than separate files for
-each group and can handle a higher incoming article rate while still being
-fast for readers.  The third (ovdb) uses S<Berkeley DB> to store overview
-information (so you need to have S<Berkeley DB> installed to use it).  The
-I<ovmethod> key in F<inn.conf> chooses the overview method to use.
-
-Note that ovdb has not been as widely tested as the other overview
-mechanisms and should be considered experimental.
-
-=item *
-
-All article storage and retrieval is now done via the storage API.
-Traditional spool is now available as a storage type under the storage
-API.  (Note that the current traditional spool implementation causes
-nightly expire to be extremely slow for a large number of articles, so
-it's not recommended that you use the tradspool storage method for the
-majority of a large spool.)
-
-=item *
-
-The timecaf storage method has been added, similar to timehash but storing
-multiple articles in a single file.  See F<INSTALL> for details on it.
-
-=item *
-
-INN now supports embedded Python filters as well as Perl and Tcl filters,
-and supports Python authentication hooks.
-
-=item *
-
-There is preliminary support for news reading over SSL, using OpenSSL.
-
-=item *
-
-To simplify anti-abuse filtering, and to be more compliant with news
-standards and proposed standards, INN now treats as control messages only
-articles containing a Control: header.  A Subject: line beginning with
-C<cmsg > is no longer sufficient for a message to be considered a control
-message, and the Also-Control: header is no longer supported.
-
-=item *
-
-The INN build system no longer uses subst.  (This will be transparent to
-most users; it's an improvement and modernization of how INN is
-configured.)
-
-=item *
-
-The build and installation system has been substantially overhauled.
-C<make update> now updates scripts as well as binaries and documentation,
-there is better support for parallel builds (C<make -j>), there is less
-C<make> recursion, and far more of the system-dependent configuration is
-handled directly by C<autoconf>.  libtool build support (including shared
-library support) should be better than previous releases.
-
-=back
-
-=head1 Changes in 2.2.3
-
-=over 2
-
-=item *
-
-B<inews> is not installed setgid news and B<rnews> is not installed setuid root
-by default any more.  If you need the old permissions, you have to give a
-flag to configure.  See F<INSTALL> for more details.
-
-=item *
-
-Fixed a security hole when I<verifycancels> was enabled in F<inn.conf> (not the
-default).
-
-=item *
-
-Message-IDs are now limited to 250 octets to prevent interoperability
-problems with other servers.
-
-=item *
-
-Embedded Perl filters now work with S<Perl 5.6.0>.
-
-=item *
-
-Lots of bug fixes and changes for security paranoia.
-
-=back
-
-=head1 Changes in 2.2.2
-
-=over 2
-
-=item *
-
-Various minor bug fixes and a Y2K bug fix.  The Y2K bug is in version
-version 2.2.1 only and will show up after S<Jan 1st>, 2000 when a news reader
-issues a NEWNEWS command for a date prior to the year 2000.
-
-=back
-
-=head1 Changes in 2.2.1
-
-=over 2
-
-=item *
-
-Various bug fixes, mostly notably fixes for potential buffer overflow
-security vulnerabilities.
-
-=back
-
-=head1 Changes in 2.2.0
-
-=over 2
-
-=item *
-
-New F<storage.conf> file (replaces F<storage.ctl>).
-
-=item *
-
-New (optional) way of handling non-cancel control messages (B<controlchan>)
-that serializes them and prevents server overload from control message
-storms.
-
-=item *
-
-Support for B<actsyncd> to fetch F<active> file with B<ftp>; configured by default
-to use L<ftp://ftp.isc.org/pub/usenet/CONFIG/active.Z> if you run B<actsyncd>.
-Be sure to read the manual page for B<actsync> to configure an F<actsync.ign>
-file for your site, and test B<simpleftp> if you do not C<configure> with B<wget>
-or B<ncftp>.  Also see L<ftp://ftp.isc.org/pub/usenet/CONFIG/README>.
-
-=item *
-
-Some options to C<configure> are now moved to F<inn.conf> (I<merge-to-groups> and
-I<pgp-verify>, without the hyphen).
-
-=item *
-
-B<inndf>, a portable version of df(1), is supplied.
-
-=item *
-
-New B<cnfsstat> program to show stats of CNFS buffers.
-
-=item *
-
-B<news2mail> and B<mailpost> programs for gatewaying news to mail and mail to
-news are supplied.
-
-=item *
-
-B<pullnews> program for doing a sucking feed is provided (not meant for large
-feeds).
-
-=item *
-
-The B<innshellvars.csh.in> script is obsolete (and lives in the F<obsolete>
-directory, for now).
-
-=back
-
-=cut
diff --git a/doc/pod/newsfeeds.pod b/doc/pod/newsfeeds.pod
deleted file mode 100644 (file)
index a57ea32..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-=head1 NAME
-
-newsfeeds - Determine where Usenet articles are sent
-
-=head1 DESCRIPTION
-
-The file I<pathetc>/newsfeeds specifies how incoming articles should be
-distributed to other programs and files on the server.  It is parsed by
-the InterNetNews server innd(8) when it starts up, or when directed to by
-ctlinnd(8).  B<innd> doesn't send articles to remote sites itself, so
-F<newsfeeds> doesn't directly determine which remote news servers articles
-are sent to.  Instead, it specifies what batch files should be created or
-which programs should be run (and what information should be sent to
-them), and then this information is used by programs like innxmit(8) and
-innfeed(8) to feed articles to remote sites.
-
-The F<newsfeeds> file isn't used solely to set up feeding accepted
-articles to remote sites but also to pass them (or bits of information
-about them) to any local programs or files that want that data.  For
-example, controlchan(8), a daemon that processes incoming control
-messages, runs out of F<newsfeeds>, as could a news to mail gateway.
-
-The file is interpreted as a set of lines, parsed according to the
-following rules:  If a line ends with a backslash, the backslash, the
-newline, and any whitespace at the start of the next line is deleted.
-This is repeated until the entire "logical" line is collected.  If the
-logical line is blank or starts with a number sign (C<#>), it is ignored.
-
-All other lines are interpreted as feed entries.  An entry should consist
-of four colon-separated fields; two of the fields may have optional
-sub-fields, marked off by a slash.  Fields or sub-fields that take
-multiple parameters should be separated by a comma.  Extra whitespace can
-cause problems and should be avoided.  Except for the site names, case is
-significant.  The format of an entry is:
-
-    sitename[/exclude,exclude,...]\
-        :pattern,pattern...[/distribution,distribution...]\
-        :flag,flag...\
-        :parameter
-
-Each field is described below.
-
-The I<sitename> is the name of the site to which a news article can be
-sent.  It is used for writing log entries and for determining if an
-article should be forwarded to a site.  (A "site" is the generic term for
-some destination of newsfeed data; it often corresponds to a remote news
-peer, but doesn't have to.  For example, a local archiving program run
-from F<newsfeeds> is also a "site.")  If I<sitename> already appears in
-the article's Path: header, then the article will not be sent to the site.
-The name is usually whatever the remote site uses to identify itself in
-the Path: header, but can be almost any word.
-
-Be careful, though, to avoid having the I<sitename> accidentally match a
-Path: header entry unintentionally.  For this reason, special local
-entries (such as archivers or gateways) should probably end with an
-exclamation point to make sure that they do not have the same name as any
-real site.  For example, C<gateway> is an obvious name for the local entry
-that forwards articles out to a mailing list.  If a site with the name
-C<gateway> posts an article, when the local site receives the article it
-will see the name in the Path and not send the article to its own
-C<gateway> entry.  Since C<gateway!> can't appear as an individual Path:
-entry since C<!> is a delimiter in the Path: header, that would be a
-better thing to use for I<sitename>.
-
-(Another way to avoid this problem is with the C<Ap> flag; see the
-description below.)
-
-If an entry has an exclusion sub-field, the article will not be sent to
-that site if any of I<exclude> appear in the Path: header.  (It's
-sometimes convenient to have the I<sitename> be an abbreviated form of the
-name of the remote site, since all the I<sitename>s to which an article
-is sent are written to the log and using shorter I<sitename>s can
-therefore improve performance for large servers.  In this case, the Path:
-header entries of those sites should be given as I<exclude> entries and
-the C<Ap> flag used so that the abbreviated I<sitename> doesn't
-accidentally match some other Path: header entry.)
-
-The same I<sitename> can be used more than once and the appropriate action
-will be taken for each entry that should receive the article, but this is
-recommended only for program feeds to avoid confusion.  Case is not
-significant in site names.
-
-The comma-separated I<pattern> specifies which groups to send to the site;
-it is interpreted to build a "subscription list" for the site.  The
-default subscription is to get all groups carried by the server.  It is a
-uwildmat(3) pattern supporting poison (C<@>) wildcards; see the uwildmat(3)
-man page for full details on the pattern matching language.  I<pattern>
-will be matched against every newsgroup carried by the server and all
-newsgroups that match will be added to the subscription list for the site.
-
-Normally, a given article (or information about it) is sent to a site if
-any of the newsgroups to which the article was posted are in that site's
-subscription list.  If a newsgroup matches a C<@> pattern in I<pattern>,
-then not only is it not added to the subscription list, but any articles
-crossposted to that newsgroup also will not be sent to that site even if
-other newsgroups to which it was crossposted are in that site's
-subscription list.  This is called a poison pattern (because matching
-groups are "poisoned").
-
-For example, to receive all comp.* groups, but only comp.sources.unix
-within the sources newsgroups, the following I<pattern> can be used:
-
-    comp.*,!comp.sources.*,comp.sources.unix
-
-Note that the trailing C<.*> is required; the pattern has to match the
-whole newsgroup name.  C<comp.sources.*> could be written C<comp.sources*>
-and would exclude the newsgroup comp.sources (if it exists) as well as the
-groups in the comp.sources.* hierarchy, but note that this would also
-exclude a newsgroup named comp.sources-only (whereas the above pattern
-would add that group to the site subscription list since it matches
-C<comp.*> and none of the other patterns.
-
-For another example, to feed alt.* and misc.* to a given site but not any
-articles posted to alt.binaries.warez (even if they're also crossposted to
-other alt.* or misc.* groups), the following pattern can be used:
-
-    alt.*,@alt.binaries.warez,misc.*
-
-Note, however, that if you reversed the C<alt.*> and <@alt.binaries.warez>
-entries, this pattern would be equivalent to C<alt.*,misc.*>, since the
-last matching pattern determines whether a given newsgroup matches and the
-poison logic only applies if the poison entry is the last matching entry.
-
-Control messages follow slightly different propagation rules than normal
-articles; see innd(8) for the details.  Note that most subscriptions
-should have C<!junk,!control,!control.*> in their pattern list due to those
-propagation rules (and since junk is a special internal newsgroup; see
-I<wanttrash> in inn.conf(5) for more details on what it's used for) and
-that the best way to keep control messages local to a site is with a
-distribution.
-
-A subscription can be further modified by specifying distributions that
-the site should or should not receive.  The default is to send all
-articles to all sites that subscribe to any of the groups where it has
-been posted, but if an article has a Distribution: header and any
-I<distribution>s are specified, then they are checked according to the
-following rules:
-
-=over 4
-
-=item 1.
-
-If the Distribution: header matches any of the values in the sub-field,
-the article is sent.
-
-=item 2.
-
-If a I<distribution> starts with an exclamation point, and it matches the
-Distribution: header, the article is not sent.
-
-=item 3.
-
-If the Distribution: header does not match any I<distribution> in the
-site's entry and no negations were used, the article is not sent.
-
-=item 4.
-
-If the Distribution: header does not match any I<distribution> in the
-site's entry and any I<distribution> started with an exclamation point,
-the article is sent.
-
-=back
-
-If an article has more than one distribution specified, then each one is
-handled according according to the above rules.  If any of the specified
-distributions indicate that the article should be sent, it is; if none do,
-it is not sent.  In other words, the rules are used as a logical or.
-
-It is almost definitely a mistake to have a single feed that specifies
-distributions that start with an exclamation point along with some that
-don't.
-
-Distributions are text words, not patterns; entries like C<*> or C<all>
-have no special meaning.
-
-The I<flag> field is described in L<"FLAG VALUES">.  The interpretation of
-the I<parameter> field depends on the type of feed and is explained in
-more detail in L<"FEED TYPES">.  It can be omitted for some types of
-feeds.
-
-The site named C<ME> is special.  There must be exactly one such entry,
-and it should be the first entry in the file.  If the C<ME> entry has an
-exclusion sub-field, incoming articles are rejected completely if any of
-the names specified in that exclusion sub-field appear in their Path:
-headers.  If the C<ME> entry has a subscription list, that list is
-prepended to the subscription list of all other entries.  For example,
-C<*,!control,!control.*,!junk,!foo.*> could be used to set the default subscription
-list for all other feeds so that local postings are not propagated unless
-C<foo.*> explicitly appears in the site's subscription list.  This feature
-tends to be somewhat confusing since the default subscription is prepended
-and can be overridden by other patterns.
-
-If the C<ME> entry has a distribution sub-field, only articles that match
-that distribution list are accepted and all other articles are rejected.
-A common use for this is to put something like C</!local> in the C<ME>
-entry to reject local postings from other misconfigured sites.
-
-Finally, it is also possible to set variables in F<newsfeeds> and use them
-later in the file.  A line starting with C<$> sets a variable.  For
-example:
-
-    $LOCALGROUPS=local.*,example.*
-
-This sets the variable C<LOCALGROUPS> to C<local.*,example.*>.  This
-variable can later be used elsewhere in the file, such as in a site entry
-like:
-
-    news.example.com:$LOCALGROUPS:Tf,Wnm:
-
-which is then completely equivalent to:
-
-    news.example.com:local.*,example.*:Tf,Wnm:
-
-Variables aren't solely simple substitution.  If either C<!> or C<@>
-immediately preceeds the variable and the value of the variable contains
-commas, that character will be duplicated before each comma.  This
-somewhat odd-sounding behavior is designed to make it easier to use
-variables to construct feed patterns.  The utility becomes more obvious
-when you observe that the line:
-
-    news.example.net:*,@$LOCALGROUPS:Tf,Wnm:
-
-is therefore equivalent to:
-
-    news.example.net:*,@local.*,@example.*:Tf,Wnm:
-
-which (as explained below) excludes all of the groups in $LOCALGROUPS from
-the feed to that site.
-
-=head1 FLAG VALUES
-
-The I<flags> parameter specifies miscellaneous parameters, including the
-type of feed, what information should be sent to it, and various
-limitations on what articles should be sent to a site.  They may be
-specified in any order and should be separated by commas.  Flags that take
-values should have the value immediately after the flag letter with no
-whitespace.  The valid flags are:
-
-=over 4
-
-=item B<E<lt>> I<size>
-
-An article will only be sent to this site if it is less than I<size> bytes
-long.  The default is no limit.
-
-=item B<E<gt>> I<size>
-
-An article will only be sent to this site if it is greater than I<size>
-bytes long.  The default is no limit.
-
-=item B<A> I<checks>
-
-An article will only be sent to this site if it meets the requirements
-specified in I<checks>, which should be chosen from the following set.
-I<checks> can be multiple letters if appropriate.
-
-=over 3
-
-=item c
-
-Exclude all kinds of control messages.
-
-=item C
-
-Only send control messages, not regular articles.
-
-=item d
-
-Only send articles with a Distribution header.  Combined with a particular
-distribution value in the I<distribution> part of the site entry, this can
-be used to limit articles sent to a site to just those with a particuliar
-distribution.
-
-=item e
-
-Only send articles where every newsgroup listed in the Newsgroups: header
-exists in the active file.
-
-=item f
-
-Don't send articles rejected by filters.  This is only useful when
-I<dontrejectfiltered> is set in F<inn.conf>.  With that variable set, this
-lets one accept all articles but not propagate filtered ones to some
-sites.
-
-=item o
-
-Only send articles for which overview data was stored.
-
-=item O
-
-Send articles to this site that don't have an X-Trace: header, even if the
-C<O> flag is also given.
-
-=item p
-
-Only check the exclusions against the Path: header of articles; don't
-check the site name.  This is useful if your site names aren't the same as
-the Path: entries added by those remote sites, or for program feeds where
-the site name is arbitrary and unrelated to the Path: header.
-
-=back
-
-If both C<c> and C<C> are given, the last specified one takes precedence.
-
-=item B<B> I<high>/I<low>
-
-If a site is being fed by a file, channel, or exploder (see below), the
-server will normally start trying to write the information as soon as
-possible.  Providing a buffer may give better system performance and help
-smooth out overall load if a large batch of news comes in.  The value of
-the this flag should be two numbers separated by a slash.  I<high>
-specifies the point at which the server can start draining the feed's I/O
-buffer, and I<low> specifies when to stop writing and begin buffering
-again; the units are bytes.  The default is to do no buffering, sending
-output as soon as it is possible to do so.
-
-=item B<C> I<count>
-
-If this flag is specified, an article will only be sent to this site if
-the number of groups it is posted to, plus the square of the number of
-groups followups would appear in, is no more than I<count>.  C<30> is a
-good value for this flag, allowing crossposts to up to 29 groups when
-followups are set to a single group or poster and only allowing crossposts
-to 5 groups when followups aren't set.
-
-=item B<F> I<name>
-
-Specifies the name of the file that should be used if it's necessary to
-begin spooling for the site (see below).  If I<name> is not an absolute
-path, it is taken to be relative to I<pathoutgoing> in F<inn.conf>.  If
-I<name> is a directory, the file F<togo> in that directory will be used as
-the file name.
-
-=item B<G> I<count>
-
-If this flag is specified, an article will only be sent to this site if it
-is posted to no more than I<count> newsgroups.  This has the problem of
-filtering out many FAQs, as well as newsgroup creation postings and
-similar administrative announcements.  Either the B<C> flag or the B<U>
-flag is a better solution.
-
-=item B<H> I<count>
-
-If this flag is specified, an article will only be sent to this site if it
-has I<count> or fewer sites in its Path: line.  This flag should only be
-used as a rough guide because of the loose interpretation of the Path:
-header; some sites put the poster's name in the header, and some sites
-that might logically be considered to be one hop become two because they
-put the posting workstation's name in the header.  The default value for
-I<count> if not specified is one.  (Also see the B<O> flag, which is
-sometimes more appropriate for some uses of this flag.)
-
-=item B<I> I<size>
-
-The flag specifies the size of the internal buffer for a file feed.  If
-there are more file feeds than allowed by the system, they will be
-buffered internally in least-recently-used order.  If the internal buffer
-grows bigger then I<size> bytes, however, the data will be written out to
-the appropriate file.  The default value is 16 KB.
-
-=item B<N> I<status>
-
-Restricts the articles sent to this site to those in newsgroups with the
-moderation status given by I<status>.  If I<status> is C<m>, only articles
-in moderated groups are sent; if I<status> is C<u>, only articles in
-unmoderated groups are sent.
-
-=item B<O> I<originator>
-
-If this flag is specified, an article will only be sent to this site if it
-contains an X-Trace: header and the first field of this header matches
-I<originator>.  I<originator> is a uwildmat(3) expression without commas or
-a list of such expressions, separated by C</>.  The article is never sent
-if the first character of the pattern begins with C<@> and the rest of the
-pattern matches.  One use of this flag is to restrict the feed to locally
-generated posts by using an I<originator> pattern that matches the
-X-Trace: header added by the local server.
-
-=item B<P> I<priority>
-
-The nice priority that this channel or program feed should receive.  This
-should be a positive number between 0 and 20 and is the priority that the
-new process will run with.  This flag can be used to raise the priority to
-normal if you're using the I<nicekids> parameter in F<inn.conf>.
-
-=item B<Q> I<hashfeed>
-
-Specifies the I<hashfeed> match expression for this site.  It must be in
-the form C<value/mod> or C<start-end/mod>.  The Message-ID of the article
-is hashed using MD5, which results in a 128-bit hash.  The lowest
-S<32 bits> are then taken by default as the hashfeed value (which is an
-integer).  If the hashfeed value modulus C<mod> plus one equals C<value> or
-is between C<start> and C<end>, the article will be fed to this site.  All
-these numbers must be integers.
-
-It is a deterministic way to control the flow of articles and to split a feed.
-For instance:
-
-    Q1/2      Feeds about 50% of all articles to this site.
-    Q2/2      Feeds the other 50% of all articles.
-
-Another example with three sites:
-
-    Q1-3/10   Feeds about 30% of all articles.
-    Q4-5/10   Feeds about 20% of all articles.
-    Q6-10/10  Feeds about 50% of all articles.
-
-If this flag is specified multiple times, the contents will be
-logically C<OR>ed together (just one match is needed).
-
-You can use an extended syntax of the form C<value/mod_offset> or
-C<start-end/mod_offset>.  As MD5 generates a 128-bit return value,
-it is possible to specify from which byte-offset the 32-bit integer
-used by hashfeed starts.  The default value for C<offset> is C<_0>
-and thirteen overlapping values from C<_0> to C<_12> can be used.
-Only up to four totally independent values exist:  C<_0>, C<_4>,
-C<_8> and C<_12>.
-
-Therefore, it allows to a generate a second level of deterministic
-distribution.  Indeed, if a news server is fed C<Q1/2>, it can go on
-splitting thanks to C<Q1-3/9_4> for instance.
-
-The algorithm is compatible with the one used by S<Diablo 5.1> and up.
-If you want to use the legacy quickhashing method used by Diablo
-before 5.1, you can put an C<@> sign just after the B<Q> flag (for
-instance C<Q@1-3/10>, but the distribution of the messages is not
-perfect with this legacy method whose use is discouraged and for
-which offsets cannot be used).
-
-=item B<S> I<size>
-
-If the amount of data queued for the site gets to be larger than I<size>
-bytes, the server will switch to spooling, appending to a file specified
-by the B<F> flag, or I<pathoutgoing>/I<sitename> if B<F> is not specified.
-Spooling usually happens only for channel or exploder feeds, when the
-spawned program isn't keeping up with its input.
-
-=item B<T> I<type>
-
-This flag specifies the type of feed for this site.  I<type> should be a
-letter chosen from the following set:
-
-    c        Channel
-    f        File
-    l        Log entry only
-    m        Funnel (multiple entries feed into one)
-    p        Program
-    x        Exploder
-
-Each feed is described below in L<"FEED TYPES">.  The default is B<Tf>,
-for a file feed.
-
-=item B<U> I<count>
-
-If this flag is specified, an article will only be sent to this site if
-followups to this article would be posted to no more than I<count>
-newsgroups.  (Also see B<C> for a more complex way of handling this.)
-
-=item B<W> I<items>
-
-For a file, channel, or exploder feed, this flag controls what information
-will be sent to this site.  For a program feed, only the asterisk (C<*>)
-has any effect.  I<items> should be chosen from the following set:
-
-=over 3
-
-=item b
-
-Size of the article (in wire format, meaning with CRLF at the end of each
-line, periods doubled at the beginning of lines, and ending in a line with
-a single period) in bytes.
-
-=item e
-
-The time the article will expire as seconds since epoch if it has an
-Expires: header, C<0> otherwise.
-
-=item f
-
-The storage API token of the article (the same as C<n>).  The article can
-be retrieved given the storage API token by using sm(8).
-
-=item g
-
-The newsgroup the article is in; if cross-posted, then the first of the
-groups to which the article was posted that this site gets.  (The
-difference from C<G> is that this sends the newsgroup to which the article
-was posted even if it is a control message.)
-
-=item h
-
-The history hash key of the article (derived from the message ID).
-
-=item m
-
-The message ID of the article.
-
-=item n
-
-The storage API token of the article.  The article can be retrieved given
-the storage API token by using sm(8).
-
-=item p
-
-The time the article was posted a seconds since epoch.
-
-=item s
-
-The site that fed the article to the server.  This is taken from either
-the Path: header or the IP address of the sending site depending on the
-value of I<logipaddr> in F<inn.conf>.  If I<logipaddr> is true and the IP
-address is C<0.0.0.0> (meaning that the article was fed from localhost by
-a program like rnews(8)), the Path: header value will be sent instead.
-
-=item t
-
-The time the article was received as seconds since epoch.
-
-=item Z<>*
-
-The names of the appropriate funnel entries, or all sites that get the
-article (see below for more details).
-
-=item D
-
-The value of the Distribution: header of the article, or C<?> if there is
-no such header in the article.
-
-=item G
-
-Where the article is stored.  If the newsgroup is crossposted, this is
-generally the first of the groups to which it was posted that this site
-receives; however, control messages are filed in control or control.*
-(which is the difference between this item and C<g>).
-
-=item H
-
-All of the headers, followed by a blank line.  The Xref header will
-already be present, and a Bytes header containing the article's size in
-bytes as in the C<b> item will be added to the headers.  If used, this
-should be the only item in the list.
-
-=item N
-
-The value of the Newsgroups: header.
-
-=item P
-
-The value of the Path: header.
-
-=item O
-
-Overview data for the article.
-
-=item R
-
-Information needed for replication (the Xref header without the site
-name).
-
-=back
-
-More than one letter can be given.  If multiple items are specified, they
-will be written in the order specified separated by spaces.  (C<H> should
-be the only item if given, but if it's not a newline will be sent before
-the beginning of the headers.)  The default is B<Wn>.
-
-The C<H> and C<O> items are intended for use by programs that create news
-overview databases or require similar information.  B<WnteO> is the flag
-to generate input needed by the overchan(8) program.
-
-The asterisk (C<*>) has special meaning.  Normally it expands to a
-space-separated list of all sites that received the current article.  If,
-however, this site is a target of a funnel feed (in other words, if it is
-named by other sites which have the B<Tm> flag), then the asterisk expands
-to the names of the funnel feeds that received the article.  Similarly, if
-the site is a program feed, an asterisk in the I<parameter> field will be
-expanded into the list of funnel feeds that received the article.  A
-program feed cannot get the site list unless it is the target of other
-B<Tm> feeds.
-
-=back
-
-=head1 FEED TYPES
-
-B<innd> provides four basic types of feeds:  log, file, program, and
-channel.  An exploder is a special type of channel.  In addition, several
-entries can feed into the same feed; these are funnel feeds, which refer
-to an entry that is one of the other types.  Funnel feeds are partially
-described above with the description of the B<W*> flag.  A funnel feed
-gets every article that would be sent to any of the feeds that funnel into
-it and normally include the B<W*> flag in their flags so that the program
-processing that feed knows which sites received which articles.  The most
-common funnel feed is innfeed(8).
-
-Note that the term "feed" is technically a misnomer, since the server
-doesn't transfer articles itself and only writes data to a file, program,
-or log telling another program to transfer the articles.
-
-The simplest feed is a log feed (B<Tl>).  Other than a mention in the news
-log file, I<pathlog>/news, no data is written out.  This is equivalent to
-a B<Tf> entry writing to F</dev/null>, except that no file is ever opened.
-Flushing a log feed does nothing.
-
-A file feed (B<Tf>) is the next simplest type of feed.  When the site
-should receive an article, the specified data is written out to the file
-named by the I<parameter> field.  If I<parameter> is not an absolute path,
-it is taken to be relative to I<pathoutgoing> in F<inn.conf>.  If
-I<parameter> is not given, it defaults to I<pathoutgoing>/I<sitename>.
-The file name should be unique (two file feeds should not ever point to
-the same file).
-
-File feeds are designed for use by external programs that periodically
-process the written data.  To cooperate with B<innd> properly, such
-external programs should first rename the batch file and then send a flush
-command for that site to B<innd> using ctlinnd(8).  B<innd> will then
-write out any buffered data, close the file, and reopen it (under the
-original name), and the program can process the data in the renamed file
-at its leisure.  File feeds are most frequently used in combination with
-nntpsend(8).
-
-A program feed (B<Tp>) spawns a given program for every article that the
-site receives.  The I<paramter> field must be the command line to execute,
-and should contain one instance of C<%s>, which will be replaced by the
-storage API token of the article (the actual article can be retrieved by
-the program using sm(8)).  The program will not receive anything on
-standard input (unlike earlier versions of INN, where the article is sent
-to the program on stdin), and standard output and error from the program
-will be set to the error log (I<pathlog>/errlog).  B<innd> will try to
-avoid spawning a shell if the command has no shell meta-characters; this
-feature can be defeated if necessary for some reason by appending a
-semi-colon to the end of the command.  The full path name of the program
-to be run must be specified unless the command will be run by the shell
-(and it is strongly recommended that the full path name always be
-specified regardless).
-
-If a program feed is the target of a funnel, and if B<W*> appears in the
-flags of the site, a single asterisk may be present in the I<parameter>
-and will be replaced by a space-separated list of names of the sites
-feeding into the funnel which received the relevant article.  If the site
-is not the target of a funnel, or if the B<W*> flag is not used, the
-asterisk has no special meaning.
-
-Flushing a program feed does nothing.
-
-For a channel (B<Tc>) or exploder (B<Tx>) feed, the I<parameter> field
-again names the process to start.  As with program feeds, the full path to
-the program must be specified.  However, rather than spawning the program
-for every article, it is spawned once and then whenever the site receives
-an article, the data specified by the site flags is written to the
-standard input of the spawned program.  Standard output and error are set
-as with program feeds.  If the process exits, it will be restarted
-automatically.  If the process cannot be started, the server will spool
-input to a file named I<pathoutgoing>/I<sitename> and will try to start
-the process again later.
-
-When a channel or exploder feed is flushed, the server closes its end of
-the pipe to the program's standard input.  Any pending data that has not
-been written will be spooled; see the description of the B<S> flag above.
-The server will then spawn a new instance of the program.  No signal is
-sent to the program; it is up to the program handling a channel or
-exploder feed to notice end of file on its standard input and exit
-appropriately.
-
-Exploders are a special type of channel feed.  In addition to the channel
-feed behavior described above, exploders can also be sent command lines.
-These lines start with an exclamation point and their interpretation is up
-to the exploder.  The following commands are generated automatically by
-the server:
-
-    !newgroup group
-    !rmgroup group
-    !flush
-    !flush site
-
-These commands are sent whenever the ctlinnd(8) command of the same name
-is received by the server.  In addition, the ctlinnd(8) C<send> command
-can be used to send an arbitrary command line to an exploder.  The primary
-exploder is buffchan(8).
-
-Finally, B<Tm> feeds are the input to a funnel.  The I<parameter> field of
-the site should name the site handling articles for all of the funnel
-inputs.
-
-=head1 EXAMPLES
-
-All of the following examples assume that INN was installed with a prefix
-of F</usr/local/news>; if you installed it somewhere else, modify the
-paths as appropriate.
-
-The syntax of the F<newsfeeds> file is so complex because you can specify
-a staggering variety of feeds.  INN is capable of interacting with a wide
-variety of programs that do various things with news articles.  Far and
-away the most common two entries in F<newsfeeds>, however, are file feeds
-for nntpsend(8) and funnel feeds for innfeed(8).
-
-The former look like this:
-
-    feed.example.com:*,!control,!control.*,!junk:Tf,Wnm:
-
-which generates a file named I<pathoutgoing>/feed.example.com containing
-one line per article consisting of the storage API token, a space, and the
-message ID.
-
-The latter look like this:
-
-    feed.example.com:*,!control,!control.*,!junk:Tm:innfeed!
-
-Very similar, except that this is the input to a funnel feed named
-C<innfeed!>.  One could also write this as:
-
-    example/feed.example.com:*,!control,!control.*,!junk:Ap,Tm:innfeed!
-
-(note the B<Ap> so that articles that contain just C<example> in the Path:
-header will still be sent), which is completely equivalent except that
-this will be logged in I<pathlog>/news as going to the site C<example>
-rather than C<feed.example.com>.
-
-The typical feed entry for innfeed(8) is a good example of a channel feed
-that's the target of various funnel feeds:
-
-    innfeed!:!*:Tc,Wnm*:/usr/local/news/bin/startinnfeed -y
-
-Note that the I<pattern> for this feed is just C<!*> so that it won't
-receive any articles directly.  The feed should only receive those
-articles that would go to one of the funnel feeds that are feeding into
-it.  innfeed(8) (spawned by B<startinnfeed>) will receive one line per
-article on its standard input containing the storage API token, the
-message ID, and a space-separated list of sites that should receive that
-article.
-
-Here's a more esoteric example of a channel feed:
-
-    watcher!:*:Tc,Wbnm\
-        :exec awk '$1 > 1000000 { print "BIG", $2, $3 }' > /dev/console
-
-This receives the byte size of each article along with the storage API
-token and message ID, and prints to the console a line for every article
-that's over a million bytes.  This is actually rather a strange way to
-write this since INN can do the size check itself; the following is
-equivalent:
-
-    watcher!:*:Tc,>1000000,Wbnm\
-        :exec awk '{ print "BIG", $2, $3}' > /dev/console
-
-Here's a cute, really simple news to mail gateway that also serves as an
-example of a fairly fancy program feed:
-
-    mailer!:!*:W*,Tp\
-        :sm %s | innmail -s "News article" *
-
-Remember that C<%s> is replaced by the storage API token, so this
-retrieves the article and pipes it into B<innmail> (which is safer than
-programs like Mail(1) because it doesn't parse the body for tilde
-commands) with a given subject line.  Note the use of C<*> in the command
-line and B<W*> in the flags; this entry is designed to be used as the
-target of funnel feeds such as:
-
-    peter@example.com:news.software.nntp:Tm:mailer!
-    sue@example.com:news.admin.misc:Tm:mailer!
-
-Suppose that the server receives an article crossposted between
-news.admin.misc and news.software.nntp.  The server will notice that the
-article should be sent to the site C<peter@example.com> and the site
-C<bob@example.com>, both of which funnel into C<mailer!>, so it will look
-at the C<mailer!> site and end up executing the command line:
-
-    sm @...@ | innmail -s "News article" peter@example.com sue@example.com
-
-which will mail the article to both Peter and Sue.
-
-Finally, another very useful example of a channel feed:  the standard
-entry for controlchan(8).
-
-    controlchan!\
-        :!*,control,control.*,!control.cancel/!collabra-internal\
-        :Tc,Wnsm:/usr/local/news/bin/controlchan
-
-This program only wants information about articles posted to a control
-newsgroup other than control.cancel, which due to the sorting of control
-messages described in innd(8) will send it all control messages except for
-cancel messages.  In this case, we also exclude any article with a
-distribution of C<collabra-internal>.  B<controlchan> gets the storage
-API token, the name of the sending site (for processing old-style ihave
-and sendme control messages, be sure to read about I<logipaddr> in
-controlchan(8)), and the message ID for each article.
-
-For many other examples, including examples of the special C<ME> site
-entry, see the example F<newsfeeds> file distributed with INN.  Also see the
-install documentation that comes with INN for information about setting up
-the standard newsfeeds entries used by most sites.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Reformatted
-and rewritten in POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: newsfeeds.pod 7741 2008-04-06 09:51:47Z iulius $
-
-=head1 SEE ALSO
-
-active(5), buffchan(8), controlchan(8), ctlinnd(8), inn.conf(5), innd(8),
-innfeed(8), innxmit(8), nntpsend(8), uwildmat(3).
-
-=cut
diff --git a/doc/pod/ninpaths.pod b/doc/pod/ninpaths.pod
deleted file mode 100644 (file)
index 98b1c51..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-=head1 NAME
-
-ninpaths - Report Usenet Path statistics (new inpaths)
-
-=head1 SYNOPSIS
-
-B<ninpaths> B<-p> B<-d> I<dumpfile>
-
-B<ninpaths> B<-r> I<site> B<-u> I<dumpfile> [B<-u> I<dumpfile> ...] B<-v>
-I<level>
-
-=head1 DESCRIPTION
-
-This is an efficient and space-saving inpaths reporting program.  It works
-as follows:  you feed it the Path lines via an INN channel feed or some
-other similar method, and from time to time the program writes all its
-internal counters accumulated so far to a dump file.  Another instance of
-the program picks up all the dump files, adds them up and formats them
-into the report.  The purpose of the final report is to summarize the
-frequency of occurrence of sites in the Path headers of articles.
-
-Some central sites accumulate the Path data from many news servers running
-this program or one like it, and then report statistics on the most
-frequently seen news servers in Usenet article Path lines.  The
-B<sendinpaths> shell script can be run once a month to mail the
-accumulated statistics to such a site and remove the old dump files.
-
-You can get a working setup by doing the following:
-
-=over 4
-
-=item 1.
-
-Create a directory at I<pathlog>/path (replacing I<pathlog> here and in
-all steps that follow with the full path to your INN log directory).
-
-=item 2.
-
-Set up a channel feed using an entry like:
-
-    inpaths!:*:Tc,WP:ninpaths -p -d <pathlog>/path/inpaths.%d
-
-if your version of INN supports WP (2.0 and later all do).  Replace
-<pathlog> with the full path to your INN log directory.
-
-=item 3.
-
-Enter into your news user crontab something like:
-
-    6 6 * * *   ctlinnd flush inpaths!
-
-(the actual time doesn't matter).  This will force B<ninpaths> to generate
-a dump file once a day.
-
-=item 4.
-
-Once per month, run the B<sendinpaths> script, which collects the dumps,
-makes a report, and then deletes the old dumps.  (You can generate a
-report without mailing it and without deleting it with C<sendinpaths -n>.)
-
-=back
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d> I<dumpfile>
-
-Save dumps in I<dumpfile>.  Any C<%d> in I<dumpfile> will be replaced with
-the current system time when the dump is made.  This option should be used
-with B<-p>.
-
-=item B<-p>
-
-Read Path lines from standard input.
-
-=item B<-r> I<site>
-
-Generate a report for I<site>.  Generally I<site> should be the value of
-I<pathhost> from F<inn.conf>.
-
-=item B<-u> I<dumpfile>
-
-Read data from I<dumpfile>.  This option can be repeated to read data from
-multiple dump files.
-
-=item B<-v> I<level>
-
-Set the verbosity level of the report.  Valid values for I<level> are 0,
-1, and 2, with 2 being the default.
-
-=back
-
-=head1 NOTES
-
-If your INN doesn't have the WP feed flag (1.5 does not, 1.6 does, 1.7 I
-don't know, 2.0 and later all do), use the following newsfeeds entry:
-
-   inpaths!:*:Tc,WH:ginpaths
-
-where B<ginpaths> is the following script:
-
-    #!/bin/sh
-    exec egrep '^Path: ' | ninpaths -p -d <pathlog>/path/inpaths.%d
-
-replacing <pathlog> as above.
-
-=head1 SEE ALSO
-
-newsfeeds(5), sendinpaths(8)
-
-This is a slightly modified version of Olaf Titz's original ninpaths
-program, which is posted to alt.sources and kept on his WWW archive under
-L<http://sites.inka.de/~bigred/sw/>.
-
-=head1 HISTORY
-
-B<ninpaths> was written by Olaf Titz <olaf@bigred.inka.de>.
-
-The idea and some implementation details for ninpaths come from the
-original inpaths program, but most of the code has been rewritten for
-clarity.  This program is in the public domain.
-
-=cut
diff --git a/doc/pod/nnrpd.pod b/doc/pod/nnrpd.pod
deleted file mode 100644 (file)
index 42080d4..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-=head1 NAME
-
-nnrpd - NNTP server for reader clients
-
-=head1 SYNOPSIS
-
-B<nnrpd> [B<-DfnoSt>] [B<-b> I<address>] [B<-c> I<configfile>]
-[B<-g> I<shadowgroup>>] [B<-i> I<initial>] [B<-I> I<instance>] [B<-p> I<port>]
-[B<-P> I<prefork>] [B<-r> I<reason>] [B<-s> I<padding>]
-
-=head1 DESCRIPTION
-
-B<nnrpd> is an NNTP server for newsreaders.  It accepts commands on its
-standard input and responds on its standard output.  It is normally
-invoked by innd(8) with those descriptors attached to a remote client
-connection.  B<nnrpd> also supports running as a standalone daemon.
-
-Unlike innd(8) B<nnrpd> supports all NNTP commands for user-oriented
-reading and posting.  B<nnrpd> uses the F<readers.conf> file to control
-who is authorized to access the Usenet database.
-
-On exit, B<nnrpd> will report usage statistics through syslog(3).
-
-B<nnrpd> only reads config files (both F<readers.conf> and F<inn.conf>)
-when it is spawned.  You can therefore never change the behavior of a
-client that's already connected.  If B<nnrpd> is run from B<innd> (the
-default) or from inetd(8), xinetd(8), or some equivalent, a new B<nnrpd>
-process is spawned for every connection and therefore any changes to
-configuration files will be immediately effective for all new
-connections.  If you are instead running B<nnrpd> with the B<-D> option,
-any configuration changes won't take effect until B<nnrpd> is restarted.
-
-The F<inn.conf> setting I<nnrpdflags> can be used to pass any of the
-options below to instances of B<nnrpd> that are spawned directly from
-B<innd>.  Many options only make sense when B<-D> is used, so these
-options should not be used with I<nnrpdflags>.  See also the discussion
-of I<nnrpdflags> in inn.conf(5).
-
-When I<nnrpdloadlimit> in F<inn.conf> is not 0, it will also reject
-connections if the load average is greater than that value (typically 16).
-B<nnrpd> can also prevent high-volume posters from abusing your
-resources. See the discussion of exponential backoff in inn.conf(5).
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-b> I<address>
-
-The B<-b> parameter instructs B<nnrpd> to bind to the specified IP
-address when started as a standalone daemon using the B<-D> flag. This
-has to be a valid IPv4 or IPv6 address belonging to an interface of
-the local host.  It can also be ::0 (although the default is 0.0.0.0
-if unspecified).
-
-=item B<-c> I<configfile>
-
-By default, B<nnrpd> reads the F<readers.conf> to determine how to
-authenticate connections.  The B<-c> flag specifies an alternate file
-for this purpose.  If the file name isn't fully qualified, it is taken
-to be relative to I<pathetc> in F<inn.conf> (this is useful to have
-several instances of B<nnrpd> running on different ports or IP
-addresses with different settings.)
-
-=item B<-D>
-
-If specified, this parameter causes B<nnrpd> to operate as a
-daemon. That is, it detaches itself and runs in the background,
-forking a process for every connection. By default B<nnrpd> listens on
-the NNTP port (119), so either innd(8) has to be started on another
-port or B<nnrpd> B<-p> parameter.  Note that with this parameter,
-B<nnrpd> continues running until killed.  This means that it reads
-F<inn.conf> once on startup and never again until restarted. B<nnrpd>
-should therefore be restarted if inn.conf is changed.
-
-When started in daemon mode, B<nnrpd> will write its PID into a file in
-the I<pathrun> directory.  The file will be named F<nnrpd-%d.pid>, where
-C<%d> is replaced with the port that B<nnrpd> is configured to listen on
-(119 unless the B<-p> option is given).
-
-=item B<-f>
-
-If specified, B<nnrpd> does not detach itself and runs in the
-foreground when started as a standalone daemon using the B<-D> flag.
-
-=item B<-g> I<shadowgroup>
-
-On systems that have a shadow password file, B<nnrpd> tries to add the
-group I<shadow> as a supplementary group if it is running in
-standalone mode. On many systems, members of that group have read
-permission for the shadow password file. The B<-g> parameter instructs
-B<nnrpd> to try to add the named group as a supplementary group on
-shadow systems instead of I<shadow>. This only works if
-C<HAVE_GETSPNAM> in F<include/config.h> is defined and B<nnrpd> is
-running in standalone mode since this call only works when B<nnrpd> is
-started as root.
-
-=item B<-i> I<initial>
-
-Specify an initial command to B<nnrpd>. When used, I<initial> is taken
-as if it were the first command received by B<nnrpd>.
-
-=item B<-I> I<instance>
-
-If specified I<instance> is used as an additional static portion
-within MessageIDs generated by B<nnrpd>; typically this option would
-be used where a cluster of machines exist with the same virtual
-hostname and must be disambiguated during posts.
-
-=item B<-n>
-
-The B<-n> flag turns off resolution of IP addresses to names.  If you
-only use IP-based restrictions in F<readers.conf> and can handle IP
-addresses in your logs, using this flag may result in some additional
-speed.
-
-=item B<-o>
-
-The B<-o> flag causes all articles to be spooled instead of sending
-them to innd(8). B<rnews> with the B<-U> flag should be invoked from
-cron on a regular basis to take care of these articles. This flag is
-useful if innd(8) in accepting articles and B<nnrpd> is started
-standalone or using inetd(8).
-
-=item B<-p> I<port>
-
-The B<-p> parameter instructs B<nnrpd> to listen on I<port> when
-started as a standalone daemon using the B<-D> flag.
-
-=item B<-P> I<prefork>
-
-The B<-P> parameter instructs B<nnrpd> to prefork I<prefork> children
-awaiting connections when started as a standalone daemon using the
-B<-D> flag.
-
-=item B<-r> I<reason>
-
-If the B<-r> flag is used, then B<nnrpd> will reject the incoming
-connection giving I<reason> as the text. This flag is used by innd(8)
-when it is paused or throttled.
-
-=item B<-s> I<padding>
-
-As each command is received, B<nnrpd> tries to change its C<argv>
-array so that ps(1) will print out the command being executed. To get
-a full display, the B<-s> flag may be used with a long string as its
-argument, which will be overwritten when the program changes its
-title.
-
-=item B<-S>
-
-If specified, B<nnrpd> will start a negotiation for SSL session as
-soon as connected. To use this flag, C<--with-openssl> must have been
-specified at C<configure> time.
-
-=item B<-t>
-
-If the B<-t> flag is used then all client commands and initial
-responses will be traced by reporting them in syslog. This flag is set
-by innd(8) under the control of the ctlinnd(8) C<trace> command, and
-is toggled upon receipt of a C<SIGHUP>; see signal(2).
-
-=back
-
-=head1 SSL SUPPORT
-
-If INN is built with C<--with-openssl>, B<nnrpd> will support news reading
-over TLS (also known as SSL).  For clients that use the STARTTLS command,
-no special configuration is needed beyond creating a TLS/SSL certificate
-for the server.  You should do this in exactly the same way that you would
-generate a certificate for a web server.
-
-If you're happy with a self-signed certificate (which will generate
-warnings with some news reader clients), you can create and install one in
-the default path by running C<make cert> after C<make install> when
-installing INN, or by running the following commands:
-
-    openssl req -new -x509 -nodes -out /usr/local/news/lib/cert.pem \
-        -days 366 -keyout /usr/local/news/lib/key.pem
-    chown news:news /usr/local/news/lib/cert.pem
-    chmod 640 /usr/local/news/lib/cert.pem
-    chown news:news /usr/local/news/lib/key.pem
-    chmod 600 /usr/local/news/lib/key.pem
-
-Replace the paths with something appropriate to your INN installation.
-This will create a self-signed certificate that will expire in a year.
-The B<openssl> program will ask you a variety of questions about your
-organization.  Enter the fully qualified domain name of the server as the
-name the certificate is for.
-
-Most news clients currently do not use the STARTTLS command, however, and
-instead expect to connect to a separate port (563) and start an SSL
-negotiation immediately.  B<innd> does not, however, know how to listen
-for connections to that port and then spawn B<nnrpd> the way that it does
-for regular reader connections.  You will therefore need to arrange for
-B<nnrpd> to listen on that port through some other means.  This can be
-done with the B<-D> flag (and C<-P 563>), but the easiest way is probably
-to add a line like:
-
-    nntps stream tcp nowait news /usr/lib/news/bin/nnrpd nnrpd -S
-
-to F</etc/inetd.conf> or the equivalent on your system and let B<inetd>
-run B<nnrpd>.  (Change the path to B<nnrpd> to match your installation if
-needed.)  You may need to replace C<nntps> with C<563> if C<nntps> isn't
-defined in F</etc/services> on your system.
-
-=head1 PROTOCOL DIFFERENCES
-
-B<nnrpd> implements the NNTP commands defined in RFC 977, with the
-following differences:
-
-=over 4
-
-=item 1.
-
-The C<slave> command is not implemented.  This command has never been
-fully defined.
-
-=item 2.
-
-The C<list> command may be followed by the optional word C<active.times>,
-C<distributions>, C<distrib.pats>, C<moderators>, C<newsgroups>,
-C<subscriptions>, or C<Ioverview.fmt> to get a list of when newsgroups
-where created, a list of valid distributions, a file specifying default
-distribution patterns, moderators list, a one-per-line description of the
-current set of newsgroups, a list of the automatic group subscriptions, or
-a listing of the F<overview.fmt> file.
-
-The command C<list active> is equivalent to the C<list> command. This
-is a common extension.
-
-=item 3.
-
-The C<xhdr>, C<authinfo user> and C<authinfo pass> commands are
-implemented.  These are based on the reference Unix implementation.  See
-RFC 2980.
-
-=item 4.
-
-A new command, C<xpat header range|MessageID pat [morepat...]>, is
-provided.  The first argument is the case-insensitive name of the header
-to be searched.  The second argument is either an article range or a
-single Message-ID, as specified in RFC 977.  The third argument is a
-C<uwildmat>(3)-style pattern; if there are additional arguments they are
-joined together separated by a single space to form the complete pattern.
-This command is similar to the C<xhdr> command.  It returns a C<221>
-response code, followed by the text response of all article numbers that
-match the pattern.
-
-=item 5.
-
-The C<listgroup group> command is provided.  This is a comment extension.
-It is equivalent to the C<group> command, except that the reply is a
-multi-line response containing the list of all article numbers in the
-group.
-
-=item 6.
-
-The C<xgtitle [group]> command is provided. This extension is used by
-ANU-News.  It returns a C<282> reply code, followed by a one-line
-description of all newsgroups thatmatch the pattern.  The default is the
-current group.
-
-=item 7.
-
-The C<xover [range]> command is provided. It returns a C<224> reply code,
-followed by the overview data for the specified range; the default is to
-return the data for the current article.
-
-=item 8.
-
-The C<xpath MessageID> command is provided; see innd(8).
-
-=item 9.
-
-The C<date> command is provided; this is based on the draft NNTP protocol
-revision (draft-ietf-nntpext-imp-04.txt).  It returns a one-line response
-code of C<111> followed by the GMT date and time on the server in the form
-C<YYYYMMDDhhmmss>.
-
-=back
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Overview
-support added by Rob Robertston <rob@violet.berkeley.edu> and Rich in
-January, 1993.  Exponential backoff (for posting) added by Dave Hayes in
-Febuary 1998.
-
-$Id: nnrpd.pod 7751 2008-04-06 14:35:40Z iulius $
-
-=head1 SEE ALSO
-
-ctlinnd(8), innd(8), inn.conf(5), signal(2), uwildmat(3).
diff --git a/doc/pod/ovdb.pod b/doc/pod/ovdb.pod
deleted file mode 100644 (file)
index 5f5b38b..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-=head1 NAME
-
-ovdb - Overview storage method for INN
-
-=head1 DESCRIPTION
-
-Ovdb is a storage method that uses the BerkeleyDB library to store
-overview data.  It requires version 2.6.x or later of the BerkeleyDB
-library, but has mostly been tested with version 3 and 4.
-
-Ovdb makes use of the full transaction/logging/locking functionality of
-the BerkeleyDB environment.  BerkeleyDB may be downloaded from
-L<http://www.sleepycat.com> and is needed to build the ovdb backend.
-
-=head1 UPGRADING
-
-This is version 2 of ovdb.  If you have a database created with a previous
-version of ovdb (such as the one shipped with INN 2.3.0) your database
-will need to be upgraded using ovdb_init(8).  See the man page
-ovdb_init(8) for upgrade instructions.
-
-=head1 INSTALLATION
-
-To build ovdb support into INN, specify the option C<--with-berkeleydb>
-when running the configure script.  By default, configure will search for
-a BerkeleyDB tree in several likely locations, and choose the highest
-version (based on the name of the directory, e.g., F<BerkeleyDB.3.0>) that
-it finds.  There will be a message in the configure output indicating the
-chosen pathname.
-
-You can override this pathname by adding a path to the option, e.g.,
-C<--with-berkeleydb=/usr/BerkeleyDB.3.1>.  This directory is expected to
-have subdirectories F<include> and F<lib>, containing F<db.h>, and the
-library itself, respectively.
-
-The ovdb database will take up more disk space for a given spool than the
-other overview methods.  Plan on needing at least 1.1 KB for every article
-in your spool (not counting crossposts).  So, if you have 5 million
-articles, you'll need at least 5.5 GB of disk space for ovdb.  With
-BerkeleyDB 2.x, the db files are 'grow only'; the library will not shrink
-them, even if data is removed.  So, reserving extra space above the
-estimate is a good idea.  Plus, you'll need additional space for
-transaction logs: at least 100 MB.  By default the transaction logs go in
-the same directory as the database.  To improve performance, they can be
-placed on a different disk -- see the DB_CONFIG section.
-
-=head1 CONFIGURATION
-
-To enable ovdb, set the I<ovmethod> parameter in F<inn.conf> to C<ovdb>.
-The ovdb database is stored in the directory specified by the
-I<pathoverview> paramter in F<inn.conf>.  This is the "DB_HOME" directory.
-To start out, this directory should be empty (other than an optional
-F<DB_CONFIG> file; see L<DB_CONFIG> for details) and B<innd> (or
-B<makehistory>) will create the files as necessary in that directory.
-Make sure the directory is owned by the news user.
-
-Other parameters for configuring ovdb are in the ovdb.conf(5)
-configuration file.  See also the sample F<ovdb.conf>.
-
-=over 4
-
-=item cachesize
-
-Size of the memory pool cache, in kilobytes.  The cache will have a
-backing store file in the DB directory which will be at least as big.  In
-general, the bigger the cache, the better.  Use C<ovdb_stat -m> to see
-cache hit percentages.  To make a change of this parameter take effect,
-shut down and restart INN (be sure to kill all of the nnrpds when shutting
-down).  Default is 8000, which is adequate for small to medium sized
-servers.  Large servers will probably need at least 20000.
-
-=item numdbfiles
-
-Overview data is split between this many files.  Currently, B<innd> will
-keep all of the files open, so don't set this too high or B<innd> may run
-out of file descriptors.  B<nnrpd> only opens one at a time, regardless.
-May be set to one, or just a few, but only do that if your OS supports
-large (>2G) files.  Changing this parameter has no effect on an
-already-established database.  Default is 32.
-
-=item txn_nosync
-
-If txn_nosync is set to false, BerkeleyDB flushes the log after every
-transaction.  This minimizes the number of transactions that may be lost
-in the event of a crash, but results in significantly degraded
-performance.  Default is true.
-
-=item useshm
-
-If useshm is set to true, BerkeleyDB will use shared memory instead of
-mmap for its environment regions (cache, lock, etc).  With some platforms,
-this may improve performance.  Default is false.  This parameter is
-ignored if you have BerkeleyDB 2.x
-
-=item shmkey
-
-Sets the shared memory key used by BerkeleyDB when 'useshm' is true.
-BerkeleyDB will create several (usually 5) shared memory segments, using
-sequentially numbered keys starting with 'shmkey'.  Choose a key that does
-not conflict with any existing shared memory segments on your system.
-Default is 6400.  This parameter is only used with BerkeleyDB 3.1 or
-newer.
-
-=item pagesize
-
-Sets the page size for the DB files (in bytes).  Must be a power of 2.
-Best choices are 4096 or 8192.  The default is 8192.  Changing this
-parameter has no effect on an already-established database.
-
-=item minkey
-
-Sets the minimum number of keys per page.  See the BerkeleyDB
-documentation for more info.  Default is based on page size:
-
-   default_minkey = MAX(2, pagesize / 2048 - 1)
-
-The lowest allowed minkey is 2.  Setting minkey higher than the default is
-not recommended, as it will cause the databases to have a lot of overflow
-pages.  Changing this parameter has no effect on an already-established
-database.
-
-=item maxlocks
-
-Sets the BerkeleyDB "lk_max" parameter, which is the maxmium number of
-locks that can exist in the database at the same time.  Default is 4000.
-
-=item nocompact
-
-The nocompact parameter affects expireover's behavior.  The expireover
-function in ovdb can do its job in one of two ways:  by simply deleting
-expired records from the database, or by re-writing the overview records
-into a different location leaving out the expired records.  The first
-method is faster, but it leaves 'holes' that result in space that can not
-immediately be reused.  The second method 'compacts' the records by
-rewriting them.
-
-If this parameter is set to 0, expireover will compact all newsgroups; if
-set to 1, expireover will not compact any newsgroups; and if set to a
-value greater than one, expireover will only compact groups that have less
-than that number of articles.
-
-Experience has shown that compacting has minimal effect (other than
-making expireover take longer) so the default is now 1.  This parameter
-will probably be removed in the future.
-
-=item readserver
-
-Normally, each nnrpd process directly accesses the BerkeleyDB environment.
-The process of attaching to the database (and detaching when finished) is
-fairly expensive, and can result in high loads in situations when there
-are lots of reader connections of relatively short duration.
-
-When the readserver parameter is "true", the nnrpds will access overview
-via a helper server (B<ovdb_server> -- which is started by B<ovdb_init>).
-This can also result in cleaner shutdowns for the database, improving
-stability and avoiding deadlocks and corrupted databases.  If you are
-experiencing any instability in ovdb, try setting this parameter to true.
-Default is false.
-
-=item numrsprocs
-
-This parameter is only used when I<readserver> is true.  It sets the
-number of ovdb_server processes.  As each ovdb_server can process only one
-transaction at a time, running more servers can improve reader response
-times.  Default is 5.
-
-=item maxrsconn
-
-This parameter is only used when I<readserver> is true.  It sets a maximum
-number of readers that a given ovdb_server process will serve at one time.
-This means the maximum number of readers for all of the ovdb_server
-processes is (numrsprocs * maxrsconn).  Default is 0, which means an
-umlimited number of connections is allowed.
-
-=back
-
-=head1 DB_CONFIG
-
-A file called F<DB_CONFIG> may be placed in the database directory to
-customize where the various database files and transaction logs are
-written.  By default, all of the files are written in the "DB_HOME"
-directory.  One way to improve performance is to put the transaction logs
-on a different disk.  To do this, put:
-
-    DB_LOG_DIR /path/to/logs
-
-in the F<DB_CONFIG> file.  If the pathname you give starts with a /, it is
-treated as an absolute path; otherwise, it is relative to the "DB_HOME"
-directory.  Make sure that any directories you specify exist and have
-proper ownership/mode before starting INN, because they won't be created
-automatically.  Also, don't change the DB_CONFIG file while anything that
-uses ovdb is running.
-
-Another thing that you can do with this file is to split the overview
-database across multiple disks.  In the F<DB_CONFIG> file, you can list
-directories that BerkeleyDB will search when it goes to open a database.
-
-For example, let's say that you have I<pathoverview> set to
-F</mnt/overview> and you have four additional file systems created on
-F</mnt/ov?>.  You would create a file "/mnt/overview/DB_CONFIG" containing
-the following lines:
-
-    set_data_dir /mnt/overview
-    set_data_dir /mnt/ov1
-    set_data_dir /mnt/ov2
-    set_data_dir /mnt/ov3
-    set_data_dir /mnt/ov4
-
-(For BerkeleyDB 2.x, replace C<set_data_dir> with C<DB_DATA_DIR>.)
-
-Distribute your ovNNNNN files into the four filesystems.  (say, 8 each).
-When called upon to open a database file, the db library will look for it
-in each of the specified directories (in order).  If said file is not
-found, one will be created in the first of those directories.
-
-Whenever you change DB_CONFIG or move database files around, make sure all
-news processes that use the database are shut down first (including
-nnrpds).
-
-The DB_CONFIG functionality is part of BerkeleyDB itself, rather than
-something provided by ovdb.  See the BerkeleyDB documentation for complete
-details for the version of BerkeleyDB that you're running.
-
-=head1 RUNNING
-
-When starting the news system, B<rc.news> will invoke B<ovdb_init>.
-B<ovdb_init> must be run before using the database.  It performs the
-following tasks:
-
-=over 4
-
-=item *
-
-Creates the database environment, if necessary.
-
-=item *
-
-If the database is idle, it performs a normal recovery.  The recovery will
-remove stale locks, recreate the memory pool cache, and repair any damage
-caused by a system crash or improper shutdown.
-
-=item *
-
-Starts the DB housekeeping processes (B<ovdb_monitor>) if they're not
-already running.
-
-=back
-
-And when stopping INN, B<rc.news> kills the ovdb_monitor processes after
-the other INN processes have been shut down.
-
-=head1 DIAGNOSTICS
-
-Problems relating to ovdb are logged to news.err with "OVDB" in the error
-message.
-
-INN programs that use overview will fail to start up if the ovdb_monitor
-processes aren't running.  Be sure to run B<ovdb_init> before running
-anything that accesses overview.
-
-Also, INN programs that use overview will fail to start up if the user
-running them is not the "news" user.
-
-If a program accessing the database crashes, or otherwise exits uncleanly,
-it might leave a stale lock in the database.  This lock could cause other
-processes to deadlock on that stale lock.  To fix this, shut down all news
-processes (using C<kill -9> if necessary) and then restart.  B<ovdb_init>
-should perform a recovery operation which will remove the locks and repair
-damage caused by killing the deadlocked processes.
-
-=head1 FILES
-
-=over 4
-
-=item inn.conf
-
-The I<ovmethod> and I<pathoverview> parameters are relevant to ovdb.
-
-=item ovdb.conf
-
-Optional configuration file for tuning.  See L<CONFIGURATION> above.
-
-=item I<pathoverview>
-
-Directory where the database goes.  BerkeleyDB calls it the 'DB_HOME'
-directory.
-
-=item I<pathoverview>/DB_CONFIG
-
-Optional file to configure the layout of the database files.
-
-=item I<pathrun>/ovdb.sem
-
-A file that gets locked by every process that is accessing the database.
-This is used by B<ovdb_init> to determine whether the database is active
-or quiescent.
-
-=item I<pathrun>/ovdb_monitor.pid
-
-Contains the process ID of B<ovdb_monitor>.
-
-=back
-
-=head1 TO DO
-
-Implement a way to limit how many databases can be open at once (to reduce
-file descriptor usage); maybe using something similar to the cache code in
-ov3.c
-
-=head1 HISTORY
-
-Written by Heath Kehoe <hakehoe@avalon.net> for InterNetNews
-
-=head1 SEE ALSO
-
-inn.conf(5), innd(8), nnrpd(8), ovdb_init(8), ovdb_monitor(8),
-ovdb_stat(8)
-
-BerkeleyDB documentation: in the F<docs> directory of the BerkeleyDB
-source distribution, or on the Sleepycat web page:
-L<http://www.sleepycat.com/>.
-
-=cut
diff --git a/doc/pod/ovdb_init.pod b/doc/pod/ovdb_init.pod
deleted file mode 100644 (file)
index d5c181f..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-=head1 NAME
-
-ovdb_init - Prepare ovdb database for use
-
-=head1 SYNOPSYS
-
-ovdb_init [C<-u>|C<-r>]
-
-=head1 DESCRIPTION
-
-This command must be run before any other process can access the
-overview database.  It performs the following steps:
-
-=over 4
-
-=item 1
-
-Creates the database environment, if necessary
-
-=item 2
-
-If the database is idle (and if the C<-u> option is not specified),
-it performs a normal recovery.  The recovery will remove stale locks,
-recreate the memory pool cache, and repair any damage caused by a system
-crash or improper shutdown.
-
-=item 3
-
-If the C<-u> option is specified, it performs any necessary upgrades
-to the database.  See the UPGRADING section below.
-
-=item 4
-
-Starts the DB housekeeping processes (ovdb_monitor) if they're not
-already running. (Unless the C<-r> option is specified).
-
-=item 5
-
-Starts the ovdb readserver (ovdb_server) processes if C<readserver>
-in F<ovdb.conf> is C<true>, and if they're not
-already running. (Unless the C<-r> option is specified).
-
-=back
-
-Returns exit status of 0 if all steps were completed successfully.
-In the event of an error, messages are written to syslog and/or stderr.
-
-If a recovery was attempted but it failed, the database may be
-damaged beyond repair, requiring a rebuild with makehistory(8).
-
-This command is normally invoked automatically by rc.news(8).
-
-It is OK to run this command multiple times.
-
-=head1 OPTIONS
-
-=over 4
-
-=item C<-r>
-
-Perform recovery only.  C<ovdb_monitor> is not started.
-
-=item C<-u>
-
-Perform any needed upgrades.  Recovery is not attempted.
-C<ovdb_monitor> is started if the upgrade succeeded.
-
-=back
-
-=head1 UPGRADING
-
-There are two situations in which the database will need to be
-upgraded:
-
-=over 4
-
-=item *
-
-You upgrade the BerkeleyDB library to a newer version, for example
-from 2.7.7 to 3.1.17.  In this case, the BerkeleyDB db->upgrade()
-method is used.
-
-=item *
-
-You upgrade ovdb to a newer major version; i.e., ovdb-1.0 to ovdb-2.0.
-
-=back
-
-In both of these cases, the database is upgraded in-place; and the
-upgrade can not be undone.  Do not interrupt the upgrade process once
-it has started, because there is a risk of irrepairable corruption.
-The upgrade may take several minutes to complete.
-If an upgrade does get interrupted, try running the upgrade again.
-
-Here's an example procedure to upgrade a database created with BerkeleyDB
-2.7.7 to use BerkeleyDB 3.1.17:
-
-=over 4
-
-=item 1
-
-Build and install the BerkeleyDB 3.1.17
-
-=item 2
-
-Run configure in the INN source tree and make sure it picks up the
-right BerkeleyDB directory (e.g., /usr/local/BerkeleyDB.3.1)
-
-=item 3
-
-Do a C<make>
-
-=item 4
-
-Shut down INN (e.g., with C<rc.news stop>).  Be sure to kill all nnrpds as
-well.
-
-=item 5
-
-Do a C<make update> to install the new binaries.
-
-=item 6
-
-Run C<ovdb_init -u> as the news user.
-
-=item 7
-
-Start INN with C<rc.news>
-
-=back
-
-It is OK to specify C<-u> even if no upgrades are needed.
-
-=head1 HISTORY
-
-Written by Heath Kehoe E<lt>hakehoe@avalon.netE<gt> for InterNetNews.
-
-=head1 SEE ALSO
-
-ovdb(5), makehistory(8)
-
-=cut
diff --git a/doc/pod/ovdb_monitor.pod b/doc/pod/ovdb_monitor.pod
deleted file mode 100644 (file)
index 14410d5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-=head1 NAME
-
-ovdb_monitor - Database maintenance
-
-=head1 SYNOPSYS
-
-Use C<ovdb_init> to start ovdb_monitor
-
-=head1 DESCRIPTION
-
-When started (by C<ovdb_init>), C<ovdb_monitor> forks three processes
-that perform routine database maintenance tasks.  These are:
-transaction checkpointing, deadlock detection, and transaction log
-removal.  The process ID of the parent is written to
-F<I<pathrun>/ovdb_monitor.pid>.  This PID is used by other INN
-commands to verify that ovdb_monitor is running.
-
-To shut down ovdb_monitor, send a TERM signal to the process ID
-in F<I<pathrun>/ovdb_monitor.pid> .  The parent process will shut
-down the three children and wait for their exit before exiting itself.
-
-=head1 HISTORY
-
-Written by Heath Kehoe E<lt>hakehoe@avalon.netE<gt> for InterNetNews.
-
-=head1 SEE ALSO
-
-ovdb(5), ovdb_init(8)
-
-=cut
diff --git a/doc/pod/ovdb_server.pod b/doc/pod/ovdb_server.pod
deleted file mode 100644 (file)
index f979cc4..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-=head1 NAME
-
-ovdb_server - overview 'helper' server
-
-=head1 SYNOPSYS
-
-Use C<ovdb_init> to start ovdb_server
-
-=head1 DESCRIPTION
-
-If the C<readserver> parameter in F<ovdb.conf> is true,
-C<ovdb_init> will start C<ovdb_server>.
-
-C<ovdb_server> opens the overview database, and accesses it
-on behalf of the nnrpd reader processes.
-
-To shut down ovdb_server, send a TERM signal to the process ID
-in F<I<pathrun>/ovdb_server.pid> .  The parent process will shut
-down its children and wait for their exit before exiting itself.
-
-=head1 HISTORY
-
-Written by Heath Kehoe E<lt>hakehoe@avalon.netE<gt> for InterNetNews.
-
-=head1 SEE ALSO
-
-ovdb(5), ovdb_init(8)
-
-=cut
diff --git a/doc/pod/ovdb_stat.pod b/doc/pod/ovdb_stat.pod
deleted file mode 100644 (file)
index fa1d673..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-=head1 NAME
-
-ovdb_stat - Display information from the ovdb database
-
-=head1 SYNOPSYS
-
-B<ovdb_stat> B<-Hgci> [B<-r> I<artnumrange>] newsgroup [newsgroup ...]
-
-B<ovdb_stat> B<-Hklmtv> [B<-d> I<database>]
-
-=head1 DESCRIPTION
-
-B<ovdb_stat> displays information from the ovdb database: BerkeleyDB
-statistics, newsgroup data, and overview records; and optionally
-outputs in HTML format.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-g>
-
-Newsgroup himark, lowmark, article count, and flag for the given newsgroups
-(as stored in the ovdb "groupinfo" database) are displayed.
-
-=item B<-c>
-
-Similar to B<-g>, except the himark, lowmark, and count are calculated
-by actually scanning the overview records and counting them.
-This can be a lengthy operation on groups with lots of articles.
-
-=item B<-i>
-
-Internal data regarding the given newsgroups are displayed.
-
-=item B<-r> I<artnumrange>
-
-Overview records are retrieved.  The I<artnumrange> parameter may be
-a single article number, or a range of articles in the format C<low-hi>.
-
-=item B<-H>
-
-Output is presented in HTML format.
-
-=item B<-k>
-
-Displays lock region statistics, as returned by the BerkeleyDB lock_stat()
-call.
-
-=item B<-l>
-
-Displays log region statistics, as returned by the BerkeleyDB log_stat()
-call.
-
-=item B<-m>
-
-Displays global memory pool statistics, as returned by the
-BerkeleyDB memp_stat() call.
-
-=item B<-M>
-
-Same as B<-m>, and also displays memory pool statistics for each
-database file.
-
-=item B<-t>
-
-Displays log region statistics, as returned by the BerkeleyDB txn_stat()
-call.
-
-=item B<-v>
-
-Displays ovdb version, and BerkeleyDB version.
-
-=item B<-d> I<database>
-
-Displays information about the given database, as returned by the
-BerkeleyDB db->stat() call.  This operation may take a long time
-on busy systems (several minutes or more).
-
-=back
-
-=head1 WARNINGS
-
-ovdb_stat may be safely killed with the INT, TERM, or HUP signals.
-It catches those signals and exits cleanly.
-Do not kill ovdb_stat with other signals, unless absolutely necessary,
-because it may leave stale locks in the DB environment.
-
-=head1 HISTORY
-
-Written by Heath Kehoe E<lt>hakehoe@avalon.netE<gt> for InterNetNews.
-
-=head1 SEE ALSO
-
-ovdb(5)
-
-=cut
diff --git a/doc/pod/passwd.nntp.pod b/doc/pod/passwd.nntp.pod
deleted file mode 100644 (file)
index d47bd3c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-=head1 NAME
-
-passwd.nntp - passwords for connecting to remote NNTP servers
-
-=head1 DESCRIPTION
-
-The file F<passwd.nntp> in I<pathetc> contains host / name / password
-triplets for use when authenticating client programs to NNTP servers.
-This file is normally interpreted by NNTPsendpassword() in libinn(3).
-Blank lines and lines beginning with a number sign (C<#>) are ignored.
-All other lines should consist of three or four fields separated by
-colons:
-
-    host:name:password
-    host:name:password:style
-
-The first field is the name of a host, and is matched in a
-case-insensitive manner.  (No detailed matching, such as comparing IP
-addresses, is done.)
-
-The second field is a user name, and the third is a password.  If either
-the username or password is empty, then that portion of the
-authentication will not occur.  (For example, when connecting to a
-remote INN for peering, only the password is needed.)
-
-The optional fourth field specifies the type of authentication to use.
-At present, the only recognized "authentication style" is C<authinfo>;
-this is also the default.  It means that NNTP "authinfo" commands are
-used to authenticate to the remote host.  (The C<authinfo> command is a
-common extension to RFC 977.)
-
-For example:
-
-    ##  UUNET needs a password, MIT doesn't.
-    mit.edu:bbn::authinfo
-    uunet.uu.net:bbn:yoyoma:authinfo
-
-This file should not be world-readable.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  This is
-revision $Revision: 5089 $, dated $Date: 2002-02-03 11:03:41 -0800 (Sun, 03 Feb 2002) $.
-
-$Id: passwd.nntp.pod 5089 2002-02-03 19:03:41Z vinocur $
-
-=head1 SEE ALSO
-
-inn.conf(5), innd(8), libinn(3).
-
-=cut
diff --git a/doc/pod/pullnews.pod b/doc/pod/pullnews.pod
deleted file mode 100644 (file)
index c2b55f0..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-=head1 NAME
-
-pullnews - Pull news from multiple news servers and feed it to another
-
-=head1 SYNOPSIS
-
-B<pullnews> [B<-hnqRx>] [B<-b> I<fraction>] [B<-c> I<config>] [B<-C> I<width>]
-[B<-d> I<level>] [B<-f> I<fraction>] [B<-F> I<fakehop>] [B<-g> I<groups>]
-[B<-G> I<newsgroups>] [B<-H> I<headers>] [B<-k> I<checkpt>] [B<-l> I<logfile>]
-[B<-m> I<header_pats>] [B<-M> I<num>] [B<-N> I<timeout>] [B<-p> I<port>]
-[B<-P> I<hop_limit>] [B<-Q> I<level>] [B<-r> I<file>] [B<-s> I<to-server>[:I<port>]]
-[B<-S> I<max-run>] [B<-t> I<retries>] [B<-T> I<connect-pause>] [B<-w> I<num>]
-[B<-z> I<article-pause>] [B<-Z> I<group-pause>] [I<from-server> ...]
-
-=head1 REQUIREMENTS
-
-The C<Net::NNTP> module must be installed.  This module is available as part
-of the libnet distribution and comes with recent versions of Perl.  For
-older versions of Perl, you can download it from L<http://www.cpan.org/>.
-
-=head1 DESCRIPTION
-
-B<pullnews> reads a config file in the running user's home directory
-(normally called F<~/.pullnews>) and connects to the upstream servers
-given there as a reader client.  By default, it connects to all servers
-listed in the configuration file, but you can limit B<pullnews> to
-specific servers by listing them on the command line:  a whitespace-separated
-list of server names can be specified, like I<from-server> for one of them.
-For each server it connects to, it pulls over articles and feeds them to the
-destination server via the IHAVE or POST commands.  This means that the system
-B<pullnews> is run on must have feeding access to the destination news server.
-
-B<pullnews> is designed for very small sites that do not want to bother
-setting up traditional peering and is not meant for handling large feeds.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-b> I<fraction>
-
-Backtrack on server numbering reset.  Specify the proportion (C<0.0> to C<1.0>)
-of a group's articles to pull when the server's article number is less than
-our high for that group.  When I<fraction> is C<1.0>, pull all the articles on
-a renumbered server.  The default is to do nothing.
-
-=item B<-c> I<config>
-
-Normally, the config file is stored in F<~/.pullnews> for the user running
-B<pullnews>.  If B<-c> is given, I<config> will be used as the config file
-instead.  This is useful if you're running B<pullnews> as a system user on
-an automated basis out of cron rather than as an individual user.
-
-See L<CONFIG FILE> below for the format of this file.
-
-=item B<-C> I<width>
-
-Use I<width> characters per line for the progress table.  The default value
-is C<50>.
-
-=item B<-d> I<level>
-
-Set the debugging level to the integer I<level>; more debugging output
-will be logged as this increases.  The default value is C<0>.
-
-=item B<-f> I<fraction>
-
-This changes the proportion of articles to get from each group to
-I<fraction> and should be in the range C<0.0> to C<1.0> (C<1.0> being
-the default).
-
-=item B<-F> I<fakehop>
-
-Prepend I<fakehop> as a host to the Path: header of articles fed.
-
-=item B<-g> I<groups>
-
-Specify a collection of groups to get.  I<groups> is a list of
-newsgroups separated by commas (only commas, no spaces).  Each group must
-be defined in the config file, and only the remote hosts that carry those
-groups will be contacted.  Note that this is a simple list of groups, not
-a wildmat expression, and wildcards are not supported.
-
-=item B<-G> I<newsgroups>
-
-Add the comma-separated list of groups I<newsgroups> to each server in the
-configuration file (see also B<-g> and B<-w>).
-
-=item B<-h>
-
-Print a usage message and exit.
-
-=item B<-H> I<headers>
-
-Remove these named headers (colon-separated list) from fed articles.
-
-=item B<-k> I<checkpt>
-
-Checkpoint (save) the config file every I<checkpt> articles
-(default is C<0>, that is to say at the end of the session).
-
-=item B<-l> I<logfile>
-
-Log progress/stats to I<logfile> (default is C<stdout>).
-
-=item B<-m> I<header_pats>
-
-Feed an article based on header matching.  The argument is a number of
-whitespace-separated tuples (each tuple being a colon-separated header and
-regular expression).  For instance:
-
-    Hdr1:regexp1 !Hdr2:regexp2
-
-specifies that the article will be passed only if the C<Hdr1:> header
-matches C<regexp1> and the C<Hdr2:> header does not match C<regexp2>.
-
-=item B<-M> I<num>
-
-Specify the maximum number of articles (per group) to process.
-The default is to process all new articles.  See also B<-f>.
-
-=item B<-n>
-
-Do nothing but read articles S<-- does> not feed articles downstream,
-writes no B<rnews> file, does not update the config file.
-
-=item B<-N> I<timeout>
-
-Specify the timeout length, as I<timeout> seconds,
-when establishing an NNTP connection.
-
-=item B<-p> I<port>
-
-Connect to the destination news server on a port other than the default of
-C<119>.  This option does not change the port used to connect to the source
-news servers.
-
-=item B<-P> I<hop_limit>
-
-Restrict feeding an article based on the number of hops it has already made.
-Count the hops in the Path: header (I<hop_count>), feeding the article only
-when I<hop_limit> is C<+num> and I<hop_count> is more than I<num>;
-or I<hop_limit> is C<-num> and I<hop_count> is less than I<num>.
-
-=item B<-q>
-
-Print out less status information while running.
-
-=item B<-Q> I<level>
-
-Set the quietness level (C<-Q 2> is equivalent to C<-q>).  The higher this
-value, the less gets logged.  The default is C<0>.
-
-=item B<-r> I<file>
-
-Rather than feeding the downloaded articles to a destination server, instead
-create a batch file that can later be fed to a server using B<rnews>.  See
-rnews(1) for more information about the batch file format.
-
-=item B<-R>
-
-Be a reader (use MODE READER and POST commands) to the downstream
-server.  The default is to use the IHAVE command.
-
-=item B<-s> I<to-server>[:I<port>]
-
-Normally, B<pullnews> will feed the articles it retrieves to the news
-server running on localhost.  To connect to a different host, specify a
-server with the B<-s> flag.  You can also specify the port with this same
-flag or use B<-p>.
-
-=item B<-S> I<max-run>
-
-Specify the maximum time I<max-run> in seconds for B<pullnews> to run.
-
-=item B<-t> I<retries>
-
-The maximum number (I<retries>) of attempts to connect to a server
-(see also B<-T>).  The default is C<0>.
-
-=item B<-T> I<connect-pause>
-
-Pause I<connect-pause> seconds between connection retries (see also B<-t>).
-The default is C<1>.
-
-=item B<-w> I<num>
-
-Set each group's high watermark (last received article number) to I<num>.
-If I<num> is negative, calculate S<I<Current>+I<num>> instead (i.e. get the last
-I<num> articles).  Therefore, a I<num> of C<0> will re-get all articles on the
-server; whereas a I<num> of C<-0> will get no old articles, setting the
-watermark to I<Current> (the most recent article on the server).
-
-=item B<-x>
-
-If the B<-x> flag is used, an Xref: header is added to any article
-that lacks one.  It can be useful for instance if articles are fed
-to a news server which has I<xrefslave> set in F<inn.conf>.
-
-=item B<-z> I<article-pause>
-
-Sleep I<article-pause> seconds between articles.  The default is C<0>.
-
-=item B<-Z> I<group-pause>
-
-Sleep I<group-pause> seconds between groups.  The default is C<0>.
-
-=back
-
-=head1 CONFIG FILE
-
-The config file for B<pullnews> is divided into blocks, one block for each
-remote server to connect to.  A block begins with the host line, which
-must have no leading whitespace and contains just the hostname of the
-remote server, optionally followed by authentication details (username
-and password for that server).
-
-Following the host line should be one or more newsgroup lines which start
-with whitespace followed by the name of a newsgroup to retrieve.  Only one
-newsgroup should be listed on each line.
-
-B<pullnews> will update the config file to include the time the group was
-last checked and the highest numbered article successfully retrieved and
-transferred to the destination server.  It uses this data to avoid doing
-duplicate work the next time it runs.
-
-The full syntax is:
-
-    <host> [<username> <password>]
-            <group> [<time> <high>]
-            <group> [<time> <high>]
-
-where the <host> line must not have leading whitespace and the <group>
-lines must.
-
-A typical configuration file would be:
-
-    # Format group date high
-    data.pa.vix.com
-            rec.bicycles.racing 908086612 783
-            rec.humor.funny 908086613 18
-            comp.programming.threads
-    nnrp.vix.com pull sekret
-            comp.std.lisp
-
-Note that an earlier run of B<pullnews> has filled in details about the
-last article downloads from the two rec.* groups.  The two comp.* groups
-were just added by the user and have not yet been checked.
-
-The nnrp.vix.com server requires authentication, and B<pullnews> will use
-the username C<pull> and the password C<sekret>.
-
-=head1 FILES
-
-=over 4
-
-=item I<pathbin>/pullnews
-
-The Perl script itself used to pull news from upstream servers and feed
-it to another news server.
-
-=item I<$HOME>/.pullnews
-
-The default config file.  It is in the running user's home directory
-(normally called F<~/.pullnews>).
-
-=back
-
-=head1 HISTORY
-
-B<pullnews> was written by James Brister for INN.  The documentation was
-rewritten in POD by Russ Allbery <rra@stanford.edu>.
-
-Geraint A. Edwards greatly improved B<pullnews>, adding no more than S<16 new>
-recognized flags, fixing some bugs and integrating the B<backupfeed>
-contrib script by Kai Henningsen, adding again S<6 other> flags.
-
-$Id: pullnews.pod 7853 2008-05-27 19:07:45Z iulius $
-
-=head1 SEE ALSO
-
-incoming.conf(5), rnews(1).
-
-=cut
diff --git a/doc/pod/qio.pod b/doc/pod/qio.pod
deleted file mode 100644 (file)
index 4f46b94..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-=head1 NAME
-
-qio - Quick I/O routines for reading files
-
-=head1 SYNOPSIS
-
-B<#include E<lt>inn/qio.hE<gt>>
-
-B<QIOSTATE *QIOopen(const char *>I<name>B<);>
-
-B<QIOSTATE *QIOfdopen(int> I<fd>B<);>
-
-B<void QIOclose(QIOSTATE *>I<qp>B<);>
-
-B<char *QIOread(QIOSTATE *>I<qp>B<);>
-
-B<int QIOfileno(QIOSTATE *>I<qp>B<);>
-
-B<size_t QIOlength(QIOSTATE *>I<qp>B<);>
-
-B<int QIOrewind(QIOSTATE *>I<qp>B<);>
-
-B<off_t QIOtell(QIOSTATE *>I<qp>B<);>
-
-B<bool QIOerror(QIOSTATE *>I<qp>B<);>
-
-B<bool QIOtoolong(QIOSTATE *>I<qp>B<);>
-
-=head1 DESCRIPTION
-
-The routines described in this manual page are part of libinn(3).  They
-are used to provide quick read access to files; the QIO routines use
-buffering adapted to the block size of the device, similar to stdio, but
-with a more convenient syntax for reading newline-terminated lines.  QIO
-is short for "Quick I/O" (a bit of a misnomer, as QIO provides read-only
-access to files only).
-
-The QIOSTATE structure returned by B<QIOopen> and B<QIOfdopen> is the
-analog to stdio's FILE structure and should be treated as a black box by
-all users of these routines.  Only the above API should be used.
-
-B<QIOopen> opens the given file for reading.  For regular files, if your
-system provides that information and the size is reasonable, QIO will use
-the block size of the underlying file system as its buffer size;
-otherwise, it will default to a buffer of 8 KB.  Returns a pointer to use
-for subsequent calls, or NULL on error.  B<QIOfdopen> performs the same
-operation except on an already-open file descriptor (I<fd> must designate
-a file open for reading).
-
-B<QIOclose> closes the open file and releases any resources used by the
-QIOSTATE structure.  The QIOSTATE pointer should not be used again after
-it has been passed to this function.
-
-B<QIOread> reads the next newline-terminated line in the file and returns
-a pointer to it, with the trailing newline replaced by nul.  The returned
-pointer is a pointer into a buffer in the QIOSTATE object and therefore
-will remain valid until B<QIOclose> is called on that object.  If EOF is
-reached, an error occurs, or if the line is longer than the buffer size,
-NULL is returned instead.  To distinguish between the error cases, use
-B<QIOerror> and B<QIOtoolong>.
-
-B<QIOfileno> returns the descriptor of the open file.
-
-B<QIOlength> returns the length in bytes of the last line returned by
-B<QIOread>.  Its return value is only defined after a successful call to
-B<QIOread>.
-
-B<QIOrewind> sets the read pointer back to the beginning of the file and
-reads the first block of the file in anticipation of future reads.  It
-returns 0 if successful and -1 on error.
-
-B<QIOtell> returns the current value of the read pointer (the lseek(2)
-offset at which the next line will start).
-
-B<QIOerror> returns true if there was an error in the last call to
-B<QIOread>, false otherwise.  B<QIOtoolong> returns true if there was an
-error and the error was that the line was too long.  If B<QIOread> returns
-NULL, these functions should be called to determine what happened.  If
-B<QIOread> returned NULL and B<QIOerror> is false, EOF was reached.  Note
-that if B<QIOtoolong> returns true, the next call to B<QIOread> will try
-to read the remainder of the line and will likely return a partial line;
-users of this library should in general treat long lines as fatal errors.
-
-=head1 EXAMPLES
-
-This block of code opens F</etc/motd> and reads it a line at a time,
-printing out each line preceeded by its offset in the file.
-
-    QIOSTATE *qp;
-    off_t offset;
-    char *p;
-
-    qp = QIOopen("/etc/motd");
-    if (qp == NULL) {
-        perror("Open error");
-        exit(1);
-    }
-    for (p = QIOread(qp); p != NULL; p = QIOread(qp))
-        printf("%ld: %s\n", (unsigned long) QIOtell(qp), p);
-    if (QIOerror(qp)) {
-        perror("Read error");
-        exit(1);
-    }
-    QIOclose(qp);
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Updated by
-Russ Allbery <rra@stanford.edu>.
-
-$Id: qio.pod 5909 2002-12-03 05:17:18Z vinocur $
diff --git a/doc/pod/radius.conf.pod b/doc/pod/radius.conf.pod
deleted file mode 100644 (file)
index 83dee3e..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-=head1 NAME
-
-radius.conf - Configuration for nnrpd RADIUS authenticator
-
-=head1 DESCRIPTION
-
-This describes the format and attributes of the configuration file for the
-nnrpd RADIUS authenticator.  See radius(1) for more information about the
-authenticator program.  The default location for this file is
-F<radius.conf> in I<pathetc>.
-
-Blank lines and lines beginning with C<#> are ignored, as is anything
-after a C<#> on a line.  All other lines should begin with a parameter
-name followed by a colon and the value of that key, except that each
-section of configuration for a particular server should be enclosed in:
-
-    server <name> {
-        # parameters...
-    }
-
-where <name> is just some convenient label for that server.
-
-The available parameters are:
-
-=over 4
-
-=item I<radhost>
-
-The hostname of the RADIUS server to use for authentication.  This
-parameter must be set.
-
-=item I<radport>
-
-The port to query on the RADIUS server.  Defaults to 1645 if not set.
-
-=item I<lochost>
-
-The hostname or IP address making the request.  The RADIUS server expects
-an IP address; a hostname will be translated into an IP address with
-gethostbyname().  If not given, this information isn't included in the
-request (not all RADIUS setups require this information).
-
-=item I<locport>
-
-The port the client being authenticated is connecting to.  If not given,
-defaults to 119.  This doesn't need to be set unless readers are
-connecting to a non-standard port.
-
-=item I<secret>
-
-The shared secret with the RADIUS server.  If your secret includes spaces,
-tabs, or C<#>, be sure to include it in double quotes.  This parameter
-must be set.
-
-=item I<prefix>
-
-Prepend the value of this parameter to all usernames before passing them
-to the RADIUS server.  Can be used to prepend something like C<news-> to
-all usernames in order to put news users into a different namespace from
-other accounts served by the same server.  If not set, nothing is
-prepended.
-
-=item I<suffix>
-
-Append the value of this parameter to all usernames before passing them to
-the RADIUS server.  This is often something like C<@example.com>,
-depending on how your RADIUS server is set up.  If not set, nothing is
-appended.
-
-=item I<ignore-source>
-
-Can be set to C<true> or C<false>.  If set to false, the RADIUS
-authenticator will check to ensure that the response it receives is from
-the same IP address as it sent the request to (for some added security).
-If set to true, it will skip this verification check (if your RADIUS
-server has multiple IP addresses or if other odd things are going on, it
-may be perfectly normal for the response to come from a different IP
-address).
-
-=back
-
-=head1 EXAMPLE
-
-Here is a configuration for a news server named news.example.com,
-authenticating users against radius.example.com and appending
-C<@example.com> to all client-supplied usernames before passing them to
-the RADIUS server:
-
-    server example {
-        radhost: radius.example.com
-        lochost: news.example.com
-        secret: IamARADIUSsecRET
-        suffix: @example.com
-    }
-
-The shared secret with the RADIUS server is C<IamARADIUSsecRET>.
-
-=head1 HISTORY
-
-This documentation was written by Russ Allbery <rra@stanford.edu> based on
-the comments in the sample radius.conf file by Yury B. Razbegin.
-
-$Id: radius.conf.pod 6736 2004-05-16 23:06:08Z rra $
-
-=head1 SEE ALSO
-
-radius(1)
-
-=cut
diff --git a/doc/pod/radius.pod b/doc/pod/radius.pod
deleted file mode 100644 (file)
index 5cf4ec4..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-=head1 NAME
-
-radius - nnrpd RADIUS password authenticator
-
-=head1 SYNOPSIS
-
-B<radius> [B<-h>] [B<-f> I<config>]
-
-=head1 DESCRIPTION
-
-B<radius> is an nnrpd authenticator, accepting a username and password
-from nnrpd (given to nnrpd by a reader connection) and attempting to
-authenticate that username and password against a RADIUS server.  See
-readers.conf(5) for more information on how to configure an nnrpd
-authenticator.  It is useful for a site that already does user
-authentication via RADIUS and wants to authenticate news reading
-connections as well.
-
-By default, B<radius> reads I<pathetc>/radius.conf for configuration
-information, but a different configuration file can be specified with
-B<-f>.  See radius.conf(5) for a description of the configuration file.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-f> I<config>
-
-Read I<config> instead of I<pathetc>/radius.conf for configuration
-information.
-
-=item B<-h>
-
-Print out a usage message and exit.
-
-=back
-
-=head1 EXAMPLE
-
-The following readers.conf(5) fragment tells nnrpd to authenticate all
-connections using this authenticator:
-
-    auth radius {
-        auth: radius
-        default: <FAIL>
-        default-domain: example.com
-    }
-
-C<@example.com> will be appended to the user-supplied identity, and if
-RADIUS authentication failes, the user will be assigned an identity of
-C<E<lt>FAILE<gt>@example.com>.
-
-=head1 BUGS
-
-It has been reported that this authenticator doesn't work with Ascend
-RADIUS servers, but does work with Cistron RADIUS servers.  It's also
-believed to work with Livingston's RADIUS server.  Contributions to make
-it work better with different types of RADIUS servers would be gratefully
-accepted.
-
-This code has not been audited against the RADIUS protocol and may not
-implement it correctly.
-
-=head1 HISTORY
-
-The RADIUS authenticator was originally written by Aidan Cully.  This
-documentation was written by Russ Allbery <rra@stanford.edu>.
-
-$Id: radius.pod 5894 2002-12-01 19:44:18Z rra $
-
-=head1 SEE ALSO
-
-nnrpd(8), radius.conf(5), readers.conf(5)
-
-RFC 2865, Remote Authentication Dial In User Service.
-
-=cut
diff --git a/doc/pod/rc.news.pod b/doc/pod/rc.news.pod
deleted file mode 100644 (file)
index bcc076e..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-=head1 NAME
-
-rc.news - Start or stop INN daemons
-
-=head1 SYNOPSIS
-
-B<rc.news> [start | stop]
-
-=head1 DESCRIPTION
-
-B<rc.news> can be used to start or stop B<innd> and supporting programs.
-It checks to make sure INN is not already running, handles cases of
-unclean shutdown, finishes up tasks which might have been interrupted by
-the preceeding shutdown, emails certain boot-time warnings to
-I<newsmaster> (as set in F<inn.conf>), and is generally safer and easier
-than starting and stopping everything directly.  It needs to be run as the
-news user so that files in I<pathrun> are created with the right ownership
-(though this is less important for C<rc.news stop>), and therefore
-requires that F<inndstart> be setuid root, see inndstart(8) for
-discussion.
-
-Programs run and stopped by this script include:
-
-=over 4
-
-=item *
-
-Always:  B<inndstart> is run, and B<innd> is stopped.
-
-=item *
-
-If I<doinnwatch> is true in F<inn.conf>:  B<innwatch> is started and
-stopped.
-
-=item *
-
-If I<docnfsstat> is true in F<inn.conf>:  B<ovdb_init> is run;
-B<ovdb_server> and B<ovdb_monitor> are stopped.
-
-=item *
-
-If F<rc.news.local> exists in I<pathbin>:  B<rc.news.local> is run with
-argument C<start> or C<stop> (to perform site-specific startup or shutdown
-tasks).
-
-=back
-
-=head1 OPTIONS
-
-=over 4
-
-=item C<start>
-
-If the first argument is C<start>, or no first argument is given,
-B<rc.news> initiates INN startup.
-
-=item C<stop>
-
-If the first argument is C<stop>, B<rc.news> initiates INN shutdown.  It
-is recommended to throttle the server first as described in ctlinnd(8).
-
-=back
-
-=head1 EXAMPLES
-
-To start INN and leave certain error messages going to the terminal:
-
-       su - news -c ~news/bin/rc.news
-
-To run INN at startup time from appropriate system boot scripts:
-
-       su - news -c ~news/bin/rc.news >/dev/console
-  
-To stop INN (throttling first):
-
-       ~news/bin/ctlinnd throttle reason
-       su - news -c '~news/bin/rc.news stop'
-
-=head1 BUGS
-
-Running C<rc.news start> as root is never the right thing to do, so we
-should at minimum check for this and error, or perhaps change effective
-user ID.
-
-=head1 HISTORY
-
-// FIXME:  any attribution for rc.news itself?
-
-This manual page written by Jeffrey M. Vinocur <jeff@litech.org> for
-InterNetNews.
-
-$Id: rc.news.pod 5908 2002-12-03 04:41:36Z vinocur $
-
-=head1 SEE ALSO
-
-ctlinnd(8),
-cnfsstat(8),
-inn.conf(5),
-inndstart(8),
-innwatch(8),
-ovdb(5).
-
-=cut
-
diff --git a/doc/pod/readers.conf.pod b/doc/pod/readers.conf.pod
deleted file mode 100644 (file)
index 5427e5f..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-=head1 NAME
-
-readers.conf - Access control and configuration for nnrpd
-
-=head1 DESCRIPTION
-
-F<readers.conf> in I<pathetc> specifies access control for nnrpd(8).  It
-controls who is allowed to connect as a news reader and what they're
-allowed to do after they connect.  nnrpd reads this file when it starts
-up.  This generally means that any changes take effect immediately on all
-subsequent connections, but B<nnrpd> may have to be restarted if you use
-the B<-D> option.  (The location I<pathetc>/readers.conf is only the
-default; the same format applies to any file specified with C<nnrpd -c>.)
-
-There are two types of entries in F<readers.conf>:  parameter/value pairs
-and configuration groups.  Blank lines and anything after a number sign
-(C<#>) are ignored, unless the character C<#> is escaped with C<\>.  The
-maximum number of characters on each line is 8,191.
-
-Parameter/value pairs consist of a keyword immediately followed by a
-colon, at least one whitespace character, and a value.  The case of the
-parameter is significant (parameter should generally be in all lowercase),
-and a parameter may contain any characters except colon, C<#>, and
-whitespace.  An example:
-
-    hosts: *.example.com
-
-Values that contain whitespace should be quoted with double quotes, as in:
-
-    hosts: "*.example.com, *.example.net"
-
-If the parameter does not contain whitespace, such as:
-
-    hosts: *.example.com,*.example.net
-
-it's not necessary to quote it, although you may wish to anyway for
-clarity.
-
-There is no way to continue a line on the next line, and therefore no way
-to have a single parameter with a value longer than about 8,180
-characters.
-
-Many parameters take a boolean value.  For all such parameters, the value
-may be specified as C<true>, C<yes>, or C<on> to turn it on and may be any
-of C<false>, C<no>, or C<off> to turn it off.  The case of these values is
-not significant.
-
-There are two basic types of configuration groups, auth and access.  The
-auth group provides mechanisms to establish the identity of the user, who
-they are.  The access group determines, given the user's identity, what
-that user is permitted to do.  Writing a F<readers.conf> file for your
-setup is a two-step process: first assigning an identity to each incoming
-connection using auth groups, and then giving each identity appropriate
-privileges with access group.  We recommend I<not> intermingling auth
-groups and access groups in the config file; it is often more sensible (in
-the absence of the I<key> parameter) to put all of the auth groups first,
-and all of the access groups below.
-
-A user identity, as established by an auth group, looks like an e-mail
-address; in other words, it's in the form "<username>@<domain>" (or
-sometimes just "<username>" if no domain is specified.
-
-If I<nnrpdauthsender> is set in F<inn.conf>, the user identity is also put
-into the Sender: header of posts made by that user.  See the documentation
-of that option in inn.conf(5) for more details.
-
-An auth group definition looks like:
-
-    auth <name> {
-        hosts: <host-wildmat>
-        auth: <auth-program>
-        res: <res-program>
-        default: <defuser>
-        default-domain: <defdomain>
-        # ...possibly other settings
-    }
-
-The <name> is used as a label for the group and is only for documentation
-purposes.  (If your syslog configuration records the C<news.debug>
-facility, the <name> will appear in the debugging output of nnrpd.
-Examining that output can be very helpful in understanding why your
-configuration doesn't do what you expect it to.)
-
-A given auth group applies only to hosts whose name or IP address matches
-the wildmat expression given with the hosts: parameter (comma-separated
-wildmat expressions allowed, but C<@> is not supported).  Rather than
-wildmat expressions, you may also use CIDR notation to match any IP
-address in a netblock; for example, "10.10.10.0/24" will match any IP
-address between 10.10.10.0 and 10.10.10.255 inclusive.
-
-If compiled against the SSL libraries, an auth group with the require_ssl:
-parameter set to true only applies if the incoming connection is using
-SSL.
-
-For any connection from a host that matches that wildmat expression or
-netblock, each <res-program> (multiple res: lines may be present in a
-block; they are run in sequence until one succeeds), if any, is run to
-determine the identity of the user just from the connection information.
-If all the resolvers fail, or if the res: parameter isn't present, the
-user is assigned an identity of "<defuser>@<defdomain>"; in other words,
-the values of the default: and default-domain: parameters are used.  If
-<res-program> only returns a username, <defdomain> is used as the
-domain.
-
-If the user later authenticates via the AUTHINFO USER/PASS commands, the
-provided username and password are passed to each <auth-program> (multiple
-auth, perl_auth, or python_auth lines may be present in a block; they are
-run in sequence until one succeeds), if any.  If one succeeds and returns
-a different identity than the one assigned at the time of the connection,
-it is matched against the available access groups again and the actions
-the user is authorized to do may change.  The most common <auth-program>
-to use is B<ckpasswd>, which supports several ways of checking passwords
-including using PAM.  See the ckpasswd(8) man page for more details.
-
-When matching auth groups, the last auth group in the file that matches a
-given connection and username/password combination is used.
-
-An access group definition usually looks like:
-
-    access <name> {
-        users: <identity-wildmat>
-        newsgroups: <group-wildmat>
-        # ...possibly other settings
-    }
-
-Again, <name> is just for documentation purposes.  This says that all
-users whose identity matches <identity-wildmat> can read and post to all
-newsgroups matching <group-wildmat> (as before, comma-separated wildmat
-expressions are allowed, but C<@> is not supported).  Alternately, you can
-use the form:
-
-    access <name> {
-        users: <identity-wildmat>
-        read: <read-wildmat>
-        post: <post-wildmat>
-    }
-
-and matching users will be able to read any group that matches
-<read-wildmat> and post to any group that matches <post-wildmat>.  You can
-also set several other things in the access group as well as override
-various inn.conf(5) parameters for just a particular group of users.
-
-Just like with auth groups, when matching access groups the last matching
-one in the file is used to determine the user's permissions.  There is
-an exception to this rule: if the auth group which matched the client
-contains a perl_access: or python_access: parameter, then the script
-given as argument is used to dynamically generate an access group.
-This new access group is then used to determine the access rights of
-the client; the access groups in the file are ignored.
-
-There is one additional special case to be aware of.  When forming
-particularly complex authentication and authorization rules, it is
-sometimes useful for the identities provided by a given auth group to only
-apply to particular access groups; in other words, rather than checking
-the identity against the users: parameter of every access group, it's
-checked against the users: parameter of only some specific access groups.
-This is done with the key: parameter.  For example:
-
-    auth example {
-        key: special
-        hosts: *.example.com
-        default: <SPECIAL>
-    }
-
-    access example {
-        key: special
-        users: <SPECIAL>
-        newsgroups: *
-    }
-
-In this case, the two key: parameters bind this auth group with this
-access group.  For any incoming connection matching "*.example.com"
-(assuming there isn't any later auth group that also matches such hosts),
-no access group that doesn't have "key: special" will even be considered.
-Similarly, the above access group will only be checked if the user was
-authenticated with an auth group containing "key: special".  This
-mechanism normally isn't useful; there is almost always a better way to
-achieve the same result.
-
-Also note in the example that there's no default-domain: parameter, which
-means that no domain is appended to the default username and the identity
-for such connections is just "<SPECIAL>".  Note that some additional
-add-ons to INN may prefer that authenticated identities always return a
-full e-mail address (including a domain), so you may want to set up your
-system that way.
-
-Below is the full list of allowable parameters for auth groups and access
-groups, and after that are some examples that may make this somewhat
-clearer.
-
-=head1 AUTH GROUP PARAMETERS
-
-An access group without at least one of the res:, auth:, perl_auth:,
-python_auth:, or default: parameters makes no sense (and in practice will
-just be ignored).
-
-=over 4
-
-=item B<hosts:>
-
-A comma-separated list of remote hosts, wildmat patterns matching either
-hostnames or IP addresses, or IP netblocks specified in CIDR notation.  If
-a user connects from a host that doesn't match this parameter, this auth
-group will not match the connection and is ignored.
-
-Note that if you have a large number of patterns that can't be merged into
-broader patterns (such as a large number of individual systems scattered
-around the net that should have access), the hosts: parameter may exceed
-the maximum line length of 8,192 characters.  In that case, you'll need to
-break that auth group into multiple auth groups, each with a portion of
-the hosts listed in its hosts: parameter, and each assigning the same user
-identity.
-
-All hosts match if this parameter is not given.
-
-=item B<localaddress:>
-
-A comma-separated list of local host or address patterns with the same
-syntax as the same as with the hosts: parameter.  If this parameter is
-specified, its auth group will only match connections made to a matching
-local interface.  (Obviously, this is only useful for servers with
-multiple interfaces.)
-
-All local addresses match if this parameter is not given.
-
-=item B<res:>
-
-A simple command line for a user resolver (shell metacharacters are not
-supported).  If a full path is not given, the program executed must be in
-the I<pathbin>/auth/resolv directory.  A resolver is an authentication
-program which attempts to figure out the identity of the connecting user
-using nothing but the connection information (in other words, the user
-has not provided a username and password).  An examples of a resolver
-would be a program that assigns an identity from an ident callback or
-from the user's hostname.
-
-One auth group can have multiple res: parameters, and they will be tried
-in the order they're listed.  The results of the first successful one
-will be used.
-
-=item B<auth:>
-
-A simple command line for a user authenticator (shell metacharacters are
-not supported).  If a full path is not given, the program executed must be
-located in the I<pathbin>/auth/passwd directory.  An authenticator is a
-program used to handle a user-supplied username and password, via a
-mechanism such as AUTHINFO USER/PASS.  Like with res:, one auth group can
-have multiple auth: parameters; they will be tried in order and the
-results of the first successful one will be used.  See also perl_auth:
-below.
-
-The most common authenticator to use is ckpasswd(8); see its man page for
-more information.
-
-=item B<perl_auth:>
-
-A path to a perl script for authentication.  The perl_auth: parameter
-works exactly like auth:, except that it calls the named script using
-the perl hook rather then an external program.  Multiple/mixed use of
-the auth, perl_auth, and python_auth parameters is permitted within any
-auth group; each line is tried in the order it appears.  perl_auth:
-has more power than auth: in that it provides the authentication
-program with additional information about the client and the ability
-to return an error string and a username.  This parameter is only
-valid if INN is compiled with Perl support (B<--with-perl> passed to
-configure).  More information may be found in F<doc/hook-perl>.
-
-=item B<python_auth:>
-
-A Python script for authentication.  The I<python_auth> parameter works
-exactly like I<auth>, except that it calls the named script (without its
-C<.py> extension) using the Python hook rather then an external program.
-Multiple/mixed use of the I<auth>, I<perl_auth>, and I<python_auth>
-parameters is permitted within any auth group; each line is tried
-in the order it appears.  I<python_auth> has more power than I<auth>
-in that it provides the authentication program with additional information
-about the client and the ability to return an error string and a username.
-This parameter is only valid if INN is compiled with Python support
-(B<--with-python> passed to B<configure>).  More information may be
-found in F<doc/hook-python>.
-
-=item B<default:>
-
-The default username for connections matching this auth group.  This is
-the username assigned to the user at connection time if all resolvers fail
-or if there are no res: parameters.  Note that it can be either a bare
-username, in which case default-domain: (if present) is appended after
-an C<@>, or a full identity string containing an C<@>, in which case it
-will be used verbatim.
-
-=item B<default-domain:>
-
-The default domain string for this auth group.  If a user resolver or
-authenticator doesn't provide a domain, or if the default username is used
-and it doesn't contain a C<@>, this domain is used to form the user
-identity.  (Note that for a lot of setups, it's not really necessary for
-user identities to be qualified with a domain name, in which case there's
-no need to use this parameter.)
-
-=item B<key:>
-
-If this parameter is present, any connection matching this auth group will
-have its privileges determined only by the subset of access groups
-containing a matching key parameter.
-
-=item B<require_ssl:>
-
-If set to true, an incoming connection only matches this auth group if
-it is encrypted using SSL.  This parameter is only valid if INN is
-compiled with SSL support (B<--with-openssl> passed to configure).
-
-=item B<perl_access:>
-
-A path to a perl script for dynamically generating an access group.  If
-an auth group matches successfully and contains a perl_access parameter,
-then the argument perl script will be used to create an access group.
-This group will then determine the access rights of the client,
-overriding any access groups in F<readers.conf>.  If and only if a
-sucessful auth group contains the perl_access parameter, F<readers.conf>
-access groups are ignored and the client's rights are instead determined
-dynamically.  This parameter is only valid if INN is compiled with Perl
-support (B<--with-perl> passed to configure).  More information may be
-found in the file F<doc/hook-perl>.
-
-=item B<python_access:>
-
-A Python script for dynamically generating an access group.  If
-an auth group matches successfully and contains a I<python_access> parameter,
-then the argument script (without its C<.py> extension) will be used to
-create an access group.  This group will then determine the access rights
-of the client, overriding any access groups in F<readers.conf>.  If and only
-if a successful auth group contains the I<python_access> parameter, F<readers.conf>
-access groups are ignored and the client's rights are instead determined
-dynamically.  This parameter is only valid if INN is compiled with Python
-support (B<--with-python> passed to B<configure>).  More information may be
-found in the file F<doc/hook-python>.
-
-=item B<python_dynamic:>
-
-A Python script for applying access control dynamically on a per newsgroup
-basis.  If an auth group matches successfully and contains a
-I<python_dynamic> parameter, then the argument script (without its
-C<.py> extension) will be used to determine the clients rights each time
-the user attempts to view a newsgroup, or read or post an article.  Access
-rights as determined by I<python_dynamic> override the values of access
-group parameters such as I<newsgroups>, I<read> and I<post>.  This parameter
-is only valid if INN is compiled with Python support (B<--with-python>
-passed to B<configure>).  More information may be found in the file
-F<doc/hook-python>.
-
-=back
-
-=head1 ACCESS GROUP PARAMETERS
-
-=over 4
-
-=item B<users:>
-
-The privileges given by this access group apply to any user identity which
-matches this comma-separated list of wildmat patterns.  If this parameter
-isn't given, the access group applies to all users (and is essentially
-equivalent to C<users: *>).
-
-=item B<newsgroups:>
-
-Users that match this access group are allowed to read and post to all
-newsgroups matching this comma-separated list of wildmat patterns.  The
-empty string is equivalent to C<newsgroups: *>; if this parameter is
-missing, the connection will be rejected (unless read: and/or post: are
-used instead, see below).
-
-=item B<read:>
-
-Like the newsgroups: parameter, but the client is only given permission to
-read the matching newsgroups.  This parameter is often used with post:
-(below) to specify some read-only groups; it cannot be used in the same
-access group with a newsgroups: parameter.  (If read: is used and post:
-is missing, the client will have only read-only access.)
-
-=item B<post:>
-
-Like the newsgroups: parameter, but the client is only given permission to
-post to the matching newsgroups.  This parameter is often used with read:
-(above) to define the patterns for reading and posting separately (usually
-to give the user permission to read more newsgroups than they're permitted
-to post to).  It cannot be used in the same access group with a
-newsgroups: parameter.
-
-=item B<access:>
-
-A set of letters specifying the permissions granted to the client.  The
-letters are chosen from the following set:
-
-=over 3
-
-=item R
-
-The client may read articles.
-
-=item P
-
-The client may post articles.
-
-=item I
-
-The client may inject articles with IHAVE.  Note that in order to
-inject articles with the IHAVE the user must also have POST permission
-(the C<P> option).
-
-=item A
-
-The client may post articles with Approved: headers (in other words, may
-approve articles for moderated newsgroups).  By default, this is not
-allowed.
-
-=item N
-
-The client may use the NEWNEWS command, overriding the global setting.
-
-=item L
-
-The client may post to newsgroups that are set to disallow local posting
-(mode C<n> in the active(5) file).
-
-=back
-
-Note that if this parameter is given, I<allownewnews> in F<inn.conf> is
-ignored for connections matching this access group and the ability of the
-client to use NEWNEWS is entirely determined by the presence of C<N> in
-the access string.  If you want to support NEWNEWS, make sure to include
-C<N> in the access string when you use this parameter.
-
-Note that if this parameter is given and C<R> isn't present in the access
-string, the client cannot read regardless of newsgroups: or read:
-parameters.  Similarly, if this parameter is given and C<P> isn't present,
-the client cannot post.  This use of access: is deprecated and confusing;
-it's strongly recommended that if the access: parameter is used, C<R> and
-C<P> always be included in the access string and newsgroups:, read:, and
-post: be used to control access.  (To grant read access but no posting
-access, one can have just a read: parameter and no post: parameter.)
-
-=item B<key:>
-
-If this parameter is present, this access group is only considered when
-finding privileges for users matching auth groups with this same key:
-parameter.
-
-=item B<reject_with:>
-
-If this parameter is present, a client matching this block will be
-disconnected with a "Permission denied" message containing the contents
-(a "reason" string) of this parameter.  Some newsreaders will then
-display the reason to the user.
-
-=item B<max_rate:>
-
-If this parameter is present (and nonzero), it is used for B<nnrpd>'s
-rate-limiting code.  The client will only be able to download at this
-speed (in bytes/second).  Note that if SSL is being used, limiting
-is applied to the pre-encryption datastream.
-
-=item B<localtime:>
-
-If a Date: header is not included in a posted article, nnrpd(8) normally
-adds a new Date: header in UTC.  If this is set to true, the Date: header
-will be formatted in local time instead.  This is a boolean value and the
-default is false.
-
-=item B<newsmaster:>
-
-Used as the contact address in the help message returned by nnrpd(8), if
-the virtualhost: parameter is set to true.
-
-=item B<strippath:>
-
-If set to true, any Path: header provided by a user in a post is stripped
-rather than used as the beginning of the Path: header of the article.
-This is a boolean value and the default is false.
-
-=item B<perlfilter:>
-
-If set to false, posts made by these users do not pass through the Perl
-filter even if it is otherwise enabled.  This is a boolean value and the
-default is true.
-
-=item B<pythonfilter:>
-
-If set to false, posts made by these users do not pass through the Python
-filter even if it is otherwise enabled.  This is a boolean value and the
-default is true.
-
-=item B<virtualhost:>
-
-Set this parameter to true in order to make B<nnrpd> behave as if it is
-running on a server with a different name than it actually is.  If you
-set this parameter to true, you must also set either pathhost: or domain:
-in the relevant access group in F<readers.conf> to something different
-than is set in F<inn.conf>.  All articles displayed to clients will then have
-their Path: and Xref: headers altered to appear to be from the server
-named in pathhost: or domain: (whichever is set), and posted articles will
-use that server name in the Path:, Message-ID:, and X-Trace: headers.
-
-Note that setting this parameter requires the server modify all posts
-before presenting them to the client and therefore may decrease
-performance slightly.
-
-=back
-
-In addition, all of the following parameters are valid in access groups
-and override the global setting in F<inn.conf>.  See inn.conf(5) for the
-descriptions of these parameters:
-
-    addnntppostingdate, addnntppostinghost, backoff_auth, backoff_db,
-    backoff_k, backoff_postfast, backoff_postslow, backoff_trigger,
-    checkincludedtext, clienttimeout, complaints, domain,
-    fromhost, localmaxartsize, moderatormailer, nnrpdauthsender,
-    nnrpdcheckart, nnrpdoverstats, nnrpdposthost, nnrpdpostport, organization,
-    pathhost, readertrack, spoolfirst, strippostcc.
-
-=head1 SUMMARY
-
-Here's a basic summary of what happens when a client connects:
-
-=over 2
-
-=item *
-
-All auth groups are scanned and the ones that don't match the client
-(due to hosts:, localaddress:, require_ssl:, etc) are eliminated.
-
-=item *
-
-The remaining auth groups are scanned from the last to the first, and an
-attempt is made to apply it to the current connection.  This means running
-res: programs, if any, and otherwise applying default:.  The first auth
-group (starting from the bottom) to return a valid user is kept as the
-active auth group.
-
-=item *
-
-If no auth groups yield a valid user (none have default: parameters or
-successful res: programs) but some of the auth groups have auth: lines
-(indicating a possibility that the user can authenticate and then obtain
-permissions), the connection is considered to have no valid auth group
-(which means that the access groups are ignored completely) but the
-connection isn't closed.  Instead, 480 is returned for everything until
-the user authenticates.
-
-=item *
-
-When the user authenticates, the auth groups are rescanned, and only the
-matching ones which contain at least one auth, perl_auth, or
-python_auth line are considered.  These auth groups are scanned from
-the last to the first, running auth: programs and perl_auth: or
-python_auth: scripts.  The first auth group (starting from the bottom)
-to return a valid user is kept as the active auth group.
-
-=item *
-
-Regardless of how an auth group is established, as soon as one is, that
-auth group is used to assign a user identity by taking the result of the
-successful res, auth, perl_auth, or python_auth line (or the
-default: if necessary), and appending the default-domain if
-necessary.  (If the perl_access: or python_access: parameter is
-present, see below.)
-
-=item *
-
-Finally, an access group is selected by scanning the access groups from
-bottom up and finding the first match.  (If the established auth group
-contained a perl_access: or python_access line, the dynamically
-generated access group returned by the script is used instead.)
-User permissions are granted based on the established access group.
-
-=back
-
-=head1 EXAMPLES
-
-Probably the simplest useful example of a complete F<readers.conf>,
-this gives permissions to read and post to all groups to any connections
-from the "example.com" domain, and no privileges for anyone connecting
-elsewhere:
-
-    auth example.com {
-        hosts: "*.example.com, example.com"
-        default: <LOCAL>
-    }
-
-    access full {
-        newsgroups: *
-    }
-
-Note that the access realm has no users: key and therefore applies to any
-user identity.  The only available auth realm only matches hosts in the
-"example.com" domain, though, so any connections from other hosts will be
-rejected immediately.
-
-If you have some systems that should only have read-only access to the
-server, you can modify the example above slightly by adding an additional
-auth and access group:
-
-    auth lab {
-        hosts: "*.lab.example.com"
-        default: <LAB>
-    }
-
-    access lab {
-        users: <LAB>
-        read: *
-    }
-
-If those are put in the file after the above example, they'll take
-precedence (because they're later in the file) for any user coming from a
-machine in the lab.example.com domain, everyone will only have read
-access, not posting access.
-
-Here's a similar example for a news server that accepts connections from
-anywhere but requires the user to specify a username and password.  The
-username and password are first checked against an external database of
-usernames and passwords, and then against the system shadow password file:
-
-    auth all {
-        auth: "ckpasswd -d <pathdb in inn.conf>/newsusers"
-        auth: "ckpasswd -s"
-    }
-
-    access full {
-        users: *
-        newsgroups: *
-    }
-
-When the user first connects, there are no res: keys and no default, so
-they don't receive any valid identity and the connection won't match any
-access groups (even ones with C<users: *>).  Such users receive nothing
-but authentication-required responses from nnrpd until they authenticate.
-
-If they then later authenticate, the username and password are checked
-first by running B<ckpasswd> with the B<-d> option for an external dbm
-file of encrypted passwords, and then with the B<-s> option to check the
-shadow password database (note that this option may require ckpasswd to
-be setgid to a shadow group, and there are security considerations; see
-ckpasswd(8) for details).  If both of those fail, the user will continue
-to have no identity; otherwise, an identity will be assigned (usually
-the supplied username, perhaps with a domain appended, although an
-authenticator technically can provide a completely different username
-for the identity), and the access group will match, giving full access.
-
-It may be educational to consider how to combine the above examples;
-general groups always go first.  The order of the auth groups actually
-doesn't matter, since the "hosts: example.com" one only matches
-connections before username/password is sent, and the "auth: ckpasswd"
-one only matches after; order would matter if either group applied to
-both cases.  The order of the access groups in this case does matter,
-provided the newsgroups: lines differ; the access group with no users:
-line needs to be first, with the "users: <LOCAL>" group after.
-
-Here's a very complicated example.  This is for an organization that has
-an internal hierarchy "example.*" only available to local shell users, who
-are on machines where identd can be trusted.  Dialup users must provide a
-username and password, which is then checked against RADIUS.  Remote users
-have to use a username and password that's checked against a database on
-the news server.  Finally, the admin staff (users "joe" and "jane") can
-post anywhere (including the "example.admin.*" groups that are read-only
-for everyone else), and are exempted from the Perl filter.  For an
-additional twist, posts from dialup users have their Sender: header
-replaced by their authenticated identity.
-
-Since this organization has some internal moderated newsgroups, the admin
-staff can also post messages with Approved: headers, but other users
-cannot.
-
-    auth default {
-        auth: "ckpasswd -f <pathdb in inn.conf>/newsusers"
-        default: <FAIL>
-        default-domain: example.com
-    }
-
-    auth shell {
-        hosts: *.shell.example.com
-        res: ident
-        auth: "ckpasswd -s"
-        default: <FAIL>
-        default-domain: shell.example.com
-    }
-
-    auth dialup {
-        hosts: *.dialup.example.com
-        auth: radius
-        default: <FAIL>
-        default-domain: dialup.example.com
-    }
-
-    access shell {
-        users: *@shell.example.com
-        read: *
-        post: "*, !example.admin.*"
-    }
-
-    access dialup {
-        users: *@dialup.example.com
-        newsgroups: *,!example.*
-        nnrpdauthsender: true
-    }
-
-    access other {
-        users: "*@example.com, !<FAIL>@example.com"
-        newsgroups: *,!example.*
-    }
-
-    access fail {
-        users: "<FAIL>@*"
-        newsgroups: !*
-    }
-
-    access admin {
-        users: "joe@*,jane@*"
-        newsgroups: *
-        access: "RPA"
-        perlfilter: false
-    }
-
-Note the use of different domains to separate dialup from shell users
-easily.  Another way to do that would be with key: parameters, but this
-way provides slightly more intuitive identity strings.  Note also that the
-fail access group catches not only failing connections from external users
-but also failed authentication of shell and dialup users and dialup users
-before they've authenticated.  The identity string given for, say, dialup
-users before RADIUS authentication has been attempted matches both the
-dialup access group and the fail access group, since it's
-"<FAIL>@dialup.example.com", but the fail group is last so it takes
-precedence.
-
-The shell auth group has an auth: parameter so that users joe and jane
-can, if they choose, use username and password authentication to gain
-their special privileges even if they're logged on as a different user on
-the shell machines (or if ident isn't working).  When they first connect,
-they'd have the default access for that user, but they could then send
-AUTHINFO USER and AUTHINFO PASS (or AUTHINFO SIMPLE) and get their
-extended access.
-
-Also note that if the users joe and jane are using their own accounts,
-they get their special privileges regardless of how they connect, whether
-the dialups, the shell machines, or even externally with a username and
-password.
-
-Finally, here's a very simple example of a configuration for a public
-server for a particular hierarchy.
-
-    auth default {
-        hosts: *
-        default: <PUBLIC>
-    }
-
-    access default {
-        users: <PUBLIC>
-        newsgroups: example.*
-    }
-
-Notice that clients aren't allowed to read any other groups; this keeps
-them from getting access to administrative groups or reading control
-messages, just as a precaution.  When running a public server like this,
-be aware that many public hierarchies will later be pulled down and
-reinjected into the main Usenet, so it's highly recommended that you also
-run a Perl or Python filter to reject any messages crossposted out of your
-local hierarchy and any messages containing a Supersedes: header.  This
-will keep messages posted to your public hierarchy from hurting any of the
-rest of Usenet if they leak out.
-
-=head1 SECURITY CONSIDERATIONS
-
-In general, separate passwords should be used for NNTP wherever
-possible; the NNTP protocol itself does not protect passwords from
-casual interception, and many implementations (including this one) do
-not "lock out" accounts or otherwise discourage password-guessing
-attacks.  So it is best to ensure that a compromised password has
-minimal effects.
-
-Authentication using the AUTHINFO USER/PASS commands passes unencrypted
-over the network.  Extreme caution should therefore be used especially
-with system passwords (e.g. C<auth: ckpasswd -s>).  Passwords can be
-protected by using NNTP over SSL or through ssh tunnels, and this usage
-can be enforced by a well-considered server configuration that only
-permits certain auth groups to be applied in certain cases.  Here are
-some ideas:
-
-=over 4
-
-=item *
-
-To restrict connections on the standard nntp port (119) to use SSL for
-some (or all) of the auth groups to match, use the require_ssl:
-parameter.
-
-=item *
-
-If you consider your local network (but not the internet) secure, have
-some auth groups with a restrictive hosts: parameter; they would go
-above, with ones having global applicability below.
-
-=item *
-
-Consider running a C<nnrpd -S> (with C<-D>, or out of "super-server"
-like B<inetd>) on the NNTPS port (563) for clients that support SSL.  See
-nnrpd(8) for more details about how to configure that.  You
-can use the require_ssl: parameter, or C<-c> to specify an alternate
-F<readers.conf> if you want a substantially different configuration for
-this case.
-
-=item *
-
-If you want to restrict an auth group to only match loopback connections
-(for users running newsreaders on localhost or connecting via an ssh
-tunnel), use the localaddress: parameter.
-
-=back
-
-=head1 HISTORY
-
-Written by Aidan Cully <aidan@panix.com> for InterNetNews.  Substantially
-expanded by Russ Allbery <rra@stanford.edu>.
-
-$Id: readers.conf.pod 7895 2008-06-22 17:54:10Z iulius $
-
-=head1 SEE ALSO
-
-auth_krb5(8), auth_smb(8), ckpasswd(8), inn.conf(5), innd(8), newsfeeds(5),
-nnrpd(8), uwildmat(3).
-
-=cut
diff --git a/doc/pod/readme.pod b/doc/pod/readme.pod
deleted file mode 100644 (file)
index 2589fe7..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-=head1 Welcome to INN 2.4!
-
-This work is sponsored by Internet Systems Consortium.
-
-Please see F<INSTALL> for installation instructions, F<NEWS> for what's
-changed from the previous release, and F<LICENSE> for the copyright,
-license, and distribution terms.
-
-=head1 What is INN?
-
-INN (InterNetNews), originally written by Rich Salz, is an extremely
-flexible and configurable Usenet / netnews news server.  For a complete
-description of the protocols behind Usenet and netnews, see RFC 1036 and
-RFC 977 (or their replacements).  In brief, netnews is a set of protocols
-for exchanging messages between a decentralized network of news servers.
-News articles are organized into newsgroups, which are themselves
-organized into hierarchies.  Each individual news server stores locally
-all articles it has received for a given newsgroup, making access to
-stored articles extremely fast.  Netnews does not require any central
-server; instead, each news server passes along articles it receives to all
-of the news servers it peers with, those servers pass the articles along
-to their peers, and so on, resulting in "flood fill" propagation of news
-articles.
-
-A news server performs three basic functions:  it accepts articles from
-other servers and stores them on disk, sends articles it has received out
-to other servers, and offers stored news articles to readers on demand.
-It additionally has to perform some periodic maintenance tasks, such as
-deleting older articles to make room for new ones.
-
-Originally, a news server would just store all of the news articles it had
-received in a file system.  Users could then read news by reading the
-article files on disk (or more commonly using news reading software that
-did this efficiently).  These days, news servers are almost always
-stand-alone systems and news reading is supported via network connections.
-A user who wants to read a newsgroup opens that newsgroup in their
-newsreader software, which opens a network connection to the news server
-and sends requests for articles and related information.  The protocol
-that a newsreader uses to talk to a news server and that a news server
-uses to talk to another news server over TCP/IP is called NNTP (Network
-News Transport Protocol).
-
-INN supports accepting articles via either NNTP connections or via UUCP.
-B<innd>, the heart of INN, handles NNTP feeding connections directly;
-UUCP newsfeeds use B<rnews> (included in INN) to hand articles off to
-innd.  Other parts of INN handle feeding articles out to other news
-servers, most commonly B<innfeed> (for real-time outgoing feeds) or
-B<nntpsend> and B<innxmit> (used to send batches of news created by innd
-to a remote site via TCP/IP).  INN can also handle outgoing UUCP feeds.
-
-The part of INN that handles connections from newsreaders is nnrpd.
-
-Also included in INN are a wide variety of supporting programs to handle
-periodic maintenance and recovery from crashes, process special control
-messages, maintain the list of active newsgroups, and generate and record
-a staggering variety of statistics and summary information on the usage
-and performance of the server.
-
-INN also supports an extremely powerful filtering system that allows the
-server administrator to reject unwanted articles (such as spam and other
-abuses of Usenet).
-
-INN is free software, supported by Internet Systems Consortium and
-volunteers around the world.  See L<"Supporting the INN Effort"> below.
-
-=head1 Prerequisites
-
-Compiling INN requires an ANSI C compiler (gcc is recommended).  INN was
-originally written in K&R C, but supporting pre-ANSI compilers has become
-enough of a headache that a lot of the newer parts of INN will no longer
-compile with a non-ANSI compiler.  gcc itself will compile with most
-vendor non-ANSI compilers, however, so if you're stuck with one,
-installing gcc is highly recommended.  Not only will it let you build INN,
-it will make installing lots of other software much easier.  You may also
-need GNU make (particularly if your system make is BSD-derived), although
-most SysV make programs should work fine.  Compiling INN also currently
-requires a yacc implementation (bison will do fine).
-
-INN uses GNU autoconf to probe the capabilities of your system, and
-therefore should compile on nearly any Unix system.  It does, however,
-make extensive use of mmap(), which can cause problems on some older
-operating systems.  See F<INSTALL> for a list of systems it is known to
-work on.  If you encounter problems compiling or running INN, or if you
-successfully run INN on a platform that isn't listed in F<INSTALL>, please
-let us know (see L<"Reporting Bugs"> below).
-
-Perl 5.003 or later is required to build INN.  Perl 5.004 is required if
-you want the embedded Perl filter support (which is highly recommended;
-some excellent spam filters have been written for INN).  Since all
-versions of Perl previous to 5.004 are buggy (including security problems)
-and have fewer features, installing Perl 5.004 or later is recommended.
-
-If you want to enable PGP verification of control messages (highly
-recommended), you will need to have a PGP implementation installed.  See
-F<INSTALL> for more details.
-
-=head1 Getting Started
-
-A news server can be a fairly complicated piece of software to set up just
-because of the wide variety of pieces that have to be configured (who is
-authorized to read from the server, what newsgroups it carries, and how
-the articles are stored on disk at a bare minimum, and if the server isn't
-completely stand-alone -- and very few servers are -- both incoming and
-outgoing feeds have to be set up and tested).  Be prepared to take some
-time to understand what's going on and how all the pieces fit together.
-If you have any specific suggestions for documentation, or comments about
-things that are unclear, please send them to the INN maintainers (see
-L<"Reporting Bugs"> below).
-
-See F<INSTALL> for step-by-step instructions for setting up and
-configuring a news server.
-
-INN also comes with a very complete set of man pages; there is a man page
-for every configuration file and program that comes with INN.  (If you
-find one that doesn't have a man page, that's a bug.  Please do report
-it.)  When trying to figure out some specific problem, reading the man
-pages for all of the configuration files involved is a very good start.
-
-=head1 Reporting Bugs
-
-We're interested in all bug reports.  Not just on the programs, but on the
-documentation too.  Please send I<all> such reports to
-
-    inn-bugs@isc.org
-
-(patches are certainly welcome, see below).  Even if you post to Usenet,
-please CC the above address.  All other INN mail should go to
-
-    inn@isc.org
-
-(please do I<not> send bug reports to this address).
-
-If you have general "how do I do this" questions or problems configuring
-your server that you don't believe are due to a bug in INN, you should
-post them to news.software.nntp.  A lot of experienced INN users,
-including several of the INN maintainers, read that newsgroup regularly.
-Please don't send general questions to the above addresses; those
-addresses are specifically for INN, and the INN maintainers usually won't
-have time to answer general questions.
-
-=head1 Contributing Code
-
-If you have a patch or a utility that you'd like to be considered for
-inclusion into INN, please mail it to
-
-    inn-patches@isc.org
-
-in the body of the message (not as an attachment), or put it on a
-webpage and send a link.  Patches included with a bug report as
-described above should follow the same procedure, but need not be sent
-to both addresses (either will do).
-
-Have fun!
-
-=head1 Mailing Lists
-
-There are various INN-related mailing lists you can join or send messages
-to if you like.  Some of them you must be a member of before you can send
-mail to them (thank the spammers for that policy), and one of them is
-read-only (no postings allowed).
-
-=over 24
-
-=item inn-announce@isc.org
-
-Where announcements about INN are set (only maintainers may post).
-
-=item inn-workers@isc.org
-
-Discussion of INN development (postings by members only).
-
-=item inn-patches@isc.org
-
-Where to send patches for consideration for inclusion into INN (open
-posting).
-
-=item inn-committers@isc.org
-
-CVS commit messages for INN are sent to this list (only the automated
-messages are sent here, no regular posting).
-
-=item inn-bugs@isc.org
-
-Where to send bug reports (open posting).  If you're an INN expert and
-have the time to help out other users, we encourage you to join this
-mailing list to answer questions.  (You may also want to read the
-newsgroup news.software.nntp, which gets a lot of INN-related questions.)
-
-=back
-
-To join these lists, send a subscription request to the C<-request>
-address.  The addresses for the above lists are:
-
-   inn-announce-request@isc.org
-   inn-workers-request@isc.org
-   inn-patches-request@isc.org
-   inn-committers-request@isc.org
-   inn-bugs-request@isc.org
-
-=head1 Who's Responsible / Who to Thank
-
-See F<CONTRIBUTORS> for a long list of past contributors as well as people
-from the inn-workers mailing list who have dedicated a lot of time and
-effort to getting this new version together.  They deserve a big round of
-applause.  They've certainly got our thanks.
-
-This product includes software developed by UUNET Technologies, Inc. and
-by the University of California, Berkeley and its contributors.
-
-Last, but certainly not least, Rich Salz, the original author of INN
-deserves a lion's share of the credit for writing INN in the first place
-and making it the most popular news server software on the planet (no NNTP
-yet to the moon, but we plan to be there first).
-
-=head1 Related Packages
-
-INN users may also be interested in the following software packages that
-work with INN or are based on it.  Please note that none of this software
-is developed or maintained by ISC; we don't support it and generally can't
-answer questions about it.
-
-=over 4
-
-=item CleanFeed
-
-URL: <http://www.bofh.it/~md/cleanfeed/>
-
-CleanFeed is an extremely powerful spam filter, probably the most widely
-used spam filter on Usenet currently.  It catches excessive multiposting
-and a host of other things, and is highly configurable.  Note that it
-requires that INN be built with Perl support (the B<--with-perl> option to
-configure).
-
-=item GUP (Group Update Program)
-
-URL: <ftp://ftp.debian.org/debian/pool/main/g/gup/>
-
-GUP provides a way for your peers to update their newsfeeds entries as
-they want without having to ask you to edit the configuration file all the
-time.  It's useful when feeding peers who take limited and very specific
-feeds that change periodically.
-
-=item inflow
-
-URL: <http://www.switch.ch/netnews/wg/netnews-wg.html>
-
-inflow generates graphs of news flow statistics in real time from INN's
-logs (things like articles accepted per peer, volume accepted per peer,
-and the like).
-
-=item News-Portal
-
-URL: <http://floh.gartenhaus.net/newsportal/>
-
-A PHP-based web news reader that works as a front-end to a regular news
-server such as INN and lets people read and post without learning a news
-reader.
-
-=item PersonalINN
-
-URL: <http://www.ritual.org/summer/pinn/>
-
-PersonalINN is a version of INN modified for personal use and with a
-friendly GUI built on top of it.  It is available for NeXTSTEP or OPENSTEP
-only, unfortunately.
-
-=item suck
-
-URL: <http://home.comcast.net/~bobyetman/index.html>
-
-suck is a separate package for downloading a news feed via a reading
-connection (rather than via a direct NNTP or UUCP feed) and sending
-outgoing local posts via POST.  It's intended primarily for personal or
-small-organization news servers who get their news via an ISP and are too
-small to warrant setting up a regular news feed.
-
-=item newsx
-
-URL: <http://www.kvaleberg.com/newsx.html>
-
-Serving the same purpose as suck, newsx is a separate package for
-downloading a news feed via a reading connectino and sending outgoing
-local posts via POST.  Some people find suck easier to configure and use,
-and some people find newsx easier.  If you have problems with one, try the
-other.
-
-=back
-
-=head1 Supporting the INN Effort
-
-Note that INN is supported by Internet Systems Consortium, and although it
-is free for use and redistribution and incorporation into vendor products
-and export and anything else you can think of, it costs money to produce.
-That money comes from ISPs, hardware and software vendors, companies who
-make extensive use of the software, and generally kind-hearted folk such
-as yourself.
-
-Internet Systems Consortium has also commissioned a DHCP server
-implementation and handles the official support/release of BIND.  You can
-learn more about the ISC's goals and accomplishments from the web page at
-<http://www.isc.org/>.
-
-                                        Russ Allbery
-                                        Katsuhiro Kondou
-                                        <inn@isc.org>
diff --git a/doc/pod/sasl.conf.pod b/doc/pod/sasl.conf.pod
deleted file mode 100644 (file)
index 8c37dba..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-=head1 NAME
-
-sasl.conf - SASL Configuration file for nnrpd.
-
-=head1 DESCRIPTION
-
-The file F<sasl.conf> in I<pathetc> specifies Simple Authentication
-and Security Layer (SASL), defined in RFC 2222, for nnrpd.
-Now nnrpd implements only Security Layer support, which is an extension
-of RFC 2595. This means you can get SSL or TLS encrypted NNRP between
-your server and newsreaders. It requires OpenSSL 0.9.3 or newer from
-http://www.openssl.org/; it has been tested with versions 0.9.4 and 0.9.5.
-
-=head1 INSTALLATION
-
-To use SSL, a certificate and private key are needed that you can
-create using the openssl binary. 
-Make certain that each keys are owned by your news user, news group,
-and are mode 0640 or 0660.
-
-=head2 EXAMPLE
-
-   openssl req -new -x509 -nodes -out /usr/local/news/lib/cert.pem\
-    -days 366 -keyout /usr/local/news/lib/cert.pem
-   chown news:news /usr/local/news/lib/cert.pem
-   chmod 640 /usr/local/news/lib/cert.pem
-
-You also can make the keys as the root user with C<make cert>.
-
-=head1 CONFIGURATION
-
-Comments begin with a number  sign  (C<#>)  and  continue through the 
-end of the line.  Blank lines and comments are ignored.
-All other lines specify parameters, and should be of the form
-
-    <option>: <value>
-
-where <option> is the name of the configuration option being set and
-<value> is the value that the configuration option is being set to.
-
-Blank lines and lines beginning with (C<#>) are ignored.
-For boolean options, the values  C<yes>,  C<on>,  C<t>,
-and  C<1> turn the option on; the values C<no>, C<off>,
-C<f>, and C<0> turn the option off.
-
-=over 4
-
-=item tls_cert_file
-
-The path to a file containing the server's certificate.
-
-=item tls_key_file
-
-The path to a file containing the server's private key.
-
-=item tls_ca_path
-
-The path to a directory containing the CA's certificate.
-
-=item tls_ca_file
-
-The path to a file containing the CA's certificate.
-
-=back
-
-=head1 TO DO
-
-Implement methods of the authentication protocols of SASL.
-
-=head1 HISTORY
-
-Written by Kenichi OKADA E<lt>okada@opaopa.orgE<gt> for InterNetNews.
-
-=head1 SEE ALSO
-
-inn.conf(5), innd(8), nnrpd(8), readers.conf(5)
-
-=cut
diff --git a/doc/pod/sendinpaths.pod b/doc/pod/sendinpaths.pod
deleted file mode 100644 (file)
index 98b1ba8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-=head1 NAME
-
-sendinpaths - Send Usenet Path statistics via e-mail
-
-=head1 SYNOPSIS
-
-B<sendinpaths> [B<-n>]
-
-=head1 DESCRIPTION
-
-B<sendinpaths> checks I<pathlog>/path for B<ninpaths> dump files, finds
-dump files generated in the past 30 days, makes sure they are valid by
-running B<ninpaths> on each one and making sure the exit status is zero,
-and passes them to B<ninpaths> to generate a cumulative report.  That
-report is mailed to the e-mail addresses configured at the beginning of
-this script (by default "pathsurvey@top1000.org" and
-"top1000@anthologeek.net").
-
-When finished, B<sendinpaths> deletes all dump files in I<pathlog>/path
-that are older than 14 days (configurable at the beginning of the script).
-
-For more information on how to set up B<ninpaths>, see ninpaths(8).
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-n>
-
-Don't e-mail the report; instead, just print it to standard output.  Don't
-delete old dump files.
-
-=back
-
-=head1 SEE ALSO
-
-ninpaths(8)
-
-=head1 HISTORY
-
-B<sendinpaths> was written by Olaf Titz <olaf@bigred.inka.de>.
-
-=cut
diff --git a/doc/pod/simpleftp.pod b/doc/pod/simpleftp.pod
deleted file mode 100644 (file)
index 0fb4df8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-=head1 NAME
-
-simpleftp - Rudimentary FTP client
-
-=head1 SYNOPSIS
-
-B<simpleftp> I<url> [...]
-
-=head1 DESCRIPTION
-
-B<simpleftp> is a Perl script that provides basic support for
-fetching files with FTP in a batch oriented fashion.  It takes one or more
-FTP URLs on the command line.  The file(s) will be retrieved from the
-remote server and placed in the current directory with the same basename
-as on the remote; e.g., L<ftp://ftp.isc.org/pub/usenet/CONFIG/active.gz>
-is stored as F<active.gz> in the current directory.
-
-The script properly understands usernames, passwords and ports specified
-as follows:
-
-    ftp://user:password@host:port/path/file
-
-=head1 BUGS
-
-B<simpleftp> is an extremely poor substitute for more complete programs
-like the freely available B<wget> or B<ncftp> utilities.  It was written
-only to provide elementary support in INN for non-interactive fetching of
-the files in L<ftp://ftp.isc.org/pub/pgpcontrol/> or
-L<ftp://ftp.isc.org/pub/usenet/CONFIG/> without requiring
-administrators to install yet another package.  Its shortcomings as a
-general purpose program are too numerous to mention, but one that stands
-out is that downloaded files by B<simpleftp> override existing files
-with the same name in the local directory.
-
-=head1 HISTORY
-
-Tossed off by David C Lawrence <tale@isc.org> for InterNetNews.
-Rewritten to use Net::FTP by Julien Elie <julien@trigofacile.com>.
-
-$Id: simpleftp.pod 7739 2008-04-06 09:38:31Z iulius $
-
-=head1 SEE ALSO
-
-actsync(8).
-
-=cut
diff --git a/doc/pod/sm.pod b/doc/pod/sm.pod
deleted file mode 100644 (file)
index 68c790e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-=head1 NAME
-
-sm - Command-line interface to the INN storage manager
-
-=head1 SYNOPSIS
-
-B<sm> [B<-dHiqRrS>] [I<token> ...]
-
-=head1 DESCRIPTION
-
-The INN storage manager is the subsystesm that stores and keeps track of
-all of the articles and what storage backend they're in.  All stored
-articles are assigned a storage API token.  B<sm> is a command-line
-interface to that storage manager, primarily used to retrieve articles by
-those tokens but also to perform other operations on the storage
-subsystem.
-
-I<token> is the token of an article (the same thing that's returned by
-B<grephistory> or stored in the history file).  It looks something like:
-
-    @0502000005A4000000010000000000000000@
-
-Any number of tokens can be given on the command line.  If none are, B<sm>
-reads tokens from standard input, one per line.  The default operation is
-to retrieve and write to standard output the corresponding article for
-each token given.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-d>, B<-r>
-
-Rather than retrieving the specified article, remove the article.  This
-will delete the article out of the news spool and it will not subsequently
-be retrievable by any part of INN.  It's equivalent to C<ctlinnd cancel>
-except it takes a storage API token instead of a message ID.
-
-=item B<-H>
-
-Retrieve only the header of the article rather than the entire article.
-This option cannot be used with B<-d>, B<-r>, B<-i>, or B<-S>.
-
-=item B<-i>
-
-Show the newsgroup name and article number associated with the token
-rather than the article itself.  Note that for crossposted articles, only
-the first newsgroup and article number to which the article is associated
-will be returned.
-
-=item B<-q>
-
-Suppress all error messages except usage errors.
-
-=item B<-R>
-
-Display the raw article.  This means that line endings won't be converted
-to native line endings and will be left as CRLF sequences, leading periods
-will still be escaped for sending over NNTP, and the article will end in
-a CRLF.CRLF sequence.
-
-=item B<-S>
-
-Write the article to standard output in the format used by rnews spool
-files.  Multiple articles can be written in this format, and the resulting
-output can be fed to rnews (on another system, for example) to inject
-those articles into INN.  This option cannot be used with B<-d>, B<-r>,
-B<-H>, B<-i>, or B<-R>.
-
-=back
-
-=head1 EXIT STATUS
-
-If all operations were successful, B<sm> exits with status 0.  If an
-operation on any of the provided tokens fails, B<sm> will exit with status
-1, even if the operations on other tokens were successful.  In other
-words, if twenty tokens are fed to C<sm -r> on stdin, 19 articles were
-successfully removed, but the sixth article couldn't be found, B<sm> will
-still exit with status 1.
-
-This means that if you need to be sure whether a particular operation
-succeeded, you should run sm on one token at a time.
-
-=head1 HISTORY
-
-Written by Katsuhiro Kondou <kondou@nec.co.jp> for InterNetNews.
-Rewritten in POD by Russ Allbery <rra@stanford.edu>.
-
-$Id: sm.pod 6683 2004-03-06 18:31:58Z rra $
-
-=head1 SEE ALSO
-
-ctlinnd(8), grephistory(1), history(5), rnews(1), storage.conf(5).
-
-=cut
diff --git a/doc/pod/subscriptions.pod b/doc/pod/subscriptions.pod
deleted file mode 100644 (file)
index e3d84d8..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-=head1 NAME
-
-subscriptions - Default recommended subscriptions
-
-=head1 DESCRIPTION
-
-The I<pathetc>/F<subscriptions> file contains a list of newsgroups that is
-returned by the NNTP command LIST SUBSCRIPTIONS.
-
-Clients that support this command and send it the first time they connect
-to a new news server use the returned list to initialize the list of
-subscribed newsgroups.  The F<subscriptions> file therefore should contain
-groups intented for new users, for testing, or that contain FAQs and other
-useful information for first-time Usenet users.
-
-The syntax of the F<subscriptions> file is trivial; it is a simple list of
-newsgroup names, one per line.  The order of newsgroups may be
-significant; the news reading client may present the groups in that order
-to the user.
-
-=head1 EXAMPLE
-
-A typical F<subscriptions> file may look like:
-
-    news.announce.newusers
-    news.newusers.questions
-    local.test
-    local.general
-    local.talk
-    misc.test
-    misc.test.moderated
-    news.answers
-    news.announce.newgroups
-
-This gives the client the FAQs and question newsgroup for new users first,
-then a local newsgroup for testing and various commonly-read local
-discussion groups, followed by the world-wide test groups, all the FAQs,
-and announcements of new world-wide newsgroups.  If there is a local new
-users group, one might want to list it first.
-
-=head1 HISTORY
-
-Written by Bettina Fink <laura@hydrophil.de> for InterNetNews.
-
-=head1 SEE ALSO
-
-nnrpd(8).
-
-=cut
diff --git a/doc/pod/tdx-util.pod b/doc/pod/tdx-util.pod
deleted file mode 100644 (file)
index 8ea6171..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-=head1 NAME
-
-tdx-util - Tradindexed overview manipulation utility
-
-=head1 SYNOPSIS
-
-B<tdx-util> [B<-AFgio>] [B<-a> I<article>] [B<-n> I<newsgroup>]
-[B<-p> I<path>] [B<-R> I<path>]
-
-=head1 DESCRIPTION
-
-B<tdx-util> is an administrative interface to the tradindexed overview
-method for INN.  It only works on tradindexed overview databases, not on
-any other type of INN overview.  It allows the administrator to dump
-various information about the internal state of the overview, audit it for
-errors, and rebuild portions of the overview database.
-
-The tradindexed overview method should lock properly and therefore it
-should be safe to run this utility and perform any operation it performs,
-including full repairs or per-group overview rebuilds, while the server is
-running.  However, note that some of the operations performed by this
-utility can take an extended period of time and will hold locks in the
-overview database during that period, which depending on what the server
-is doing may cause the server to stall until B<tdx-util> completes its
-operation.
-
-The dump operations are B<-i>, which dumps the master index for the
-overview database, B<-g>, which dumps the index for an individual group,
-and B<-o>, which dumps the overview information for a particular group
-(including the additional metadata stored in the index).  For B<-g> and
-B<-o>, the B<-n> option must also be given to specify a newsgroup to
-operate on.
-
-To audit the entire overview database for problems, use B<-A>.  Any
-problems found will be reported to standard error.  There is not (yet) a
-corresponding option to correct the errors found.
-
-To rebuild the database for a particular newsgroup, use B<-R>.  The B<-R>
-option takes a path to a directory which contains all of the articles for
-that newsgroup, one per file.  The names of the files must be the numbers
-of the articles in that group.  (In other words, this directory must be a
-traditional spool directory for that group.)  The B<-n> option must also
-be given to specify the newsgroup for which the overview is being rebuilt.
-
-For all operations performed by B<tdx-util>, a different overview database
-than the one specified in F<inn.conf> may be specified using the B<-p>
-option.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-A>
-
-Audit the entire overview database for problems.  This runs the internal
-consistency checks built into the tradindexed overview implementation,
-checking such things as the validity and reachability of all group index
-entries, the format of the individual overview entries, the correspondance
-of index entries to overview data, and similar such things.  No changes
-will be made to the database, but problems will be reported to standard
-error.
-
-=item B<-a> I<article>
-
-The article number to act on.  Only useful in combination with the B<-o>
-option to dump overview information.
-
-=item B<-F>
-
-Audit the entire overview database for problems, fixing them as they're
-detected where possible. This runs the internal consistency checks built
-into the tradindexed overview implementation, checking such things as the
-validity and reachability of all group index entries, the format of the
-individual overview entries, the correspondance of index entries to
-overview data, and similar such things.  The strategy used when fixing
-problems is to throw away data that's unrecoverable, so be warned that
-using this option may result in inaccessible articles if their overview
-data has been corrupted.
-
-To see what would be changed by B<-F>, run B<tdx-util> with B<-A> first.
-
-=item B<-g>
-
-Dump the master index of the overview database.  This contains similar
-information to the server active file, such as high and low water marks
-and moderation status, and is the information that nnrpd hands out to
-clients.
-
-The fields are, in order, the newsgroup name, the high water mark, the low
-water mark, the base article number (the point at which the group index
-begins), the count of articles in the group, the group status flag, the
-time (in seconds since epoch) when that newsgroup was deleted or 0 if it
-hasn't been, and the inode of the index file for that group.
-
-=item B<-i>
-
-Dump the index of a particular group.  The fields are, in order, the
-article number, the offset of the data for that article in the overview
-data file for that group, the length of the overview data, the time (in
-seconds since epoch) when the article arrived on the server, the time (in
-seconds since epoch) when the article should expire based on its Expires
-header (or 0 if there is no Expires header), and the storage API token of
-the article.
-
-If this option is given, the B<-n> option must also be given to specify
-the newsgroup on which to act.
-
-=item B<-n> I<newsgroup>
-
-Specify the newsgroup on which to act, required for the B<-i>, B<-o>, and
-B<-R> options.
-
-=item B<-o>
-
-Dump the overview information for a newsgroup, in the same format as it
-would be returned to clients but with one modification.  Appended to the
-end of each entry will be four additional pieces of data:  the article
-number according to the index file for that group, the storage API token
-for that article, the arrival date for that article on the server in RFC
-822 date format, and the expiration date for that article (from the
-Expires header) in RFC 822 date format if there is any.
-
-If this option is given, the B<-n> option must also be given to specify
-the newsgroup on which to act.  By default, all of the overview
-information for that newsgroup is dumped, but the B<-a> option may be
-given to restrict the dump to the information for a single article.
-
-=item B<-p> I<path>
-
-Act on the overview database rooted in I<path>, overriding the overview
-path specified in F<inn.conf>.
-
-=item B<-R> I<path>
-
-Rebuild the overview for a given group from the articles stored in
-I<path>.  The articles must be in the form of a traditional spool
-directory; in other words, each article must be in a separate file and the
-name of the file must match the article number of the article.
-
-If this option is given, the B<-n> option must also be given to specify
-the newsgroup on which to act.
-
-=back
-
-=head1 EXAMPLES
-
-Dump the master index for the overview database in F</news/overview>,
-regardless of the overview path specified in F<inn.conf>:
-
-    tdx-util -i -p /news/overview
-
-Dump the group index for example.test:
-
-    tdx-util -g -n example.test
-
-Dump the complete overview information for example.test:
-
-    tdx-util -o -n example.test
-
-Audit the entire overview database for any problems:
-
-    tdx-util -A
-
-Rebuild the overview information for example.test from a traditional spool
-directory:
-
-    tdx-util -R /news/spool/articles/example/test -n example.test
-
-The last command may be useful for recovering from a bad crash or
-corrupted overview information for a particular group, if you are also
-using the tradspool article storage method.
-
-=head1 HISTORY
-
-Written by Russ Allbery <rra@stanford.edu> for InterNetNews.
-
-$Id: tdx-util.pod 7047 2004-12-19 19:41:49Z rra $
-
-=head1 SEE ALSO
-
-makehistory(8)
-
-=cut
-
diff --git a/doc/pod/tst.pod b/doc/pod/tst.pod
deleted file mode 100644 (file)
index 2b7d8da..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-=head1 NAME
-
-tst - ternary search trie functions
-
-=head1 SYNOPSIS
-
-B<#include E<lt>inn/tst.hE<gt>>
-
-B<struct tst;>
-
-B<struct tst *tst_init(int >I<node_line_width>B<);>
-
-B<void tst_cleanup(struct tst *>I<tst>B<);>
-
-B<int tst_insert(struct tst *>I<tst>B<, const unsigned char *>I<key>B<, void *>I<data>B<, int >I<option>B<, void **>I<exist_ptr>B<);>
-
-B<void *tst_search(struct tst *>I<tst>B<, const unsigned char *>I<key>B<);>
-
-B<void *tst_delete(struct tst *>I<tst>B<, const unsigned char *>I<key>B<);>
-
-=head1 DESCRIPTION
-
-B<tst_init> allocates memory for members of I<struct tst>, and
-allocates the first I<node_line_width> nodes. A NULL pointer is
-returned by B<tst_init> if any part of the memory allocation fails. On
-success, a pointer to a I<struct tst> is returned.
-
-The value for I<node_line_width> must be chosen very carefully. One
-node is required for every character in the tree. If you choose a
-value that is too small, your application will spend too much time
-calling malloc(3) and your node space will be too spread out. Too large
-a value is just a waste of space.
-
-B<tst_cleanup> frees all memory allocated to nodes, internal structures,
-as well as I<tst> itself.
-
-B<tst_insert> inserts the string I<key> into the tree. Behavior when a
-duplicate key is inserted is controlled by I<option>. If I<key> is
-already in the tree then B<TST_DUPLICATE_KEY> is returned, and the
-data pointer for the existing key is placed in I<exist_ptr>.  If
-I<option> is set to B<TST_REPLACE> then the existing data pointer for
-the existing key is replaced by I<data>.  Note that the old data
-pointer will still be placed in I<exist_ptr>.
-
-If a duplicate key is encountered and I<option> is not set to
-B<TST_REPLACE> then B<TST_DUPLICATE_KEY> is returned. If I<key> is
-zero length then B<TST_NULL_KEY> is returned. A successful insert or
-replace returns B<TST_OK>. A return value of B<TST_ERROR> indicates
-that a memory allocation error occurred while trying to grow the node
-free.
-
-Note that the I<data> argument must never be B<NULL>. If it is, then
-calls to B<tst_search> will fail for a key that exists because the
-data value was set to B<NULL>, which is what B<tst_search> returns. If
-you just want a simple existence tree, use the B<tst> pointer as the
-data pointer.
-
-B<tst_search> finds the string I<key> in the tree if it exists and
-returns the data pointer associated with that key.
-
-If I<key> is not found then B<NULL> is returned, otherwise the data pointer
-associated with I<key> is returned.
-
-B<tst_delete> deletes the string I<key> from the tree if it exists and
-returns the data pointer assocaited with that key.
-
-If I<key> is not found then B<NULL> is returned, otherwise the data
-pointer associated with I<key> is returned.
-
-=head1 HISTORY
-
-Converted to POD from Peter A. Friend's ternary search trie
-documentation by Alex Kiernan <alex.kiernan@thus.net> for InterNetNews
-2.4.0.
-
-$Id: tst.pod 6104 2003-01-02 09:16:09Z alexk $
diff --git a/doc/pod/uwildmat.pod b/doc/pod/uwildmat.pod
deleted file mode 100644 (file)
index 41fffff..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-=head1 NAME
-
-uwildmat, uwildmat_simple, uwildmat_poison - Perform wildmat matching
-
-=head1 SYNOPSIS
-
-B<#include E<lt>libinn.hE<gt>>
-
-B<bool uwildmat(const char *>I<text>B<, const char *>I<pattern>B<);>
-
-B<bool uwildmat_simple(const char *>I<text>B<, const char *>I<pattern>B<);>
-
-B<enum uwildmat uwildmat_poison(const char *>I<text>B<,
-const char *>I<pattern>B<);>
-
-=head1 DESCRIPTION
-
-B<uwildmat> compares I<text> against the wildmat expression I<pattern>,
-returning true if and only if the expression matches the text.  C<@> has
-no special meaning in I<pattern> when passed to B<uwildmat>.  Both I<text>
-and I<pattern> are assumed to be in the UTF-8 character encoding, although
-malformed UTF-8 sequences are treated in a way that attempts to be mostly
-compatible with single-octet character sets like ISO 8859-1.  (In other
-words, if you try to match ISO 8859-1 text with these routines everything
-should work as expected unless the ISO 8859-1 text contains valid UTF-8
-sequences, which thankfully is somewhat rare.)
-
-B<uwildmat_simple> is identical to B<uwildmat> except that neither C<!>
-nor C<,> have any special meaning and I<pattern> is always treated as a
-single pattern.  This function exists solely to support legacy interfaces
-like NNTP's XPAT command, and should be avoided when implementing new
-features.
-
-B<uwildmat_poison> works similarly to B<uwildmat>, except that C<@> as the
-first character of one of the patterns in the expression (see below)
-"poisons" the match if it matches.  B<uwildmat_poison> returns
-B<UWILDMAT_MATCH> if the expression matches the text, B<UWILDMAT_FAIL> if
-it doesn't, and B<UWILDMAT_POISON> if the expression doesn't match because
-a poisoned pattern matched the text.  These enumeration constants are
-defined in the B<libinn.h> header.
-
-=head1 WILDMAT EXPRESSIONS
-
-A wildmat expression follows rules similar to those of shell filename
-wildcards but with some additions and changes.  A wildmat I<expression> is
-composed of one or more wildmat I<patterns> separated by commas.  Each
-character in the wildmat pattern matches a literal occurance of that same
-character in the text, with the exception of the following metacharacters:
-
-=over 8
-
-=item ?
-
-Matches any single character (including a single UTF-8 multibyte
-character, so C<?> can match more than one byte).
-
-=item *Z<>
-
-Matches any sequence of zero or more characters.
-
-=item \
-
-Turns off any special meaning of the following character; the following
-character will match itself in the text.  C<\> will escape any character,
-including another backslash or a comma that otherwise would separate a
-pattern from the next pattern in an expression.  Note that C<\> is not
-special inside a character range (no metacharacters are).
-
-=item [...]
-
-A character set, which matches any single character that falls within that
-set.  The presence of a character between the brackets adds that character
-to the set; for example, C<[amv]> specifies the set containing the
-characters C<a>, C<m>, and C<v>.  A range of characters may be specified
-using C<->; for example, C<[0-5abc]> is equivalent to C<[012345abc]>.  The
-order of characters is as defined in the UTF-8 character set, and if the
-start character of such a range falls after the ending character of the
-range in that ranking the results of attempting a match with that pattern
-are undefined.
-
-In order to include a literal C<]> character in the set, it must be the
-first character of the set (possibly following C<^>); for example, C<[]a]>
-matches either C<]> or C<a>.  To include a literal C<-> character in the
-set, it must be either the first or the last character of the set.
-Backslashes have no special meaning inside a character set, nor do any
-other of the wildmat metacharacters.
-
-=item [^...]
-
-A negated character set.  Follows the same rules as a character set above,
-but matches any character B<not> contained in the set.  So, for example,
-C<[^]-]> matches any character except C<]> and C<->.
-
-=back
-
-In addition, C<!> (and possibly C<@>) have special meaning as the first
-character of a pattern; see below.
-
-When matching a wildmat expression against some text, each comma-separated
-pattern is matched in order from left to right.  In order to match, the
-pattern must match the whole text; in regular expression terminology, it's
-implicitly anchored at both the beginning and the end.  For example, the
-pattern C<a> matches only the text C<a>; it doesn't match C<ab> or C<ba>
-or even C<aa>.  If none of the patterns match, the whole expression
-doesn't match.  Otherwise, whether the expression matches is determined
-entirely by the rightmost matching pattern; the expression matches the
-text if and only if the rightmost matching pattern is not negated.
-
-For example, consider the text C<news.misc>.  The expression C<*> matches
-this text, of course, as does C<comp.*,news.*> (because the second pattern
-matches).  C<news.*,!news.misc> does not match this text because both
-patterns match, meaning that the rightmost takes precedence, and the
-rightmost matching pattern is negated.  C<news.*,!news.misc,*.misc> does
-match this text, since the rightmost matching pattern is not negated.
-
-Note that the expression C<!news.misc> can't match anything.  Either the
-pattern doesn't match, in which case no patterns match and the expression
-doesn't match, or the pattern does match, in which case because it's
-negated the expression doesn't match.  C<*,!news.misc>, on the other hand,
-is a useful pattern that matches anything except C<news.misc>.
-
-C<!> has significance only as the first character of a pattern; anywhere
-else in the pattern, it matches a literal C<!> in the text like any other
-non-metacharacter.
-
-If the B<uwildmat_poison> interface is used, then C<@> behaves the same as
-C<!> except that if an expression fails to match because the rightmost
-matching pattern began with C<@>, B<UWILDMAT_POISON> is returned instead of
-B<UWILDMAT_FAIL>.
-
-If the B<uwildmat_simple> interface is used, the matching rules are the
-same as above except that none of C<!>, C<@>, or C<,> have any special
-meaning at all and only match those literal characters.
-
-=head1 BUGS
-
-All of these functions internally convert the passed arguments to const
-unsigned char pointers.  The only reason why they take regular char
-pointers instead of unsigned char is for the convenience of INN and other
-callers that may not be using unsigned char everywhere they should.  In a
-future revision, the public interface should be changed to just take
-unsigned char pointers.
-
-=head1 HISTORY
-
-Written by Rich $alz <rsalz@uunet.uu.net> in 1986, and posted to Usenet
-several times since then, most notably in comp.sources.misc in
-March, 1991.
-
-Lars Mathiesen <thorinn@diku.dk> enhanced the multi-asterisk failure
-mode in early 1991.
-
-Rich and Lars increased the efficiency of star patterns and reposted it to
-comp.sources.misc in April, 1991.
-
-Robert Elz <kre@munnari.oz.au> added minus sign and close bracket handling
-in June, 1991.
-
-Russ Allbery <rra@stanford.edu> added support for comma-separated patterns
-and the C<!> and C<@> metacharacters to the core wildmat routines in July,
-2000.  He also added support for UTF-8 characters, changed the default
-behavior to assume that both the text and the pattern are in UTF-8, and
-largely rewrote this documentation to expand and clarify the description
-of how a wildmat expression matches.
-
-Please note that the interfaces to these functions are named B<uwildmat>
-and the like rather than B<wildmat> to distinguish them from the
-B<wildmat> function provided by Rich $alz's original implementation.
-While this code is heavily based on Rich's original code, it has
-substantial differences, including the extension to support UTF-8
-characters, and has noticable functionality changes.  Any bugs present in
-it aren't Rich's fault.
-
-$Id: uwildmat.pod 5533 2002-08-10 18:51:37Z rra $
-
-=head1 SEE ALSO
-
-grep(1), fnmatch(3), regex(3), regexp(3).
-
-=cut
diff --git a/doc/sample-control b/doc/sample-control
deleted file mode 100644 (file)
index 5caafb4..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Path: bounce-back
-From: group-admin@isc.org (David C Lawrence)
-Newsgroups: news.announce.newusers
-Subject: cmsg newgroup news.announce.newusers moderated
-Control: newgroup news.announce.newusers moderated
-Approved: newgroups-request@isc.org
-Message-ID: <868485430.2655@isc.org>
-Date: Wed, 09 Jul 1997 21:57:10 GMT
-Lines: 8
-X-Info: ftp://ftp.isc.org/pub/pgpcontrol/README.html
-       ftp://ftp.isc.org/pub/pgpcontrol/README
-X-PGP-Sig: 2.6.2 Subject,Control,Message-ID,Date,From,Sender
-       iQCVAwUBM8QJNsJdOtO4janBAQGkUAP6AlzO065jDQFrG20/b3/SaOm4WGQBly5D
-       pXlVJdYBqPAG3HvxVqAdKM7y6ixM7Mml4OdfK0JeVCH03nqeGuBc51sTDIZ6kyAx
-       +YHlNSnp/JJnpDuJCfXZjwNl4kWImucGgwI5BxrQco8re949Cg5m5TFXiwYMiR/+
-       AjKZCTtmV1Y=
-       =uSbd
-
-news.announce.newusers is a moderated newsgroup which has existed
-since the mid-1980s.
-
-Group submission address:  netannounce@deshaw.com
-Moderator contact address: netannounce@deshaw.com (Mark Moraes)
-
-For your newsgroups file:
-news.announce.newusers Explanatory postings for new users. (Moderated)
diff --git a/expire/Makefile b/expire/Makefile
deleted file mode 100644 (file)
index a2cb05d..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top           = ..
-CFLAGS        = $(GCFLAGS)
-
-ALL           = convdate expire expireover expirerm fastrm grephistory \
-               makedbz makehistory prunehistory
-
-SOURCES       = convdate.c expire.c expireover.c fastrm.c grephistory.c \
-               makedbz.c makehistory.c prunehistory.c
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       for F in convdate fastrm grephistory ; do \
-           $(LI_XPUB) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for F in expire expireover makedbz makehistory prunehistory ; do \
-           $(LI_XPRI) $$F $D$(PATHBIN)/$$F ; \
-       done
-       $(CP_XPRI) expirerm $D$(PATHBIN)/expirerm
-
-clean:
-       rm -f *.o $(ALL)
-       rm -f profiled expirep
-       rm -rf .libs
-
-clobber distclean: clean
-       rm -f tags
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES)
-
-
-##  Compilation rules.
-
-BOTH           = $(LIBHIST) $(LIBSTORAGE) $(LIBINN)
-
-LINK            = $(LIBLD) $(LDFLAGS) -o $@
-INNLIBS                = $(LIBINN) $(LIBS)
-STORELIBS      = $(BOTH) $(EXTSTORAGELIBS) $(LIBS)
-
-FIX             = $(FIXSCRIPT)
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-convdate:      convdate.o     $(LIBINN) ; $(LINK) convdate.o     $(INNLIBS)
-expire:                expire.o       $(BOTH)   ; $(LINK) expire.o       $(STORELIBS)
-expireover:    expireover.o   $(BOTH)   ; $(LINK) expireover.o   $(STORELIBS)
-fastrm:                fastrm.o       $(BOTH)   ; $(LINK) fastrm.o       $(STORELIBS)
-grephistory:   grephistory.o  $(BOTH)   ; $(LINK) grephistory.o  $(STORELIBS)
-makedbz:       makedbz.o      $(LIBINN) ; $(LINK) makedbz.o      $(INNLIBS)
-makehistory:   makehistory.o  $(BOTH)   ; $(LINK) makehistory.o  $(STORELIBS)
-prunehistory:  prunehistory.o $(BOTH)   ; $(LINK) prunehistory.o $(STORELIBS)
-
-expirerm:      expirerm.in    $(FIX)    ; $(FIX) expirerm.in
-
-$(LIBINN):     ; (cd ../lib ; $(MAKE))
-$(LIBSTORAGE): ; (cd ../storage ; $(MAKE))
-$(LIBHIST):    ; (cd ../history ; $(MAKE))
-
-
-##  Profiling.  These rules have not been checked for a while and may need
-##  some work.
-
-profiled:      expirep 
-       date >$@
-
-expirep:       expire.c
-       rm -f expire.o
-       $(MAKEPROFILING) expire
-       mv expire expirep
-       rm -f expire.o
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend:        Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-convdate.o: convdate.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h
-expire.o: expire.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/history.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h \
-  ../include/inndcomm.h ../include/libinn.h ../include/paths.h \
-  ../include/storage.h
-expireover.o: expireover.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ../include/paths.h ../include/storage.h
-fastrm.o: fastrm.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/storage.h
-grephistory.o: grephistory.c ../include/clibrary.h ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h \
-  ../include/inn/history.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h ../include/libinn.h \
-  ../include/paths.h ../include/storage.h
-makedbz.o: makedbz.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/dbz.h ../include/libinn.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/messages.h ../include/inn/qio.h \
-  ../include/libinn.h ../include/paths.h ../include/storage.h
-makehistory.o: makehistory.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/wait.h ../include/config.h ../include/inn/buffer.h \
-  ../include/inn/defines.h ../include/inn/history.h \
-  ../include/inn/innconf.h ../include/inn/messages.h ../include/inn/qio.h \
-  ../include/inn/wire.h ../include/libinn.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ../include/paths.h \
-  ../include/storage.h
-prunehistory.o: prunehistory.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/history.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h ../include/libinn.h \
-  ../include/paths.h
diff --git a/expire/convdate.c b/expire/convdate.c
deleted file mode 100644 (file)
index d508bb8..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*  $Id: convdate.c 6372 2003-05-31 19:48:28Z rra $
-**
-**  Convert date strings and numbers to numbers and strings.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <time.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-static const char usage[] = "\
-Usage: convdate -n [date ...]\n\
-       convdate [-dl] -c [time ...]\n\
-       convdate [-dl] [-s] [date ...]\n\
-\n\
-convdate -n converts a date (in any format parseable by parsedate) to the\n\
-number of seconds since epoch.  convdate -s does the same, but converts\n\
-to a date string.  convdate -c converts seconds since epoch to a date\n\
-string.  The default output is the output of ctime (normally the same format\n\
-as returned by the date command).  If -d is given, the output is formatted\n\
-as a valid Usenet article Date header.  If -l is given with -d, format the\n\
-time in local time rather than UTC.  If no options are given, the -s\n\
-behavior is the default; if no dates are given, the current time is used.\n";
-
-/* Whether to format the output as a Date header. */
-static bool date_format = false;
-
-/* Whether to use local time instead of UTC. */
-static bool date_local = false;
-
-
-/*
-**  Return true if the given string is entirely digits.
-*/
-static bool
-isdigits(const char *p)
-{
-    for (; *p; p++)
-        if (!CTYPE(isdigit, *p))
-            return false;
-    return true;
-}
-
-
-/*
-**  Print date corresponding to the provided time_t.  By default, the output
-**  of ctime is printed, but if date_format is true, makedate is used
-**  instead.  If date_local is true, format in local time; otherwise, use
-**  UTC.  Returns success.
-*/
-static bool
-print_date(time_t date)
-{
-    char date_buffer[128];
-    char *result;
-
-    if (date_format) {
-        if (!makedate(date, date_local, date_buffer, sizeof(date_buffer))) {
-            warn("can't format %ld", (long) date);
-            return false;
-        } else {
-            printf("%s\n", date_buffer);
-        }
-    } else {
-        result = ctime(&date);
-        if (result == NULL) {
-            warn("can't format %ld", (long) date);
-            return false;
-        } else {
-            printf("%s", result);
-        }
-    }
-    return true;
-}
-
-
-/*
-**  The core function.  Given a string representing a date (in some format
-**  given by the mode) and a mode ('s', 'n', or 'c', corresponding to the
-**  basic three options to the program), convert the date and print the
-**  output.  date may be NULL, in which case the current date is used.
-**  Returns true if conversion was successful, false otherwise.
-*/
-static bool
-convdate(const char *date, char mode)
-{
-    time_t seconds;
-
-    /* Convert the given date to seconds or obtain the current time. */
-    if (date == NULL) {
-        seconds = time(NULL);
-    } else if (mode == 'c') {
-        if (!isdigits(date)) {
-            warn("\"%s\" doesn't look like a number", date);
-            return false;
-        } else {
-            seconds = (time_t) atol(date);
-        }
-    } else {
-        seconds = parsedate((char *) date, NULL);
-        if (seconds == (time_t) -1) {
-            warn("can't convert \"%s\"", date);
-            return false;
-        }
-    }
-
-    /* Output the resulting date. */
-    if (mode == 'n') {
-        printf("%ld\n", (long) seconds);
-        return true;
-    } else {
-        return print_date(seconds);
-    }
-}
-
-
-int
-main(int argc, char *argv[])
-{
-    int option, status;
-    char *date;
-    char mode = '\0';
-
-    message_program_name = "convdate";
-
-    /* Parse options. */
-    while ((option = getopt(argc, argv, "cdhlns")) != EOF) {
-        switch (option) {
-        case 'h':
-            printf("%s\n", usage);
-            exit(0);
-            break;
-        case 'd':
-            date_format = true;
-            break;
-        case 'l':
-            date_local = true;
-            break;
-        case 'c':
-        case 'n':
-        case 's':
-            if (mode != 0) die("only one of -c, -n, or -s is allowed");
-            mode = option;
-            break;
-        default:
-            fprintf(stderr, "%s", usage);
-            exit(1);
-            break;
-        }
-    }
-    if (mode == '\0')
-        mode = 's';
-    argc -= optind;
-    argv += optind;
-
-    /* Perform the desired action for each provided argument. */
-    if (argc == 0) {
-        exit(convdate(NULL, mode) ? 0 : 1);
-    } else {
-        for (date = *argv, status = 0; date != NULL; date = *++argv)
-            status += (convdate(date, mode) ? 0 : 1);
-        exit(status);
-    }
-}
diff --git a/expire/expire.c b/expire/expire.c
deleted file mode 100644 (file)
index 108ce1f..0000000
+++ /dev/null
@@ -1,727 +0,0 @@
-/*  $Id: expire.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Expire news articles.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <pwd.h>
-#include <sys/stat.h>
-#include <syslog.h>
-#include <time.h>
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inndcomm.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-
-typedef struct _EXPIRECLASS {
-    time_t              Keep;
-    time_t              Default;
-    time_t              Purge;
-    bool                Missing;
-    bool                ReportedMissing;
-} EXPIRECLASS;
-
-/*
-**  Expire-specific stuff.
-*/
-#define MAGIC_TIME     49710.
-
-static bool            EXPtracing;
-static bool            EXPusepost;
-static bool            Ignoreselfexpire = false;
-static FILE            *EXPunlinkfile;
-static EXPIRECLASS      EXPclasses[NUM_STORAGE_CLASSES+1];
-static char            *EXPreason;
-static time_t          EXPremember;
-static time_t          Now;
-static time_t          RealNow;
-
-/* Statistics; for -v flag. */
-static char            *EXPgraph;
-static int             EXPverbose;
-static long            EXPprocessed;
-static long            EXPunlinked;
-static long            EXPallgone;
-static long            EXPstillhere;
-static struct history  *History;
-static char            *NHistory;
-
-static void CleanupAndExit(bool Server, bool Paused, int x);
-
-static int EXPsplit(char *p, char sep, char **argv, int count);
-
-enum KR {Keep, Remove};
-
-\f
-
-/*
-**  Open a file or give up.
-*/
-static FILE *
-EXPfopen(bool Unlink, const char *Name, const char *Mode, bool Needclean,
-        bool Server, bool Paused)
-{
-    FILE *F;
-
-    if (Unlink && unlink(Name) < 0 && errno != ENOENT)
-        syswarn("cannot remove %s", Name);
-    if ((F = fopen(Name, Mode)) == NULL) {
-        syswarn("cannot open %s in %s mode", Name, Mode);
-       if (Needclean)
-           CleanupAndExit(Server, Paused, 1);
-       else
-           exit(1);
-    }
-    return F;
-}
-
-
-/*
-**  Split a line at a specified field separator into a vector and return
-**  the number of fields found, or -1 on error.
-*/
-static int EXPsplit(char *p, char sep, char **argv, int count)
-{
-    int                        i;
-
-    if (!p)
-      return 0;
-
-    while (*p == sep)
-      ++p;
-
-    if (!*p)
-      return 0;
-
-    if (!p)
-      return 0;
-
-    while (*p == sep)
-      ++p;
-
-    if (!*p)
-      return 0;
-
-    for (i = 1, *argv++ = p; *p; )
-       if (*p++ == sep) {
-           p[-1] = '\0';
-           for (; *p == sep; p++)
-               ;
-           if (!*p)
-               return i;
-           if (++i == count)
-               /* Overflow. */
-               return -1;
-           *argv++ = p;
-       }
-    return i;
-}
-
-
-/*
-**  Parse a number field converting it into a "when did this start?".
-**  This makes the "keep it" tests fast, but inverts the logic of
-**  just about everything you expect.  Print a message and return false
-**  on error.
-*/
-static bool EXPgetnum(int line, char *word, time_t *v, const char *name)
-{
-    char               *p;
-    bool               SawDot;
-    double             d;
-
-    if (strcasecmp(word, "never") == 0) {
-       *v = (time_t)0;
-       return true;
-    }
-
-    /* Check the number.  We don't have strtod yet. */
-    for (p = word; ISWHITE(*p); p++)
-       ;
-    if (*p == '+' || *p == '-')
-       p++;
-    for (SawDot = false; *p; p++)
-       if (*p == '.') {
-           if (SawDot)
-               break;
-           SawDot = true;
-       }
-       else if (!CTYPE(isdigit, (int)*p))
-           break;
-    if (*p) {
-        warn("bad '%c' character in %s field on line %d", *p, name, line);
-       return false;
-    }
-    d = atof(word);
-    if (d > MAGIC_TIME)
-       *v = (time_t)0;
-    else
-       *v = Now - (time_t)(d * 86400.);
-    return true;
-}
-
-
-/*
-**  Parse the expiration control file.  Return true if okay.
-*/
-static bool EXPreadfile(FILE *F)
-{
-    char               *p;
-    int                        i;
-    int                        j;
-    bool               SawDefault;
-    char               buff[BUFSIZ];
-    char               *fields[7];
-
-    /* Scan all lines. */
-    EXPremember = -1;
-    SawDefault = false;
-
-    for (i = 0; i <= NUM_STORAGE_CLASSES; i++) {
-       EXPclasses[i].ReportedMissing = false;
-        EXPclasses[i].Missing = true;
-    }
-    
-    for (i = 1; fgets(buff, sizeof buff, F) != NULL; i++) {
-       if ((p = strchr(buff, '\n')) == NULL) {
-            warn("line %d too long", i);
-           return false;
-       }
-       *p = '\0';
-        p = strchr(buff, '#');
-       if (p)
-           *p = '\0';
-       else
-           p = buff + strlen(buff);
-       while (--p >= buff) {
-           if (isspace((int)*p))
-                *p = '\0';
-            else
-                break;
-        }
-        if (buff[0] == '\0')
-           continue;
-       if ((j = EXPsplit(buff, ':', fields, ARRAY_SIZE(fields))) == -1) {
-            warn("too many fields on line %d", i);
-           return false;
-       }
-
-       /* Expired-article remember line? */
-       if (strcmp(fields[0], "/remember/") == 0) {
-           if (j != 2) {
-                warn("invalid format on line %d", i);
-               return false;
-           }
-           if (EXPremember != -1) {
-                warn("duplicate /remember/ on line %d", i);
-               return false;
-           }
-           if (!EXPgetnum(i, fields[1], &EXPremember, "remember"))
-               return false;
-           continue;
-       }
-
-       /* Storage class line? */
-       if (j == 4) {
-            /* Is this the default line? */
-            if (fields[0][0] == '*' && fields[0][1] == '\0') {
-                if (SawDefault) {
-                    warn("duplicate default on line %d", i);
-                    return false;
-                }
-                j = NUM_STORAGE_CLASSES;
-                SawDefault = true;
-            } else {
-                j = atoi(fields[0]);
-                if ((j < 0) || (j >= NUM_STORAGE_CLASSES))
-                    warn("bad storage class %d on line %d", j, i);
-            }
-       
-           if (!EXPgetnum(i, fields[1], &EXPclasses[j].Keep,    "keep")
-               || !EXPgetnum(i, fields[2], &EXPclasses[j].Default, "default")
-               || !EXPgetnum(i, fields[3], &EXPclasses[j].Purge,   "purge"))
-               return false;
-           /* These were turned into offsets, so the test is the opposite
-            * of what you think it should be.  If Purge isn't forever,
-            * make sure it's greater then the other two fields. */
-           if (EXPclasses[j].Purge) {
-               /* Some value not forever; make sure other values are in range. */
-               if (EXPclasses[j].Keep && EXPclasses[j].Keep < EXPclasses[j].Purge) {
-                    warn("keep time longer than purge time on line %d", i);
-                   return false;
-               }
-               if (EXPclasses[j].Default && EXPclasses[j].Default < EXPclasses[j].Purge) {
-                    warn("default time longer than purge time on line %d", i);
-                   return false;
-               }
-           }
-           EXPclasses[j].Missing = false;
-           continue;
-       }
-
-       /* Regular expiration line -- right number of fields? */
-       if (j != 5) {
-            warn("bad format on line %d", i);
-           return false;
-       }
-       continue; /* don't process this line--per-group expiry is done by expireover */
-    }
-
-    return true;
-}
-
-/*
-**  Should we keep the specified article?
-*/
-static enum KR EXPkeepit(const TOKEN *token, time_t when, time_t Expires)
-{
-    EXPIRECLASS         class;
-
-    class = EXPclasses[token->class];
-    if (class.Missing) {
-        if (EXPclasses[NUM_STORAGE_CLASSES].Missing) {
-            /* no default */
-            if (!class.ReportedMissing) {
-                warn("class definition for %d missing from control file,"
-                     " assuming it should never expire", token->class);
-                EXPclasses[token->class].ReportedMissing = true;
-            }
-            return Keep;
-        } else {
-            /* use the default */
-            class = EXPclasses[NUM_STORAGE_CLASSES];
-            EXPclasses[token->class] = class;
-        }
-    }
-    /* Bad posting date? */
-    if (when > (RealNow + 86400)) {
-       /* Yes -- force the article to go to right now */
-       when = Expires ? class.Purge : class.Default;
-    }
-    if (EXPverbose > 2) {
-       if (EXPverbose > 3)
-           printf("%s age = %0.2f\n", TokenToText(*token), (Now - when) / 86400.);
-       if (Expires == 0) {
-           if (when <= class.Default)
-               printf("%s too old (no exp)\n", TokenToText(*token));
-       } else {
-           if (when <= class.Purge)
-               printf("%s later than purge\n", TokenToText(*token));
-           if (when >= class.Keep)
-               printf("%s earlier than min\n", TokenToText(*token));
-           if (Now >= Expires)
-               printf("%s later than header\n", TokenToText(*token));
-       }
-    }
-    
-    /* If no expiration, make sure it wasn't posted before the default. */
-    if (Expires == 0) {
-       if (when >= class.Default)
-           return Keep;
-       
-       /* Make sure it's not posted before the purge cut-off and
-        * that it's not due to expire. */
-    } else {
-       if (when >= class.Purge && (Expires >= Now || when >= class.Keep))
-           return Keep;
-    }
-    return Remove;
-
-}
-
-
-/*
-**  An article can be removed.  Either print a note, or actually remove it.
-**  Also fill in the article size.
-*/
-static void
-EXPremove(const TOKEN *token)
-{
-    /* Turn into a filename and get the size if we need it. */
-    if (EXPverbose > 1)
-       printf("\tunlink %s\n", TokenToText(*token));
-
-    if (EXPtracing) {
-       EXPunlinked++;
-       printf("%s\n", TokenToText(*token));
-       return;
-    }
-    
-    EXPunlinked++;
-    if (EXPunlinkfile) {
-       fprintf(EXPunlinkfile, "%s\n", TokenToText(*token));
-       if (!ferror(EXPunlinkfile))
-           return;
-        syswarn("cannot write to -z file (will ignore it for rest of run)");
-       fclose(EXPunlinkfile);
-       EXPunlinkfile = NULL;
-    }
-    if (!SMcancel(*token) && SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT)
-        warn("cannot unlink %s", TokenToText(*token));
-}
-
-/*
-**  Do the work of expiring one line.
-*/
-static bool
-EXPdoline(void *cookie UNUSED, time_t arrived, time_t posted, time_t expires,
-         TOKEN *token)
-{
-    time_t             when;
-    bool               HasSelfexpire = false;
-    bool               Selfexpired = false;
-    ARTHANDLE          *article;
-    enum KR             kr;
-    bool               r;
-
-    if (innconf->groupbaseexpiry || SMprobe(SELFEXPIRE, token, NULL)) {
-       if ((article = SMretrieve(*token, RETR_STAT)) == (ARTHANDLE *)NULL) {
-           HasSelfexpire = true;
-           Selfexpired = true;
-       } else {
-           /* the article is still alive */
-           SMfreearticle(article);
-           if (innconf->groupbaseexpiry || !Ignoreselfexpire)
-               HasSelfexpire = true;
-       }
-    }
-    if (EXPusepost && posted != 0)
-       when = posted;
-    else
-       when = arrived;
-    EXPprocessed++;
-       
-    if (HasSelfexpire) {
-       if (Selfexpired || token->type == TOKEN_EMPTY) {
-           EXPallgone++;
-           r = false;
-       } else {
-           EXPstillhere++;
-           r = true;
-       }
-    } else  {
-       kr = EXPkeepit(token, when, expires);
-       if (kr == Remove) {
-           EXPremove(token);
-           EXPallgone++;
-           r = false;
-       } else {
-           EXPstillhere++;
-           r = true;
-       }
-    }
-
-    return r;
-}
-
-\f
-
-/*
-**  Clean up link with the server and exit.
-*/
-static void
-CleanupAndExit(bool Server, bool Paused, int x)
-{
-    FILE       *F;
-
-    if (Server) {
-       ICCreserve("");
-       if (Paused && ICCgo(EXPreason) != 0) {
-            syswarn("cannot unpause server");
-           x = 1;
-       }
-    }
-    if (Server && ICCclose() < 0) {
-        syswarn("cannot close communication link to server");
-       x = 1;
-    }
-    if (EXPunlinkfile && fclose(EXPunlinkfile) == EOF) {
-        syswarn("cannot close -z file");
-       x = 1;
-    }
-
-    /* Report stats. */
-    if (EXPverbose) {
-       printf("Article lines processed %8ld\n", EXPprocessed);
-       printf("Articles retained       %8ld\n", EXPstillhere);
-       printf("Entries expired         %8ld\n", EXPallgone);
-       if (!innconf->groupbaseexpiry)
-           printf("Articles dropped        %8ld\n", EXPunlinked);
-    }
-
-    /* Append statistics to a summary file */
-    if (EXPgraph) {
-       F = EXPfopen(false, EXPgraph, "a", false, false, false);
-       fprintf(F, "%ld %ld %ld %ld %ld\n",
-                     (long)Now, EXPprocessed, EXPstillhere, EXPallgone,
-                     EXPunlinked);
-       fclose(F);
-    }
-
-    SMshutdown();
-    HISclose(History);
-    if (EXPreason != NULL)
-       free(EXPreason);
-       
-    if (NHistory != NULL)
-       free(NHistory);
-    closelog();
-    exit(x);
-}
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: expire [flags] [expire.ctl]\n");
-    exit(1);
-}
-
-
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    int                 i;
-    char               *p;
-    FILE               *F;
-    char               *HistoryText;
-    const char         *NHistoryPath = NULL;
-    const char         *NHistoryText = NULL;
-    char               *EXPhistdir;
-    char               buff[SMBUF];
-    bool               Server;
-    bool               Bad;
-    bool               IgnoreOld;
-    bool               Writing;
-    bool               UnlinkFile;
-    bool               val;
-    time_t             TimeWarp;
-    size_t              Size = 0;
-
-    /* First thing, set up logging and our identity. */
-    openlog("expire", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "expire";
-
-    /* Set defaults. */
-    Server = true;
-    IgnoreOld = false;
-    Writing = true;
-    TimeWarp = 0;
-    UnlinkFile = false;
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    HistoryText = concatpath(innconf->pathdb, _PATH_HISTORY);
-
-    umask(NEWSUMASK);
-
-    /* find the default history file directory */
-    EXPhistdir = xstrdup(HistoryText);
-    p = strrchr(EXPhistdir, '/');
-    if (p != NULL) {
-       *p = '\0';
-    }
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "f:h:d:g:iNnpr:s:tv:w:xz:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'd':
-           NHistoryPath = optarg;
-           break;
-       case 'f':
-           NHistoryText = optarg;
-           break;
-       case 'g':
-           EXPgraph = optarg;
-           break;
-       case 'h':
-           HistoryText = optarg;
-           break;
-       case 'i':
-           IgnoreOld = true;
-           break;
-       case 'N':
-           Ignoreselfexpire = true;
-           break;
-       case 'n':
-           Server = false;
-           break;
-       case 'p':
-           EXPusepost = true;
-           break;
-       case 'r':
-           EXPreason = xstrdup(optarg);
-           break;
-       case 's':
-           Size = atoi(optarg);
-           break;
-       case 't':
-           EXPtracing = true;
-           break;
-       case 'v':
-           EXPverbose = atoi(optarg);
-           break;
-       case 'w':
-           TimeWarp = (time_t)(atof(optarg) * 86400.);
-           break;
-       case 'x':
-           Writing = false;
-           break;
-       case 'z':
-           EXPunlinkfile = EXPfopen(true, optarg, "a", false, false, false);
-           UnlinkFile = true;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if ((ac != 0 && ac != 1))
-       Usage();
-
-    /* if EXPtracing is set, then pass in a path, this ensures we
-     * don't replace the existing history files */
-    if (EXPtracing || NHistoryText || NHistoryPath) {
-       if (NHistoryPath == NULL)
-           NHistoryPath = innconf->pathdb;
-       if (NHistoryText == NULL)
-           NHistoryText = _PATH_HISTORY;
-       NHistory = concatpath(NHistoryPath, NHistoryText);
-    }
-    else {
-       NHistory = NULL;
-    }
-
-    time(&Now);
-    RealNow = Now;
-    Now += TimeWarp;
-
-    /* Change users if necessary. */
-    setuid_news();
-
-    /* Parse the control file. */
-    if (av[0]) {
-        if (strcmp(av[0], "-") == 0)
-            F = stdin;
-        else
-            F = EXPfopen(false, av[0], "r", false, false, false);
-    } else {
-        char *path;
-
-        path = concatpath(innconf->pathetc, _PATH_EXPIRECTL);
-       F = EXPfopen(false, path, "r", false, false, false);
-        free(path);
-    }
-    if (!EXPreadfile(F)) {
-       fclose(F);
-        die("format error in expire.ctl");
-    }
-    fclose(F);
-
-    /* Set up the link, reserve the lock. */
-    if (Server) {
-       if (EXPreason == NULL) {
-           snprintf(buff, sizeof(buff), "Expiring process %ld",
-                     (long) getpid());
-           EXPreason = xstrdup(buff);
-       }
-    }
-    else {
-       EXPreason = NULL;
-    }
-
-    if (Server) {
-       /* If we fail, leave evidence behind. */
-       if (ICCopen() < 0) {
-            syswarn("cannot open channel to server");
-           CleanupAndExit(false, false, 1);
-       }
-       if (ICCreserve((char *)EXPreason) != 0) {
-            warn("cannot reserve server");
-           CleanupAndExit(false, false, 1);
-       }
-    }
-
-    History = HISopen(HistoryText, innconf->hismethod, HIS_RDONLY);
-    if (!History) {
-        warn("cannot open history");
-       CleanupAndExit(Server, false, 1);
-    }
-
-    /* Ignore failure on the HISctl()s, if the underlying history
-     * manager doesn't implement them its not a disaster */
-    HISctl(History, HISCTLS_IGNOREOLD, &IgnoreOld);
-    if (Size != 0) {
-       HISctl(History, HISCTLS_NPAIRS, &Size);
-    }
-
-    val = true;
-    if (!SMsetup(SM_RDWR, (void *)&val) || !SMsetup(SM_PREOPEN, (void *)&val)) {
-        warn("cannot set up storage manager");
-       CleanupAndExit(Server, false, 1);
-    }
-    if (!SMinit()) {
-        warn("cannot initialize storage manager: %s", SMerrorstr);
-       CleanupAndExit(Server, false, 1);
-    }
-    if (chdir(EXPhistdir) < 0) {
-        syswarn("cannot chdir to %s", EXPhistdir);
-       CleanupAndExit(Server, false, 1);
-    }
-
-    Bad = HISexpire(History, NHistory, EXPreason, Writing, NULL,
-                   EXPremember, EXPdoline) == false;
-
-    if (UnlinkFile && EXPunlinkfile == NULL)
-       /* Got -z but file was closed; oops. */
-       Bad = true;
-
-    /* If we're done okay, and we're not tracing, slip in the new files. */
-    if (EXPverbose) {
-       if (Bad)
-           printf("Expire errors: history files not updated.\n");
-       if (EXPtracing)
-           printf("Expire tracing: history files not updated.\n");
-    }
-
-    if (!Bad && NHistory != NULL) {
-       snprintf(buff, sizeof(buff), "%s.n.done", NHistory);
-       fclose(EXPfopen(false, buff, "w", true, Server, false));
-       CleanupAndExit(Server, false, Bad ? 1 : 0);
-    }
-
-    CleanupAndExit(Server, !Bad, Bad ? 1 : 0);
-    /* NOTREACHED */
-    abort();
-}
diff --git a/expire/expireover.c b/expire/expireover.c
deleted file mode 100644 (file)
index 57e0cdb..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*  $Id: expireover.c 6708 2004-05-16 19:59:26Z rra $
-**
-**  Expire the overview database.
-**
-**  This program handles the nightly expiration of overview information.  If
-**  groupbaseexpiry is true, this program also handles the removal of
-**  articles that have expired.  It's separate from the process that scans
-**  and expires the history file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <syslog.h>
-#include <time.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-#include "storage.h"
-
-static const char usage[] = "\
-Usage: expireover [-ekNpqs] [-w offset] [-z rmfile] [-Z lowmarkfile]\n";
-
-/* Set to 1 if we've received a signal; expireover then terminates after
-   finishing the newsgroup that it's working on (this prevents corruption of
-   the overview by killing expireover). */
-static volatile sig_atomic_t signalled = 0;
-
-
-/*
-**  Handle a fatal signal and set signalled.  Restore the default signal
-**  behavior after receiving a signal so that repeating the signal will kill
-**  the program immediately.
-*/
-static RETSIGTYPE
-fatal_signal(int sig)
-{
-    signalled = 1;
-    xsignal(sig, SIG_DFL);
-}
-
-
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-int
-main(int argc, char *argv[])
-{
-    int option, low;
-    char *line, *p;
-    QIOSTATE *qp;
-    bool value;
-    OVGE ovge;
-    char *active_path = NULL;
-    char *lowmark_path = NULL;
-    char *path;
-    FILE *lowmark = NULL;
-    bool purge_deleted = false;
-    bool always_stat = false;
-    struct history *history;
-
-    /* First thing, set up logging and our identity. */
-    openlog("expireover", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "expireover";
-
-    /* Set up some default options for group-based expiration, although none
-       of these will be used if groupbaseexpiry isn't true. */
-    ovge.earliest = false;
-    ovge.keep = false;
-    ovge.ignoreselfexpire = false;
-    ovge.usepost = false;
-    ovge.quiet = false;
-    ovge.timewarp = 0;
-    ovge.filename = NULL;
-    ovge.delayrm = false;
-
-    /* Parse the command-line options. */
-    while ((option = getopt(argc, argv, "ef:kNpqsw:z:Z:")) != EOF) {
-        switch (option) {
-        case 'e':
-            ovge.earliest = true;
-            break;
-        case 'f':
-            active_path = xstrdup(optarg);
-            break;
-        case 'k':
-            ovge.keep = true;
-            break;
-        case 'N':
-            ovge.ignoreselfexpire = true;
-            break;
-        case 'p':
-            ovge.usepost = true;
-            break;
-        case 'q':
-            ovge.quiet = true;
-            break;
-        case 's':
-            always_stat = true;
-            break;
-        case 'w':
-            ovge.timewarp = (time_t) (atof(optarg) * 86400.);
-            break;
-        case 'z':
-            ovge.filename = optarg;
-            ovge.delayrm = true;
-            break;
-        case 'Z':
-            lowmark_path = optarg;
-            break;
-        default:
-            fprintf(stderr, "%s", usage);
-            exit(1);
-        }
-    }
-    if (ovge.earliest && ovge.keep)
-        die("-e and -k cannot be specified at the same time");
-
-    /* Initialize innconf. */
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Change to the news user if necessary. */
-    setuid_news();
-
-    /* Initialize the lowmark file, if one was requested. */
-    if (lowmark_path != NULL) {
-        if (unlink(lowmark_path) < 0 && errno != ENOENT)
-            syswarn("can't remove %s", lowmark_path);
-        lowmark = fopen(lowmark_path, "a");
-        if (lowmark == NULL)
-            sysdie("can't open %s", lowmark_path);
-    }
-
-    /* Set up the path to the list of newsgroups we're going to use and open
-       that file.  This could be stdin. */
-    if (active_path == NULL) {
-        active_path = concatpath(innconf->pathdb, _PATH_ACTIVE);
-        purge_deleted = true;
-    }
-    if (strcmp(active_path, "-") == 0) {
-        qp = QIOfdopen(fileno(stdin));
-        if (qp == NULL)
-            sysdie("can't reopen stdin");
-    } else {
-        qp = QIOopen(active_path);
-        if (qp == NULL)
-            sysdie("can't open active file (%s)", active_path);
-    }
-    free(active_path);
-
-    /* open up the history manager */
-    path = concatpath(innconf->pathdb, _PATH_HISTORY);
-    history = HISopen(path, innconf->hismethod, HIS_RDONLY);
-    free(path);
-
-    /* Initialize the storage manager.  We only need to initialize it in
-       read/write mode if we're not going to be writing a separate file for
-       the use of fastrm. */
-    if (!ovge.delayrm) {
-        value = true;
-        if (!SMsetup(SM_RDWR, &value))
-            die("can't setup storage manager read/write");
-    }
-    value = true;
-    if (!SMsetup(SM_PREOPEN, &value))
-        die("can't setup storage manager");
-    if (!SMinit())
-        die("can't initialize storage manager: %s", SMerrorstr);
-
-    /* Initialize and configure the overview subsystem. */
-    if (!OVopen(OV_READ | OV_WRITE))
-        die("can't open overview database");
-    if (innconf->groupbaseexpiry) {
-        time(&ovge.now);
-        if (!OVctl(OVGROUPBASEDEXPIRE, &ovge))
-            die("can't configure group-based expire");
-    }
-    if (!OVctl(OVSTATALL, &always_stat))
-        die("can't configure overview stat behavior");
-
-    /* We want to be careful about being interrupted from this point on, so
-       set up our signal handlers. */
-    xsignal(SIGTERM, fatal_signal);
-    xsignal(SIGINT, fatal_signal);
-    xsignal(SIGHUP, fatal_signal);
-
-    /* Loop through each line of the input file and process each group,
-       writing data to the lowmark file if desired. */
-    line = QIOread(qp);
-    while (line != NULL && !signalled) {
-        p = strchr(line, ' ');
-        if (p != NULL)
-            *p = '\0';
-        p = strchr(line, '\t');
-        if (p != NULL)
-            *p = '\0';
-        if (!OVexpiregroup(line, &low, history))
-            warn("can't expire %s", line);
-        else if (lowmark != NULL && low != 0)
-            fprintf(lowmark, "%s %u\n", line, low);
-        line = QIOread(qp);
-    }
-    if (signalled)
-        warn("received signal, exiting");
-
-    /* If desired, purge all deleted newsgroups. */
-    if (!signalled && purge_deleted)
-        if (!OVexpiregroup(NULL, NULL, history))
-            warn("can't expire deleted newsgroups");
-
-    /* Close everything down in an orderly fashion. */
-    QIOclose(qp);
-    OVclose();
-    SMshutdown();
-    HISclose(history);
-    if (lowmark != NULL)
-        if (fclose(lowmark) == EOF)
-            syswarn("can't close %s", lowmark_path);
-
-    return 0;
-}
diff --git a/expire/expirerm.in b/expire/expirerm.in
deleted file mode 100644 (file)
index 4757ef2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  Remove articles listed by expire -z.
-##  Remove all files specified in the input file.
-
-MAIL="${MAILCMD} -s 'Problem removing expired files' ${NEWSMASTER}"
-
-#RMPROC="xargs rm"
-RMPROC="fastrm -e ${SPOOL}"
-
-if [ -z "$1" ] ; then
-    echo "Expire called with zero list of files on `hostname`" \
-  | eval ${MAIL}
-    exit 0
-fi
-if [ ! -f $1 ] ; then
-    echo "Expire called with no files to expire on `hostname`" \
-  | eval ${MAIL}
-    exit 0
-fi
-
-eval "cd ${SPOOL} \
-    && ${RMPROC} <$1 \
-    && mv $1 ${MOST_LOGS}/expire.list"
-if [ -f $1 ] ; then
-    echo "Expire had problems removing articles on `hostname`" \
-       | eval ${MAIL}
-    exit 1
-fi
diff --git a/expire/fastrm.c b/expire/fastrm.c
deleted file mode 100644 (file)
index bd2144a..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/*  $Id: fastrm.c 6155 2003-01-19 19:58:25Z rra $
-**
-**  Delete a list of filenames or tokens from stdin.
-**
-**  Originally written by <kre@munnari.oz.au> (to only handle files)
-**
-**  Files that can't be unlinked because they didn't exist are considered
-**  okay.  Any error condition results in exiting with non-zero exit
-**  status.  Input lines in the form @...@ are taken to be storage API
-**  tokens.  Input filenames should be fully qualified.  For maximum
-**  efficiency, input filenames should be sorted; fastrm will cd into each
-**  directory to avoid additional directory lookups when removing a lot of
-**  files in a single directory.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "storage.h"
-
-/* We reject any path names longer than this. */
-#define MAX_DIR_LEN 2048
-
-/* Data structure for a list of files in a single directory. */
-typedef struct filelist {
-    int count;
-    int size;
-    char *dir;
-    char **files;
-} filelist;
-
-/* All relative paths are relative to this directory. */
-static char *base_dir = NULL;
-
-/* The absolute path of the current working directory. */
-static char current_dir[MAX_DIR_LEN];
-
-/* The prefix for the files that we're currently working with.  We sometimes
-   also use this as working space for forming file names to remove, so give
-   ourselves a bit of additional leeway just in case. */
-static char prefix_dir[MAX_DIR_LEN * 2];
-static int prefix_len;
-
-/* Some threshold values that govern the optimizations that we are willing
-   to perform.  chdir_threshold determines how many files to be removed we
-   want in a directory before we chdir to that directory.  sort_threshold
-   determines how many files must be in a directory before we use readdir to
-   remove them in order.  relative_threshold determines how many levels of
-   "../" we're willing to try to use to move to the next directory rather
-   than just calling chdir with the new absolute path. */
-static int chdir_threshold = 3;
-static int relative_threshold = 0;
-static int sort_threshold = 0;
-
-/* True if we should only print what we would do, not actually do it. */
-static bool debug_only = false;
-
-/* A string used for constructing relative paths. */
-static const char dotdots[] = "../../../../";
-
-/* The number of errors encountered, used to determine exit status. */
-static int error_count = 0;
-
-/* Whether the storage manager has been initialized. */
-static bool sm_initialized = false;
-
-/* True if unlink may be able to remove directories. */
-static bool unlink_dangerous = false;
-
-
-
-/*
-**  Sorting predicate for qsort and bsearch.
-*/
-static int
-file_compare(const void *a, const void *b)
-{
-    const char *f1, *f2;
-
-    f1 = *((const char **) a);
-    f2 = *((const char **) b);
-    return strcmp(f1, f2);
-}
-
-
-/*
-**  Create a new filelist.
-*/
-static filelist *
-filelist_new(char *dir)
-{
-    filelist *new;
-
-    new = xmalloc(sizeof(filelist));
-    new->count = 0;
-    new->size = 0;
-    new->dir = dir;
-    new->files = NULL;
-    return new;
-}
-
-
-/*
-**  Insert a file name into a list of files (unsorted).
-*/
-static void
-filelist_insert(filelist *list, char *name)
-{
-    if (list->count == list->size) {
-        list->size = (list->size == 0) ? 16 : list->size * 2;
-        list->files = xrealloc(list->files, list->size * sizeof(char *));
-    }
-    list->files[list->count++] = xstrdup(name);
-}
-
-
-/*
-**  Find a file name in a sorted list of files.
-*/
-static char *
-filelist_lookup(filelist *list, const char *name)
-{
-    char **p;
-
-    p = bsearch(&name, list->files, list->count, sizeof(char *),
-                file_compare);
-    return (p == NULL ? NULL : *p);
-}
-
-
-/*
-**  Empty a list of files, freeing all of the names but keeping the
-**  structure intact.
-*/
-static void
-filelist_empty(filelist *list)
-{
-    int i;
-
-    for (i = 0; i < list->count; i++)
-        free(list->files[i]);
-    list->count = 0;
-}
-
-
-/*
-**  Free a list of files.
-*/
-static void
-filelist_free(filelist *list)
-{
-    filelist_empty(list);
-    if (list->files != NULL)
-        free(list->files);
-    if (list->dir != NULL)
-        free(list->dir);
-    free(list);
-}
-
-
-/*
-**  Exit handler for die.  Shut down the storage manager before exiting.
-*/
-static int
-sm_cleanup(void)
-{
-    SMshutdown();
-    return 1;
-}
-
-
-/*
-**  Initialize the storage manager.  This includes parsing inn.conf, which
-**  fastrm doesn't need for any other purpose.
-*/
-static void
-sm_initialize(void)
-{
-    bool value;
-
-    if (!innconf_read(NULL))
-        exit(1);
-    value = true;
-    if (!SMsetup(SM_RDWR, &value) || !SMsetup(SM_PREOPEN, &value))
-        die("can't set up storage manager");
-    if (!SMinit())
-        die("can't initialize storage manager: %s", SMerrorstr);
-    sm_initialized = true;
-    message_fatal_cleanup = sm_cleanup;
-}
-
-
-/*
-**  Get a line from a given QIO stream, returning a pointer to it.  Warn
-**  about and then skip lines that are too long.  Returns NULL at EOF or on
-**  an error.
-*/
-static char *
-get_line(QIOSTATE *qp)
-{
-    static int count;
-    char *p;
-
-    p = QIOread(qp);
-    count++;
-    while (QIOtoolong(qp) || (p != NULL && strlen(p) >= MAX_DIR_LEN)) {
-        warn("line %d too long", count);
-        error_count++;
-        while (p == NULL && QIOtoolong(qp))
-            p = QIOread(qp);
-        p = QIOread(qp);
-    }
-    if (p == NULL) {
-        if (QIOerror(qp)) {
-            syswarn("read error");
-            error_count++;
-        }
-        return NULL;
-    }
-    return p;
-}
-
-
-/*
-**  Read lines from stdin (including the first that may have been there
-**  from our last time in) until we reach EOF or until we get a line that
-**  names a file not in the same directory as the previous lot.  Remember
-**  the file names in the directory we're examining and return the list.
-*/
-static filelist *
-process_line(QIOSTATE *qp, int *queued, int *deleted)
-{
-    static char *line = NULL;
-    filelist *list = NULL;
-    char *p;
-    char *dir = NULL;
-    int dlen = -1;
-
-    *queued = 0;
-    *deleted = 0;
-
-    if (line == NULL)
-        line = get_line(qp);
-
-    for (; line != NULL; line = get_line(qp)) {
-        if (IsToken(line)) {
-            (*deleted)++;
-            if (debug_only) {
-                printf("Token %s\n", line);
-                continue;
-            }
-            if (!sm_initialized)
-                sm_initialize();
-            if (!SMcancel(TextToToken(line)))
-                if (SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT) {
-                    warn("can't cancel %s", line);
-                    error_count++;
-                }
-        } else {
-            if (list == NULL) {
-                p = strrchr(line, '/');
-                if (p != NULL) {
-                    *p++ = '\0';
-                    dlen = strlen(line);
-                    dir = xstrdup(line);
-                } else {
-                    p = line;
-                    dlen = -1;
-                    dir = NULL;
-                }
-                list = filelist_new(dir);
-            } else {
-                if ((dlen < 0 && strchr(line, '/'))
-                    || (dlen >= 0 && (line[dlen] != '/'
-                                      || strchr(line + dlen + 1, '/')
-                                      || strncmp(dir, line, dlen))))
-                    return list;
-            }
-            filelist_insert(list, line + dlen + 1);
-            (*queued)++;
-        }
-    }
-    return list;
-}
-
-
-/*
-**  Copy n leading segments of a path.
-*/
-static void
-copy_segments(char *to, const char *from, int n)
-{
-    char c;
-
-    for (c = *from++; c != '\0'; c = *from++) {
-        if (c == '/' && --n <= 0)
-            break;
-        *to++ = c;
-    }
-    *to = '\0';
-}
-
-
-/*
-**  Return the count of path segments in a file name (the number of
-**  slashes).
-*/
-static int
-slashcount(char *name)
-{
-    int i;
-
-    for (i = 0; *name != '\0'; name++)
-        if (*name == '/')
-            i++;
-    return i;
-}
-
-
-/*
-**  Unlink a file, reporting errors if the unlink fails for a reason other
-**  than the file not existing doesn't exist.  Be careful to avoid unlinking
-**  a directory if unlink_dangerous is true.
-*/
-static void
-unlink_file(const char *file)
-{
-    struct stat st;
-
-    /* On some systems, unlink will remove directories if used by root.  If
-       we're running as root, unlink_dangerous will be set, and we need to
-       make sure that the file isn't a directory first. */
-    if (unlink_dangerous) {
-        if (stat(file, &st) < 0) {
-            if (errno != ENOENT) {
-                if (*file == '/')
-                    syswarn("can't stat %s", file);
-                else
-                    syswarn("can't stat %s in %s", file, current_dir);
-                error_count++;
-            }
-            return;
-        }
-        if (S_ISDIR(st.st_mode)) {
-            if (*file == '/')
-                syswarn("%s is a directory", file);
-            else
-                syswarn("%s in %s is a directory", file, current_dir);
-            error_count++;
-            return;
-        }
-    }
-
-    if (debug_only) {
-        if (*file != '/')
-            printf("%s / ", current_dir);
-        printf("%s\n", file);
-        return;
-    }
-
-    if (unlink(file) < 0 && errno != ENOENT) {
-        if (*file == '/')
-            syswarn("can't unlink %s", file);
-        else
-            syswarn("can't unlink %s in %s", file, current_dir);
-    }
-}
-
-
-/*
-**  A wrapper around chdir that dies if chdir fails for a reason other than
-**  the directory not existing, returns false if the directory doesn't
-**  exist (reporting an error), and otherwise returns true.  It also checks
-**  to make sure that filecount is larger than chdir_threshold, and if it
-**  isn't it instead just sets prefix_dir and prefix_len to point to the new
-**  directory without changing the working directory.
-*/
-static bool
-chdir_checked(const char *path, int filecount)
-{
-    if (filecount < chdir_threshold) {
-        strlcpy(prefix_dir, path, sizeof(prefix_dir));
-        prefix_len = strlen(path);
-    } else {
-        prefix_len = 0;
-        if (chdir(path) < 0) {
-            if (errno != ENOENT)
-                sysdie("can't chdir from %s to %s", current_dir, path);
-            else {
-                syswarn("can't chdir from %s to %s", current_dir, path);
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-
-/*
-**  Set our environment (process working directory, and global vars) to
-**  reflect a change of directory to dir (relative to base_dir if dir is not
-**  an absolute path).  We're likely to want to do different things
-**  depending on the amount of work to do in dir, so we also take the number
-**  of files to remove in dir as the second argument.  Return false if the
-**  directory doesn't exist (and therefore all files in it have already been
-**  removed; otherwise, return true.
-*/
-static bool
-setup_dir(char *dir, int filecount)
-{
-    char *p, *q, *absolute;
-    char path[MAX_DIR_LEN];
-    int base_depth, depth;
-
-    /* Set absolute to the absolute path to the new directory. */
-    if (dir == NULL)
-        absolute = base_dir;
-    else if (*dir == '/')
-        absolute = dir;
-    else if (*dir == '\0') {
-        strlcpy(path, "/", sizeof(path));
-        absolute = path;
-    } else {
-        /* Strip off leading "./". */
-        while (dir[0] == '.' && dir[1] == '/')
-            for (dir += 2; *dir == '/'; dir++)
-                ;
-
-        /* Handle any leading "../", but only up to the number of segments
-           in base_dir. */
-        base_depth = slashcount(base_dir);
-        while (base_depth > 0 && strncmp(dir, "../", 3) == 0)
-            for (base_depth--, dir += 3; *dir == '/'; dir++)
-                ;
-        if (base_depth <= 0)
-            die("too many ../'s in path %s", dir);
-        copy_segments(path, base_dir, base_depth + 1);
-        if (strlen(path) + strlen(dir) + 2 > MAX_DIR_LEN)
-            die("path %s too long", dir);
-        strlcat(path, "/", sizeof(path));
-        strlcat(path, dir, sizeof(path));
-        absolute = path;
-    }
-
-    /* Find the first point of difference between absolute and current_dir.
-       If there is no difference, we're done; we're changing to the same
-       directory we were in (this is probably some sort of error, but can
-       happen with odd relative paths). */
-    for (p = absolute, q = current_dir; *p == *q; p++, q++)
-        if (*p == '\0')
-            return true;
-
-    /* If we reached the end of current_dir and there's more left of
-       absolute, we're changing to a subdirectory of where we were. */
-    if (*q == '\0' && *p == '/') {
-        p++;
-        if (!chdir_checked(p, filecount))
-            return false;
-        if (prefix_len == 0)
-            strlcpy(current_dir, absolute, sizeof(current_dir));
-        return true;
-    }
-
-    /* Otherwise, if we were promised that we have a pure tree (in other
-       words, no symbolic links to directories), see if it's worth going up
-       the tree with ".." and then down again rather than chdir to the
-       absolute path.  relative_threshold determines how many levels of ".."
-       we're willing to use; the default of 1 seems fractionally faster than
-       2 and 0 indicates to always use absolute paths.  Values larger than 3
-       would require extending the dotdots string, but are unlikely to be
-       worth it.
-
-       FIXME: It's too hard to figure out what this code does.  It needs to be
-       rewritten. */
-    if (p != '\0' && relative_threshold > 0) {
-        depth = slashcount(q);
-        if (depth <= relative_threshold) {
-            while (p > absolute && *--p != '/')
-                ;
-            p++;
-            strlcpy(prefix_dir, dotdots + 9 - depth * 3, sizeof(prefix_dir));
-            strlcat(prefix_dir, p, sizeof(prefix_dir));
-            if (!chdir_checked(prefix_dir, filecount))
-                return false;
-
-            /* Now patch up current_dir to reflect where we are. */
-            if (prefix_len == 0) {
-                while (q > current_dir && *--q != '/')
-                    ;
-                q[1] = '\0';
-                strlcat(current_dir, p, sizeof(current_dir));
-            }
-            return true;
-        }
-    }
-
-    /* All else has failed; just use the absolute path.  This includes the
-       case where current_dir is a subdirectory of absolute, in which case
-       it may be somewhat faster to use chdir("../..") or the like rather
-       than the absolute path, but this case rarely happens when the user
-       cares about speed (it usually doesn't happen with sorted input).  So
-       we don't bother. */
-    if (!chdir_checked(absolute, filecount))
-        return false;
-    if (prefix_len == 0)
-        strlcpy(current_dir, absolute, sizeof(current_dir));
-    return true;
-}
-
-
-/*
-**  Process a filelist of files to be deleted, all in the same directory.
-*/
-static void
-unlink_filelist(filelist *list, int filecount)
-{
-    bool sorted;
-    DIR *dir;
-    struct dirent *entry;
-    char *file;
-    int i;
-
-    /* If setup_dir returns false, the directory doesn't exist and we're
-       already all done. */
-    if (!setup_dir(list->dir, filecount)) {
-        filelist_free(list);
-        return;
-    }
-
-    /* We'll use prefix_dir as a buffer to write each file name into as we
-       go, so get it set up. */
-    if (prefix_len == 0)
-        file = prefix_dir;
-    else {
-        prefix_dir[prefix_len++] = '/';
-        file = prefix_dir + prefix_len;
-        *file = '\0';
-    }
-
-    /* If we're not sorting directories or if the number of files is under
-       the threshold, just remove the files. */
-    if (sort_threshold == 0 || filecount < sort_threshold) {
-        for (i = 0; i < list->count; i++) {
-            strlcpy(file, list->files[i], sizeof(prefix_dir) - prefix_len);
-            unlink_file(prefix_dir);
-        }
-        filelist_free(list);
-        return;
-    }
-
-    /* We have enough files to remove in this directory that it's worth
-       optimizing.  First, make sure the list of files is sorted.  It's not
-       uncommon for the files to already be sorted, so check first. */
-    for (sorted = true, i = 1; sorted && i < list->count; i++)
-        sorted = (strcmp(list->files[i - 1], list->files[i]) <= 0);
-    if (!sorted)
-        qsort(list->files, list->count, sizeof(char *), file_compare);
-
-    /* Now, begin doing our optimized unlinks.  The technique we use is to
-       open the directory containing the files and read through it, checking
-       each file in the directory to see if it's one of the files we should
-       be removing.  The theory is that we want to minimize the amount of
-       time the operating system spends doing string compares trying to find
-       the file to be removed in the directory.  This is often an O(n)
-       operation.  Note that this optimization may slightly slow more
-       effecient operating systems. */
-    dir = opendir(prefix_len == 0 ? "." : prefix_dir);
-    if (dir == NULL) {
-        if (prefix_len > 0 && prefix_dir[0] == '/')
-            warn("can't open directory %s", prefix_dir);
-        else
-            warn("can't open directory %s in %s",
-                 (prefix_len == 0) ? "." : prefix_dir, current_dir);
-        error_count++;
-        filelist_free(list);
-        return;
-    }
-    for (i = 0, entry = readdir(dir); entry != NULL; entry = readdir(dir))
-        if (filelist_lookup(list, entry->d_name) != NULL) {
-            i++;
-            strlcpy(file, entry->d_name, sizeof(prefix_dir) - prefix_len);
-            unlink_file(prefix_dir);
-            if (i == list->count)
-                break;
-        }
-    closedir(dir);
-    filelist_free(list);
-}
-
-
-/*
-**  Check a path to see if it's okay (not likely to confuse us).  This
-**  ensures that it doesn't contain elements like "./" or "../" and doesn't
-**  contain doubled slashes.
-*/
-static bool
-bad_path(const char *p)
-{
-    if (strlen(p) >= MAX_DIR_LEN)
-        return true;
-    while (*p) {
-        if (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/')))
-            return true;
-        while (*p && *p != '/')
-            p++;
-        if (p[0] == '/' && p[1] == '/')
-            return true;
-        if (*p == '/')
-            p++;
-    }
-    return false;
-}
-
-
-/*
-**  Main routine.  Parse options, initialize the storage manager, and
-**  initalize various global variables, and then go into a loop calling
-**  process_line and unlink_filelist as needed.
-*/
-int
-main(int argc, char *argv[])
-{
-    const char *name;
-    char *p, **arg;
-    QIOSTATE *qp;
-    filelist *list;
-    int filecount, deleted;
-    bool empty_error = false;
-
-    /* Establish our identity.  Since we use the storage manager, we need to
-       set up syslog as well, although we won't use it ourselves. */
-    name = argv[0];
-    if (*name == '\0')
-        name = "fastrm";
-    else {
-        p = strrchr(name, '/');
-        if (p != NULL)
-            name = p + 1;
-    }
-    message_program_name = name;
-    openlog(name, LOG_CONS | LOG_PID, LOG_INN_PROG);
-
-    /* If we're running as root, unlink may remove directories. */
-    unlink_dangerous = (geteuid() == 0);
-
-    /* Unfortunately, we can't use getopt, because several of our options
-       take optional arguments.  Bleh. */
-    arg = argv + 1;
-    while (argc >= 2 && **arg == '-') {
-        p = *arg;
-        while (*++p) {
-            switch (*p) {
-            default:
-                die("invalid option -- %c", *p);
-            case 'a':
-            case 'r':
-                continue;
-            case 'c':
-                chdir_threshold = 1;
-                if (!CTYPE(isdigit, p[1]))
-                    continue;
-                chdir_threshold = atoi(p + 1);
-                break;
-            case 'd':
-                debug_only = true;
-                continue;
-            case 'e':
-                empty_error = true;
-                continue;
-            case 's':
-                sort_threshold = 5;
-                if (!CTYPE(isdigit, p[1]))
-                    continue;
-                sort_threshold = atoi(p + 1);
-                break;
-            case 'u':
-                relative_threshold = 1;
-                if (!CTYPE(isdigit, p[1]))
-                    continue;
-                relative_threshold = atoi(p + 1);
-                if (relative_threshold >= (int) strlen(dotdots) / 3)
-                    relative_threshold = strlen(dotdots) / 3 - 1;
-                break;
-            }
-            break;
-        }
-        argc--;
-        arg++;
-    }
-    if (argc != 2)
-        die("usage error, wrong number of arguments");
-
-    /* The remaining argument is the base path.  Make sure it's valid and
-       not excessively large and then change to it. */
-    base_dir = *arg;
-    if (*base_dir != '/' || bad_path(base_dir))
-        die("bad base path %s", base_dir);
-    strlcpy(current_dir, base_dir, sizeof(current_dir));
-    if (chdir(current_dir) < 0)
-        sysdie("can't chdir to base path %s", current_dir);
-
-    /* Open our input stream and then loop through it, building filelists
-       and processing them until done. */
-    qp = QIOfdopen(fileno(stdin));
-    if (qp == NULL)
-        sysdie("can't reopen stdin");
-    while ((list = process_line(qp, &filecount, &deleted)) != NULL) {
-        empty_error = false;
-        unlink_filelist(list, filecount);
-    }
-    if (deleted > 0)
-        empty_error = false;
-
-    /* All done. */
-    SMshutdown();
-    if (empty_error)
-        die("no files to remove");
-    exit(error_count > 0 ? 1 : 0);
-}
diff --git a/expire/grephistory.c b/expire/grephistory.c
deleted file mode 100644 (file)
index ed6135d..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*  $Id: grephistory.c 7041 2004-12-19 08:33:49Z rra $
-**
-**  Get data from history database.
-*/
-
-#include "clibrary.h"
-#include <syslog.h>  
-#include <sys/stat.h>
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-/*
-**  Read stdin for list of Message-ID's, output list of ones we
-**  don't have.  Or, output list of files for ones we DO have.
-*/
-static void
-IhaveSendme(struct history *h, char What)
-{
-    char               *p;
-    char               *q;
-    char               buff[BUFSIZ];
-
-    while (fgets(buff, sizeof buff, stdin) != NULL) {
-       time_t arrived, posted, expires;
-       TOKEN token;
-
-       for (p = buff; ISWHITE(*p); p++)
-           ;
-       if (*p != '<')
-           continue;
-       for (q = p; *q && *q != '>' && !ISWHITE(*q); q++)
-           ;
-       if (*q != '>')
-           continue;
-       *++q = '\0';
-
-       if (!HIScheck(h, p)) {
-           if (What == 'i')
-               printf("%s\n", p);
-           continue;
-       }
-
-       /* Ihave -- say if we want it, and continue. */
-       if (What == 'i') {
-           continue;
-       }
-
-       if (HISlookup(h, p, &arrived, &posted, &expires, &token))
-           printf("%s\n", TokenToText(token));
-    }
-}
-
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: grephistory [flags] MessageID\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    int                        i;
-    const char         *History;
-    char                *key;
-    char               What;
-    struct history     *history;
-    time_t arrived, posted, expires;
-    TOKEN token;
-    unsigned int       Verbosity = 0;
-
-    /* First thing, set up logging and our identity. */
-    openlog("grephistory", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "grephistory";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-
-    History = concatpath(innconf->pathdb, _PATH_HISTORY);
-
-    What = '?';
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "vf:eilnqs")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'v':
-           Verbosity++;
-           break;
-       case 'f':
-           History = optarg;
-           break;
-       case 'e':
-       case 'i':
-       case 'l':
-       case 'n':
-       case 'q':
-       case 's':
-           if (What != '?') {
-                die("only one [eilnqs] flag allowed");
-           }
-           What = (char)i;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    history = HISopen(History, innconf->hismethod, HIS_RDONLY);
-    if (history == NULL)
-        die("cannot open history");
-
-    /* Set operating mode. */
-    switch (What) {
-    case '?':
-       What = 'n';
-       break;
-    case 'i':
-    case 's':
-       IhaveSendme(history, What);
-       HISclose(history);
-       exit(0);
-       /* NOTREACHED */
-    }
-
-    /* All modes other than -i -l want a Message-ID. */
-    if (ac != 1)
-       Usage();
-
-    key = av[0];
-    if (*key == '[') {
-        warn("accessing history by hash isn't supported");
-       HISclose(history);
-       exit(1);
-    } else {
-        /* Add optional braces if not already present. */
-       if (*key != '<')
-            key = concat("<", key, ">", (char *) 0);
-    }
-
-    if (!HIScheck(history, key)) {
-       if (What == 'n') {
-           if (Verbosity > 0)
-               die("not found (hash is %s)", HashToText(HashMessageID(key)));
-           else
-               die("not found");
-       }
-    }
-    else if (What != 'q') {
-       if (HISlookup(history, key, &arrived, &posted, &expires, &token)) {
-           if (What == 'l') {
-               printf("[]\t%ld~-~%ld\t%s\n", (long)arrived, (long)posted,
-                      TokenToText(token));
-           }
-           else {
-               if (Verbosity > 0)
-                   printf("%s (hash is %s)\n", TokenToText(token),
-                           HashToText(HashMessageID(key)));
-               else
-                   printf("%s\n", TokenToText(token));
-           }
-       }
-       else if (What == 'n')
-           printf("/dev/null\n");
-    }
-    HISclose(history);
-    return 0;
-}
diff --git a/expire/makedbz.c b/expire/makedbz.c
deleted file mode 100644 (file)
index bc1fe7d..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/*  $Id: makedbz.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Rebuild dbz file for history db.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <pwd.h>
-#include <syslog.h>  
-
-#include "dbz.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-/* FIXME: once we figure out how to integrate this stuff with the
- * history API this external visibility of internal voodoo should
- * go */
-#define HIS_FIELDSEP            '\t'
-
-char *TextFile = NULL;
-char *HistoryDir = NULL;
-char *HISTORY = NULL;
-
-/*
-**  Remove the DBZ files for the specified base text file.
-*/
-static void
-RemoveDBZFiles(char *p)
-{
-    char       buff[SMBUF];
-
-    snprintf(buff, sizeof(buff), "%s.dir", p);
-    if (unlink(buff) && errno != ENOENT)
-        syswarn("cannot unlink %s", buff);
-#ifdef DO_TAGGED_HASH
-    snprintf(buff, sizeof(buff), "%s.pag", p);
-    if (unlink(buff) && errno != ENOENT)
-        syswarn("cannot unlink %s", buff);
-#else
-    snprintf(buff, sizeof(buff), "%s.index", p);
-    if (unlink(buff) && errno != ENOENT)
-        syswarn("cannot unlink %s", buff);
-    snprintf(buff, sizeof(buff), "%s.hash", p);
-    if (unlink(buff) && errno != ENOENT)
-        syswarn("cannot unlink %s", buff);
-#endif
-}
-
-
-/*
-**  Count lines in the history text.  A long-winded way of saying "wc -l"
-*/
-static off_t
-Countlines(void)
-{
-    QIOSTATE *qp;
-    off_t count;
-
-    /* Open the text file. */
-    qp = QIOopen(TextFile);
-    if (qp == NULL)
-        sysdie("cannot open %s", TextFile);
-
-    /* Loop through all lines in the text file. */
-    count = 0;
-    for (; QIOread(qp) != NULL;)
-       count++;
-    if (QIOerror(qp))
-        sysdie("cannot read %s near line %lu", TextFile,
-               (unsigned long) count);
-    if (QIOtoolong(qp))
-        sysdie("line %lu of %s is too long", (unsigned long) count,
-               TextFile);
-
-    QIOclose(qp);
-    return count;
-}
-
-
-/*
-**  Rebuild the DBZ file from the text file.
-*/
-static void
-Rebuild(off_t size, bool IgnoreOld, bool Overwrite)
-{
-    QIOSTATE           *qp;
-    char               *p;
-    char               *save;
-    off_t              count;
-    off_t              where;
-    HASH               key;
-    char               temp[SMBUF];
-    dbzoptions          opt;
-
-    if (chdir(HistoryDir) < 0)
-        sysdie("cannot chdir to %s", HistoryDir);
-
-    /* If we are ignoring the old database and the user didn't specify a table
-       size, determine one ourselves from the size of the text history file.
-       Note that this will still use the defaults in dbz if the text file is
-       empty, since size will still be left set to 0. */
-    if (IgnoreOld == true && size == 0) {
-       size = Countlines();
-       size += (size / 10);
-        if (size > 0)
-            warn("no size specified, using %ld", (unsigned long) size);
-    }
-
-    /* Open the text file. */
-    qp = QIOopen(TextFile);
-    if (qp == NULL)
-        sysdie("cannot open %s", TextFile);
-
-    /* If using the standard history file, force DBZ to use history.n. */
-    if (strcmp(TextFile, HISTORY) == 0 && !Overwrite) {
-       snprintf(temp, sizeof(temp), "%s.n", HISTORY);
-       if (link(HISTORY, temp) < 0)
-            sysdie("cannot create temporary link to %s", temp);
-       RemoveDBZFiles(temp);
-       p = temp;
-    }
-    else {
-       temp[0] = '\0';
-       /* 
-       ** only do removedbz files if a. we're using something besides 
-       ** $pathdb/history, or b. we're ignoring the old db.
-       */
-       if (strcmp(TextFile, HISTORY) != 0 || IgnoreOld)
-            RemoveDBZFiles(TextFile);
-       p = TextFile;
-    }
-
-    /* Open the new database, using the old file if desired and possible. */
-    dbzgetoptions(&opt);
-    opt.pag_incore = INCORE_MEM;
-#ifndef        DO_TAGGED_HASH
-    opt.exists_incore = INCORE_MEM;
-#endif
-    dbzsetoptions(opt);
-    if (IgnoreOld) {
-       if (!dbzfresh(p, dbzsize(size))) {
-            syswarn("cannot do dbzfresh");
-           if (temp[0])
-               unlink(temp);
-           exit(1);
-       }
-    }
-    else {
-       if (!dbzagain(p, HISTORY)) {
-            syswarn("cannot do dbzagain");
-           if (temp[0])
-               unlink(temp);
-           exit(1);
-       }
-    }
-
-    /* Loop through all lines in the text file. */
-    count = 0;
-    for (where = QIOtell(qp); (p = QIOread(qp)) != NULL; where = QIOtell(qp)) {
-       count++;
-       if ((save = strchr(p, HIS_FIELDSEP)) == NULL) {
-            warn("bad line #%lu: %.40s", (unsigned long) count, p);
-           if (temp[0])
-               unlink(temp);
-           exit(1);
-       }
-       *save = '\0';
-       switch (*p) {
-       case '[':
-           if (strlen(p) != ((sizeof(HASH) * 2) + 2)) {
-                warn("invalid length for hash %s, skipping", p);
-               continue;
-           }
-           key = TextToHash(p+1);
-           break;
-       default:
-            warn("invalid message ID %s in history text", p);
-           continue;
-       }
-       switch (dbzstore(key, where)) {
-       case DBZSTORE_EXISTS:
-            warn("duplicate message ID %s in history text", p);
-           break;
-       case DBZSTORE_ERROR:
-            syswarn("cannot store %s", p);
-           if (temp[0])
-               unlink(temp);
-           exit(1);
-       default:
-           break;
-       }
-    }
-    if (QIOerror(qp)) {
-        syswarn("cannot read %s near line %lu", TextFile,
-                (unsigned long) count);
-       if (temp[0])
-           unlink(temp);
-       exit(1);
-    }
-    if (QIOtoolong(qp)) {
-        warn("line %lu is too long", (unsigned long) count);
-       if (temp[0])
-           unlink(temp);
-       exit(1);
-    }
-
-    /* Close files. */
-    QIOclose(qp);
-    if (!dbzclose()) {
-        syswarn("cannot close history");
-       if (temp[0])
-           unlink(temp);
-       exit(1);
-    }
-
-    if (temp[0])
-       unlink(temp);
-}
-
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: makedbz [-f histfile] [-s numlines] [-i] [-o]\n");
-    exit(1);
-}
-
-
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files, so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-int
-main(int argc, char **argv)
-{
-    bool       Overwrite;
-    bool       IgnoreOld;
-    off_t      size = 0;
-    int                i;
-    char       *p;
-
-    /* First thing, set up logging and our identity. */
-    openlog("makedbz", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "makedbz";
-       
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    TextFile = concatpath(innconf->pathdb, _PATH_HISTORY);
-    HISTORY = concatpath(innconf->pathdb, _PATH_HISTORY);
-    HistoryDir = innconf->pathdb;
-    IgnoreOld = false;
-    Overwrite = false;
-
-    while ((i = getopt(argc, argv, "s:iof:")) != EOF) {
-       switch (i) {
-       default:
-           Usage();
-       case 'f':
-           TextFile = optarg;
-           break;
-       case 's':
-           size = atol(optarg);
-           IgnoreOld = true;
-           break;
-       case 'o':
-           Overwrite = true;
-           break;
-       case 'i':
-           IgnoreOld = true;
-           break;
-       }
-    }
-
-    argc -= optind;
-    argv += optind;
-    if (argc) {
-       Usage();
-    }
-
-    if ((p = strrchr(TextFile, '/')) == NULL) {
-       /* find the default history file directory */
-       HistoryDir = innconf->pathdb;
-    } else {
-       *p = '\0';
-       HistoryDir = xstrdup(TextFile);
-       *p = '/';
-    }
-
-    if (chdir(HistoryDir) < 0)
-        sysdie("cannot chdir to %s", HistoryDir);
-
-    /* Change users if necessary. */
-    setuid_news();
-
-    Rebuild(size, IgnoreOld, Overwrite);
-    closelog();
-    exit(0);
-}
diff --git a/expire/makehistory.c b/expire/makehistory.c
deleted file mode 100644 (file)
index 7152b99..0000000
+++ /dev/null
@@ -1,944 +0,0 @@
-/*  $Id: makehistory.c 7468 2005-12-12 03:23:21Z eagle $
-**
-**  Rebuild history/overview databases.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-#include <assert.h>
-#include <errno.h>
-#include <pwd.h>
-#include <syslog.h>  
-
-#include "inn/buffer.h"
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-#include "storage.h"
-
-static const char usage[] = "\
-Usage: makehistory [-bOIax] [-f file] [-l count] [-s size] [-T tmpdir]\n\
-\n\
-    -b          delete bad articles from spool\n\
-    -e          read entire articles to compute proper byte count\n\
-    -f          write history entries to file (default $pathdb/history)\n\
-    -s size     size new history database for approximately size entries\n\
-    -a          open output history file in append mode\n\
-    -O          create overview entries for articles\n\
-    -I          do not create overview for articles numbered below lowmark\n\
-    -l count    size of overview updates (default 10000)\n\
-    -x          don't write history entries\n\
-    -T tmpdir   use directory tmpdir for temporary files\n\
-    -F          fork when writing overview\n";
-
-
-/*
-**  Information about the schema of the news overview files.
-*/
-typedef struct _ARTOVERFIELD {
-    char       *Headername;
-    int                HeadernameLength;
-    bool       NeedHeadername;
-    const char *Header;
-    int                HeaderLength;
-    bool       HasHeader;
-} ARTOVERFIELD;
-
-#define DEFAULT_SEGSIZE        10000;
-
-bool NukeBadArts;
-char *SchemaPath = NULL;
-char *ActivePath = NULL;
-char *HistoryPath = NULL;
-struct history *History;
-FILE *Overchan;
-bool DoOverview;
-bool Fork;
-bool Cutofflow = false;
-char *TmpDir;
-int OverTmpSegSize, OverTmpSegCount;
-FILE *OverTmpFile;
-char *OverTmpPath = NULL;
-bool NoHistory;
-OVSORTTYPE sorttype;
-int RetrMode;
-
-TIMEINFO Now;
-
-/* Misc variables needed for the overview creation code. */
-static char            MESSAGEID[] = "Message-ID";
-static char            EXPIRES[] = "Expires";
-static char            DATE[] = "Date";
-static char            XREF[] = "Xref";
-static ARTOVERFIELD    *ARTfields; /* overview fields listed in overview.fmt */
-static size_t          ARTfieldsize;
-static ARTOVERFIELD    *Datep = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD    *Msgidp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD    *Expp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD    *Xrefp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD    *Missfields; /* header fields not listed in 
-                                       overview.fmt, but ones that we need
-                                       (e.g. message-id */
-static size_t          Missfieldsize = 0;
-
-static void OverAddAllNewsgroups(void);
-
-/*
-**  Check and parse an date header line.  Return the new value or
-**  zero on error.
-*/
-static long
-GetaDate(char *p)
-{
-    time_t             t;
-
-    while (ISWHITE(*p))
-       p++;
-    if ((t = parsedate(p, &Now)) == -1)
-       return 0L;
-    return (long)t;
-}
-
-/*
-**  Check and parse a Message-ID header line.  Return private space.
-*/
-static const char *
-GetMessageID(char *p)
-{
-    static struct buffer buffer = { 0, 0, 0, NULL };
-
-    while (ISWHITE(*p))
-       p++;
-    if (p[0] != '<' || p[strlen(p) - 1] != '>')
-       return "";
-
-    /* Copy into re-used memory space, including NUL. */
-    buffer_set(&buffer, p, strlen(p)+1);
-    return buffer.data;
-}
-
-/*
- * The overview temp file is used to accumulate overview lines as articles are
- * scanned.  The format is
- * (1st) newsgroup name\tToken\toverview data.
- * When about 10000 lines of this overview data are accumulated, the data
- * file is sorted and then read back in and the data added to overview.
- * The sorting/batching helps improve efficiency.
- */
-
-/*
- * Flush the unwritten OverTempFile data to disk, sort the file, read it 
- * back in, and add it to overview. 
- */
-
-static void
-FlushOverTmpFile(void)
-{
-    char temp[SMBUF];
-    char *SortedTmpPath;
-    int i, pid, fd;
-    TOKEN token;
-    QIOSTATE *qp;
-    int count;
-    char *line, *p;
-    char *q = NULL;
-    char *r = NULL;
-    time_t arrived, expires;
-    static int first = 1;
-
-    if (OverTmpFile == NULL)
-       return;
-    if (fflush(OverTmpFile) == EOF || ferror(OverTmpFile) || fclose(OverTmpFile) == EOF)
-        sysdie("cannot close temporary overview file");
-    if(Fork) {
-        if(!first) { /* if previous one is running, wait for it */
-           int status;
-           wait(&status);
-           if((WIFEXITED(status) && WEXITSTATUS(status) != 0)
-                   || WIFSIGNALED(status))
-               exit(1);
-       }
-
-       pid = fork();
-       if(pid == -1)
-            sysdie("cannot fork");
-       if(pid > 0) {
-           /* parent */
-           first = 0;
-           free(OverTmpPath);
-           OverTmpPath = NULL;
-           return;
-       }
-
-       /* child */
-       /* init the overview setup. */
-       if (!OVopen(OV_WRITE)) {
-            warn("cannot open overview");
-           _exit(1);
-       }
-       if (!OVctl(OVSORT, (void *)&sorttype)) {
-            warn("cannot obtain overview sorting information");
-           OVclose();
-           _exit(1);
-       }
-       if (!OVctl(OVCUTOFFLOW, (void *)&Cutofflow)) {
-            warn("cannot obtain overview cutoff information");
-           OVclose();
-           _exit(1);
-       }
-    }
-
-    /* This is a bit odd, but as long as other user's files can't be deleted
-       out of the temporary directory, it should work.  We're using mkstemp to
-       create a file and then passing its name to sort, which will then open
-       it again and overwrite it. */
-    SortedTmpPath = concatpath(TmpDir, "hisTXXXXXX");
-    fd = mkstemp(SortedTmpPath);
-    if (fd < 0) {
-        syswarn("cannot create temporary file");
-        OVclose();
-        Fork ? _exit(1) : exit(1);
-    }
-    close(fd);
-    snprintf(temp, sizeof(temp), "exec %s -T %s -t'%c' -o %s %s", _PATH_SORT,
-             TmpDir, '\t', SortedTmpPath, OverTmpPath);
-    
-    i = system(temp) >> 8;
-    if (i != 0) {
-        syswarn("cannot sort temporary overview file (%s exited %d)",
-                _PATH_SORT, i);
-       OVclose();
-       Fork ? _exit(1) : exit(1);
-    }
-
-    /* don't need old path anymore. */
-    unlink(OverTmpPath);
-    free(OverTmpPath);
-    OverTmpPath = NULL;
-
-    /* read sorted lines. */
-    if ((qp = QIOopen(SortedTmpPath)) == NULL) {
-        syswarn("cannot open sorted overview file %s", SortedTmpPath);
-       OVclose();
-       Fork ? _exit(1) : exit(1);
-    }
-
-    for (count = 1; ; ++count) {
-       line = QIOread(qp);
-       if (line == NULL) {
-           if (QIOtoolong(qp)) {
-                warn("overview line %d is too long", count);
-               continue;
-           } else
-               break;
-       }
-       if ((p = strchr(line, '\t')) == NULL 
-           || (q = strchr(p+1, '\t')) == NULL
-           || (r = strchr(q+1, '\t')) == NULL) {
-            warn("sorted overview file %s has a bad line at %d",
-                 SortedTmpPath, count);
-           continue;
-       }
-       /* p+1 now points to start of token, q+1 points to start of overline. */
-       if (sorttype == OVNEWSGROUP) {
-           *p++ = '\0';
-           *q++ = '\0';
-           *r++ = '\0';
-           arrived = (time_t)atol(p);
-           expires = (time_t)atol(q);
-           q = r;
-           if ((r = strchr(r, '\t')) == NULL) {
-                warn("sorted overview file %s has a bad line at %d",
-                     SortedTmpPath, count);
-               continue;
-           }
-           *r++ = '\0';
-       } else {
-           *p++ = '\0';
-           *q++ = '\0';
-           *r++ = '\0';
-           arrived = (time_t)atol(line);
-           expires = (time_t)atol(p);
-       }
-       token = TextToToken(q);
-       if (OVadd(token, r, strlen(r), arrived, expires) == OVADDFAILED) {
-           if (OVctl(OVSPACE, (void *)&i) && i == OV_NOSPACE) {
-                warn("no space left for overview");
-               OVclose();
-               Fork ? _exit(1) : exit(1);
-           }
-            warn("cannot write overview data \"%.40s\"", q);
-       }
-    }
-    /* Check for errors and close. */
-    if (QIOerror(qp)) {
-        syswarn("cannot read sorted overview file %s", SortedTmpPath);
-       OVclose();
-       Fork ? _exit(1) : exit(1);
-    }
-    QIOclose(qp);
-    /* unlink sorted tmp file */
-    unlink(SortedTmpPath);
-    free(SortedTmpPath);
-    if(Fork) {
-       OVclose();
-       _exit(0);
-    }
-}
-           
-
-/*
- * Write a line to the overview temp file. 
- */
-static void
-WriteOverLine(TOKEN *token, const char *xrefs, int xrefslen, 
-             char *overdata, int overlen, time_t arrived, time_t expires)
-{
-    char temp[SMBUF];
-    const char *p, *q, *r;
-    int i, fd;
-
-    if (sorttype == OVNOSORT) {
-       if (Fork) {
-           fprintf(Overchan, "%s %ld %ld ", TokenToText(*token), (long)arrived, (long)expires);
-           if (fwrite(overdata, 1, overlen, Overchan) != (size_t) overlen)
-                sysdie("writing overview failed");
-           fputc('\n', Overchan);
-       } else if (OVadd(*token, overdata, overlen, arrived, expires) == OVADDFAILED) {
-           if (OVctl(OVSPACE, (void *)&i) && i == OV_NOSPACE) {
-                warn("no space left for overview");
-               OVclose();
-               exit(1);
-           }
-            warn("cannot write overview data for article %s",
-                 TokenToText(*token));
-       }
-       return;
-    }
-    if (OverTmpPath == NULL) {
-       /* need new temp file, so create it. */
-        OverTmpPath = concatpath(TmpDir, "histXXXXXX");
-        fd = mkstemp(OverTmpPath);
-        if (fd < 0)
-            sysdie("cannot create temporary file");
-        OverTmpFile = fdopen(fd, "w");
-       if (OverTmpFile == NULL)
-            sysdie("cannot open %s", OverTmpPath);
-       OverTmpSegCount = 0;
-    }
-    if (sorttype == OVNEWSGROUP) {
-       /* find first ng name in xref. */
-       for (p = xrefs, q=NULL ; p < xrefs+xrefslen ; ++p) {
-           if (*p == ' ') {
-               q = p+1; /* found space */
-               break;
-           }
-       }
-       if (!q) {
-            warn("bogus Xref data for %s", TokenToText(*token));
-           /* XXX do nuke here? */
-           return;
-       }
-
-       for (p = q, r=NULL ; p < xrefs+xrefslen ; ++p) {
-           if (*p == ':') {
-               r=p;
-               break;
-           }
-       }
-       if (!r) {
-            warn("bogus Xref data for %s", TokenToText(*token));
-           /* XXX do nuke here? */
-           return;
-       }
-       /* q points to start of ng name, r points to its end. */
-        assert(sizeof(temp) > r - q + 1);
-       memcpy(temp, q, r - q + 1);
-        temp[r - q + 1] = '\0';
-       fprintf(OverTmpFile, "%s\t%10lu\t%lu\t%s\t", temp,
-                (unsigned long) arrived, (unsigned long) expires,
-                TokenToText(*token));
-    } else
-       fprintf(OverTmpFile, "%10lu\t%lu\t%s\t", (unsigned long) arrived,
-                (unsigned long) expires,
-                TokenToText(*token));
-
-    fwrite(overdata, overlen, 1, OverTmpFile);
-    fprintf(OverTmpFile, "\n");
-    OverTmpSegCount++;
-
-    if (OverTmpSegSize != 0 && OverTmpSegCount >= OverTmpSegSize) {
-       FlushOverTmpFile();
-    }
-}
-
-
-/*
-**  Read the overview schema.
-*/
-static void
-ARTreadschema(bool Overview)
-{
-    FILE                        *F;
-    char                        *p;
-    ARTOVERFIELD                *fp;
-    int                         i;
-    char                        buff[SMBUF];
-    bool                        foundxreffull = false;
-
-    if (Overview) {
-       /* Open file, count lines. */
-       if ((F = fopen(SchemaPath, "r")) == NULL)
-            sysdie("cannot open %s", SchemaPath);
-       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 (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->NeedHeadername = (strcmp(p, "full") == 0);
-           }
-           else
-               fp->NeedHeadername = false;
-           fp->Headername = xstrdup(buff);
-           fp->HeadernameLength = strlen(buff);
-           fp->Header = (char *)NULL;
-           fp->HasHeader = false;
-           fp->HeaderLength = 0;
-           if (strncasecmp(buff, DATE, strlen(DATE)) == 0)
-               Datep = fp;
-           if (strncasecmp(buff, MESSAGEID, strlen(MESSAGEID)) == 0)
-               Msgidp = fp;
-           if (strncasecmp(buff, EXPIRES, strlen(EXPIRES)) == 0)
-               Expp = fp;
-           if (strncasecmp(buff, XREF, strlen(XREF)) == 0) {
-               Xrefp = fp;
-               foundxreffull = fp->NeedHeadername;
-            }
-           fp++;
-       }
-       ARTfieldsize = fp - ARTfields;
-       fclose(F);
-    }
-    if (Msgidp == (ARTOVERFIELD *)NULL)
-       Missfieldsize++;
-    if (Datep == (ARTOVERFIELD *)NULL)
-       Missfieldsize++;
-    if (Expp == (ARTOVERFIELD *)NULL)
-       Missfieldsize++;
-    if (Overview && (Xrefp == (ARTOVERFIELD *)NULL || !foundxreffull))
-        die("Xref:full must be included in %s", SchemaPath);
-    if (Missfieldsize > 0) {
-       Missfields = xmalloc(Missfieldsize * sizeof(ARTOVERFIELD));
-        fp = Missfields;
-       if (Msgidp == (ARTOVERFIELD *)NULL) {
-           fp->NeedHeadername = false;
-           fp->Headername = xstrdup(MESSAGEID);
-           fp->HeadernameLength = strlen(MESSAGEID);
-           fp->Header = (char *)NULL;
-           fp->HasHeader = false;
-           fp->HeaderLength = 0;
-           Msgidp = fp++;
-       }
-       if (Datep == (ARTOVERFIELD *)NULL) {
-           fp->NeedHeadername = false;
-           fp->Headername = xstrdup(DATE);
-           fp->HeadernameLength = strlen(DATE);
-           fp->Header = (char *)NULL;
-           fp->HasHeader = false;
-           fp->HeaderLength = 0;
-           Datep = fp++;
-       }
-       if (Expp == (ARTOVERFIELD *)NULL) {
-           fp->NeedHeadername = false;
-           fp->Headername = xstrdup(EXPIRES);
-           fp->HeadernameLength = strlen(EXPIRES);
-           fp->Header = (char *)NULL;
-           fp->HasHeader = false;
-           fp->HeaderLength = 0;
-           Expp = fp++;
-       }
-        if (Overview && Xrefp == (ARTOVERFIELD *)NULL) {
-           fp->NeedHeadername = false;
-           fp->Headername = xstrdup(XREF);
-           fp->HeadernameLength = strlen(XREF);
-           fp->Header = (char *)NULL;
-           fp->HasHeader = false;
-           fp->HeaderLength = 0;
-           Xrefp = fp++;
-       }
-    }
-}
-
-/*
- * Handle a single article.  This routine's fairly complicated. 
- */
-static void
-DoArt(ARTHANDLE *art)
-{
-    ARTOVERFIELD               *fp;
-    const char                  *p, *end;
-    char                        *q;
-    static struct buffer        buffer = { 0, 0, 0, NULL };
-    static char                        SEP[] = "\t";
-    static char                        NUL[] = "\0";
-    static char                        COLONSPACE[] = ": ";
-    size_t                     i, j, len;
-    const char                 *MessageID;
-    time_t                     Arrived;
-    time_t                     Expires;
-    time_t                     Posted;
-    char                       overdata[BIG_BUFFER];
-    char                       bytes[BIG_BUFFER];
-    struct artngnum            ann;
-
-    /* Set up place to store headers. */
-    for (fp = ARTfields, i = 0; i < ARTfieldsize; i++, fp++) {
-       if (fp->HeaderLength) {
-           fp->Header = 0;
-       }
-       fp->HeaderLength = 0;
-       fp->HasHeader = false;
-    }
-    if (Missfieldsize > 0) {
-       for (fp = Missfields, i = 0; i < Missfieldsize; i++, fp++) {
-           if (fp->HeaderLength) {
-               fp->Header = 0;
-           }
-           fp->HeaderLength = 0;
-           fp->HasHeader = false;
-       }
-    }
-    for (fp = ARTfields, i = 0; i < ARTfieldsize; i++, fp++) {
-        fp->Header = wire_findheader(art->data, art->len, fp->Headername);
-
-        /* Someone managed to break their server so that they were appending
-           multiple Xref headers, and INN had a bug where it wouldn't notice
-           this and reject the article.  Just in case, see if there are
-           multiple Xref headers and use the last one. */
-        if (fp == Xrefp) {
-            const char *next = fp->Header;
-            size_t left;
-
-            while (next != NULL) {
-                next = wire_endheader(fp->Header, art->data + art->len - 1);
-                if (next == NULL)
-                    break;
-                next++;
-                left = art->len - (next - art->data);
-                next = wire_findheader(next, left, fp->Headername);
-                if (next != NULL)
-                    fp->Header = next;
-            }
-        }
-
-        /* Now, if we have a header, find and record its length. */
-        if (fp->Header != NULL) {
-           fp->HasHeader = true;
-            p = wire_endheader(fp->Header, art->data + art->len - 1);
-            if (p == NULL)
-               continue;
-
-            /* The true length of the header is p - fp->Header + 1, but p
-               points to the \n at the end of the header, so subtract 2 to
-               peel off the \r\n (we're guaranteed we're dealing with
-               wire-format articles. */
-            fp->HeaderLength = p - fp->Header - 1;
-       } else if (RetrMode == RETR_ALL 
-                   && strcmp(fp->Headername, "Bytes") == 0) {
-            snprintf(bytes, sizeof(bytes), "%lu", (unsigned long) art->len);
-           fp->HasHeader = true;
-           fp->Header = bytes;
-           fp->HeaderLength = strlen(bytes);
-       }
-    }
-    if (Missfieldsize > 0) {
-       for (fp = Missfields, i = 0; i < Missfieldsize; i++, fp++) {
-            fp->Header = wire_findheader(art->data, art->len, fp->Headername);
-            if (fp->Header != NULL) {
-               fp->HasHeader = true;
-                p = wire_endheader(fp->Header, art->data + art->len - 1);
-                if (p == NULL)
-                    continue;
-               fp->HeaderLength = p - fp->Header - 1;
-           }
-       }
-    }
-    if (DoOverview && Xrefp->HeaderLength == 0) {
-       if (!SMprobe(SMARTNGNUM, art->token, (void *)&ann)) {
-           Xrefp->Header = NULL;
-           Xrefp->HeaderLength = 0;
-       } else {
-            if (ann.artnum == 0 || ann.groupname == NULL)
-                return;
-            len = strlen(innconf->pathhost) + 1 + strlen(ann.groupname) + 1
-                + 16 + 1;
-            if (len > BIG_BUFFER) {
-                Xrefp->Header = NULL;
-                Xrefp->HeaderLength = 0;
-            } else {
-                snprintf(overdata, sizeof(overdata), "%s %s:%lu",
-                         innconf->pathhost, ann.groupname, ann.artnum);
-                Xrefp->Header = overdata;
-                Xrefp->HeaderLength = strlen(overdata);
-            }
-            if (ann.groupname != NULL)
-                free(ann.groupname);
-        }
-    }
-
-    MessageID = (char *)NULL;
-    Arrived = art->arrived;
-    Expires = 0;
-    Posted = 0;
-
-    if (!Msgidp->HasHeader) {
-        warn("no Message-ID header in %s", TokenToText(*art->token));
-       if (NukeBadArts)
-           SMcancel(*art->token);
-       return;
-    }
-
-    buffer_set(&buffer, Msgidp->Header, Msgidp->HeaderLength);
-    buffer_append(&buffer, NUL, 1);
-    for (i = 0, q = buffer.data; i < buffer.left; q++, i++)
-       if (*q == '\t' || *q == '\n' || *q == '\r')
-           *q = ' ';
-    MessageID = GetMessageID(buffer.data);
-    if (*MessageID == '\0') {
-        warn("no Message-ID header in %s", TokenToText(*art->token));
-       if (NukeBadArts)
-           SMcancel(*art->token);
-       return;
-    }
-
-    /*
-     * check if msgid is in history if in update mode, or if article is 
-     * newer than start time of makehistory. 
-     */
-
-    if (!Datep->HasHeader) {
-       Posted = Arrived;
-    } else {
-        buffer_set(&buffer, Datep->Header, Datep->HeaderLength);
-        buffer_append(&buffer, NUL, 1);
-       for (i = 0, q = buffer.data; i < buffer.left; q++, i++)
-           if (*q == '\t' || *q == '\n' || *q == '\r')
-               *q = ' ';
-       if ((Posted = GetaDate(buffer.data)) == 0)
-           Posted = Arrived;
-    }
-
-    if (Expp->HasHeader) {
-        buffer_set(&buffer, Expp->Header, Expp->HeaderLength);
-        buffer_append(&buffer, NUL, 1);
-       for (i = 0, q = buffer.data; i < buffer.left; q++, i++)
-           if (*q == '\t' || *q == '\n' || *q == '\r')
-               *q = ' ';
-       Expires = GetaDate(buffer.data);
-    }
-
-    if (DoOverview && Xrefp->HeaderLength > 0) {
-       for (fp = ARTfields, j = 0; j < ARTfieldsize; j++, fp++) {
-           if (fp == ARTfields)
-                buffer_set(&buffer, "", 0);
-           else
-                buffer_append(&buffer, SEP, strlen(SEP));
-            if (fp->HeaderLength == 0)
-                continue;
-           if (fp->NeedHeadername) {
-                buffer_append(&buffer, fp->Headername, fp->HeadernameLength);
-                buffer_append(&buffer, COLONSPACE, strlen(COLONSPACE));
-           }
-           i = buffer.left;
-            buffer_resize(&buffer, buffer.left + fp->HeaderLength);
-            end = fp->Header + fp->HeaderLength - 1;
-            for (p = fp->Header, q = &buffer.data[i]; p <= end; p++) {
-                if (*p == '\r' && p < end && p[1] == '\n') {
-                    p++;
-                    continue;
-                }
-                if (*p == '\0' || *p == '\t' || *p == '\n' || *p == '\r')
-                    *q++ = ' ';
-                else
-                    *q++ = *p;
-                buffer.left++;
-            }
-       }
-       WriteOverLine(art->token, Xrefp->Header, Xrefp->HeaderLength,
-                     buffer.data, buffer.left, Arrived, Expires);
-    }
-
-    if (!NoHistory) {
-       bool r;
-
-       r = HISwrite(History, MessageID,
-                    Arrived, Posted, Expires, art->token);
-       if (r == false)
-            sysdie("cannot write history line");
-    }
-}
-
-
-/*
-** Add all groups to overview group.index. --rmt
-*/
-static void
-OverAddAllNewsgroups(void)
-{
-    QIOSTATE *qp;
-    int count;
-    char *q,*p;
-    char *line;
-    ARTNUM hi, lo;
-
-    if ((qp = QIOopen(ActivePath)) == NULL)
-        sysdie("cannot open %s", ActivePath);
-    for (count = 1; (line = QIOread(qp)) != NULL; count++) {
-       if ((p = strchr(line, ' ')) == NULL) {
-            warn("bad active line %d: %.40s", count, line);
-           continue;
-       }
-       *p++ = '\0';
-       hi = (ARTNUM)atol(p);
-       if ((p = strchr(p, ' ')) == NULL) {
-            warn("bad active line %d: %.40s", count, line);
-           continue;
-       }
-       *p++ = '\0';
-       lo = (ARTNUM)atol(p);
-       if ((q = strrchr(p, ' ')) == NULL) {
-            warn("bad active line %d: %.40s", count, line);
-           continue;
-       }
-       /* q+1 points to NG flag */
-       if (!OVgroupadd(line, lo, hi, q+1))
-            die("cannot add %s to overview group index", line);
-    }
-    /* Test error conditions; QIOtoolong shouldn't happen. */
-    if (QIOtoolong(qp))
-        die("active file line %d is too long", count);
-    if (QIOerror(qp))
-        sysdie("cannot read %s around line %d", ActivePath, count);
-    QIOclose(qp);
-}
-
-
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may create new database files, so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-int
-main(int argc, char **argv)
-{
-    ARTHANDLE *art = NULL;
-    bool AppendMode;
-    int i;
-    bool val;
-    char *HistoryDir;
-    char *p;
-    char *buff;
-    size_t npairs = 0;
-
-    /* First thing, set up logging and our identity. */
-    openlog("makehistory", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "makehistory";
-       
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    HistoryPath = concatpath(innconf->pathdb, _PATH_HISTORY);
-    ActivePath = concatpath(innconf->pathdb, _PATH_ACTIVE);
-    TmpDir = innconf->pathtmp;
-    SchemaPath = concatpath(innconf->pathetc, _PATH_SCHEMA);
-
-    OverTmpSegSize = DEFAULT_SEGSIZE;
-    OverTmpSegCount = 0;
-    NukeBadArts = false;
-    DoOverview = false;
-    Fork = false;
-    AppendMode = false;
-    NoHistory = false;
-    RetrMode = RETR_HEAD;
-
-    while ((i = getopt(argc, argv, "aebf:Il:OT:xFs:")) != EOF) {
-       switch(i) {
-       case 'T':
-           TmpDir = optarg;
-           break;
-       case 'x':
-           NoHistory = true;
-           break;
-       case 'a':
-           AppendMode = true;
-           break;
-       case 'b':
-           NukeBadArts = true;
-           break;
-       case 'f':
-           HistoryPath = optarg;
-           break;
-       case 'I':
-           Cutofflow = true;
-           break;
-       case 'l':
-           OverTmpSegSize = atoi(optarg);
-           break;
-       case 'O':
-           DoOverview = true;
-           break;
-       case 'F':
-           Fork = true;
-           break;
-       case 'e':
-           RetrMode = RETR_ALL;
-           break;
-       case 's':
-           npairs = atoi(optarg);
-           break;
-           
-       default:
-           fprintf(stderr, "%s", usage);
-            exit(1);
-           break;
-       }
-    }
-    argc -= optind;
-    argv += optind;
-    if (argc) {
-        fprintf(stderr, "%s", usage);
-        exit(1);
-    }
-
-    if ((p = strrchr(HistoryPath, '/')) == NULL) {
-       /* find the default history file directory */
-       HistoryDir = innconf->pathdb;
-    } else {
-       *p = '\0';
-       HistoryDir = xstrdup(HistoryPath);
-       *p = '/';
-    }
-
-    if (chdir(HistoryDir) < 0)
-        sysdie("cannot chdir to %s", HistoryDir);
-
-    /* Change users if necessary. */
-    setuid_news();
-
-    /* Read in the overview schema */
-    ARTreadschema(DoOverview);
-    
-    if (DoOverview) {
-       /* init the overview setup. */
-       if (!OVopen(OV_WRITE))
-            sysdie("cannot open overview");
-       if (!OVctl(OVSORT, (void *)&sorttype))
-            die("cannot obtain overview sort information");
-       if (!Fork) {
-           if (!OVctl(OVCUTOFFLOW, (void *)&Cutofflow))
-                die("cannot obtain overview cutoff information");
-           OverAddAllNewsgroups();
-       } else {
-           OverAddAllNewsgroups();
-           if (sorttype == OVNOSORT) {
-               buff = concat(innconf->pathbin, "/", "overchan", NULL);
-               if ((Overchan = popen(buff, "w")) == NULL)
-                    sysdie("cannot fork overchan process");
-               free(buff);
-           }
-           OVclose();
-       }
-    }
-
-    /* Init the Storage Manager */
-    val = true;
-    if (!SMsetup(SM_RDWR, (void *)&val) || !SMsetup(SM_PREOPEN, (void *)&val))
-        sysdie("cannot set up storage manager");
-    if (!SMinit())
-        sysdie("cannot initialize storage manager: %s", SMerrorstr);
-
-    /* Initialise the history manager */
-    if (!NoHistory) {
-       int flags = HIS_RDWR | HIS_INCORE;
-
-       if (!AppendMode)
-           flags |= HIS_CREAT;
-       History = HISopen(NULL, innconf->hismethod, flags);
-       if (History == NULL)
-            sysdie("cannot create history handle");
-       HISctl(History, HISCTLS_NPAIRS, &npairs);
-       if (!HISctl(History, HISCTLS_PATH, HistoryPath))
-            sysdie("cannot open %s", HistoryPath);
-    }
-
-    /* Get the time.  Only get it once, which is good enough. */
-    if (GetTimeInfo(&Now) < 0)
-        sysdie("cannot get the time");
-
-    /*
-     * Scan the entire spool, nuke any bad arts if needed, and process each
-     * article.
-     */
-       
-    while ((art = SMnext(art, RetrMode)) != NULL) {
-       if (art->len == 0) {
-           if (NukeBadArts && art->data == NULL && art->token != NULL)
-               SMcancel(*art->token);
-           continue;
-       }
-       DoArt(art);
-    }
-
-    if (!NoHistory) {
-       /* close history file. */
-       if (!HISclose(History))
-            sysdie("cannot close history file");
-    }
-
-    if (DoOverview) {
-       if (sorttype == OVNOSORT && Fork)
-           if (fflush(Overchan) == EOF || ferror(Overchan) || pclose(Overchan) == EOF)
-                sysdie("cannot flush overview data");
-       if (sorttype != OVNOSORT) {
-           int status;
-           FlushOverTmpFile();
-           if(Fork)
-               wait(&status);
-       }
-    }
-    if(!Fork)
-       OVclose();
-    exit(0);
-}
-
diff --git a/expire/prunehistory.c b/expire/prunehistory.c
deleted file mode 100644 (file)
index cb30c75..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*  $Id: prunehistory.c 6124 2003-01-14 06:03:29Z rra $
-**
-**  Prune file names from history file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <syslog.h>
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-
-
-/*
-**  Print usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage:  prunehistory [-p] [-f file] [input]\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    char                *p;
-    int                 i;
-    char               buff[BUFSIZ];
-    const char         *History;
-    bool               Passing;
-    struct history     *history = NULL;
-    int                        rc = 0;
-
-    /* First thing, set up logging and our identity. */
-    openlog("prunehistory", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "prunehistory";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-
-    History = concatpath(innconf->pathdb, _PATH_HISTORY);
-    Passing = false;
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "f:p")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'f':
-           History = optarg;
-           break;
-       case 'p':
-           Passing = true;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if (ac) {
-       Usage();
-       rc = 1;
-       goto fail;
-    }
-
-    history = HISopen(History, innconf->hismethod, HIS_RDWR);
-    if (history == NULL) {
-        syswarn("cannot set up %s database", History);
-       rc = 1;
-       goto fail;
-    }
-
-    /* Loop over all input. */
-    while (fgets(buff, sizeof buff, stdin) != NULL) {
-       time_t arrived, posted, expires;
-
-       if ((p = strchr(buff, '\n')) == NULL) {
-           if (Passing)
-               printf("%s\n", buff);
-           else
-                warn("line too long, ignored: %.40s", buff);
-           continue;
-       }
-       *p = '\0';
-
-       /* Ignore blank and comment lines. */
-       if (buff[0] == '\0' || buff[0] == '#') {
-           if (Passing)
-               printf("%s\n", buff);
-           continue;
-       }
-
-       if (buff[0] != '<' || (p = strchr(buff, '>')) == NULL) {
-           if (Passing)
-               printf("%s\n", buff);
-           else
-                warn("line doesn't start with a message ID, ignored: %.40s",
-                     buff);
-           continue;
-       }
-       *++p = '\0';
-
-       if (HISlookup(history, buff, &arrived, &posted, &expires, NULL)) {
-           if (!HISreplace(history, buff, arrived, posted, expires, NULL))
-                syswarn("cannot write new text for %s", buff);
-        } else {
-            syswarn("no entry for %s", buff);
-        }
-    }
-
- fail:
-    /* Close files; we're done. */
-    if (history != NULL && !HISclose(history)) {
-        syswarn("cannot close %s", History);
-       rc = 1;
-    }
-
-    return rc;
-}
diff --git a/extra/active b/extra/active
deleted file mode 100644 (file)
index f98b10a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-control 0000000000 0000000001 n
-control.cancel 0000000000 0000000001 n
-control.checkgroups 0000000000 0000000001 n
-control.newgroup 0000000000 0000000001 n
-control.rmgroup 0000000000 0000000001 n
-junk 0000000000 0000000001 n
-local.general 0000000000 0000000001 y
-local.test 0000000000 0000000001 y
diff --git a/extra/buildinnkeyring b/extra/buildinnkeyring
deleted file mode 100644 (file)
index 7d2c247..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-. /usr/lib/news/innshellvars
-
-cd $PATHTMP
-
-KEYSURL=ftp://ftp.isc.org/pub/pgpcontrol/PGPKEYS
-KEYSFILE=PGPKEYS
-
-KEYRING=${NEWSETC}/pgp/pubring.gpg
-
-trap "rm -f $KEYSFILE" 0 1 2 15
-
-rm -f ${KEYSFILE}
-${GETFTP} ${KEYSURL}
-
-test -f ${KEYSFILE} || exit 1
-
-gpg --batch --no-permission-warning \
-       --no-default-keyring --keyring=${KEYRING} --no-options \
-       --allow-non-selfsigned-uid --fast-import ${KEYSFILE}
-
-exit $$
-# this does not work because gpg refuses to use RSA-style fingerprints
-
-KEYSERVER=keyserver.linux.it
-
-SERVERKEYS=$(grep fingerprint ${CTLFILE} \
-       | sed -e 's/ //g' -e 's/.*[:=]/0x/' \
-       | grep -v '^#')
-
-for key in $SERVERKEYS; do
-    gpg --batch --no-permission-warning --verbose \
-       --no-default-keyring --keyring=${KEYRING} --no-options \
-       --keyserver=${KEYSERVER} --recv-keys ${key}
-done
-
diff --git a/extra/bunbatch b/extra/bunbatch
deleted file mode 100644 (file)
index ba380ff..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec /bin/bzip2 -d -c
diff --git a/extra/dh_cloneconf b/extra/dh_cloneconf
deleted file mode 100644 (file)
index d04d1c6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh -e
-
-IN="$1"
-OUT="$2"
-
-for file in debian/$IN.* debian/$IN*.files; do
-  case "$file" in
-    *.log) continue ;;
-  esac
-  [ -h $file ] && continue
-  base=${file##*/}
-  newfile=$(echo $file | sed -re "s#/$IN#/$OUT#")
-  [ -e $newfile ] || ln -s $base $newfile
-done
-
diff --git a/extra/ginpaths2 b/extra/ginpaths2
deleted file mode 100644 (file)
index ba021d3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh -e
-
-# Add this line in /etc/news/newsfeeds:
-# !inpaths:*:Tc,WP:/usr/lib/news/bin/ginpaths2
-
-exec /usr/lib/news/bin/ninpaths -p -d /var/log/news/path/inpaths.%d
diff --git a/extra/newsgroups b/extra/newsgroups
deleted file mode 100644 (file)
index 9d2ed2a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-control                        Various control messages (no posting)
-control.cancel         Cancel messages (no posting)
-control.checkgroups    Hierarchy check control messages (no posting)
-control.newgroup       Newsgroup creation control messages (no posting)
-control.rmgroup                Newsgroup removal control messages (no posting)
-junk                   Unfiled articles (no posting)
-local.general          Local general group
-local.test             Local test group
diff --git a/extra/sasl.conf b/extra/sasl.conf
deleted file mode 100644 (file)
index 94d894d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-tls_cert_file:         /etc/news/nnrpd-cert.pem
-tls_key_file:          /etc/news/nnrpd-key.pem
-tls_ca_path:           /etc/news
-tls_ca_file:           /etc/news/nnrpd-ca-cert.pem
diff --git a/extra/send-uucp.cf b/extra/send-uucp.cf
deleted file mode 100644 (file)
index ea7ac95..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# send-uucp.cf Configuration file for send-uucp
-#
-# Format:      sitename<Space>compressor<Space>maxsize<Space>batchtime
-#
-#              compressor, maxsize and batchtime can be left out and will
-#              then use the # default values. You can't leave out the second
-#              field (compressor) and still use the third (maxsize) etc.!
-#              So if you want to set a maxsize, you HAVE to add a
-#              compression method.
-#
-#              Compress keywords are: compress gzip none
-#
-#              You can use flags with your compressor, just add them. Use
-#              the `_' character instead of a space.
-#              For example   compress_-b13    for 13 bits compression.
-#
-#              Remember that the size you set is the size *before* compression!
-#
-#zoetermeer    gzip            1048576         5,18,22
-#hoofddorp     gzip            1048576         5,18,22
-#pa3ebv                gzip            1048576         5,18,22
-#drinkel       gzip            1048576         5,6,18,20,22,0,2
-#manhole       compress        1048576         5,18,22
-#owl           compress        1048576         5,18,22
-#able          compress        1048576         5,18,22
diff --git a/frontends/Makefile b/frontends/Makefile
deleted file mode 100644 (file)
index 0e44f2d..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top           = ..
-CFLAGS        = $(GCFLAGS)
-
-ALL          = c7unbatch cnfsheadconf cnfsstat ctlinnd decode encode \
-               getlist gunbatch inews innconfval mailpost pullnews \
-               ovdb_init ovdb_monitor ovdb_server ovdb_stat rnews \
-               scanspool sm
-
-SOURCES              = ctlinnd.c decode.c encode.c getlist.c inews.c innconfval.c \
-               ovdb_init.c ovdb_monitor.c ovdb_server.c ovdb_stat.c rnews.c \
-               sm.c
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_INEWS) inews $D$(PATHBIN)/inews
-       $(LI_RNEWS) rnews $D$(PATHBIN)/rnews
-       $(CP_XPRI) cnfsheadconf $D$(PATHBIN)/cnfsheadconf
-       for F in cnfsstat mailpost pullnews scanspool ; do \
-           $(CP_XPUB) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for F in ctlinnd ovdb_init ovdb_monitor ovdb_server ovdb_stat ; do \
-           $(LI_XPRI) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for F in getlist innconfval sm ; do \
-           $(LI_XPUB) $$F $D$(PATHBIN)/$$F ; \
-       done
-       $(CP_XPUB) c7unbatch $D$(PATHBIN)/rnews.libexec/c7unbatch
-       $(LI_XPUB) decode $D$(PATHBIN)/rnews.libexec/decode
-       $(LI_XPUB) encode $D$(PATHBIN)/rnews.libexec/encode
-       $(CP_XPUB) gunbatch $D$(PATHBIN)/rnews.libexec/gunbatch
-
-clean:
-       rm -f *.o $(ALL)
-       rm -rf .libs
-
-clobber distclean: clean
-       rm -f tags
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES)
-
-profiled:
-       $(MAKEPROFILING) all
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Compilation rules.
-
-BOTH           = $(LIBSTORAGE) $(LIBHIST) $(LIBINN)
-
-LINK           = $(LIBLD) $(LDFLAGS) -o $@
-INNLIBS                = $(LIBINN) $(LIBS)
-STORELIBS      = $(BOTH) $(EXTSTORAGELIBS) $(LIBS)
-
-FIX            = $(FIXSCRIPT)
-
-ctlinnd:       ctlinnd.o      $(LIBINN) ; $(LINK) ctlinnd.o      $(INNLIBS)
-decode:                decode.o       $(LIBINN) ; $(LINK) decode.o       $(INNLIBS)
-encode:                encode.o                 ; $(LINK) encode.o
-getlist:       getlist.o      $(LIBINN) ; $(LINK) getlist.o      $(INNLIBS)
-inews:         inews.o        $(LIBINN) ; $(LINK) inews.o        $(INNLIBS)
-innconfval:    innconfval.o   $(LIBINN) ; $(LINK) innconfval.o   $(INNLIBS)
-ovdb_init:     ovdb_init.o    $(BOTH)   ; $(LINK) ovdb_init.o    $(STORELIBS)
-ovdb_monitor:  ovdb_monitor.o $(BOTH)   ; $(LINK) ovdb_monitor.o $(STORELIBS)
-ovdb_server:   ovdb_server.o  $(BOTH)   ; $(LINK) ovdb_server.o  $(STORELIBS)
-ovdb_stat:     ovdb_stat.o    $(BOTH)   ; $(LINK) ovdb_stat.o    $(STORELIBS)
-rnews:         rnews.o        $(LIBINN) ; $(LINK) rnews.o        $(STORELIBS)
-sm:            sm.o           $(BOTH)   ; $(LINK) sm.o           $(STORELIBS)
-
-ovdb_init.o: ovdb_init.c
-       $(CC) $(CFLAGS) $(BERKELEY_DB_CFLAGS) -c $<
-
-ovdb_monitor.o: ovdb_monitor.c
-       $(CC) $(CFLAGS) $(BERKELEY_DB_CFLAGS) -c $<
-
-ovdb_server.o: ovdb_server.c
-       $(CC) $(CFLAGS) $(BERKELEY_DB_CFLAGS) -c $<
-
-ovdb_stat.o: ovdb_stat.c
-       $(CC) $(CFLAGS) $(BERKELEY_DB_CFLAGS) -c $<
-
-cnfsheadconf:  cnfsheadconf.in  $(FIX) ; $(FIX) cnfsheadconf.in
-cnfsstat:      cnfsstat.in      $(FIX) ; $(FIX) cnfsstat.in
-mailpost:      mailpost.in      $(FIX) ; $(FIX) mailpost.in
-pullnews:      pullnews.in      $(FIX) ; $(FIX) -i pullnews.in
-scanspool:     scanspool.in     $(FIX) ; $(FIX) scanspool.in
-
-c7unbatch: Makefile ../Makefile.global
-       ( echo '#! $(SHELL)' ; echo 'decode | $(UNCOMPRESS)' ) > $@
-       chmod 755 c7unbatch
-
-gunbatch: Makefile ../Makefile.global
-       ( echo '#! $(SHELL)' ; echo 'exec $(GZIP) -d -c' ) > $@
-       chmod 755 gunbatch
-
-##  Not normally built.
-feedone:       feedone.o     $(LIBINN) ; $(LINK) feedone.o $(INNLIBS)
-sys2nf:                sys2nf.o      $(LIBINN) ; $(LINK) sys2nf.o  $(INNLIBS)
-
-$(LIBINN):     ; (cd ../lib ; $(MAKE))
-$(LIBSTORAGE): ; (cd ../storage ; $(MAKE))
-$(LIBHIST):    ; (cd ../history ; $(MAKE))
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend:        Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-ctlinnd.o: ctlinnd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inndcomm.h ../include/libinn.h \
-  ../include/paths.h
-decode.o: decode.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h
-encode.o: encode.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-getlist.o: getlist.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/paths.h
-inews.o: inews.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/messages.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h
-innconfval.o: innconfval.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h
-ovdb_init.o: ovdb_init.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../storage/ovdb/ovdb.h \
-  ../storage/ovdb/ovdb-private.h
-ovdb_monitor.o: ovdb_monitor.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/setproctitle.h \
-  ../include/config.h ../include/portable/wait.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/messages.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ../storage/ovdb/ovdb.h ../storage/ovdb/ovdb-private.h
-ovdb_server.o: ovdb_server.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h \
-  ../include/portable/time.h ../include/portable/setproctitle.h \
-  ../include/portable/socket.h ../include/portable/wait.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/paths.h \
-  ../include/storage.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../storage/ovdb/ovdb.h \
-  ../storage/ovdb/ovdb-private.h
-ovdb_stat.o: ovdb_stat.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ../include/paths.h \
-  ../include/storage.h ../storage/ovdb/ovdb.h \
-  ../storage/ovdb/ovdb-private.h
-rnews.o: rnews.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/wait.h ../include/config.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/messages.h \
-  ../include/inn/wire.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-sm.o: sm.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/qio.h ../include/storage.h
diff --git a/frontends/cnfsheadconf.in b/frontends/cnfsheadconf.in
deleted file mode 100644 (file)
index a87ebe1..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-#  $Id: cnfsheadconf.in 6727 2004-05-16 21:21:14Z rra $
-# 
-#  Copyright Andreas Lamrecht 1998
-#  <Andreas.Lamprect@siemens.at>
-#
-#  Modified by Kjetil T. Homme 1998
-#  <kjetilho@ifi.uio.no>
-#
-#  Modified by Robert R. Collier 1998
-#  <rob@lspace.org>
-# 
-#  bigint support added by Duane Currie (sandman@hub.org) 1998
-#
-#  cnfsheadconf is originally from cnfsstat 1999
-#  <kondou@nec.co.jp>
-
-use vars qw($opt_h $opt_w);
-use Getopt::Long;
-
-# required for >32bit ints
-require 'bigint.pl';
-
-my($conffile) = "$inn::pathetc/cycbuff.conf";
-my($storageconf) = "$inn::pathetc/storage.conf";
-
-# Hex to bigint conversion routine
-# bhex(HEXSTRING) returns BIGINT  (with leading + chopped off)
-#
-# In most langauge, unlimited size integers are done using string math
-# libraries usually called bigint.  (Java, Perl, etc...)
-
-# Bigint's are really just strings.
-
-# Mathematics routines for bigint's:
-
-#   bneg(BINT) return BINT              negation
-#   babs(BINT) return BINT              absolute value
-#   bcmp(BINT,BINT) return CODE         compare numbers (undef,<0,=0,>0)
-#   badd(BINT,BINT) return BINT         addition
-#   bsub(BINT,BINT) return BINT         subtraction
-#   bmul(BINT,BINT) return BINT         multiplication
-#   bdiv(BINT,BINT) return (BINT,BINT)  division (quo,rem) just quo if scalar
-#   bmod(BINT,BINT) return BINT         modulus
-#   bgcd(BINT,BINT) return BINT         greatest common divisor
-#   bnorm(BINT) return BINT             normalization
-
-sub bhex {
-    my $hexValue = shift;
-    $hexValue =~ s/^0x//;
-
-    my $integerValue = '0';
-    for (my $i = 0; $i < length($hexValue); $i+=2) {
-        # Could be more efficient going at larger increments, but byte
-        # by byte is safer for the case of 9 byte values, 11 bytes, etc.. 
-
-        my $byte = substr($hexValue,$i,2);
-        my $byteIntValue = hex($byte);
-
-        $integerValue = bmul($integerValue,'256');        
-        $integerValue = badd($integerValue,"$byteIntValue");
-        }
-
-    $integerValue =~ s/^\+//;
-    return $integerValue;
-    }
-
-sub bint2hex {
-    my $d = shift; 
-    my $o = 0;
-
-    while ($d > 0) {
-        my $h = bmod("$d",'16');
-        $d = bdiv("$d",'16');
-        $h =~ s/^\+//;
-        $h='a' if $h eq '10';
-        $h='b' if $h eq '11';
-        $h='c' if $h eq '12';
-        $h='d' if $h eq '13';
-        $h='e' if $h eq '14';
-        $h='f' if $h eq '15';
-        $h =~ s/^\+//;
-        $o="$h$o";  
-    }
-
-    return "$o";
-}
-
-sub usage {
-    print <<_end_;
-Summary tool for cycbuff header manipulation
-
-Usage:
-       $0 [-c CYCBUFF] [-h] [-w]
-
-       If called without args, does a one-time status of all CNFS buffers
-       -c <cycbuff>:  prints out status of cycbuff
-       -w:            change header
-       -h:            This information
-_end_
-    exit(1);
-}
-
-my(@line, %class, %metamode, %buff, %stor, $c, @buffers, $cycbuff);
-
-my($gr, $cl, $min, $max, @storsort, $header_printed);
-
-GetOptions("-c=s", \$cycbuff, "-w", "-h");
-
-&usage if $opt_h;
-
-unless (&read_cycbuffconf) {
-    print STDERR "Cannot open CycBuff Conffile $conffile ...\n";
-    exit (1);
-}
-
-unless (&read_storageconf) {
-    print STDERR "No valid $storageconf.\n";
-    exit (1);
-}
-
-sub read_cycbuffconf {
-    return 0 unless open (CONFFILE, $conffile);
-
-    while(<CONFFILE>) {
-       $_ =~ s/^\s*(.*?)\s*$/$1/;
-       # \x23 below is #.  Emacs perl-mode gets confused by the "comment"
-       next if($_ =~ /^\s*$/ || $_ =~ /^\x23/);
-       next if($_ =~ /^cycbuffupdate:/ || $_ =~ /^refreshinterval:/);
-
-       if($_ =~ /^metacycbuff:/) {
-           @line = split(/:/, $_);
-           if($class{$line[1]}) {
-               print STDERR "Class $line[1] more than one time in CycBuff Conffile $conffile ...\n";
-               return 0;
-           }
-
-           $class{$line[1]} = $line[2];
-           if ($line[3] ne "") {
-               $metamode{$line[1]} = $line[3];
-           } else {
-               $metamode{$line[1]} = "INTERLEAVE";
-           }
-           next;
-       }
-
-       if ($_ =~ /^cycbuff/) {
-           @line = split(/:/, $_);
-           if($buff{$line[1]}) {
-               print STDERR "Buff $line[1] more than one time in CycBuff Conffile $conffile ...\n";
-               return 1;
-           }
-           $buff{$line[1]} = $line[2];
-           next;
-       }
-
-       print STDERR "Unknown config line \"$_\" in CycBuff Conffile $conffile ...\n";
-    }
-    close(CONFFILE);
-    return 1;
-}
-
-sub read_storageconf {
-    my $line = 0;
-    return 0 unless open (STOR, $storageconf);
-
-    while (<STOR>) {
-       ++$line;
-       next if /^\s*#/;
-
-       # defaults
-       %key = ("NEWSGROUPS" => "*",
-               "SIZE" => "0,0");
-
-       if (/method\s+cnfs\s+\{/) {
-           while (<STOR>) {
-               ++$line;
-               next if /^\s*#/;
-               last if /\}/;
-               if (/(\w+):\s+(\S+)/i) {
-                   $key{uc($1)} = $2;
-               }
-           }
-           unless (defined $key{'CLASS'} && defined $key{'OPTIONS'}) {
-               print STDERR "storage.conf:$line: ".
-                       "Missing 'class' or 'options'\n";
-               return 0;
-           }
-
-           $key{'SIZE'} .= ",0" unless $key{'SIZE'} =~ /,/;
-           $key{'SIZE'} =~ s/,/:/;
-
-           if (defined $stor{$key{'OPTIONS'}}) {
-               print STDERR "storage.conf:$line: ".
-                       "Class $key{'CLASS'} has several criteria\n";
-           } else {
-               $stor{$key{'OPTIONS'}} = "$key{'NEWSGROUPS'}:$key{'CLASS'}:" .
-                       "$key{'SIZE'}:$key{'OPTIONS'}";
-               push(@storsort, $key{'OPTIONS'});
-           }
-       }
-    }
-    return 1;
-}
-
-START:
-
-if (! $buff{$cycbuff} ) {
-       print STDERR "No buffer definition for buffer $cycbuff ...\n";
-       exit(1);
-}
-&print_cycbuff_head($buff{$cycbuff});
-
-sub make_time {
-    my ($t) = @_;
-    my (@ret);
-
-    my ($sec,$min,$hour,$mday,$mon,$year) =
-           (localtime($t))[0..5];
-    push (@ret, sprintf("%04d-%02d-%02d %2d:%02d:%02d",
-                       $year + 1900, $mon + 1, $mday, $hour, $min, $sec));
-    $t = time - $t;
-
-    $mday = int($t/86400); $t = $t % 86400;
-    $hour = int($t/3600);  $t = $t % 3600;
-    $min  = int($t/60);    $t = $t % 60;
-
-    push (@ret, sprintf("%4d days, %2d:%02d:%02d",
-                       $mday, $hour, $min, $t));
-    return @ret;
-}
-
-sub print_cycbuff_head {
-    my($buffpath) = $_[0];
-    my($CNFSMASIZ)=8;
-    my($CNFSNASIZ)=16;
-    my($CNFSPASIZ)=64;
-    my($CNFSLASIZ)=16;
-    my($headerlength) = 2 * $CNFSMASIZ + 2 * $CNFSNASIZ + $CNFSPASIZ + (5 * $CNFSLASIZ);
-    my($buff, @entries, $e);
-    my($magic, $name, $path, $lena, $freea, $updatea, $cyclenuma, $metaname, $orderinmeta, $currentbuff);
-
-    if ($opt_w) {
-       if(! open(BUFF, "+< $buffpath") ) {
-           print STDERR "Cannot open Cycbuff $buffpath ...\n";
-           exit(1);
-       }
-    } else {
-       if(! open(BUFF, "< $buffpath") ) {
-           print STDERR "Cannot open Cycbuff $buffpath ...\n";
-           exit(1);
-       }
-    }
-
-    $buff = "";
-    if(! read(BUFF, $buff, $headerlength) ) {
-       print STDERR "Cannot read $headerlength bytes from file $buffpath...\n";
-       exit(1);
-    }
-    
-    ($magic, $name, $path, $lena, $freea, $updatea, $cyclenuma, $metaname, $orderinmeta, $currentbuff)  = unpack("a8 a16 a64 a16 a16 a16 a16 a16 a16 a8", $buff);
-
-    if(!$magic) {
-       print STDERR "Error while unpacking header ...\n";
-       exit(1);
-    }
-
-    my($len) = bhex($lena);
-    my($free) = bhex($freea);
-    my($update) = hex($updatea);
-    my($cyclenum) = hex($cyclenuma) - 1;
-
-    my ($nupdate_str, $nago_str) = &make_time ($update);
-
-    $name =~ s/\0//g;
-    print " Buffer $name, len: ";
-    printf("%.2f", $len / (1024 * 1024));
-    print " Mbytes, used: ";
-    printf("%.2f Mbytes", $free / (1024 * 1024));
-    printf(" (%4.1f%%) %3d cycles\n", 100 * $free/$len, $cyclenum);
-    print(" Meta $metaname, order: ");
-    printf("%d", $orderinmeta);
-    print(", current: $currentbuff");
-    
-    print "\n Newest: $nupdate_str, $nago_str ago\n";
-
-    if ($opt_w) {
-       print "\nBuffer [$name] => ";
-       $in = <>;
-       chop $in;
-       if ($in ne "") {
-           $name = sprintf("%0.9s\0", $in);
-       }
-       print "Path [$path] => ";
-       $in = <>;
-       chop $in;
-       if ($in ne "") {
-           $path = sprintf("%0.65s\0", $in);
-       }
-        print "Length [$len ($lena)] => ";
-        $in = <>;
-        chop $in;
-        if ($in ne "") {
-            $in = bint2hex($in);
-            $lena = sprintf("%017.17s\0", $in);
-        }
-       print "Free [$free ($freea)] => ";
-       $in = <>;
-       chop $in;
-       if ($in ne "") {
-            $in = bint2hex($in);
-           $freea = sprintf("%017.17s\0", $in);
-       }
-       print "Meta [$metaname] => ";
-       $in = <>;
-       chop $in;
-       if ($in ne "") {
-           $metaname = sprintf("%0.17s\0", $in);
-       }
-       print "Order [$orderinmeta] => ";
-       $in = <>;
-       chop $in;
-       if ($in ne "") {
-           $orderinmeta = sprintf("%016d\0", $in);
-       }
-       print "Currentbuff [$currentbuff] => ";
-       $in = <>;
-       chop $in;
-       if ($in eq "TRUE" || $in eq "FALSE") {
-           $currentbuff = sprintf("%0.8s", $in);
-       }
-       $buff = pack("a8 a16 a64 a16 a16 a16 a16 a16 a16 a8", $magic, $name, $path, $lena, $freea, $updatea, $cyclenuma, $metaname, $orderinmeta, $currentbuff);
-       seek(BUFF, 0, 0);
-           if(! syswrite(BUFF, $buff, $headerlength) ) {
-           print STDERR "Cannot write $headerlength bytes to file $buffpath...\n";
-           exit(1);
-       }
-    }
-    close(BUFF);
-}
diff --git a/frontends/cnfsstat.in b/frontends/cnfsstat.in
deleted file mode 100644 (file)
index dd449b9..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-#  $Id: cnfsstat.in 7060 2004-12-19 21:36:38Z rra $
-# 
-#  Copyright Andreas Lamrecht 1998
-#  <Andreas.Lamprect@siemens.at>
-#
-#  Modified by Kjetil T. Homme 1998, 2000
-#  <kjetilho@ifi.uio.no>
-#
-#  Modified by Robert R. Collier 1998
-#  <rob@lspace.org>
-# 
-#  bigint support added by Duane Currie (sandman@hub.org) 1998
-
-use vars qw($opt_l $opt_h $opt_a $opt_s);
-use Getopt::Long;
-use Math::BigInt;
-use Math::BigFloat;
-use English;
-
-my($conffile) = "$inn::pathetc/cycbuff.conf";
-my($storageconf) = "$inn::pathetc/storage.conf";
-
-sub usage {
-    print <<_end_;
-Summary tool for CNFS
-
-Usage:
-       $0 [-c CLASS] [-l [seconds]]
-
-       If called without args, does a one-time status of all CNFS buffers
-       -a:          print the age of the oldest article in the cycbuff
-       -c <CLASS>:  prints out status of CNFS buffers in class CLASS
-       -l seconds:  loops like vmstat, default seconds = 600
-       -s:          logs through syslog
-       -h:          This information
-       -m <BUFFER>: prints out information suitable for mrtg
-       -p:          prints out an mrtg config file 
-       -P:          write PID into $inn::pathrun/cnfsstat.pid
-_end_
-    exit(1);
-}
-
-my(@line, %class, %buff, %stor, $c, @buffers);
-
-my($gr, $cl, $min, $max, @storsort, $oclass, $header_printed);
-
-Getopt::Long::config('no_ignore_case');
-GetOptions("-a", "-c=s", \$oclass, "-h", "-l:i", "-s", "-m=s", \$obuffer,
-           "-p", "-P");
-
-&usage if $opt_h;
-
-if ($opt_s) {
-    $use_syslog = 0;
-    ## Comment out this eval line if you don't want to try to syslog
-    eval { require Sys::Syslog; import Sys::Syslog; $use_syslog = 1 };
-    if ($use_syslog) {
-       if (defined &Sys::Syslog::setlogsock && $] >= 5.00403) {
-           # we really need a common module to work all this junk out
-           if ($OSNAME eq "dec_osf") {
-               sub Sys::Syslog::_PATH_LOG { "/dev/log" }
-            }
-            Sys::Syslog::setlogsock('unix')
-                if $OSNAME =~ /linux|freebsd|dec_osf|darwin/;
-        }
-       openlog ('cnfsstat', 'pid', $inn::syslog_facility);
-    } else {
-       print STDERR "Syslog is not available.  -s option is ignored.\n";
-    }
-}
-
-if ($opt_P) {
-    open(FILE, ">$inn::pathrun/cnfsstat.pid") && do {
-       print FILE "$$\n";
-       close FILE;
-    };
-}
-
-my($sleeptime) = (defined($opt_l) && $opt_l > 0) ? $opt_l : 600;
-
-unless (&read_cycbuffconf) {
-    print STDERR "Cannot open CycBuff Conffile $conffile ...\n";
-    exit (1);
-}
-
-unless (&read_storageconf) {
-    print STDERR "No valid $storageconf.\n";
-    exit (1);
-}
-
-
-&mrtg($obuffer) if $obuffer;
-&mrtg_config if $opt_p;
-
-#foreach $c (keys(%class)) {
-#  print "Class: $c, definition: $class{$c}\n";
-#}
-#foreach $c (keys(%buff)) {
-#  print "Buff: $c, definition: $buff{$c}\n";
-#}
-# exit(0);
-
-START:
-
-undef($logline);
-if ($oclass) {
-    if ($class{$oclass}) {
-       if (!$header_printed) {
-           ($gr, $cl, $min, $max) = split(/:/, $stor{$oclass});
-           if ($use_syslog) {
-               if ($min || $max) {
-                   $logline = sprintf("Class %s for groups matching \"%s\" article size min/max: %d/%d", $oclass, $gr, $min, $max); 
-               } else {
-                   $logline = sprintf("Class %s for groups matching \"%s\"", $oclass, $gr); 
-               }
-           } else {
-               print STDOUT "Class $oclass";
-               print STDOUT " for groups matching \"$gr\"";
-               if ($min || $max) {
-                   print STDOUT ", article size min/max: $min/$max";
-               }
-               print STDOUT "\n";
-           }
-           $header_printed = 1;
-       }
-       
-       @buffers = split(/,/, $class{$oclass});
-       if (! @buffers) {
-           print STDERR "No buffers in Class $main::ARGV[0] ...\n";
-           next;
-       }
-       
-       foreach $b (@buffers) {
-           if (! $buff{$b} ) {
-               print STDERR "No buffer definition for buffer $b ...\n";
-               next;
-           }
-           &print_cycbuff_head($buff{$b});
-       }
-    } else {
-       print STDERR "Class $ARGV[1] not found ...\n";
-    }
-} else { # Print all Classes
-    
-    foreach $c (@storsort) {
-       ($gr, $cl, $min, $max) = split(/:/, $stor{$c});
-       if ($use_syslog) {
-           if ($min || $max) {
-               $logline = sprintf("Class %s for groups matching \"%s\" article size min/max: %d/%d", $c, $gr, $min, $max); 
-           } else {
-               $logline = sprintf("Class %s for groups matching \"%s\"", $c, $gr); 
-           }
-       } else {
-           print STDOUT "Class $c ";
-           print STDOUT " for groups matching \"$gr\"";
-           if($min || $max) {
-               print STDOUT ", article size min/max: $min/$max";
-           }
-           print STDOUT "\n";
-       }
-       @buffers = split(/,/, $class{$c});
-       if(! @buffers) {
-           print STDERR "No buffers in Class $c ...\n";
-           next;
-       }
-       
-       foreach $b (@buffers) {
-           if(! $buff{$b} ) {
-               print STDERR "No buffer definition for buffer $b ...\n";
-               next;
-           }
-           &print_cycbuff_head($buff{$b});
-       }
-       if ($use_syslog == 0) {
-           print STDOUT "\n";
-       }
-    }
-}
-
-if(defined($opt_l)) {
-    sleep($sleeptime);
-    if ($use_syslog == 0) {
-       print STDOUT "$sleeptime seconds later:\n";
-    }
-    goto START;
-}
-
-sub read_cycbuffconf {
-    return 0 unless open (CONFFILE, $conffile);
-
-    while(<CONFFILE>) {
-       $_ =~ s/^\s*(.*?)\s*$/$1/;
-       # Here we handle continuation lines
-       while (m/\\$/) {
-           $contline = <CONFFILE>;
-           $contline =~ s/^\s*(.*?)\s*$/$1/;
-           chop;
-           $_ .= $contline;
-       }
-       # \x23 below is #.  Emacs perl-mode gets confused by the "comment"
-       next if($_ =~ /^\s*$/ || $_ =~ /^\x23/);
-       next if($_ =~ /^cycbuffupdate:/ || $_ =~ /^refreshinterval:/);
-       
-       if($_ =~ /^metacycbuff:/) {
-           @line = split(/:/, $_);
-           if($class{$line[1]}) {
-               print STDERR "Class $line[1] more than one time in CycBuff Conffile $conffile ...\n";
-               return 0;
-           }
-
-           $class{$line[1]} = $line[2];
-           next;
-       }
-
-       if ($_ =~ /^cycbuff/) {
-           @line = split(/:/, $_);
-           if($buff{$line[1]}) {
-               print STDERR "Buff $line[1] more than one time in CycBuff Conffile $conffile ...\n";
-               return 1;
-           }
-           $buff{$line[1]} = $line[2];
-           next;
-       }
-
-       print STDERR "Unknown config line \"$_\" in CycBuff Conffile $conffile ...\n";
-    }
-    close(CONFFILE);
-    return 1;
-}
-
-sub read_storageconf {
-    my $line = 0;
-    return 0 unless open (STOR, $storageconf);
-
-    while (<STOR>) {
-       ++$line;
-       next if /^\s*#/;
-
-       # defaults
-       %key = ("NEWSGROUPS" => "*",
-               "SIZE" => "0,0");
-               
-       if (/method\s+cnfs\s+\{/) {
-           while (<STOR>) {
-               ++$line;
-               next if /^\s*#/;
-               last if /\}/;
-               if (/(\w+):\s+(\S+)/i) {
-                   $key{uc($1)} = $2;
-               }
-           }
-           unless (defined $key{'CLASS'} && defined $key{'OPTIONS'}) {
-               print STDERR "storage.conf:$line: ".
-                       "Missing 'class' or 'options'\n";
-               return 0;
-           }
-
-           $key{'SIZE'} .= ",0" unless $key{'SIZE'} =~ /,/;
-           $key{'SIZE'} =~ s/,/:/;
-           
-           if (!defined $stor{$key{'OPTIONS'}}) {
-               $stor{$key{'OPTIONS'}} = "$key{'NEWSGROUPS'}:$key{'CLASS'}:" .
-                       "$key{'SIZE'}:$key{'OPTIONS'}";
-               push(@storsort, $key{'OPTIONS'});
-           }
-       }
-    }
-    return 1;
-}
-
-sub print_cycbuff_head {
-    my ($buffpath) = $_[0];
-    my ($name, $len, $free, $update, $cyclenum, $oldart) =
-           &get_cycbuff_info($buffpath);
-    
-    if ($use_syslog) {
-       ($name) = split(/\s/, $name);
-       $name =~ s/\0//g;
-       syslog ('notice', '%s Buffer %s, len: %.2f  Mbytes, used: %.2f Mbytes (%4.1f%%) %3d cycles',
-               $logline, $name, $len / (1024 * 1024),
-               Math::BigFloat->new ($free) / (1024 * 1024),
-               100 * Math::BigFloat->new ($free) / $len, $cyclenum);
-       return 0;
-    }
-
-    $name =~ s/\0//g;
-    print " Buffer $name, size: ", &human_readable($len, 4);
-    print ", position: ", &human_readable($free, 4);
-    printf("  %.2f cycles\n", $cyclenum + Math::BigFloat->new ($free) / $len);
-    my ($when, $ago) = &make_time($update);
-    print "  Newest: $when, $ago ago\n";
-
-    if ($opt_a) {
-       my ($when, $ago) = &make_time($oldart);
-       print "  Oldest: $when, $ago ago\n";
-    }
-}
-
-sub make_time {
-    my ($t) = @_;
-    my (@ret);
-
-    my ($sec,$min,$hour,$mday,$mon,$year) =
-           (localtime($t))[0..5];
-    push (@ret, sprintf("%04d-%02d-%02d %2d:%02d:%02d",
-                       $year + 1900, $mon + 1, $mday, $hour, $min, $sec));
-    $t = time - $t;
-
-    $mday = int($t/86400); $t = $t % 86400;
-    $hour = int($t/3600);  $t = $t % 3600;
-    $min  = int($t/60);    $t = $t % 60;
-
-    push (@ret, sprintf("%4d days, %2d:%02d:%02d",
-                       $mday, $hour, $min, $t));
-    return @ret;
-}
-
-sub human_readable {
-    my ($val, $digits) = @_;
-    $val =~ s/\+//;
-
-    my @name = ("kBytes", "MBytes", "GBytes", "TBytes");
-    my $base = 1024;
-    my $factor = 1024;
-
-    my $unit = -1;
-    my $oldscaled = Math::BigFloat->new ($val) / $base;
-    my $scaled = $oldscaled;
-    while ( ( int($scaled) > 0 ) && ( $unit < $#name ) ) {
-       $oldscaled = $scaled;
-       $scaled /= $factor;
-       $unit++;
-    }
-    $scaled = $oldscaled;
-    my $predigits = length (int($scaled));
-    my $postdigits = $digits - $predigits - 1;
-    $postdigits = 0 if $postdigits < 0;
-    ++$digits;
-
-    return sprintf ("%${digits}.${postdigits}f %s", $scaled, $name[$unit]);
-}
-
-sub mrtg {
-       my $buffer = shift;
-       # print "Buffer = $buff{$buffer}\n";
-       @info = &get_cycbuff_info($buff{$buffer});
-       print "$info[1]\n";
-       print "$info[2]\n";
-       print "$info[4]\n";
-       print "$info[0]\n";
-       exit(0);
-}
-
-sub mrtg_config {
-       print "Sub MRTG-CONFIG\n";
-       foreach $class (sort(keys(%class))) {
-               print "##\n## Class  : $class\n## Wildmat: $stor{$class}\n##\n\n";
-               foreach $buffer (split /\,/,$class{$class}) {
-                       &mrtg_buffer($class,$buffer);
-               }
-       }
-       exit(0);
-}
-
-sub mrtg_buffer {
-       my ($class,$buffer) = @_;
-       #my ($name, $num, $buff, $size) = @_;
-        $tag = 'cnfs-' . $buffer;
-
-        print 'Target[', $tag, ']: `', "$inn::pathbin/cnfsstat -m ", $buffer, '`', "\n";  
-        print 'MaxBytes[', $tag, ']: ', (&get_cycbuff_info($buff{$buffer}))[1], "\n";
-        print 'Title[', $tag, ']: ', "${buffer} Usage\n";
-        print 'Options[', $tag, ']: growright gauge', "\n";
-        print 'YLegend[', $tag, ']: ', "${buffer}\n";
-        print 'ShortLegend[', $tag, ']: MB', "\n";
-        print 'PageTop[', $tag, ']: ', "<H1>Usage of ${buffer}</H1>\n";
-       print "<BR><TT>$stor{$class}</TT>\n";
-        print "\n";
-        1;
-}
-
-sub bigsysseek {
-    my($handle, $offset) = @_;
-
-    # $offset may be a bigint; and have a value that doesn't fit in a signed long.
-    # Even with largefiles enabled, perl will still truncate the argument to lseek64
-    # to 32 bits.  So we seek multiple times, <2G at a time.
-
-    if($offset > 2147483647) {
-       # Since perl truncates the return value of lseek64 to 32 bits, it might
-       # see a successful return value as negative, and return FALSE (undef).
-       # So we must ignore the return value of sysseek and assume that it worked.
-
-       seek($handle, 0, 0);
-       while($offset > 2000000000) {
-           sysseek($handle, 2000000000, 1) || return 0;
-           $offset -= 2000000000;
-       }
-       sysseek($handle, $offset, 1) || return 0;
-       return 1;
-    } else {
-       return sysseek($handle, $offset, 0);
-    }
-}
-
-sub check_read_return {
-  my $result = shift;
-  die "read: $!\n" unless defined($result);
-  die "read reached eof\n" unless $result;
-  return $result;
-}
-
-sub get_cycbuff_info {
-    my($buffpath) = $_[0];
-    
-    my($CNFSMASIZ)=8;
-    my($CNFSNASIZ)=16;
-    my($CNFSPASIZ)=64;
-    my($CNFSLASIZ)=16;
-    my($headerlength) = $CNFSMASIZ + $CNFSNASIZ + $CNFSPASIZ + (4 * $CNFSLASIZ);
-    
-    my($buff, @entries, $e);
-    my($magic, $name, $path, $lena, $freea, $updatea, $cyclenuma);
-    
-    if(! open(BUFF, "< $buffpath") ) {
-       print STDERR "Cannot open Cycbuff $buffpath ...\n";
-       exit(1);
-    }
-    
-    $buff = "";
-    if(! read(BUFF, $buff, $headerlength) ) {
-       print STDERR "Cannot read $headerlength bytes from file $buffpath...\n";
-       exit(1);
-    }
-    
-    ($magic, $name, $path, $lena, $freea, $updatea, $cyclenuma) =
-           unpack("a8 a16 a64 a16 a16 a16 a16", $buff);
-    
-    if(!$magic) {
-       print STDERR "Error while unpacking header ...\n";
-       exit(1);
-    }
-    
-    my($len) = bhex($lena);
-    my($free) = bhex($freea);
-    my($update) = hex($updatea);
-    my($cyclenum) = hex($cyclenuma) - 1;
-    
-    if ($opt_a) {
-
-       my $pagesize = 16384;
-       my $minartoffset = int($len / (512 * 8)) + 512;
-       # Align upwards:
-       $minartoffset = ($minartoffset + $pagesize) & ~($pagesize - 1);
-       
-       if ($cyclenum == 0 && $free == $minartoffset) {
-           # The cycbuff has no articles yet.
-           goto done;
-       }
-
-       # Don't loop endlessly, set rough upper bound
-       my $sentinel = $cyclenum == 0 ? $free : $len;
-       my $offset = $cyclenum == 0 ? $minartoffset : $free + $pagesize;
-
-       bigsysseek (BUFF, $offset) || die "sysseek: $!\n";
-       check_read_return (sysread (BUFF, $buff, $pagesize));
-       do {
-           check_read_return (sysread (BUFF, $chunk, $pagesize));
-           
-           $buff .= $chunk;
-           while ($buff =~ /^message-id:\s+(<.*?>)/mi) {
-               $buff = $POSTMATCH;
-               $oldart = &lookup_age ($1);
-               next unless $oldart;
-               
-               # Is the article newer than the last update?
-               if ($oldart >= $update) {
-                   $update = $oldart;
-               } elsif ($oldart < $update - 60) {
-                   goto done;
-               }
-           }
-           # Just in case we chopped Message-ID in two, use the end
-           # at the front in next iteration.
-           $buff = substr ($buff, -512);
-
-       } while ($sentinel -= $pagesize > 0);
-    }
-
-done:    
-    close(BUFF);
-    return($name,$len,$free,$update,$cyclenum,$oldart);
-}
-
-sub lookup_age {
-    my ($msgid) = @_;
-
-    my $history = &safe_run("grephistory", "-l", $msgid);
-    if ($history =~ /\t(\d+)~/) {
-       return $1;
-    }
-    print "  (Missing $msgid)\n";
-    return 0;
-}
-
-sub safe_run {
-    my $output = "";
-
-    my $pid = open(KID_TO_READ, "-|");
-    die "fork: $!\n" unless defined $pid;
-    if ($pid) {
-       while (<KID_TO_READ>) {
-           $output .= $_;
-       }
-       close(KID_TO_READ);
-    } else {
-       exec(@_) || die "can't exec $_[0]: $!";
-       # NOTREACHED
-    }
-    return $output;
-}
-
-# Hex to bigint conversion routine
-# bhex(HEXSTRING) returns BIGINT  (with leading + chopped off)
-#
-# In most languages, unlimited size integers are done using string math
-# libraries usually called bigint.  (Java, Perl, etc...)
-
-# Bigint's are really just strings.
-
-sub bhex {
-    my $hexValue = shift;
-    $hexValue =~ s/^0x//;
-    
-    my $integerValue = new Math::BigInt '0';
-    for (my $i = 0; $i < length($hexValue); $i += 2) {
-        # Could be more efficient going at larger increments, but byte
-        # by byte is safer for the case of 9 byte values, 11 bytes, etc.. 
-        my $byte = substr($hexValue, $i, 2);
-        my $byteIntValue = hex($byte);
-
-        $integerValue = $integerValue * "256";
-        $integerValue = $integerValue + "$byteIntValue";
-    }
-
-    $integerValue =~ s/^\+//;
-    return $integerValue;
-}
diff --git a/frontends/ctlinnd.c b/frontends/ctlinnd.c
deleted file mode 100644 (file)
index e2d8ada..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*  $Id: ctlinnd.c 6155 2003-01-19 19:58:25Z rra $
-**
-**  Send control messages to the InterNetNews daemon.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inndcomm.h"
-#include "libinn.h"
-#include "paths.h"
-
-
-/*
-**  Datatype for an entry in the command table.
-*/
-typedef struct _COMMAND {
-    const char *Command;
-    const char *Text;
-    int                argc;
-    char       Letter;
-    bool       Glue;
-} COMMAND;
-
-
-static COMMAND Commands[] = {
-    {  "addhist",      "id arr exp post token...\tAdd history line",
-       5,      SC_ADDHIST,     true    },
-    {  "allow",        "reason...\t\t\tAllow remote connections",
-       1,      SC_ALLOW,       true    },
-    {  "begin",        "site\t\t\tStart newly-added site",
-       1,      SC_BEGIN,       false   },
-    {  "cancel",       "id\t\t\tCancel message locally",
-       1,      SC_CANCEL,      false   },
-    {  "changegroup",  "group rest\tChange mode of group",
-       2,      SC_CHANGEGROUP, false   },
-    {  "checkfile",    "\t\t\tCheck syntax of newsfeeds file",
-       0,      SC_CHECKFILE,   false   },
-    {  "drop",         "site\t\t\tStop feeding site",
-       1,      SC_DROP,        false           },
-    {  "feedinfo",             "site\t\t\tPrint state of feed to site*",
-       1,      SC_FEEDINFO,    false           },
-#if defined(DO_TCL)
-    {  "tcl",                  "flag\t\t\tEnable or disable Tcl filtering",
-       1,      SC_FILTER,      false           },
-#endif /* defined(DO_TCL) */
-    {  "flush",        "site\t\t\tFlush feed for site*",
-       1,      SC_FLUSH,       false   },
-    {  "flushlogs",    "\t\t\tFlush log files",
-       0,      SC_FLUSHLOGS,   false   },
-    {  "go",           "reason...\t\t\tRestart after pause or throttle",
-       1,      SC_GO,          true    },
-    {  "hangup",       "channel\t\tHangup specified incoming channel",
-       1,      SC_HANGUP,      false   },
-    {  "logmode",              "\t\t\t\tSend server mode to syslog",
-       0,      SC_LOGMODE,     false           },
-    {  "mode",         "\t\t\t\tPrint operating mode",
-       0,      SC_MODE,        false           },
-    {  "name",         "nnn\t\t\tPrint name of specified channel*",
-       1,      SC_NAME,        false           },
-    {  "newgroup",     "group rest creator\tCreate new group",
-       3,      SC_NEWGROUP,    false   },
-    {  "param",        "letter value\t\tChange command-line parameters",
-       2,      SC_PARAM,       false   },
-    {  "pause",        "reason...\t\tShort-term pause in accepting articles",
-       1,      SC_PAUSE,       true    },
-#if defined(DO_PERL)
-    {  "perl",                 "flag\t\t\tEnable or disable Perl filtering",
-       1,      SC_PERL,        false   },
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-    {  "python",               "flag\t\t\tEnable or disable Python filtering",
-       1,      SC_PYTHON,      false   },
-#endif /* (DO_PYTHON) */
-    {  "readers",      "flag text...\t\tEnable or disable newsreading",
-       2,      SC_READERS,     true    },
-    {  "reject",       "reason...\t\t\tReject remote connections",
-       1,      SC_REJECT,      true    },
-    {  "reload",       "what reason...\t\tRe-read config files*",
-       2,      SC_RELOAD,      true    },
-    {  "renumber",     "group\t\tRenumber the active file*",
-       1,      SC_RENUMBER,    false   },
-    {  "reserve",      "reason...\t\tReserve the next pause or throttle",
-       1,      SC_RESERVE,     true    },
-    {  "rmgroup",      "group\t\t\tRemove named group",
-       1,      SC_RMGROUP,     false   },
-    {  "send",         "feed text...\t\tSend text to exploder feed",
-       2,      SC_SEND,        true    },
-    {  "shutdown",     "reason...\t\tShut down server",
-       1,      SC_SHUTDOWN,    true    },
-    {  "stathist",     "filename|off\t\tLog into filename some history stats",
-       1,      SC_STATHIST,    false   },
-    {  "status",       "interval|off\t\tTurn innd status generation on or off",
-       1,      SC_STATUS,      false   },
-    {  "kill", "signal site\t\tSend signal to site's process",
-       2,      SC_SIGNAL,      false   },
-    {  "throttle",     "reason...\t\tStop accepting articles",
-       1,      SC_THROTTLE,    true    },
-    {   "timer",       "interval|off\t\tTurn performance monitoring on or off",
-       1,      SC_TIMER,       false   },
-    {  "trace",        "innd|#|nnrpd flag\tTurn tracing on or off",
-       2,      SC_TRACE,       false   },
-    {  "xabort",       "text...\t\tAbort the server",
-       1,      SC_XABORT,      true    },
-    { "lowmark",       "filename\t\tReset active file low article marks",
-       1,      SC_LOWMARK,     false   },
-    { "renumberlow",   "filename\t\tReset active file low article marks",
-       1,      SC_LOWMARK,     false   },
-    {  "xexec",        "path\t\t\tExec new server",
-       1,      SC_XEXEC,       false   }
-};
-
-\f
-
-/*
-**  Print a help summary.
-*/
-static void
-Help(char *p)
-{
-    COMMAND    *cp;
-
-    if (p == NULL) {
-       printf("Command summary:\n");
-       for (cp = Commands; cp < ARRAY_END(Commands); cp++)
-           printf("  %s %s\n", cp->Command, cp->Text);
-       printf("*   Empty string means all sites/groups/etc.\n");
-       printf("... All trailing words are glued together.\n");
-       exit(0);
-    }
-    for (cp = Commands; cp < ARRAY_END(Commands); cp++)
-       if (strcmp(p, cp->Command) == 0) {
-           printf("Command usage:\n");
-           printf("  %s %s\n", cp->Command, cp->Text);
-           exit(0);
-       }
-    printf("No such command.\n");
-    exit(0);
-}
-
-
-/*
-**  Print a command-usage message and exit.
-*/
-static void
-WrongArgs(COMMAND *cp)
-{
-    printf("Wrong number of arguments -- usage:\n");
-    printf("  %s %s\n", cp->Command, cp->Text);
-    exit(1);
-}
-
-
-/*
-**  Print an error message and exit.
-*/
-static void
-Failed(const char *p)
-{
-    if (ICCfailure)
-        syswarn("cannot %s (%s failure)", p, ICCfailure);
-    else
-        syswarn("cannot %s", p);
-    ICCclose();
-    exit(1);
-}
-
-
-/*
-**  Print an error reporting incorrect usage.
-*/
-static void
-Usage(const char *what)
-{
-    fprintf(stderr, "Usage error (%s) -- try -h for help.\n", what);
-    exit(1);
-}
-
-
-int main(int ac, char *av[])
-{
-    static char                Y[] = "y";
-    static char                EMPTY[] = "";
-    COMMAND            *cp;
-    char               *p;
-    int                        i;
-    bool               Silent;
-    bool               NeedHelp;
-    char               *reply;
-    char               *new;
-    int                        length;
-    char               *nv[4];
-    struct stat                Sb;
-    char               buff[SMBUF];
-
-    /* First thing, set up our identity. */
-    message_program_name = "ctlinnd";
-
-    /* Set defaults. */
-    if (!innconf_read(NULL))
-        exit(1);
-    Silent = false;
-    NeedHelp = false;
-    ICCsettimeout(CTLINND_TIMEOUT);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "hst:")) != EOF)
-       switch (i) {
-       default:
-           Usage("bad flags");
-           /* NOTREACHED */
-       case 'h':               /* Get help                     */
-           NeedHelp = true;
-           break;
-       case 's':               /* Silent -- no output          */
-           Silent = true;
-           break;
-       case 't':               /* Time to wait for reply       */
-           ICCsettimeout(atoi(optarg));
-           break;
-       }
-    ac -= optind;
-    av += optind;
-    if (NeedHelp)
-       Help(av[0]);
-    if (ac == 0)
-       Usage("missing command");
-
-    /* Look up the command word and move to the arguments. */
-    if (strcmp(av[0], "help") == 0)
-       Help(av[1]);
-    for (cp = Commands; cp < ARRAY_END(Commands); cp++)
-       if (strcmp(av[0], cp->Command) == 0)
-           break;
-    if (cp == ARRAY_END(Commands))
-       Usage("unknown command");
-    ac--;
-    av++;
-
-    /* Check argument count. */
-    if (cp->Letter == SC_NEWGROUP) {
-       /* Newgroup command has defaults. */
-       switch (ac) {
-       default:
-           WrongArgs(cp);
-           /* NOTREACHED */
-       case 1:
-           nv[0] = av[0];
-           nv[1] = Y;
-           nv[2] = EMPTY;
-           nv[3] = NULL;
-           av = nv;
-           break;
-       case 2:
-           nv[0] = av[0];
-           nv[1] = av[1];
-           nv[2] = EMPTY;
-           nv[3] = NULL;
-           av = nv;
-           break;
-       case 3:
-           break;
-       }
-       ac = 3;
-    }
-    else if (ac > cp->argc && cp->Glue) {
-       /* Glue any extra words together. */
-       for (length = 0, i = cp->argc - 1; (p = av[i++]) != NULL; )
-           length += strlen(p) + 1;
-        new = xmalloc(length);
-        *new = '\0';
-       for (i = cp->argc - 1; av[i]; i++) {
-           if (i >= cp->argc)
-                strlcat(new, " ", length);
-            strlcat(new, av[i], length);
-       }
-       av[cp->argc - 1] = new;
-       av[cp->argc] = NULL;
-    }
-    else if (ac != cp->argc)
-       /* All other commands must have the right number of arguments. */
-       WrongArgs(cp);
-
-    /* For newgroup and changegroup, make sure the mode is valid. */
-    if (cp->Letter == SC_NEWGROUP || cp->Letter == SC_CHANGEGROUP) {
-       switch (av[1][0]) {
-       default:
-           Usage("Bad group mode");
-           /* NOTREACHED */
-       case NF_FLAG_ALIAS:
-       case NF_FLAG_EXCLUDED:
-       case NF_FLAG_MODERATED:
-       case NF_FLAG_OK:
-       case NF_FLAG_NOLOCAL:
-       case NF_FLAG_IGNORE:
-           break;
-       }
-    }
-
-    /* Make sure there are no separators in the parameters. */
-    for (i = 0; (p = av[i++]) != NULL; )
-       if (strchr(p, SC_SEP) != NULL)
-            die("illegal character \\%03o in %s", SC_SEP, p);
-
-    /* Do the real work. */
-    if (ICCopen() < 0)
-       Failed("setup communication");
-    i = ICCcommand(cp->Letter, (const char **) av, &reply);
-    if (i < 0) {
-       i = errno;
-       p = concatpath(innconf->pathrun, _PATH_SERVERPID);
-       if (stat(p, &Sb) < 0)
-            warn("no innd.pid file; did server die?");
-        free(p);
-       snprintf(buff, sizeof(buff), "send \"%s\" command", cp->Command);
-       errno = i;
-       Failed(buff);
-    }
-
-    if (reply) {
-       /* Skip "<exitcode><space>" part of reply. */
-       for (p = reply; *p && CTYPE(isdigit, *p); p++)
-           continue;
-       while (*p && ISWHITE(*p))
-           p++;
-       if (i != 0)
-            warn("%s", p);
-       else if (!Silent)
-           printf("%s\n", p);
-    }
-
-    if (ICCclose() < 0)
-       Failed("end communication");
-
-    exit(i);
-    /* NOTREACHED */
-}
diff --git a/frontends/decode.c b/frontends/decode.c
deleted file mode 100644 (file)
index a862ccf..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-**  Decode seven-bit input into full binary output.
-**  From @(#)decode.c 1.3 5/15/85, distributed with B2.11 News.
-**
-**  Collect runs of 12 seven-bit characters.  Combine them in pairs to
-**  make six 13-bit characters.  Extract the top bit of each pair to make
-**  a 13th six-bit character, and split the remaining six 12-bit
-**  characters to form 12 six-bit characters.  Collect four six-bit
-**  characters and convert it to three eight-bit characters.
-**
-**  Got that?  All the remaining work in this program is to get the
-**  ending conditions right.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-
-
-/*
-**  These characters can't appear in normal output, so we use them to
-**  mark that the data that follows is the terminator.  The character
-**  immediately following this pair is the length of the terminator (which
-**  otherwise might be indeterminable)
-*/
-#define ENDMARK1       ((90 * 91 + 90) / 91)
-#define ENDMARK2       ((90 * 91 + 90) % 91)
-
-
-static char    Buffer[4];
-static int     count;
-
-
-static void
-pack6(int n, int last)
-{
-    char       *q;
-    int        i;
-    char               b3[3];
-
-    i = 3;
-    if (last && (i = Buffer[n - 1]) >= 3) {
-       /* Do the best we can. */
-        warn("badly-terminated file");
-       i = 3;
-    }
-
-    b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
-    b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
-    b3[2] = (Buffer[2] << 6) | ( Buffer[3]       & 0x3F);
-    for (q = b3; --i >= 0; )
-       putchar(*q++);
-}
-
-
-static void
-pack12(char *p, int n, int last)
-{
-    char       *q;
-    int        c13;
-    int        c;
-    int        i;
-    char               b13[13];
-    char               b3[3];
-
-    for (q = b13, c13 = 0, i = 0; i < n; i += 2) {
-       c = *p++ * 91;
-       c += *p++;
-       c13 <<= 1;
-       if (c & (1 << 12))
-           c13 |= 1;
-       *q++ = (c >> 6) & 0x3F;
-       *q++ = c & 0x3F;
-    }
-    *q++ = (char)c13;
-    if (last)
-       q = &b13[last];
-
-    for (p = b13, n = q - p, i = count, q = &Buffer[count]; --n > 0; ) {
-       *q++ = *p++;
-       if (++i == 4) {
-           /* Inline expansion of pack6. */
-           b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
-           b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
-           b3[2] = (Buffer[2] << 6) | ( Buffer[3]       & 0x3F);
-           putchar(b3[0]);
-           putchar(b3[1]);
-           putchar(b3[2]);
-           i = 0;
-           q = Buffer;
-       }
-    }
-
-    /* The last octet. */
-    *q++ = *p++;
-    i++;
-
-    if (last || i == 4) {
-       pack6(i, last);
-       i = 0;
-    }
-
-    count = i;
-}
-
-
-int
-main(void)
-{
-    int        c;
-    char       *p;
-    int        i;
-    int        first;
-    int        cnt;
-    char               *base;
-    char               b12[12];
-    char               c12[12];
-
-    message_program_name = "decode";
-
-    base = p = b12;
-    for (i = 12, cnt = 0, first = 1; (c = getchar()) != EOF; ) {
-       if (c < ' ' || c >= ' ' + 91)
-            die("bad data");
-       if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
-           cnt = c - ' ';
-           i = 12;
-           p -= 2;
-           continue;
-       }
-       *p++ = c - ' ';
-       if (--i == 0) {
-           if (p == &b12[12]) {
-               if (!first)
-                   pack12(c12, 12, 0);
-               else
-                   first = 0;
-               base = p = c12;
-           }
-           else {
-               pack12(b12, 12, 0);
-               base = p = b12;
-           }
-           i = 12;
-       }
-    }
-
-    if (base == b12) {
-       if (!first)
-           pack12(c12, 12, i == 12 ? cnt : 0);
-    }
-    else
-       pack12(b12, 12, i == 12 ? cnt : 0);
-
-    if (i != 12)
-       pack12(base, 12 - i, cnt);
-
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/frontends/encode.c b/frontends/encode.c
deleted file mode 100644 (file)
index f23b882..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*  $Id: encode.c 6119 2003-01-13 07:59:39Z rra $
-**
-**  Produce a seven-bit printable encoding of stdin on stdout.
-**  From @(#)encode.c 1.3 5/15/85, distributed with B2.11 News.
-**
-**  The encoding uses characters from 0x20 (' ') through 0x7A ('z').
-**  (That fits nicely into the UUCP 'f' protocol by Piet Beertema.) First,
-**  expand three eight-bit charcters into four six-bit ones.  Collect
-**  until we have 13, and spread the last one over the first 12, so that
-**  we have 12 6.5-bit characters.  Since there are very few half-bit
-**  machines, collect them into pairs, making six 13-bit characters.  We
-**  can do this as A * 91 + B where A and B are less then 91 after we add
-**  0x20 to make it printable.
-**
-**  And if you thought that was unclear, then we won't even get into the
-**  terminating conditions!
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-
-/*
-**  These characters can't appear in normal output, so we use them to
-**  mark that the data that follows is the terminator.  The character
-**  immediately following this pair is the length of the terminator (which
-**  otherwise might be indeterminable)
-*/
-#define ENDMARK1       ((90 * 91 + 90) / 91 + ' ')
-#define ENDMARK2       ((90 * 91 + 90) % 91 + ' ')
-
-static char    Buffer[13];
-static int     Count;
-
-
-static void
-dumpcode(char *p, int n)
-{
-    int        last;
-    int        c;
-
-    if (n == 13) {
-       n--;
-       last = p[12];
-    }
-    else if (n & 1)
-       last = 1 << (6 - 1);
-    else
-       last = 0;
-
-    for (; n > 0; n -= 2) {
-       c = *p++ << 6;
-       c |= *p++;
-       if (last & (1 << (6 - 1)))
-           c |= (1 << 12);
-       last <<= 1;
-
-       putchar((c / 91) + ' ');
-       putchar((c % 91) + ' ');
-    }
-}
-
-static void
-flushout(void)
-{
-    putchar(ENDMARK1);
-    putchar(ENDMARK2);
-    putchar(Count + ' ');
-    dumpcode(Buffer, Count);
-}
-
-
-static void
-encode(char *dest, int n)
-{
-    char       *p;
-    int        i;
-    int        j;
-    char               b4[4];
-
-    b4[0] = (dest[0] >> 2) & 0x3F;
-    b4[1] = ((dest[0] & 0x03) << 4) | ((dest[1] >> 4) & 0x0F);
-    b4[2] = ((dest[1] & 0x0F) << 2) | ((dest[2] >> 6) & 0x03);
-    b4[3] = (char)(n == 3 ? dest[2] & 0x3F : n);
-
-    for (p = b4, i = Count, dest = &Buffer[i], j = 4; --j >= 0; i++) {
-       if (i == 13) {
-           dumpcode(Buffer, 13);
-           dest = Buffer;
-           i = 0;
-       }
-       *dest++ = *p++;
-    }
-    Count = i;
-}
-
-
-int
-main(void)
-{
-    char       *p;
-    int        c;
-    char               b3[3];
-
-    for (p = b3; (c = getchar()) != EOF; ) {
-       *p++ = (char)c;
-       if (p == &b3[3]) {
-           encode(b3, 3);
-           p = b3;
-       }
-    }
-    encode(b3, (int)(p - b3));
-    flushout();
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/frontends/feedone.c b/frontends/feedone.c
deleted file mode 100644 (file)
index 21dc78a..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*  $Id: feedone.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Connect to the NNTP server and feed one article.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "nntp.h"
-
-
-static FILE    *FromServer;
-static FILE    *ToServer;
-static int     Tracing;
-
-
-/*
-**  Read a line from the server or die trying.
-*/
-static void
-GetFromServer(buff, size, text)
-    char       *buff;
-    int                size;
-    char       *text;
-{
-    if (fgets(buff, size, FromServer) == NULL)
-        sysdie("s", text);
-    if (Tracing)
-       printf("S: %s", buff);
-}
-
-
-/*
-**  Flush a stdio FILE; exit if there are any errors.
-*/
-static void
-SafeFlush(F)
-    FILE       *F;
-{
-    if (fflush(F) == EOF || ferror(F))
-        sysdie("cannot send text to server");
-}
-
-
-static void
-SendQuit(x)
-    int                x;
-{
-    char       buff[BUFSIZ];
-
-    /* Close up. */
-    fprintf(ToServer, "quit\r\n");
-    SafeFlush(ToServer);
-    fclose(ToServer);
-    GetFromServer(buff, sizeof buff, "cannot get reply to quit");
-    exit(x);
-}
-
-
-static void
-Usage()
-{
-    fprintf(stderr, "Usage: feedone [-r|-m msgid] [-p] [-t] articlefile\n");
-    exit(1);
-}
-
-
-int
-main(ac, av)
-    int                ac;
-    char       *av[];
-{
-    static char        MESGIDHDR[] = "Message-ID:";
-    int                i;
-    FILE       *F;
-    char       buff[BUFSIZ];
-    char       *mesgid = NULL;
-    size_t      length;
-    char       *p;
-    char       *q;
-    bool       PostMode;
-
-    /* Set defaults. */
-    mesgid[0] = '\0';
-    PostMode = false;
-    message_program_name = "feedone";
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "m:prt")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'm':                       /* Specified Message-ID */
-           if (*optarg == '<')
-               mesgid = optarg;
-           else
-                mesgid = concat("<", optarg, ">", (char *) 0);
-           break;
-       case 'p':                       /* Use Post, not ihave  */
-           PostMode = true;
-           break;
-       case 'r':                       /* Random Message-ID    */
-            length = snprintf(NULL, 0, "<%ld@%ld>", (long) getpid(),
-                              (long) time(NULL));
-            mesgid = xmalloc(length + 1);
-            snprintf(mesgid, length, "<%ld@%ld>", (long) getpid(),
-                     (long) time(NULL));
-           break;
-       case 't':
-           Tracing = true;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    /* One argument; the input filename. */
-    if (ac != 1)
-       Usage();
-    if ((F = fopen(av[0], "r")) == NULL)
-        sysdie("cannot open input");
-
-    /* Scan for the message-id. */
-    if (mesgid == NULL) {
-       while (fgets(buff, sizeof buff, F) != NULL)
-           if (strncasecmp(buff, MESGIDHDR, strlen(MESGIDHDR)) == 0) {
-               if ((p = strchr(buff, '<')) == NULL
-                 || (q = strchr(p, '>')) == NULL)
-                    die("bad message ID line");
-               q[1] = '\0';
-                mesgid = xstrdup(p);
-               break;
-           }
-       if (mesgid == NULL)
-            die("no message ID");
-    }
-
-    /* Connect to the server. */
-    if (NNTPremoteopen(NNTP_PORT, &FromServer, &ToServer, buff) < 0
-     || FromServer == NULL
-     || ToServer == NULL) {
-       if (buff[0])
-            warn("server says: %s", buff);
-        sysdie("cannot connect to server");
-    }
-
-    /* Does the server want this article? */
-    if (PostMode) {
-       fprintf(ToServer, "post\r\n");
-       i = NNTP_START_POST_VAL;
-    }
-    else {
-       fprintf(ToServer, "ihave %s\r\n", mesgid);
-       i = NNTP_SENDIT_VAL;
-    }
-    SafeFlush(ToServer);
-    GetFromServer(buff, sizeof buff, "cannot offer article to server");
-    if (atoi(buff) != i) {
-        warn("server doesn't want the article: %s", buff);
-       SendQuit(1);
-    }
-
-    /* Send the file over. */
-    fseeko(F, 0, SEEK_SET);
-    while (fgets(buff, sizeof buff, F) != NULL) {
-       if (strncasecmp(buff, MESGIDHDR, strlen(MESGIDHDR)) == 0) {
-           fprintf(ToServer, "%s %s\r\n", MESGIDHDR, mesgid);
-           continue;
-       }
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       fprintf(ToServer, buff[0] == '.' ? ".%s\r\n" : "%s\r\n",
-               buff);
-       SafeFlush(ToServer);
-    }
-    fprintf(ToServer, ".\r\n");
-    SafeFlush(ToServer);
-    fclose(F);
-
-    /* How did the server respond? */
-    GetFromServer(buff, sizeof buff,
-       "no reply from server after sending the article");
-    i = PostMode ? NNTP_POSTEDOK_VAL : NNTP_TOOKIT_VAL;
-    if (atoi(buff) != i)
-        sysdie("cannot send article to the server: %s", buff);
-
-    SendQuit(0);
-    /* NOTREACHED */
-}
diff --git a/frontends/getlist.c b/frontends/getlist.c
deleted file mode 100644 (file)
index 3e770d7..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*  $Id: getlist.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Get a file list from an NNTP server.
-*/
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "paths.h"
-
-
-/*
-**  Print usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: getlist [-p port] [-h host] [-A] [type [pat [groups]]\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    FILE       *active;
-    FILE       *FromServer;
-    FILE       *ToServer;
-    QIOSTATE   *qp;
-    char       *field4;
-    char       *types;
-    char       *host;
-    char       *line;
-    const char *list;
-    char       *p;
-    char       *pattern;
-    char       buff[512 + 1];
-    int                port;
-    int                authinfo;
-    int                i;
-
-    /* First thing, set up our identity. */
-    message_program_name = "getlist";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Set defaults. */
-    host = NULL;
-    pattern = NULL;
-    types = NULL;
-    port = NNTP_PORT;
-    authinfo = 0;
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "Ah:p:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'A':
-           authinfo = 1;
-           break;
-       case 'h':
-           host = optarg;
-           break;
-       case 'p':
-           port = atoi(optarg);
-           if (port <= 0)
-                die("illegal value for -p option");
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    /* Parse parameters. */
-    switch (ac) {
-    default:
-       Usage();
-       /* NOTREACHED */
-    case 0:
-    case 1:
-       break;
-    case 2:
-       pattern = av[1];
-       break;
-    case 3:
-       pattern = av[1];
-       types = av[2];
-       break;
-    }
-    if (av[0] == NULL)
-       list = "active";
-    else {
-       list = av[0];
-        if (strcmp(list, "active") != 0 && types != NULL)
-            Usage();
-       if (strcmp(list, "active") != 0 && strcmp(list, "newsgroups") != 0
-         && pattern != NULL)
-           Usage();
-    }
-
-    /* Open a connection to the server. */
-    if (host == NULL && (host = innconf->server) == NULL)
-        sysdie("cannot get server name");
-    buff[0] = '\0';
-    if (NNTPconnect(host, port, &FromServer, &ToServer, buff) < 0)
-        die("cannot connect to server: %s", buff[0] ? buff : strerror(errno));
-    if (authinfo && NNTPsendpassword(host, FromServer, ToServer) < 0)
-        die("cannot authenticate to server");
-
-    /* Get the data from the server. */
-    active = CAlistopen(FromServer, ToServer,
-                        (strcmp(list, "active") == 0) ? NULL : list);
-    if (active == NULL)
-        sysdie("cannot retrieve data");
-
-    /* Set up to read it quickly. */
-    if ((qp = QIOfdopen((int)fileno(active))) == NULL)
-        sysdie("cannot read temporary file");
-
-    /* Scan server's output, displaying appropriate lines. */
-    i = 1;
-    while ((line = QIOread(qp)) != NULL) {
-       i++;
-
-       /* No pattern means print all. */
-       if (pattern == NULL) {
-           printf("%s\n", line);
-           continue;
-       }
-
-       /* Get the group name, see if it's one we want. */
-       if ((p = strchr(line, ' ')) == NULL) {
-            warn("line %d is malformed", i);
-           continue;
-       }
-       *p = '\0';
-       if (!uwildmat(line, pattern))
-           continue;
-       *p = ' ';
-
-       /* If no group types, we want them all. */
-       if (types == NULL) {
-           printf("%s\n", line);
-           continue;
-       }
-
-       /* Find the fourth field. */
-       if ((p = strchr(p + 1, ' ')) == NULL) {
-            warn("line %d (field 2) is malformed", i);
-           continue;
-       }
-       if ((p = strchr(p + 1, ' ')) == NULL) {
-            warn("line %d (field 3) is malformed", i);
-           continue;
-       }
-       field4 = p + 1;
-       if ((p = strchr(field4, ' ')) != NULL) {
-            warn("line %d has more than 4 fields", i);
-           continue;
-       }
-
-       /* Is this the type of line we want? */
-       if (strchr(types, field4[0]) != NULL)
-           printf("%s\n", line);
-    }
-
-    /* Determine why we stopped */
-    if (QIOerror(qp)) {
-        syswarn("cannot read temporary file at line %d", i);
-       i = 1;
-    }
-    else if (QIOtoolong(qp)) {
-        warn("line %d is too long", i);
-       i = i;
-    }
-    else
-       i = 0;
-
-    /* All done. */
-    CAclose();
-    fprintf(ToServer, "quit\r\n");
-    fclose(ToServer);
-    fgets(buff, sizeof buff, FromServer);
-    fclose(FromServer);
-    exit(i);
-    /* NOTREACHED */
-}
diff --git a/frontends/inews.c b/frontends/inews.c
deleted file mode 100644 (file)
index ff57635..0000000
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*  $Id: inews.c 7769 2008-04-13 08:11:41Z iulius $
-**
-**  Send an article (prepared by someone on the local site) to the
-**  master news server.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-/* Signature handling.  The separator will be appended before the signature,
-   and at most SIG_MAXLINES will be appended. */
-#define SIG_MAXLINES           4
-#define SIG_SEPARATOR          "-- \n"
-
-#define FLUSH_ERROR(F)         (fflush((F)) == EOF || ferror((F)))
-#define LPAREN                 '('     /* For vi :-) */
-#define HEADER_DELTA           20
-#define GECOSTERM(c)           \
-           ((c) == ',' || (c) == ';' || (c) == ':' || (c) == LPAREN)
-#define HEADER_STRLEN          998
-
-typedef enum _HEADERTYPE {
-    HTobs,
-    HTreq,
-    HTstd
-} HEADERTYPE;
-
-typedef struct _HEADER {
-    const char *Name;
-    bool       CanSet;
-    HEADERTYPE Type;
-    int                Size;
-    char       *Value;
-} HEADER;
-
-static bool    Dump;
-static bool    Revoked;
-static bool    Spooling;
-static char    **OtherHeaders;
-static char    SIGSEP[] = SIG_SEPARATOR;
-static FILE    *FromServer;
-static FILE    *ToServer;
-static int     OtherCount;
-static int     OtherSize;
-static const char *Exclusions = "";
-static const char * const BadDistribs[] = {
-    BAD_DISTRIBS
-};
-
-static HEADER  Table[] = {
-    /*         Name                    Canset  Type    */
-    {  "Path",                 true,   HTstd,  0, NULL },
-#define _path           0
-    {  "From",                 true,   HTstd,  0, NULL },
-#define _from           1
-    {  "Newsgroups",           true,   HTreq,  0, NULL },
-#define _newsgroups     2
-    {  "Subject",              true,   HTreq,  0, NULL },
-#define _subject        3
-    {  "Control",              true,   HTstd,  0, NULL },
-#define _control        4
-    {  "Supersedes",           true,   HTstd,  0, NULL },
-#define _supersedes     5
-    {  "Followup-To",          true,   HTstd,  0, NULL },
-#define _followupto     6
-    {  "Date",                 true,   HTstd,  0, NULL },
-#define _date           7
-    {  "Organization",         true,   HTstd,  0, NULL },
-#define _organization   8
-    {  "Lines",                true,   HTstd,  0, NULL },
-#define _lines          9
-    {  "Sender",               true,   HTstd,  0, NULL },
-#define _sender                10
-    {  "Approved",             true,   HTstd,  0, NULL },
-#define _approved      11
-    {  "Distribution",         true,   HTstd,  0, NULL },
-#define _distribution  12
-    {  "Expires",              true,   HTstd,  0, NULL },
-#define _expires       13
-    {  "Message-ID",           true,   HTstd,  0, NULL },
-#define _messageid     14
-    {  "References",           true,   HTstd,  0, NULL },
-#define _references    15
-    {  "Reply-To",             true,   HTstd,  0, NULL },
-#define _replyto       16
-    {  "Also-Control",         true,   HTstd,  0, NULL },
-#define _alsocontrol   17
-    {  "Xref",                 false,  HTstd,  0, NULL },
-    {  "Summary",              true,   HTstd,  0, NULL },
-    {  "Keywords",             true,   HTstd,  0, NULL },
-    {  "Date-Received",        false,  HTobs,  0, NULL },
-    {  "Received",             false,  HTobs,  0, NULL },
-    {  "Posted",               false,  HTobs,  0, NULL },
-    {  "Posting-Version",      false,  HTobs,  0, NULL },
-    {  "Relay-Version",        false,  HTobs,  0, NULL },
-};
-
-#define HDR(_x)        (Table[(_x)].Value)
-
-\f
-
-/*
-**  Send the server a quit message, wait for a reply.
-*/
-static void
-QuitServer(int x)
-{
-    char       buff[HEADER_STRLEN];
-    char       *p;
-
-    if (Spooling)
-       exit(x);
-    if (x)
-        warn("article not posted");
-    fprintf(ToServer, "quit\r\n");
-    if (FLUSH_ERROR(ToServer))
-        sysdie("cannot send quit to server");
-    if (fgets(buff, sizeof buff, FromServer) == NULL)
-        sysdie("warning: server did not reply to quit");
-    if ((p = strchr(buff, '\r')) != NULL)
-       *p = '\0';
-    if ((p = strchr(buff, '\n')) != NULL)
-       *p = '\0';
-    if (atoi(buff) != NNTP_GOODBYE_ACK_VAL)
-        die("server did not reply to quit properly: %s", buff);
-    fclose(FromServer);
-    fclose(ToServer);
-    exit(x);
-}
-
-
-/*
-**  Failure handler, called by die.  Calls QuitServer to cleanly shut down the
-**  connection with the remote server before exiting.
-*/
-static int
-fatal_cleanup(void)
-{
-    /* Don't recurse. */
-    message_fatal_cleanup = NULL;
-
-    /* QuitServer does all the work. */
-    QuitServer(1);
-    return 1;
-}
-
-
-/*
-**  Flush a stdio FILE; exit if there are any errors.
-*/
-static void
-SafeFlush(FILE *F)
-{
-    if (FLUSH_ERROR(F))
-        sysdie("cannot send text to server");
-}
-
-
-/*
-**  Trim trailing spaces, return pointer to first non-space char.
-*/
-static char *
-TrimSpaces(char *p)
-{
-    char       *start;
-
-    for (start = p; ISWHITE(*start); start++)
-       continue;
-    for (p = start + strlen(start); p > start && CTYPE(isspace, p[-1]); )
-       *--p = '\0';
-    return start;
-}
-
-
-/*
-**  Mark the end of the header starting at p, and return a pointer
-**  to the start of the next one.  Handles continuations.
-*/
-static char *
-NextHeader(char *p)
-{
-    for ( ; ; p++) {
-       if ((p = strchr(p, '\n')) == NULL)
-            die("article is all headers");
-       if (!ISWHITE(p[1])) {
-           *p = '\0';
-           return p + 1;
-       }
-    }
-}
-
-
-/*
-**  Strip any headers off the article and dump them into the table.
-*/
-static char *
-StripOffHeaders(char *article)
-{
-    char       *p;
-    char       *q;
-    HEADER     *hp;
-    char       c;
-    int        i;
-
-    /* Set up the other headers list. */
-    OtherSize = HEADER_DELTA;
-    OtherHeaders = xmalloc(OtherSize * sizeof(char *));
-    OtherCount = 0;
-
-    /* Scan through buffer, a header at a time. */
-    for (i = 0, p = article; ; i++) {
-
-       if ((q = strchr(p, ':')) == NULL)
-            die("no colon in header line \"%.30s...\"", p);
-       if (q[1] == '\n' && !ISWHITE(q[2])) {
-           /* Empty header; ignore this one, get next line. */
-           p = NextHeader(p);
-           if (*p == '\n')
-               break;
-       }
-
-       if (q[1] != '\0' && !ISWHITE(q[1])) {
-           if ((q = strchr(q, '\n')) != NULL)
-               *q = '\0';
-            die("no space after colon in \"%.30s...\"", p);
-       }
-
-       /* See if it's a known header. */
-       c = CTYPE(islower, *p) ? toupper(*p) : *p;
-       for (hp = Table; hp < ARRAY_END(Table); hp++)
-           if (c == hp->Name[0]
-            && p[hp->Size] == ':'
-            && ISWHITE(p[hp->Size + 1])
-            && strncasecmp(p, hp->Name, hp->Size) == 0) {
-               if (hp->Type == HTobs)
-                    die("obsolete header: %s", hp->Name);
-               if (hp->Value)
-                    die("duplicate header: %s", hp->Name);
-               for (q = &p[hp->Size + 1]; ISWHITE(*q); q++)
-                   continue;
-               hp->Value = q;
-               break;
-           }
-
-       /* Too many headers? */
-       if (++i > 5 * HEADER_DELTA)
-            die("more than %d lines of header", i);
-
-       /* No; add it to the set of other headers. */
-       if (hp == ARRAY_END(Table)) {
-           if (OtherCount >= OtherSize - 1) {
-               OtherSize += HEADER_DELTA;
-                OtherHeaders = xrealloc(OtherHeaders, OtherSize * sizeof(char *));
-           }
-           OtherHeaders[OtherCount++] = p;
-       }
-
-       /* Get start of next header; if it's a blank line, we hit the end. */
-       p = NextHeader(p);
-       if (*p == '\n')
-           break;
-    }
-
-    return p + 1;
-}
-
-\f
-
-/*
-**  See if the user is allowed to cancel the indicated message.  Assumes
-**  that the Sender or From line has already been filled in.
-*/
-static void
-CheckCancel(char *msgid, bool JustReturn)
-{
-    char               localfrom[SMBUF];
-    char       *p;
-    char               buff[BUFSIZ];
-    char               remotefrom[SMBUF];
-
-    /* Ask the server for the article. */
-    fprintf(ToServer, "head %s\r\n", msgid);
-    SafeFlush(ToServer);
-    if (fgets(buff, sizeof buff, FromServer) == NULL
-     || atoi(buff) != NNTP_HEAD_FOLLOWS_VAL) {
-       if (JustReturn)
-           return;
-        die("server has no such article");
-    }
-
-    /* Read the headers, looking for the From or Sender. */
-    remotefrom[0] = '\0';
-    while (fgets(buff, sizeof buff, FromServer) != NULL) {
-       if ((p = strchr(buff, '\r')) != NULL)
-           *p = '\0';
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '.' && buff[1] == '\0')
-           break;
-        if (strncmp(buff, "Sender:", 7) == 0)
-            strlcpy(remotefrom, TrimSpaces(&buff[7]), SMBUF);
-        else if (remotefrom[0] == '\0' && strncmp(buff, "From:", 5) == 0)
-            strlcpy(remotefrom, TrimSpaces(&buff[5]), SMBUF);
-    }
-    if (remotefrom[0] == '\0') {
-       if (JustReturn)
-           return;
-        die("article is garbled");
-    }
-    HeaderCleanFrom(remotefrom);
-
-    /* Get the local user. */
-    strlcpy(localfrom, HDR(_sender) ? HDR(_sender) : HDR(_from), SMBUF);
-    HeaderCleanFrom(localfrom);
-
-    /* Is the right person cancelling? */
-    if (strcasecmp(localfrom, remotefrom) != 0)
-        die("article was posted by \"%s\" and you are \"%s\"", remotefrom,
-            localfrom);
-}
-
-
-/*
-**  See if the user is the news administrator.
-*/
-static bool
-AnAdministrator(char *name, gid_t group)
-{
-    struct passwd      *pwp;
-    struct group       *grp;
-    char               **mem;
-    char               *p;
-
-    if (Revoked)
-       return false;
-
-    /* Find out who we are. */
-    if ((pwp = getpwnam(NEWSUSER)) == NULL)
-       /* Silent falure; clients might not have the group. */
-       return false;
-    if (getuid() == pwp->pw_uid)
-       return true;
-
-    /* See if the we're in the right group. */
-    if ((grp = getgrnam(NEWSGRP)) == NULL || (mem = grp->gr_mem) == NULL)
-       /* Silent falure; clients might not have the group. */
-       return false;
-    if (group == grp->gr_gid)
-       return true;
-    while ((p = *mem++) != NULL)
-       if (strcmp(name, p) == 0)
-           return true;
-    return false;
-}
-
-
-/*
-**  Check the control message, and see if it's legit.
-*/
-static void
-CheckControl(char *ctrl, struct passwd *pwp)
-{
-    char       *p;
-    char       *q;
-    char               save;
-    char               name[SMBUF];
-
-    /* Snip off the first word. */
-    for (p = ctrl; ISWHITE(*p); p++)
-       continue;
-    for (ctrl = p; *p && !ISWHITE(*p); p++)
-       continue;
-    if (p == ctrl)
-        die("emtpy control message");
-    save = *p;
-    *p = '\0';
-
-    if (strcmp(ctrl, "cancel") == 0) {
-       for (q = p + 1; ISWHITE(*q); q++)
-           continue;
-       if (*q == '\0')
-            die("message ID missing in cancel");
-       if (!Spooling)
-           CheckCancel(q, false);
-    }
-    else if (strcmp(ctrl, "checkgroups") == 0
-         || strcmp(ctrl, "ihave")       == 0
-         || strcmp(ctrl, "sendme")      == 0
-         || strcmp(ctrl, "newgroup")    == 0
-         || strcmp(ctrl, "rmgroup")     == 0
-         || strcmp(ctrl, "sendsys")     == 0
-         || strcmp(ctrl, "senduuname")  == 0
-         || strcmp(ctrl, "version")     == 0) {
-       strlcpy(name, pwp->pw_name, SMBUF);
-       if (!AnAdministrator(name, pwp->pw_gid))
-            die("ask your news administrator to do the %s for you", ctrl);
-    }
-    else {
-        die("%s is not a valid control message", ctrl);
-    }
-    *p = save;
-}
-
-\f
-
-/*
-**  Parse the GECOS field to get the user's full name.  This comes Sendmail's
-**  buildfname routine.  Ignore leading stuff like "23-" "stuff]-" or
-**  "stuff -" as well as trailing whitespace, or anything that comes after
-**  a comma, semicolon, or in parentheses.  This seems to strip off most of
-**  the UCB or ATT stuff people fill out the entries with.  Also, turn &
-**  into the login name, with perhaps an initial capital.  (Everyone seems
-**  to hate that, but everyone also supports it.)
-*/
-static char *
-FormatUserName(struct passwd *pwp, char *node)
-{
-    char       outbuff[SMBUF];
-    char        *buff;
-    char       *out;
-    char       *p;
-    int         left;
-
-#if    !defined(DONT_MUNGE_GETENV)
-    memset(outbuff, 0, SMBUF);
-    if ((p = getenv("NAME")) != NULL)
-       strlcpy(outbuff, p, SMBUF);
-    if (strlen(outbuff) == 0) {
-#endif /* !defined(DONT_MUNGE_GETENV) */
-
-
-#ifndef DO_MUNGE_GECOS
-    strlcpy(outbuff, pwp->pw_gecos, SMBUF);
-#else
-    /* Be very careful here.  If we're not, we can potentially overflow our
-     * buffer.  Remember that on some Unix systems, the content of the GECOS
-     * field is under (untrusted) user control and we could be setgid. */
-    p = pwp->pw_gecos;
-    left = SMBUF - 1;
-    if (*p == '*')
-       p++;
-    for (out = outbuff; *p && !GECOSTERM(*p) && left; p++) {
-       if (*p == '&') {
-           strncpy(out, pwp->pw_name, left);
-           if (CTYPE(islower, *out)
-            && (out == outbuff || !CTYPE(isalpha, out[-1])))
-               *out = toupper(*out);
-           while (*out) {
-               out++;
-                left--;
-            }
-       }
-       else if (*p == '-'
-             && p > pwp->pw_gecos
-              && (CTYPE(isdigit, p[-1]) || CTYPE(isspace, p[-1])
-                  || p[-1] == ']')) {
-           out = outbuff;
-            left = SMBUF - 1;
-        }
-       else {
-           *out++ = *p;
-            left--;
-        }
-    }
-    *out = '\0';
-#endif /* DO_MUNGE_GECOS */
-
-#if    !defined(DONT_MUNGE_GETENV)
-    }
-#endif /* !defined(DONT_MUNGE_GETENV) */
-
-    out = TrimSpaces(outbuff);
-    if (out[0])
-        buff = concat(pwp->pw_name, "@", node, " (", out, ")", (char *) 0);
-    else
-        buff = concat(pwp->pw_name, "@", node, (char *) 0);
-    return buff;
-}
-
-
-/*
-**  Check the Distribution header, and exit on error.
-*/
-static void CheckDistribution(char *p)
-{
-    static char        SEPS[] = " \t,";
-    const char  * const *dp;
-
-    if ((p = strtok(p, SEPS)) == NULL)
-        die("cannot parse Distribution header");
-    do {
-       for (dp = BadDistribs; *dp; dp++)
-           if (uwildmat(p, *dp))
-                die("illegal distribution %s", p);
-    } while ((p = strtok((char *)NULL, SEPS)) != NULL);
-}
-
-
-/*
-**  Process all the headers.  FYI, they're done in RFC-order.
-*/
-static void
-ProcessHeaders(bool AddOrg, int linecount, struct passwd *pwp)
-{
-    static char                PATHFLUFF[] = PATHMASTER;
-    HEADER              *hp;
-    char                *p;
-    TIMEINFO           Now;
-    char               buff[SMBUF];
-    char               from[SMBUF];
-
-    /* Do some preliminary fix-ups. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++) {
-       if (!hp->CanSet && hp->Value)
-            die("cannot set system header %s", hp->Name);
-       if (hp->Value) {
-           hp->Value = TrimSpaces(hp->Value);
-           if (*hp->Value == '\0')
-               hp->Value = NULL;
-       }
-    }
-
-    /* Set From or Sender. */
-    if ((p = innconf->fromhost) == NULL)
-        sysdie("cannot get hostname");
-    if (HDR(_from) == NULL)
-       HDR(_from) = FormatUserName(pwp, p);
-    else {
-      if (strlen(pwp->pw_name) + strlen(p) + 2 > sizeof(buff))
-          die("username and host are too long");
-      sprintf(buff, "%s@%s", pwp->pw_name, p);
-      strlcpy(from, HDR(_from), SMBUF);
-      HeaderCleanFrom(from);
-      if (strcmp(from, buff) != 0)
-        HDR(_sender) = xstrdup(buff);
-    }
-
-    if (HDR(_date) == NULL) {
-       /* Set Date. */
-       if (!makedate(-1, true, buff, sizeof(buff)))
-           die("cannot generate Date header");
-       HDR(_date) = xstrdup(buff);
-    }
-
-    /* Newsgroups are checked later. */
-
-    /* Set Subject; Control overrides the subject. */
-    if (HDR(_control)) {
-       CheckControl(HDR(_control), pwp);
-    }
-    else {
-       p = HDR(_subject);
-       if (p == NULL)
-            die("required Subject header is missing or empty");
-       else if (HDR(_alsocontrol))
-           CheckControl(HDR(_alsocontrol), pwp);
-#if    0
-       if (strncmp(p, "Re: ", 4) == 0 && HDR(_references) == NULL)
-            die("article subject begins with \"Re: \" but has no references");
-#endif /* 0 */
-    }
-
-    /* Set Message-ID */
-    if (HDR(_messageid) == NULL) {
-       if ((p = GenerateMessageID(innconf->domain)) == NULL)
-            die("cannot generate Message-ID header");
-       HDR(_messageid) = xstrdup(p);
-    }
-    else if ((p = strchr(HDR(_messageid), '@')) == NULL
-             || strchr(++p, '@') != NULL) {
-        die("message ID must have exactly one @");
-    }
-
-    /* Set Path */
-    if (HDR(_path) == NULL) {
-#if    defined(DO_INEWS_PATH)
-       if ((p = innconf->pathhost) != NULL) {
-           if (*p)
-                HDR(_path) = concat(Exclusions, p, "!", PATHFLUFF, (char *) 0);
-           else
-                HDR(_path) = concat(Exclusions, PATHFLUFF, (char *) 0);
-       }
-       else if (innconf->server != NULL) {
-           if ((p = GetFQDN(innconf->domain)) == NULL)
-                sysdie("cannot get hostname");
-           HDR(_path) = concat(Exclusions, p, "!", PATHFLUFF, (char *) 0);
-       }
-       else {
-           HDR(_path) = concat(Exclusions, PATHFLUFF, (char *) 0);
-       }
-#else
-       HDR(_path) = concat(Exclusions, PATHFLUFF, (char *) 0);
-#endif /* defined(DO_INEWS_PATH) */
-    }
-
-    /* Reply-To; left alone. */
-    /* Sender; set above. */
-    /* Followup-To; checked with Newsgroups. */
-
-    /* Check Expires. */
-    if (GetTimeInfo(&Now) < 0)
-        sysdie("cannot get the time");
-    if (HDR(_expires) && parsedate(HDR(_expires), &Now) == -1)
-        die("cannot parse \"%s\" as an expiration date", HDR(_expires));
-
-    /* References; left alone. */
-    /* Control; checked above. */
-
-    /* Distribution. */
-    if ((p = HDR(_distribution)) != NULL) {
-       p = xstrdup(p);
-       CheckDistribution(p);
-       free(p);
-    }
-
-    /* Set Organization. */
-    if (AddOrg
-     && HDR(_organization) == NULL
-     && (p = innconf->organization) != NULL) {
-       HDR(_organization) = xstrdup(p);
-    }
-
-    /* Keywords; left alone. */
-    /* Summary; left alone. */
-    /* Approved; left alone. */
-
-    /* Set Lines */
-    sprintf(buff, "%d", linecount);
-    HDR(_lines) = xstrdup(buff);
-
-    /* Check Supersedes. */
-    if (HDR(_supersedes))
-       CheckCancel(HDR(_supersedes), true);
-
-    /* Now make sure everything is there. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Type == HTreq && hp->Value == NULL)
-            die("required header %s is missing or empty", hp->Name);
-}
-
-
-/*
-**  Try to append $HOME/.signature to the article.  When in doubt, exit
-**  out in order to avoid postings like "Sorry, I forgot my .signature
-**  -- here's the article again."
-*/
-static char *
-AppendSignature(bool UseMalloc, char *article, char *homedir, int *linesp)
-{
-    static char        NOSIG[] = "Can't add your .signature (%s), article not posted";
-    int                i;
-    int                length;
-    size_t      artsize;
-    char       *p;
-    char       buff[BUFSIZ];
-    FILE       *F;
-
-    /* Open the file. */
-    *linesp = 0;
-    if (strlen(homedir) > sizeof(buff) - 14)
-        die("home directory path too long");
-    sprintf(buff, "%s/.signature", homedir);
-    if ((F = fopen(buff, "r")) == NULL) {
-       if (errno == ENOENT)
-           return article;
-       fprintf(stderr, NOSIG, strerror(errno));
-       QuitServer(1);
-    }
-
-    /* Read it in. */
-    length = fread(buff, 1, sizeof buff - 2, F);
-    i = feof(F);
-    fclose(F);
-    if (length == 0)
-        die("signature file is empty");
-    if (length < 0)
-        sysdie("cannot read signature file");
-    if (length == sizeof buff - 2 && !i)
-        die("signature is too large");
-
-    /* Make sure the buffer ends with \n\0. */
-    if (buff[length - 1] != '\n')
-       buff[length++] = '\n';
-    buff[length] = '\0';
-
-    /* Count the lines. */
-    for (i = 0, p = buff; (p = strchr(p, '\n')) != NULL; p++)
-       if (++i > SIG_MAXLINES)
-            die("signature has too many lines");
-    *linesp = 1 + i;
-
-    /* Grow the article to have the signature. */
-    i = strlen(article);
-    artsize = i + sizeof(SIGSEP) - 1 + length + 1;
-    if (UseMalloc) {
-        p = xmalloc(artsize);
-        strlcpy(p, article, artsize);
-       article = p;
-    }
-    else
-        article = xrealloc(article, artsize);
-    strlcat(article, SIGSEP, artsize);
-    strlcat(article, buff, artsize);
-    return article;
-}
-
-
-/*
-**  See if the user has more included text than new text.  Simple-minded, but
-**  reasonably effective for catching neophyte's mistakes.  A line starting
-**  with > is included text.  Decrement the count on lines starting with <
-**  so that we don't reject diff(1) output.
-*/
-static void
-CheckIncludedText(char *p, int lines)
-{
-    int        i;
-
-    for (i = 0; ; p++) {
-       switch (*p) {
-       case '>':
-           i++;
-           break;
-       case '|':
-           i++;
-           break;
-       case ':':
-           i++;
-           break;
-       case '<':
-           i--;
-           break;
-       }
-       if ((p = strchr(p, '\n')) == NULL)
-           break;
-    }
-    if ((i * 2 > lines) && (lines > 40))
-        die("more included text than new text");
-}
-
-\f
-
-/*
-**  Read stdin into a string and return it.  Can't use ReadInDescriptor
-**  since that will fail if stdin is a tty.
-*/
-static char *
-ReadStdin(void)
-{
-    int        size;
-    char       *p;
-    char               *article;
-    char       *end;
-    int        i;
-
-    size = BUFSIZ;
-    article = xmalloc(size);
-    end = &article[size - 3];
-    for (p = article; (i = getchar()) != EOF; *p++ = (char)i)
-       if (p == end) {
-            article = xrealloc(article, size + BUFSIZ);
-           p = &article[size - 3];
-           size += BUFSIZ;
-           end = &article[size - 3];
-       }
-
-    /* Force a \n terminator. */
-    if (p > article && p[-1] != '\n')
-       *p++ = '\n';
-    *p = '\0';
-    return article;
-}
-
-\f
-
-/*
-**  Offer the article to the server, return its reply.
-*/
-static int
-OfferArticle(char *buff, bool Authorized)
-{
-    fprintf(ToServer, "post\r\n");
-    SafeFlush(ToServer);
-    if (fgets(buff, HEADER_STRLEN, FromServer) == NULL)
-        sysdie(Authorized ? "Can't offer article to server (authorized)"
-                          : "Can't offer article to server");
-    return atoi(buff);
-}
-
-
-/*
-**  Spool article to temp file.
-*/
-static void
-Spoolit(char *article, size_t Length, char *deadfile)
-{
-    HEADER *hp;
-    FILE *F;
-    int i;
-
-    /* Try to write to the deadfile. */
-    if (deadfile == NULL)
-        return;
-    F = xfopena(deadfile);
-    if (F == NULL)
-        sysdie("cannot create spool file");
-
-    /* Write the headers and a blank line. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value)
-           fprintf(F, "%s: %s\n", hp->Name, hp->Value);
-    for (i = 0; i < OtherCount; i++)
-       fprintf(F, "%s\n", OtherHeaders[i]);
-    fprintf(F, "\n");
-    if (FLUSH_ERROR(F))
-        sysdie("cannot write headers");
-
-    /* Write the article and exit. */
-    if (fwrite(article, 1, Length, F) != Length)
-        sysdie("cannot write article");
-    if (FLUSH_ERROR(F))
-        sysdie("cannot write article");
-    if (fclose(F) == EOF)
-        sysdie("cannot close spool file");
-}
-
-
-/*
-**  Print usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage: inews [-D] [-h] [header_flags] [article]\n");
-    /* Don't call QuitServer here -- connection isn't open yet. */
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    static char                NOCONNECT[] = "cannot connect to server";
-    int                 i;
-    char                *p;
-    HEADER              *hp;
-    int                        j;
-    int                        port;
-    int                        Mode;
-    int                        SigLines;
-    struct passwd      *pwp;
-    char               *article;
-    char               *deadfile;
-    char               buff[HEADER_STRLEN];
-    char               SpoolMessage[HEADER_STRLEN];
-    bool               DoSignature;
-    bool               AddOrg;
-    size_t             Length;
-    uid_t               uid;
-
-    /* First thing, set up logging and our identity. */
-    message_program_name = "inews";
-
-    /* Find out who we are. */
-    uid = geteuid();
-    if (uid == (uid_t) -1)
-        sysdie("cannot get your user ID");
-    if ((pwp = getpwuid(uid)) == NULL)
-        sysdie("cannot get your passwd entry");
-
-    /* Set defaults. */
-    Mode = '\0';
-    Dump = false;
-    DoSignature = true;
-    AddOrg = true;
-    port = 0;
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    while ((i = getopt(ac, av, "DNAVWORShx:a:c:d:e:f:n:p:r:t:F:o:w:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'D':
-       case 'N':
-           Dump = true;
-           break;
-       case 'A':
-       case 'V':
-       case 'W':
-           /* Ignore C News options. */
-           break;
-       case 'O':
-           AddOrg = false;
-           break;
-       case 'R':
-           Revoked = true;
-           break;
-       case 'S':
-           DoSignature = false;
-           break;
-       case 'h':
-           Mode = i;
-           break;
-       case 'x':
-            Exclusions = concat(optarg, "!", (char *) 0);
-           break;
-        case 'p':
-           port = atoi(optarg);
-           break;
-       /* Header lines that can be specified on the command line. */
-       case 'a':       HDR(_approved) = optarg;                break;
-       case 'c':       HDR(_control) = optarg;                 break;
-       case 'd':       HDR(_distribution) = optarg;            break;
-       case 'e':       HDR(_expires) = optarg;                 break;
-       case 'f':       HDR(_from) = optarg;                    break;
-       case 'n':       HDR(_newsgroups) = optarg;              break;
-       case 'r':       HDR(_replyto) = optarg;                 break;
-       case 't':       HDR(_subject) = optarg;                 break;
-       case 'F':       HDR(_references) = optarg;              break;
-       case 'o':       HDR(_organization) = optarg;            break;
-       case 'w':       HDR(_followupto) = optarg;              break;
-       }
-    ac -= optind;
-    av += optind;
-
-    /* Parse positional arguments; at most one, the input file. */
-    switch (ac) {
-    default:
-       Usage();
-       /* NOTREACHED */
-    case 0:
-       /* Read stdin. */
-       article = ReadStdin();
-       break;
-    case 1:
-       /* Read named file. */
-       article = ReadInFile(av[0], (struct stat *)NULL);
-       if (article == NULL)
-            sysdie("cannot read input file");
-       break;
-    }
-
-    if (port == 0)
-        port = NNTP_PORT;
-
-    /* Try to open a connection to the server. */
-    if (NNTPremoteopen(port, &FromServer, &ToServer, buff) < 0) {
-       Spooling = true;
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if ((p = strchr(buff, '\r')) != NULL)
-           *p = '\0';
-       strcpy(SpoolMessage, buff[0] ? buff : NOCONNECT);
-        deadfile = concatpath(pwp->pw_dir, "dead.article");
-    }
-    else {
-        /* We now have an open server connection, so close it on failure. */
-        message_fatal_cleanup = fatal_cleanup;
-
-       /* See if we can post. */
-       i = atoi(buff);
-
-       /* Tell the server we're posting. */
-       setbuf(FromServer, xmalloc(BUFSIZ));
-       setbuf(ToServer, xmalloc(BUFSIZ));
-       fprintf(ToServer, "mode reader\r\n");
-       SafeFlush(ToServer);
-       if (fgets(buff, HEADER_STRLEN, FromServer) == NULL)
-            sysdie("cannot tell server we're reading");
-       if ((j = atoi(buff)) != NNTP_BAD_COMMAND_VAL)
-           i = j;
-
-        if (i != NNTP_POSTOK_VAL) {
-            /* We try to authenticate in case it is all the same possible
-             * to post. */
-            if (NNTPsendpassword((char *)NULL, FromServer, ToServer) < 0)
-                die("you do not have permission to post");
-        }
-       deadfile = NULL;
-    }
-
-    /* Basic processing. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       hp->Size = strlen(hp->Name);
-    if (Mode == 'h')
-       article = StripOffHeaders(article);
-    for (i = 0, p = article; (p = strchr(p, '\n')) != NULL; i++, p++)
-       continue;
-    if (innconf->checkincludedtext)
-       CheckIncludedText(article, i);
-    if (DoSignature)
-       article = AppendSignature(Mode == 'h', article, pwp->pw_dir, &SigLines);
-    else
-       SigLines = 0;
-    ProcessHeaders(AddOrg, i + SigLines, pwp);
-    Length = strlen(article);
-    if ((innconf->localmaxartsize > 0)
-           && (Length > (size_t)innconf->localmaxartsize))
-        die("article is larger than local limit of %ld bytes",
-            innconf->localmaxartsize);
-
-    /* Do final checks. */
-    if (i == 0 && HDR(_control) == NULL)
-        die("article is empty");
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value && (int)strlen(hp->Value) + hp->Size > HEADER_STRLEN)
-            die("%s header is too long", hp->Name);
-    for (i = 0; i < OtherCount; i++)
-       if ((int)strlen(OtherHeaders[i]) > HEADER_STRLEN)
-            die("header too long (maximum length is %d): %.40s...",
-                HEADER_STRLEN, OtherHeaders[i]);
-
-    if (Dump) {
-       /* Write the headers and a blank line. */
-       for (hp = Table; hp < ARRAY_END(Table); hp++)
-           if (hp->Value)
-               printf("%s: %s\n", hp->Name, hp->Value);
-       for (i = 0; i < OtherCount; i++)
-           printf("%s\n", OtherHeaders[i]);
-       printf("\n");
-       if (FLUSH_ERROR(stdout))
-            sysdie("cannot write headers");
-
-       /* Write the article and exit. */
-       if (fwrite(article, 1, Length, stdout) != Length)
-            sysdie("cannot write article");
-       SafeFlush(stdout);
-       QuitServer(0);
-    }
-
-    if (Spooling) {
-        warn("warning: %s", SpoolMessage);
-        warn("article will be spooled");
-       Spoolit(article, Length, deadfile);
-       exit(0);
-    }
-
-    /* Article is prepared, offer it to the server. */
-    i = OfferArticle(buff, false);
-    if (i == NNTP_AUTH_NEEDED_VAL) {
-       /* Posting not allowed, try to authorize. */
-       if (NNTPsendpassword((char *)NULL, FromServer, ToServer) < 0)
-            sysdie("authorization error");
-       i = OfferArticle(buff, true);
-    }
-    if (i != NNTP_START_POST_VAL)
-        die("server doesn't want the article: %s", buff);
-
-    /* Write the headers, a blank line, then the article. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value)
-           fprintf(ToServer, "%s: %s\r\n", hp->Name, hp->Value);
-    for (i = 0; i < OtherCount; i++)
-       fprintf(ToServer, "%s\r\n", OtherHeaders[i]);
-    fprintf(ToServer, "\r\n");
-    if (NNTPsendarticle(article, ToServer, true) < 0)
-        sysdie("cannot send article to server");
-    SafeFlush(ToServer);
-
-    if (fgets(buff, sizeof buff, FromServer) == NULL)
-        sysdie("no reply from server after sending the article");
-    if ((p = strchr(buff, '\r')) != NULL)
-       *p = '\0';
-    if ((p = strchr(buff, '\n')) != NULL)
-       *p = '\0';
-    if (atoi(buff) != NNTP_POSTEDOK_VAL)
-        die("cannot send article to server: %s", buff);
-
-    /* Close up. */
-    QuitServer(0);
-    /* NOTREACHED */
-    return 1;
-}
diff --git a/frontends/innconfval.c b/frontends/innconfval.c
deleted file mode 100644 (file)
index 2f830c5..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*  $Id: innconfval.c 5962 2002-12-08 19:52:13Z rra $
-**
-**  Get a config value from INN.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-/*
-**  Print the INN version string with appropriate quoting.
-*/
-static void
-print_version(FILE *file, enum innconf_quoting quoting)
-{
-    switch (quoting) {
-    case INNCONF_QUOTE_NONE:
-        fprintf(file, "%s\n", inn_version_string);
-        break;
-    case INNCONF_QUOTE_SHELL:
-        fprintf(file, "VERSION='%s'; export VERSION\n", inn_version_string);
-        break;
-    case INNCONF_QUOTE_PERL:
-        fprintf(file, "$version = '%s';\n", inn_version_string);
-        break;
-    case INNCONF_QUOTE_TCL:
-        fprintf(file, "set inn_version \"%s\"\n", inn_version_string);
-        break;
-    }
-}
-
-
-/*
-**  Main routine.  Most of the real work is done by the innconf library
-**  routines.
-*/
-int
-main(int argc, char *argv[])
-{
-    int option, i;
-    char *file = NULL;
-    enum innconf_quoting quoting = INNCONF_QUOTE_NONE;
-    bool okay = true;
-    bool version = false;
-    bool checking = false;
-
-    message_program_name = "innconfval";
-
-    while ((option = getopt(argc, argv, "Ci:pstv")) != EOF)
-        switch (option) {
-        default:
-            die("usage error");
-            break;
-        case 'C':
-            checking = true;
-            break;
-        case 'i':
-            file = optarg;
-            break;
-        case 'p':
-            quoting = INNCONF_QUOTE_PERL;
-            break;
-        case 's':
-            quoting = INNCONF_QUOTE_SHELL;
-            break;
-        case 't':
-            quoting = INNCONF_QUOTE_TCL;
-            break;
-        case 'v':
-            version = true;
-            break;
-        }
-    argc -= optind;
-    argv += optind;
-
-    if (version) {
-        print_version(stdout, quoting);
-        exit(0);
-    }
-    if (checking)
-        exit(innconf_check(file) ? 0 : 1);
-
-    /* Read in the inn.conf file specified. */
-    if (!innconf_read(file))
-        exit(1);
-
-    /* Perform the specified action. */
-    if (argv[0] == NULL) {
-        innconf_dump(stdout, quoting);
-        print_version(stdout, quoting);
-    } else {
-        for (i = 0; i < argc; i++)
-            if (strcmp(argv[i], "version") == 0)
-                print_version(stdout, quoting);
-            else if (!innconf_print_value(stdout, argv[i], quoting))
-                okay = false;
-    }
-    exit(okay ? 0 : 1);
-}
diff --git a/frontends/mailpost.in b/frontends/mailpost.in
deleted file mode 100644 (file)
index 5d1695b..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# mailpost - Yet another mail-to-news filter
-# 
-# $Id: mailpost.in 7795 2008-04-26 08:28:08Z iulius $
-#
-# 21feb00 [added "lc" to duplicate header fixer stmt to make it case-insensitive]
-# doka 11may99 [fixed duplicate headers problem]
-# brister 19oct98 [cleaned up somewhat for Perl v. 5. and made a little more robust]
-# vixie 29jan95 [RCS'd]
-# vixie 15jun93 [added -m]
-# vixie 30jun92 [added -a and -d]
-# vixie 17jun92 [attempt simple-minded fixup to $path]
-# vixie 14jun92 [original]
-
-use Getopt::Std;
-use IPC::Open3;
-use IO::Select;
-use Sys::Syslog;
-use strict;
-
-my $debugging = 0 ;
-my $tmpfile ;
-my $tmpfile2 ;
-my $msg ;
-
-END {
-    unlink ($tmpfile) if $tmpfile ;            # in case we die()
-    unlink ($tmpfile2) if $tmpfile2 ;          # in case we die()
-}
-
-my $LOCK_SH = 1;
-my $LOCK_EX = 2;
-my $LOCK_NB = 4;
-my $LOCK_UN = 8;
-
-my $usage = $0 ;
-$usage =~ s!.*/!! ;
-my $prog = $usage ;
-
-openlog $usage, "pid", $inn::syslog_facility ;
-
-$usage .= "[ -r addr ][ -f addr ][ -a approved ][ -d distribution ]" .
-    " [ -m mailing-list ][ -b database ][ -o output-path ] [ -c wait-time ]" .
-    " [ -x header[:header...] ] [ -p port ] newsgroups" ;
-
-use vars qw($opt_r $opt_f $opt_a $opt_d $opt_m $opt_b $opt_n $opt_o $opt_h $opt_c $opt_x $opt_p) ;
-getopts("hr:f:a:d:m:b:no:c:x:p:") || die "usage: $usage\n" ;
-die "usage: $usage\n" if $opt_h ;
-
-#
-# $Submit is a program which takes no arguments and whose stdin is supposed
-# to be a news article (without the #!rnews header but with the news hdr).
-#
-
-my $Sendmail = $inn::mta ;
-my $Submit = $inn::inews . " -S -h" . ($opt_p ? " -p $opt_p" : '');
-my $Database = ($opt_b || $inn::pathtmp) . "/mailpost-msgid" ;
-my $Maintainer = $inn::newsmaster || "usenet" ; 
-my $WhereTo = $opt_o || $Submit ;
-my $Mailname = $inn::fromhost ;
-
-# Can't use $inn::pathtmp as we're usually not running as news.
-my $Tmpdir = "/var/tmp" ;      
-
-if ($debugging || $opt_n) {
-    $Sendmail = "cat" ;
-    $WhereTo = "cat" ;
-}
-
-chop ($Mailname = `/bin/hostname`) if ! $Mailname ;
-
-
-#
-# Our command-line argument(s) are the list of newsgroups to post to.
-#
-# There may be a "-r sender" or "-f sender" which becomes the $path
-# (which is in turn overridden below by various optional headers).
-#
-# -d (distribution) and -a (approved) are also supported to supply
-# or override the mail headers by those names.
-#
-
-my $path = 'nobody';
-my $newsgroups = undef;
-my $approved = undef;
-my $distribution = undef;
-my $mailing_list = undef;
-my $references = undef;
-my @errorText = ();
-
-if ($opt_r || $opt_f) {
-    $path = $opt_r || $opt_f ;
-    push @errorText, "((path: $path))\n" ;
-}
-
-if ($opt_a) {
-    $approved = &fix_sender_addr($opt_a);
-    push @errorText, "((approved: $approved))\n";
-}
-
-if ($opt_d) {
-    $distribution = $opt_d ;
-    push @errorText, "((distribution: $distribution))\n";
-}
-
-if ($opt_m) {
-    $mailing_list = "<" . $opt_m . "> /dev/null";
-    push @errorText, "((mailing_list: $mailing_list))\n";
-}
-
-my $exclude = 'Organization|Distribution';
-if ($opt_x) {
-    $exclude .= '|' . join('|', split(/:/, $opt_x));
-}
-
-$newsgroups = join ",", @ARGV ;
-
-die "usage:  $0 newsgroup [newsgroup ...]\n" unless $newsgroups;
-
-
-#
-# Do the header.  Our input is a mail message, with or without the From.
-#
-
-#$message_id = sprintf("<mailpost.%d.%d@%s>", time, $$, $Hostname);
-my $real_news_hdrs = '';
-my $weird_mail_hdrs = '';
-my $fromHdr = "MAILPOST-UNKNOWN-FROM" ;
-my $dateHdr= "MAILPOST-UNKNOWN-DATE" ;
-my $msgIdHdr = "MAILPOST-UNKNOWN-MESSAGE-ID" ;
-my $from = undef;
-my $date = undef;
-my $hdr = undef;
-my $txt = undef;
-my $message_id ;
-my $subject = "(NONE)";
-
-$_ = <STDIN>;
-if (!$_) {
-    if ( $debugging || -t STDERR ) {
-       die "empty input" ;
-    } else {
-       syslog "err", "empty input" ;
-       exit (0) ;
-    }
-}
-
-chomp $_;
-
-my $line = undef;
-if (/^From\s+([^\s]+)\s+/) {
-    $path = $1;
-    push @errorText, "((path: $path))\n";
-    $_ = $';
-    if (/ remote from /) {
-       $path = $' . '!' . $path;
-       $_ = $`;
-    }
-} else {
-    $line = $_;
-}
-
-for (;;) {
-    last if defined($line) && ($line =~ /^$/) ;
-
-    $_ = <STDIN> ;
-    last unless defined $_ ;
-    chomp ;
-
-    # Gather up a single header with possible continuation lines into $line.
-    if (/^\s+/) {
-       if (! $line) {
-           $msg = "First line with leading whitespace!" ;
-           syslog "err", $msg unless -t STDERR ;
-           die "$msg\n" ;
-       }           
-
-       $line .= "\n" . $_ ;
-       next ;
-    }
-
-    # On the first header, $line will be undefined.
-    ($_, $line) = ($line, $_) ; # Swap $line and $_.
-
-    last if defined($_) && /^$/ ;
-    next if /^$/ ;             # Only on first header will this happen.
-
-    push @errorText, "($_)\n";
-
-    next if /^Approved:\s/sio && defined($approved);
-    next if /^Distribution:\s/sio && defined($distribution);
-
-    if (/^($exclude):\s*/sio) {
-       $real_news_hdrs .= "$_\n";
-       next;
-    }
-
-    if (/^Subject:\s*/sio) {
-       $subject = $';
-       next;
-    }
-
-    if (/^Message-ID:\s*/sio) {
-       $message_id = $';
-       next;
-    }
-
-    if (/^Mailing-List:\s*/sio) {
-       $mailing_list = $';
-       next;
-    }
-
-    if (/^(Sender|Approved):\s*/sio) {
-       $real_news_hdrs .= "$&" . fix_sender_addr($') . "\n";
-       next;
-    }
-
-    if (/^Return-Path:\s*/sio) {
-       $path = $';
-       $path = $1 if ($path =~ /\<([^\>]*)\>/);
-       push@errorText, "((path: $path))\n";
-       next;
-    }
-
-    if (/^Date:\s*/sio) {
-       $date = $';
-       next;
-    }
-
-    if (/^From:\s*/sio) {
-       $from = &fix_sender_addr($');
-       next;
-    }
-
-    if (/^References:\s*/sio) {
-       $references = $';
-       next;
-    }
-
-    if (!defined($references) && /^In-Reply-To:[^\<]*\<([^\>]+)\>/sio) {
-       $references = "<$1>";
-       # FALLTHROUGH
-    }
-
-    if (/^(MIME|Content)-[^:]+:\s*/sio) {
-       $real_news_hdrs .= $_ . "\n" ;
-       next ;
-    }
-
-    # Strip out news X-Trace: and X-Complaints-To: headers since otherwise posting
-    # may fail.  Other trace headers will be renamed to add 'X-' so we don't have
-    # to worry about them.
-    if (/^X-(Trace|Complaints-To):\s*/sio) {
-        next ;
-    }
-
-    # Random unknown header.  Prepend 'X-' if it is not already there.
-    $_ = "X-$_" unless /^X-/sio ;
-    $weird_mail_hdrs .= "$_\n";
-}
-
-
-$msgIdHdr = $message_id if $message_id ;
-$fromHdr = $from if $from ;
-$dateHdr = $date if $date ;
-
-if ($path !~ /\!/) {
-    $path = "$'!$`" if ($path =~ /\@/);
-}
-
-$real_news_hdrs .= "Subject: ${subject}\n";
-$real_news_hdrs .= "Message-ID: ${msgIdHdr}\n"       if defined($message_id);
-$real_news_hdrs .= "Mailing-List: ${mailing_list}\n" if defined($mailing_list);
-$real_news_hdrs .= "Distribution: ${distribution}\n" if defined($distribution);
-$real_news_hdrs .= "Approved: ${approved}\n"         if defined($approved);
-$real_news_hdrs .= "References: ${references}\n"     if defined($references);
-
-# Remove duplicate headers.
-my %headers = ();
-$real_news_hdrs =~ s/((.*?:) .*?($|\n)([ \t]+.*?($|\n))*)/$headers{lc$2}++?"":"$1"/ges;
-
-# inews writes error messages to stdout.  We want to capture those and mail
-# them back to the newsmaster.  Trying to write and read from a subprocess is 
-# ugly and prone to deadlock, so we use a temp file.
-$tmpfile = sprintf "%s/mailpost.%d.%d", $Tmpdir, time, $$ ;
-
-if (!open TMPFILE,">$tmpfile") {
-    $msg = "can't open temp file ($tmpfile): $!" ;
-    $tmpfile = undef ;
-    syslog("err", "$msg\n") unless $debugging || -t STDERR ;
-    open(TMPFILE, "|" . sprintf ($Sendmail, $Maintainer)) ||
-       die "die(no tmpfile): sendmail: $!\n" ;
-    print TMPFILE <<"EOF";
-To: $Maintainer
-Subject: mailpost failure ($newsgroups):  $msg
-
--------- Article Contents
-
-EOF
-}
-            
-print TMPFILE <<"EOF";
-Path: ${path}
-From: ${fromHdr}
-Newsgroups: ${newsgroups}
-${real_news_hdrs}Date: ${dateHdr}
-${weird_mail_hdrs}
-EOF
-    
-my $rest;
-$rest .= $_ while (<STDIN>);
-$rest =~ s/\n*$/\n/g;          # Remove trailing \n except very last.
-
-print TMPFILE $rest;
-close TMPFILE ;
-
-if ( ! $tmpfile ) {
-    # We had to bail and mail the article to the admin.
-    exit (0) ;
-}
-
-
-##
-## We've got the article in a temp file and now we validate some of the 
-## data we found and update our Message-ID database.
-##
-
-mailArtAndDie ("no From: found") unless $from;
-mailArtAndDie ("no Message-ID: found") unless $message_id;
-mailArtAndDie ("Malformed Message-ID ($message_id)") 
-    if ($message_id !~ /\<(\S+)\@(\S+)\>/);
-
-
-# Update (with locking) our Message-ID database.  This is used to make sure we
-# don't loop our own gatewayed articles back through the mailing list.
-
-my ($lhs, $rhs) = ($1, $2);    # Of message_id matched above.
-$rhs =~ tr/A-Z/a-z/;
-
-$message_id = "${lhs}\@${rhs}";
-
-push @errorText, "(TAS Message-ID database for $message_id)\n";
-
-my $lockfile = sprintf("%s.lock", $Database);
-
-open(LOCKFILE, "<$lockfile") || 
-    open(LOCKFILE, ">$lockfile") ||
-    mailArtAndDie ("can't open $lockfile: $!") ;
-
-my $i ;
-for ($i = 0 ; $i < 5 ; $i++) {
-    flock(LOCKFILE, $LOCK_EX) && last ;
-    sleep 1 ;
-}
-
-mailArtAndDie ("can't lock $lockfile: $!") if ($i == 5) ;
-
-my %DATABASE ;
-dbmopen(%DATABASE, $Database, 0666) || mailArtAndDie ("can't dbmopen $Database: $!");
-
-if (defined $DATABASE{$message_id}) {
-
-  exit 0 if (!$opt_c) ;
-
-## crosspost -c
-  $newsgroups = &append_newsgroups($DATABASE{$message_id}, $newsgroups) ;
-  syslog "err", "crosspost $newsgroups\n" if $debugging ;
-}
-
-#$DATABASE{$message_id} = sprintf "%d.%s", time, 'mailpost' ;
-$DATABASE{$message_id} = $newsgroups ;
-
-mailArtAndDie ("TAS didn't set $message_id") unless defined $DATABASE{$message_id};
-
-dbmclose(%DATABASE) || mailArtAndDie ("can't dbmclose $Database: $!") ;
-
-flock(LOCKFILE, $LOCK_UN) || mailArtAndDie ("can't unlock $lockfile: $!");
-close LOCKFILE ;
-
-## For crosspost.
-
-if ($opt_c) {
-  if (fork() != 0) {
-    undef $tmpfile;  # Don't unlink $tmpfile.
-    exit 0;
-  }
-  sleep $opt_c ;
-
-  open(LOCKFILE, "<$lockfile") || 
-    open(LOCKFILE, ">$lockfile") ||
-      mailArtAndDie ("can't open $lockfile: $!") ;
-
-  my $i ;
-  for ($i = 0 ; $i < 5 ; $i++) {
-    flock(LOCKFILE, $LOCK_EX) && last ;
-    sleep 1 ;
-  }
-  mailArtAndDie ("can't lock $lockfile: $!") if ($i == 5) ;
-
-  my $umask_bak = umask();
-  umask(000);
-  dbmopen(%DATABASE, $Database, 0666) || mailArtAndDie ("can't dbmopen $Database: $!");
-  umask($umask_bak);
-
-  my $dup = undef ;
-  syslog "err", "check   " . $DATABASE{$message_id} . " :  $newsgroups\n" if $debugging ;
-  $dup = 1 if ($DATABASE{$message_id} ne $newsgroups) ;
-
-  dbmclose(%DATABASE) || mailArtAndDie ("can't dbmclose $Database: $!") ;
-
-  flock(LOCKFILE, $LOCK_UN) || mailArtAndDie ("can't unlock $lockfile: $!");
-  close LOCKFILE ;
-
-  if (defined($dup)) {
-    syslog "err", "mismatch $newsgroups\n" if $debugging ;
-    exit 0 ;
-  }
-
-  # Replace Newsgroups:.
-  open(TMPFILE, "$tmpfile") || mailArtAndDie ("can't open temp file ($tmpfile): $!") ;
-  $tmpfile2 = sprintf "%s/mailpost-crosspost.%d.%d", $Tmpdir, time, $$ ;
-    if ( !open TMPFILE2, ">$tmpfile2") {
-    $msg = "can't open temp file ($tmpfile2): $!" ;
-    $tmpfile2 = undef ;
-    die $msg ;
-  }
-    for (;;) {
-    $_ = <TMPFILE> ;
-    chomp ;
-    last if defined($_) && /^$/ ;
-
-    if (/^Newsgroups:\s*/sio) {
-      printf TMPFILE2 "Newsgroups: %s\n", $newsgroups ;
-      next ;
-    }
-    print TMPFILE2 "$_\n" ;
-  }
-  printf TMPFILE2 "\n" ;
-
-  my $rest;
-  $rest .= $_ while (<TMPFILE>);
-  $rest =~ s/\n*$/\n/g;                # Remove trailing \n except very last.
-
-  print TMPFILE2 $rest;
-  close TMPFILE2 ;
-  close TMPFILE ;
-  rename($tmpfile2, $tmpfile) || mailArtAndDie ("can't rename $tmpfile2 $tmpfile: $!") ;
-  $tmpfile2 = undef ;
-
-}
-
-if (!open INEWS, "$WhereTo < $tmpfile 2>&1 |") {
-    mailArtAndDie ("can't start $WhereTo: $!") ;
-}
-
-my @inews = <INEWS> ;
-close INEWS ;
-my $status = $? ;
-
-if (@inews) {
-    chomp @inews ;
-    mailArtAndDie ("inews failed: @inews") ;
-}
-
-unlink $tmpfile ;
-
-exit $status;
-
-sub mailArtAndDie {
-    my ($msg) = @_ ;
-    
-    print STDERR $msg,"\n" if -t STDERR ;
-    
-    open(SENDMAIL, "|" . sprintf ($Sendmail,$Maintainer)) ||
-       die "die($msg): sendmail: $!\n" ;
-    print SENDMAIL <<"EOF" ;
-To: $Maintainer
-Subject: mailpost failure ($newsgroups)
-
-$msg
-
-EOF
-            
-    if ($tmpfile && -f $tmpfile) {
-       print SENDMAIL "\n-------- Article Contents\n\n" ;
-       open(FILE, "<$tmpfile") || die "open($tmpfile): $!\n" ;
-       print SENDMAIL while <FILE> ;
-       close FILE ;
-    } else {
-       print "No article left to send back.\n" ;
-    }
-    close SENDMAIL ;
-    
-#    unlink $tmpfile ;
-    
-    exit (0) ;                 # Using a non-zero exit may cause problems.
-}
-
-
-#
-# Take 822-format name (either "comment <addr> comment" or "addr (comment)")
-# and return in always-qualified 974-format ("addr (comment)").
-#
-sub fix_sender_addr {
-    my ($address) = @_;
-    my ($lcomment, $addr, $rcomment, $comment);
-    local ($',$`,$_) ;
-
-    if ($address =~ /\<([^\>]*)\>/) {
-       ($lcomment, $addr, $rcomment) = (&dltb($`), &dltb($1), &dltb($'));
-    } elsif ($address =~ /\(([^\)]*)\)/) {
-       ($lcomment, $addr, $rcomment) = ('', &dltb($`.$'), &dltb($1));
-    } else {
-       ($lcomment, $addr, $rcomment) = ('', &dltb($address), '');
-    }
-    
-    #print STDERR "fix_sender_addr($address) == ($lcomment, $addr, $rcomment)\n";
-    
-    $addr .= "\@$Mailname" unless ($addr =~ /\@/);
-    
-    if ($lcomment && $rcomment) {
-       $comment = $lcomment . ' ' . $rcomment;
-    } else {
-       $comment = $lcomment . $rcomment;
-    }
-    
-    $_ = $addr;
-    $_ .= " ($comment)" if $comment;
-    
-    #print STDERR "\t-> $_\n";
-    
-    return $_;
-}
-
-#
-# Delete leading and trailing blanks.
-#
-
-sub dltb {
-    my ($str) = @_;
-    
-    $str =~ s/^\s+//o;
-    $str =~ s/\s+$//o;
-    
-    return $str;
-}
-
-sub append_newsgroups ($$) {
-  my (@orig) = split(/,/,$_[0]) ;
-  my (@new) = split(/,/,$_[1]) ;
-  my $newsgroup ;
-
-  foreach $newsgroup (@new) {
-    if ( !grep($_ eq $newsgroup,@orig)) {
-      push @orig, $newsgroup ;
-    } else {
-#      mailArtAndDie ("Duplicate Newsgroups: $newsgroup") ;
-    }
-  }
-  return join ",", @orig ;
-
-}
-
diff --git a/frontends/ovdb_init.c b/frontends/ovdb_init.c
deleted file mode 100644 (file)
index b87ec68..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * ovdb_init
- *  Performs recovery on OV database, if needed
- *  Performs upgrade of OV database, if needed and if '-u' used
- *  Starts ovdb_monitor, if needed
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-#include <errno.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "ov.h"
-#include "../storage/ovdb/ovdb.h"
-#include "../storage/ovdb/ovdb-private.h"
-
-#ifndef USE_BERKELEY_DB
-
-int main(int argc UNUSED, char **argv UNUSED)
-{
-    die("BerkeleyDB support not compiled");
-}
-
-#else /* USE_BERKELEY_DB */
-
-static int open_db(DB **db, const char *name, int type)
-{
-    int ret;
-#if DB_VERSION_MAJOR == 2
-    DB_INFO dbinfo;
-    memset(&dbinfo, 0, sizeof dbinfo);
-
-    ret = db_open(name, type, DB_CREATE, 0666, OVDBenv, &dbinfo, db);
-    if (ret != 0) {
-       warn("db_open failed: %s", db_strerror(ret));
-       return ret;
-    }
-#else
-    ret = db_create(db, OVDBenv, 0);
-    if (ret != 0) {
-       warn("db_create failed: %s\n", db_strerror(ret));
-       return ret;
-    }
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    ret = (*db)->open(*db, NULL, name, NULL, type, DB_CREATE, 0666);
-#else
-    ret = (*db)->open(*db, name, NULL, type, DB_CREATE, 0666);
-#endif
-    if (ret != 0) {
-       (*db)->close(*db, 0);
-        warn("%s->open failed: %s", name, db_strerror(ret));
-       return ret;
-    }
-#endif
-    return 0;
-}
-
-/* Upgrade BerkeleyDB version */
-static int upgrade_database(const char *name UNUSED)
-{
-#if DB_VERSION_MAJOR == 2
-    return 0;
-#else
-    int ret;
-    DB *db;
-
-    ret = db_create(&db, OVDBenv, 0);
-    if (ret != 0)
-       return ret;
-
-    notice("upgrading %s...", name);
-    ret = db->upgrade(db, name, 0);
-    if (ret != 0)
-        warn("db->upgrade(%s) failed: %s", name, db_strerror(ret));
-
-    db->close(db, 0);
-    return ret;
-#endif
-}
-
-
-struct groupstats {
-    ARTNUM low;
-    ARTNUM high;
-    int count;
-    int flag;
-    time_t expired;
-};
-
-static int v1_which_db(char *group)
-{
-    HASH grouphash;
-    unsigned int i;
-
-    grouphash = Hash(group, strlen(group));
-    memcpy(&i, &grouphash, sizeof(i));
-    return i % ovdb_conf.numdbfiles;
-}
-
-/* Upgrade ovdb data format version 1 to 2 */
-/* groupstats and groupsbyname are replaced by groupinfo */
-static int upgrade_v1_to_v2(void)
-{
-    DB *groupstats, *groupsbyname, *groupinfo, *vdb;
-    DBT key, val, ikey, ival;
-    DBC *cursor;
-    group_id_t gid, higid = 0, higidbang = 0;
-    struct groupinfo gi;
-    struct groupstats gs;
-    char group[MAXHEADERSIZE];
-    u_int32_t v2 = 2;
-    int ret;
-    char *p;
-
-    notice("upgrading data to version 2");
-    ret = open_db(&groupstats, "groupstats", DB_BTREE);
-    if (ret != 0)
-       return ret;
-    ret = open_db(&groupsbyname, "groupsbyname", DB_HASH);
-    if (ret != 0)
-       return ret;
-    ret = open_db(&groupinfo, "groupinfo", DB_BTREE);
-    if (ret != 0)
-       return ret;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    memset(&ikey, 0, sizeof ikey);
-    memset(&ival, 0, sizeof ival);
-
-    ret = groupsbyname->cursor(groupsbyname, NULL, &cursor, 0);
-    if (ret != 0)
-       return ret;
-
-    while((ret = cursor->c_get(cursor, &key, &val, DB_NEXT)) == 0) {
-       if(key.size == 1 && *((char *)(key.data)) == '!') {
-           if(val.size == sizeof(group_id_t))
-               memcpy(&higidbang, val.data, sizeof(group_id_t));
-           continue;
-       }
-       if(key.size >= MAXHEADERSIZE)
-           continue;
-       memcpy(group, key.data, key.size);
-       group[key.size] = 0;
-
-       if(val.size != sizeof(group_id_t))
-           continue;
-       memcpy(&gid, val.data, sizeof(group_id_t));
-       if(gid > higid)
-           higid = gid;
-       ikey.data = &gid;
-       ikey.size = sizeof(group_id_t);
-
-        ret = groupstats->get(groupstats, NULL, &ikey, &ival, 0);
-       if (ret != 0)
-           continue;
-       if(ival.size != sizeof(struct groupstats))
-           continue;
-       memcpy(&gs, ival.data, sizeof(struct groupstats));
-
-       gi.low = gs.low;
-       gi.high = gs.high;
-       gi.count = gs.count;
-       gi.flag = gs.flag;
-       gi.expired = gs.expired;
-       gi.current_gid = gi.new_gid = gid;
-       gi.current_db = gi.new_db = v1_which_db(group);
-       gi.expiregrouppid = gi.status = 0;
-
-       val.data = &gi;
-       val.size = sizeof(gi);
-        ret = groupinfo->put(groupinfo, NULL, &key, &val, 0);
-       if (ret != 0) {
-            warn("groupinfo->put failed: %s", db_strerror(ret));
-           cursor->c_close(cursor);
-           return ret;
-       }
-    }
-    cursor->c_close(cursor);
-    if(ret != DB_NOTFOUND) {
-        warn("cursor->get failed: %s", db_strerror(ret));
-       return ret;
-    }
-
-    higid++;
-    if(higidbang > higid)
-       higid = higidbang;
-
-    key.data = (char *) "!groupid_freelist";
-    key.size = sizeof("!groupid_freelist");
-    val.data = &higid;
-    val.size = sizeof(group_id_t);
-
-    ret = groupinfo->put(groupinfo, NULL, &key, &val, 0);
-    if (ret != 0) {
-        warn("groupinfo->put failed: %s", db_strerror(ret));
-       return ret;
-    }
-
-    ret = open_db(&vdb, "version", DB_BTREE);
-    if (ret != 0)
-       return ret;
-
-    key.data = (char *) "dataversion";
-    key.size = sizeof("dataversion");
-    val.data = &v2;
-    val.size = sizeof v2;
-
-    ret = vdb->put(vdb, NULL, &key, &val, 0);
-    if (ret != 0) {
-        warn("version->put failed: %s", db_strerror(ret));
-       return ret;
-    }
-
-    groupstats->close(groupstats, 0);
-    groupsbyname->close(groupsbyname, 0);
-    groupinfo->close(groupinfo, 0);
-    vdb->close(vdb, 0);
-    
-#if DB_VERSION_MAJOR >= 3
-    ret = db_create(&groupstats, OVDBenv, 0);
-    if (ret != 0)
-       return ret;
-    groupstats->remove(groupstats, "groupstats", NULL, 0);
-    ret = db_create(&groupsbyname, OVDBenv, 0);
-    if (ret != 0)
-       return ret;
-    groupsbyname->remove(groupsbyname, "groupsbyname", NULL, 0);
-#else
-    /* This won't work if someone changed DB_DATA_DIR in DB_CONFIG */
-    p = concatpath(ovdb_conf.home, "groupstats");
-    unlink(p);
-    free(p);
-    p = concatpath(ovdb_conf.home, "groupsbyname");
-    unlink(p);
-    free(p);
-#endif
-
-    return 0;
-}
-
-static int check_upgrade(int do_upgrade)
-{
-    int ret, i;
-    DB *db;
-    DBT key, val;
-    u_int32_t dv;
-    char name[50];
-
-    if(do_upgrade && (ret = upgrade_database("version")))
-       return ret;
-
-    ret = open_db(&db, "version", DB_BTREE);
-    if (ret != 0)
-       return ret;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    key.data = (char *) "dataversion";
-    key.size = sizeof("dataversion");
-    ret = db->get(db, NULL, &key, &val, 0);
-    if (ret != 0) {
-       if(ret != DB_NOTFOUND) {
-            warn("cannot retrieve version: %s", db_strerror(ret));
-           db->close(db, 0);
-           return ret;
-       }
-    }
-    if(ret == DB_NOTFOUND || val.size != sizeof dv) {
-       dv = DATA_VERSION;
-
-       val.data = &dv;
-       val.size = sizeof dv;
-        ret = db->put(db, NULL, &key, &val, 0);
-       if (ret != 0) {
-            warn("cannot store version: %s", db_strerror(ret));
-           db->close(db, 0);
-           return ret;
-       }
-    } else
-       memcpy(&dv, val.data, sizeof dv);
-
-    key.data = (char *) "numdbfiles";
-    key.size = sizeof("numdbfiles");
-    if ((ret = db->get(db, NULL, &key, &val, 0)) == 0)
-       if(val.size == sizeof(ovdb_conf.numdbfiles))
-           memcpy(&(ovdb_conf.numdbfiles), val.data, sizeof(ovdb_conf.numdbfiles));
-    db->close(db, 0);
-
-    if(do_upgrade) {
-       if(dv == 1) {
-            ret = upgrade_database("groupstats");
-           if (ret != 0)
-               return ret;
-            ret = upgrade_database("groupsbyname");
-           if (ret != 0)
-               return ret;
-       } else {
-            ret = upgrade_database("groupinfo");
-           if (ret != 0)
-               return ret;
-       }
-        ret = upgrade_database("groupaliases");
-       if (ret != 0)
-           return ret;
-       for(i = 0; i < ovdb_conf.numdbfiles; i++) {
-           snprintf(name, sizeof(name), "ov%05d", i);
-            ret = upgrade_database(name);
-           if (ret != 0)
-               return ret;
-       }
-    }
-
-    if(dv > DATA_VERSION) {
-        warn("cannot open database: unknown version %d", dv);
-       return EINVAL;
-    }
-    if(dv < DATA_VERSION) {
-       if(do_upgrade)
-           return upgrade_v1_to_v2();
-
-        warn("database needs to be upgraded");
-       return EINVAL;
-    }
-    return 0;
-}
-
-int
-upgrade_environment(void)
-{
-    int ret;
-
-    ovdb_close_berkeleydb();
-    ret = ovdb_open_berkeleydb(OV_WRITE, OVDB_UPGRADE);
-    if (ret != 0)
-       return ret;
-#if DB_VERSION_MAJOR >= 3
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
-    ret = OVDBenv->remove(OVDBenv, ovdb_conf.home, NULL, 0);
-#else
-    ret = OVDBenv->remove(OVDBenv, ovdb_conf.home, 0);
-#endif
-    if (ret != 0)
-       return ret;
-    OVDBenv = NULL;
-    ret = ovdb_open_berkeleydb(OV_WRITE, 0);
-#endif
-    return ret;
-}
-
-int main(int argc, char **argv)
-{
-    int ret, c, do_upgrade = 0, recover_only = 0, err = 0;
-    bool locked;
-    int flags;
-
-    openlog("ovdb_init", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "ovdb_init";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    if(strcmp(innconf->ovmethod, "ovdb"))
-        die("ovmethod not set to ovdb in inn.conf");
-
-    if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
-
-    chdir(innconf->pathtmp);
-    ovdb_errmode = OVDB_ERR_STDERR;
-
-    while((c = getopt(argc, argv, "ru")) != -1) {
-       switch(c) {
-       case 'r':
-           recover_only = 1;
-           break;
-       case 'u':
-           do_upgrade = 1;
-           break;
-       case '?':
-            warn("unrecognized option -%c", optopt);
-           err++;
-           break;
-       }
-    }
-    if(recover_only && do_upgrade) {
-        warn("cannot use both -r and -u at the same time");
-       err++;
-    }
-    if(err) {
-       fprintf(stderr, "Usage: ovdb_init [-r|-u]\n");
-       exit(1);
-    }
-
-    locked = ovdb_getlock(OVDB_LOCK_EXCLUSIVE);
-    if(locked) {
-       if(do_upgrade) {
-            notice("database is quiescent, upgrading");
-           flags = OVDB_RECOVER | OVDB_UPGRADE;
-       }
-       else {
-            notice("database is quiescent, running normal recovery");
-           flags = OVDB_RECOVER;
-       }
-    } else {
-        warn("database is active");
-       if(do_upgrade) {
-            warn("upgrade will not be attempted");
-           do_upgrade = 0;
-       }
-       if(recover_only)
-            die("recovery will not be attempted");
-       ovdb_getlock(OVDB_LOCK_ADMIN);
-       flags = 0;
-    }
-
-    ret = ovdb_open_berkeleydb(OV_WRITE, flags);
-    if(ret == DB_RUNRECOVERY) {
-       if(locked)
-            die("database could not be recovered");
-       else {
-            warn("database needs recovery but cannot be locked");
-            die("other processes accessing the database must exit to start"
-                " recovery");
-        }
-    }
-    if(ret != 0)
-        die("cannot open BerkeleyDB: %s", db_strerror(ret));
-
-    if(recover_only)
-       exit(0);
-
-    if(do_upgrade) {
-       ret = upgrade_environment();
-       if(ret != 0)
-           die("cannot upgrade BerkeleyDB environment: %s", db_strerror(ret));
-    }
-
-    if(check_upgrade(do_upgrade)) {
-       ovdb_close_berkeleydb();
-       exit(1);
-    }
-
-    ovdb_close_berkeleydb();
-    ovdb_releaselock();
-
-    if(ovdb_check_pidfile(OVDB_MONITOR_PIDFILE) == false) {
-        notice("starting ovdb monitor");
-       switch(fork()) {
-       case -1:
-            sysdie("cannot fork");
-       case 0:
-           setsid();
-           execl(concatpath(innconf->pathbin, "ovdb_monitor"),
-               "ovdb_monitor", SPACES, NULL);
-            syswarn("cannot exec ovdb_monitor");
-           _exit(1);
-       }
-       sleep(2);       /* give the monitor a chance to start */
-    } else
-        warn("ovdb_monitor already running");
-
-    if(ovdb_conf.readserver) {
-       if(ovdb_check_pidfile(OVDB_SERVER_PIDFILE) == false) {
-            notice("starting ovdb server");
-           daemonize(innconf->pathtmp);
-           execl(concatpath(innconf->pathbin, "ovdb_server"), "ovdb_server",
-               SPACES, NULL);
-            syswarn("cannot exec ovdb_server");
-           _exit(1);
-       } else
-            warn("ovdb_server already running");
-    }
-
-    exit(0);
-}
-#endif /* USE_BERKELEY_DB */
-
diff --git a/frontends/ovdb_monitor.c b/frontends/ovdb_monitor.c
deleted file mode 100644 (file)
index 3fbd9b7..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * ovdb_monitor
- *   Performs database maintenance tasks
- *   + Transaction checkpoints
- *   + Deadlock detection
- *   + Transaction log removal
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/setproctitle.h"
-#include "portable/wait.h"
-#include <fcntl.h>
-#include <signal.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "ov.h"
-
-#include "../storage/ovdb/ovdb.h"
-#include "../storage/ovdb/ovdb-private.h"
-
-#ifndef USE_BERKELEY_DB
-
-int main(int argc UNUSED, char **argv UNUSED)
-{
-    exit(0);
-}
-
-#else /* USE_BERKELEY_DB */
-
-static int signalled = 0;
-static void sigfunc(int sig UNUSED)
-{
-    signalled = 1;
-}
-
-
-static pid_t deadlockpid = 0;
-static pid_t checkpointpid = 0;
-static pid_t logremoverpid = 0;
-
-static int putpid(const char *path)
-{
-    char buf[30];
-    int fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0664);
-    if(!fd) {
-        syswarn("cannot open %s", path);
-       return -1;
-    }
-    snprintf(buf, sizeof(buf), "%d\n", getpid());
-    if(write(fd, buf, strlen(buf)) < 0) {
-        syswarn("cannot write to %s", path);
-       close(fd);
-       return -1;
-    }
-    close(fd);
-    return 0;
-}
-
-static void deadlock(void)
-{
-    int ret, status = 0;
-    u_int32_t atype = DB_LOCK_YOUNGEST;
-
-    if(ovdb_open_berkeleydb(OV_WRITE, 0))
-       _exit(1);
-
-    setproctitle("deadlock");
-
-    while(!signalled) {
-#if DB_VERSION_MAJOR == 2
-       ret = lock_detect(OVDBenv->lk_info, 0, atype);
-#elif DB_VERSION_MAJOR == 3
-       ret = lock_detect(OVDBenv, 0, atype, NULL);
-#else
-       ret = OVDBenv->lock_detect(OVDBenv, 0, atype, NULL);
-#endif
-       if(ret != 0) {
-            warn("OVDB: lock_detect: %s", db_strerror(ret));
-           status = 1;
-           break;
-       }
-       sleep(30);
-    }
-
-    ovdb_close_berkeleydb();
-    _exit(status);
-}
-
-static void checkpoint(void)
-{
-    int ret, status = 0;
-    DB *db;
-#if DB_VERSION_MAJOR == 2
-    DB_INFO dbinfo;
-#endif
-
-    if(ovdb_open_berkeleydb(OV_WRITE, 0))
-       _exit(1);
-
-    setproctitle("checkpoint");
-
-    /* Open a database and close it.  This is so a necessary initialization
-       gets performed (by the db->open function).  */
-
-#if DB_VERSION_MAJOR == 2
-    memset(&dbinfo, 0, sizeof dbinfo);
-    ret = db_open("version", DB_BTREE, DB_CREATE, 0666, OVDBenv, &dbinfo, &db);
-    if (ret != 0) {
-        warn("OVDB: checkpoint: db_open failed: %s", db_strerror(ret));
-        _exit(1);
-    }
-#else
-    ret = db_create(&db, OVDBenv, 0);
-    if (ret != 0) {
-        warn("OVDB: checkpoint: db_create: %s", db_strerror(ret));
-        _exit(1);
-    }
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    ret = db->open(db, NULL, "version", NULL, DB_BTREE, DB_CREATE, 0666);
-#else
-    ret = db->open(db, "version", NULL, DB_BTREE, DB_CREATE, 0666);
-#endif
-    if (ret != 0) {
-        db->close(db, 0);
-        warn("OVDB: checkpoint: version open: %s", db_strerror(ret));
-        _exit(1);
-    }
-#endif
-    db->close(db, 0);
-
-
-    while(!signalled) {
-#if DB_VERSION_MAJOR == 2
-       ret = txn_checkpoint(OVDBenv->tx_info, 2048, 1);
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
-       ret = txn_checkpoint(OVDBenv, 2048, 1);
-#elif DB_VERSION_MAJOR == 3
-       ret = txn_checkpoint(OVDBenv, 2048, 1, 0);
-#elif DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1
-       ret = OVDBenv->txn_checkpoint(OVDBenv, 2048, 1, 0);
-#else
-       OVDBenv->txn_checkpoint(OVDBenv, 2048, 1, 0);
-#endif
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-       sleep(30);
-#else
-       if(ret != 0 && ret != DB_INCOMPLETE) {
-            warn("OVDB: txn_checkpoint: %s", db_strerror(ret));
-           status = 1;
-           break;
-       }
-       if(ret == DB_INCOMPLETE)
-           sleep(2);
-       else
-           sleep(30);
-#endif
-    }
-
-    ovdb_close_berkeleydb();
-    _exit(status);
-}
-
-static void logremover(void)
-{
-    int ret, status = 0;
-    char **listp, **p;
-
-    if(ovdb_open_berkeleydb(OV_WRITE, 0))
-       _exit(1);
-
-    setproctitle("logremover");
-
-    while(!signalled) {
-#if DB_VERSION_MAJOR == 2
-       ret = log_archive(OVDBenv->lg_info, &listp, DB_ARCH_ABS, malloc);
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-       ret = log_archive(OVDBenv, &listp, DB_ARCH_ABS, malloc);
-#elif DB_VERSION_MAJOR == 3
-       ret = log_archive(OVDBenv, &listp, DB_ARCH_ABS);
-#else
-       ret = OVDBenv->log_archive(OVDBenv, &listp, DB_ARCH_ABS);
-#endif
-       if(ret != 0) {
-            warn("OVDB: log_archive: %s", db_strerror(ret));
-           status = 1;
-           break;
-       }
-       if(listp != NULL) {
-           for(p = listp; *p; p++)
-               unlink(*p);
-           free(listp);
-       }
-       sleep(45);
-    }
-
-    ovdb_close_berkeleydb();
-    _exit(status);
-}
-
-static int start_process(pid_t *pid, void (*func)(void))
-{
-    pid_t child;
-
-    switch(child = fork()) {
-    case 0:
-       (*func)();
-       _exit(0);
-    case -1:
-        syswarn("cannot fork");
-       return -1;
-    default:
-       *pid = child;
-       return 0;
-    }
-    /*NOTREACHED*/
-}
-
-static void cleanup(int status)
-{
-    int cs;
-
-    if(deadlockpid)
-       kill(deadlockpid, SIGTERM);
-    if(checkpointpid)
-       kill(checkpointpid, SIGTERM);
-    if(logremoverpid)
-       kill(logremoverpid, SIGTERM);
-
-    xsignal(SIGINT, SIG_DFL);
-    xsignal(SIGTERM, SIG_DFL);
-    xsignal(SIGHUP, SIG_DFL);
-
-    if(deadlockpid)
-       waitpid(deadlockpid, &cs, 0);
-    if(checkpointpid)
-       waitpid(checkpointpid, &cs, 0);
-    if(logremoverpid)
-       waitpid(logremoverpid, &cs, 0);
-
-    unlink(concatpath(innconf->pathrun, OVDB_MONITOR_PIDFILE));
-    exit(status);
-}
-
-static void monitorloop(void)
-{
-    int cs, restartit;
-    pid_t child;
-
-    while(!signalled) {
-       child = waitpid(-1, &cs, WNOHANG);
-       if(child > 0) {
-           if(WIFSIGNALED(cs)) {
-               restartit = 0;
-           } else {
-               if(WEXITSTATUS(cs) == 0)
-                   restartit = 1;
-               else
-                   restartit = 0;
-           }
-           if(child == deadlockpid) {
-               deadlockpid = 0;
-               if(restartit && start_process(&deadlockpid, deadlock))
-                   cleanup(1);
-           } else if(child == checkpointpid) {
-               checkpointpid = 0;
-               if(restartit && start_process(&checkpointpid, checkpoint))
-                   cleanup(1);
-           } else if(child == logremoverpid) {
-               logremoverpid = 0;
-               if(restartit && start_process(&logremoverpid, logremover))
-                   cleanup(1);
-           }
-           if(!restartit)
-               cleanup(1);
-       }
-       sleep(20);
-    }
-    cleanup(0);
-}
-
-
-int main(int argc, char **argv)
-{
-    char *pidfile;
-
-    setproctitle_init(argc, argv);
-
-    openlog("ovdb_monitor", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "ovdb_monitor";
-
-    if(argc != 2 || strcmp(argv[1], SPACES))
-        die("should be started by ovdb_init");
-    message_handlers_warn(1, message_log_syslog_err);
-    message_handlers_die(1, message_log_syslog_err);
-
-    if (!innconf_read(NULL))
-       exit(1);
-
-    if(strcmp(innconf->ovmethod, "ovdb"))
-        die("ovmethod not set to ovdb in inn.conf");
-    if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
-    if(!ovdb_getlock(OVDB_LOCK_ADMIN))
-        die("cannot lock database");
-
-    xsignal(SIGINT, sigfunc);
-    xsignal(SIGTERM, sigfunc);
-    xsignal(SIGHUP, sigfunc);
-
-    pidfile = concatpath(innconf->pathrun, OVDB_MONITOR_PIDFILE);
-    if(putpid(pidfile))
-       exit(1);
-    if(start_process(&deadlockpid, deadlock))
-       cleanup(1);
-    if(start_process(&checkpointpid, checkpoint))
-       cleanup(1);
-    if(start_process(&logremoverpid, logremover))
-       cleanup(1);
-
-    monitorloop();
-
-    /* Never reached. */
-    return 1;
-}
-
-#endif /* USE_BERKELEY_DB */
-
diff --git a/frontends/ovdb_server.c b/frontends/ovdb_server.c
deleted file mode 100644 (file)
index af6d7cb..0000000
+++ /dev/null
@@ -1,744 +0,0 @@
-/*
- * ovdb_server.c
- * ovdb read server
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include "portable/time.h"
-#include "portable/setproctitle.h"
-#include "portable/socket.h"
-#include "portable/wait.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#include <syslog.h>
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-#include "ov.h"
-
-#include "../storage/ovdb/ovdb.h"
-#include "../storage/ovdb/ovdb-private.h"
-
-#ifndef USE_BERKELEY_DB
-
-int
-main(int argc UNUSED, char **argv UNUSED)
-{
-    die("BerkeleyDB support not compiled");
-}
-
-#else /* USE_BERKELEY_DB */
-
-
-#define SELECT_TIMEOUT 15
-
-
-/* This will work unless user sets a larger clienttimeout
-   in readers.conf */
-#define CLIENT_TIMEOUT (innconf->clienttimeout + 60)
-/*#define CLIENT_TIMEOUT 3600*/
-
-
-static int listensock;
-
-#define MODE_READ   0
-#define MODE_WRITE  1
-#define MODE_CLOSED 2
-#define STATE_READCMD 0
-#define STATE_READGROUP 1
-struct reader {
-    int fd;
-    int mode;
-    int state;
-    int buflen;
-    int bufpos;
-    void *buf;
-    time_t lastactive;
-    void *currentsearch;
-};
-
-static struct reader *readertab;
-static int readertablen;
-static int numreaders;
-static time_t now;
-static pid_t parent;
-
-struct child {
-    pid_t pid;
-    int num;
-    time_t started;
-};
-static struct child *children;
-#define wholistens (children[ovdb_conf.numrsprocs].num)
-
-static int signalled = 0;
-static void
-sigfunc(int sig UNUSED)
-{
-    signalled = 1;
-}
-
-static int updated = 0;
-static void
-childsig(int sig UNUSED)
-{
-    updated = 1;
-}
-
-static void
-parentsig(int sig UNUSED)
-{
-    int i, which, smallest;
-    if(wholistens < 0) {
-       which = smallest = -1;
-       for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-           if(children[i].pid == -1)
-               continue;
-           if(!ovdb_conf.maxrsconn || children[i].num <= ovdb_conf.maxrsconn) {
-               if(smallest == -1 || children[i].num < smallest) {
-                   smallest = children[i].num;
-                   which = i;
-               }
-           }
-       }
-       if(which != -1) {
-           wholistens = which;
-           kill(children[which].pid, SIGUSR1);
-       } else {
-           wholistens = -2;
-       }
-       updated = 1;
-    }
-}
-
-static int putpid(const char *path)
-{
-    char buf[30];
-    int fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0664);
-    if(fd == -1) {
-        syswarn("cannot open %s", path);
-        return -1;
-    }
-    snprintf(buf, sizeof(buf), "%d\n", getpid());
-    if(write(fd, buf, strlen(buf)) < 0) {
-        syswarn("cannot write to %s", path);
-        close(fd);
-        return -1;
-    }
-    close(fd);
-    return 0;
-}
-
-static void
-do_groupstats(struct reader *r)
-{
-    struct rs_groupstats *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    reply = xmalloc(sizeof(struct rs_groupstats));
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_groupstats '%s'", group);*/
-    if(ovdb_groupstats(group, &reply->lo, &reply->hi, &reply->count, &reply->flag)) {
-       reply->status = CMD_GROUPSTATS;
-       reply->aliaslen = 0;
-    } else {
-       reply->status = CMD_GROUPSTATS | RPLY_ERROR;
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->buflen = sizeof(struct rs_groupstats);
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_opensrch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_opensrch *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    reply = xmalloc(sizeof(struct rs_opensrch));
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_opensrch '%s' %d %d", group, cmd->artlo, cmd->arthi);*/
-
-    if(r->currentsearch != NULL) {
-       /* can only open one search at a time */
-       reply->status = CMD_OPENSRCH | RPLY_ERROR;
-    } else {
-       reply->handle = ovdb_opensearch(group, cmd->artlo, cmd->arthi);
-       if(reply->handle == NULL) {
-           reply->status = CMD_OPENSRCH | RPLY_ERROR;
-       } else {
-           reply->status = CMD_OPENSRCH;
-       }
-       r->currentsearch = reply->handle;
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->buflen = sizeof(struct rs_opensrch);
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_srch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_srch *reply;
-    ARTNUM artnum;
-    TOKEN token;
-    time_t arrived;
-    int len;
-    char *data;
-
-    if(ovdb_search(cmd->handle, &artnum, &data, &len, &token, &arrived)) {
-       reply = xmalloc(sizeof(struct rs_srch) + len);
-       reply->status = CMD_SRCH;
-       reply->artnum = artnum;
-       reply->token = token;
-       reply->arrived = arrived;
-       reply->len = len;
-       memcpy((char *)reply + sizeof(struct rs_srch), data, len);
-       r->buflen = sizeof(struct rs_srch) + len;
-    } else {
-       reply = xmalloc(sizeof(struct rs_srch));
-       reply->status = CMD_SRCH | RPLY_ERROR;
-       r->buflen = sizeof(struct rs_srch);
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_closesrch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-
-    ovdb_closesearch(cmd->handle);
-    free(r->buf);
-    r->buf = NULL;
-    r->bufpos = r->buflen = 0;
-    r->mode = MODE_READ;
-    r->currentsearch = NULL;
-}
-
-static void
-do_artinfo(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_artinfo *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    TOKEN token;
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_artinfo: '%s' %d", group, cmd->artlo);*/
-    if(ovdb_getartinfo(group, cmd->artlo, &token)) {
-       reply = xmalloc(sizeof(struct rs_artinfo));
-       reply->status = CMD_ARTINFO;
-       reply->token = token;
-       r->buflen = sizeof(struct rs_artinfo);
-    } else {
-       reply = xmalloc(sizeof(struct rs_artinfo));
-       reply->status = CMD_ARTINFO | RPLY_ERROR;
-       r->buflen = sizeof(struct rs_artinfo);
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-
-static int
-process_cmd(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-
-    if(r->state == STATE_READCMD) {
-       switch(cmd->what) {
-       case CMD_GROUPSTATS:
-       case CMD_OPENSRCH:
-       case CMD_ARTINFO:
-           r->state = STATE_READGROUP;
-           if(cmd->grouplen == 0) {
-               /* shoudn't happen... */
-               r->mode = MODE_CLOSED;
-               close(r->fd);
-               free(r->buf);
-               r->buf = NULL;
-               return 0;
-           }
-           r->buflen += cmd->grouplen;
-            r->buf = xrealloc(r->buf, r->buflen);
-           return 1;
-       }
-    }
-
-    switch(cmd->what) {
-    case CMD_GROUPSTATS:
-       ((char *)r->buf)[r->buflen - 1] = 0;    /* make sure group is null-terminated */
-       do_groupstats(r);
-       break;
-    case CMD_OPENSRCH:
-       ((char *)r->buf)[r->buflen - 1] = 0;
-       do_opensrch(r);
-       break;
-    case CMD_SRCH:
-       do_srch(r);
-       break;
-    case CMD_CLOSESRCH:
-       do_closesrch(r);
-       break;
-    case CMD_ARTINFO:
-       ((char *)r->buf)[r->buflen - 1] = 0;
-       do_artinfo(r);
-       break;
-    default:
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-       break;
-    }
-
-    return 0;
-}
-
-static void
-handle_read(struct reader *r)
-{
-    int n;
-    r->lastactive = now;
-
-    if(r->buf == NULL) {
-       r->state = STATE_READCMD;
-       r->buf = xmalloc(sizeof(struct rs_cmd));
-       r->buflen = sizeof(struct rs_cmd);
-       r->bufpos = 0;
-    }
-again:
-    n = read(r->fd, (char *)(r->buf) + r->bufpos, r->buflen - r->bufpos);
-    if(n <= 0) {
-       if(n < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
-           return;
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-    }
-    r->bufpos += n;
-
-    if(r->bufpos >= r->buflen)
-       if(process_cmd(r))
-           goto again;
-}
-
-static void
-handle_write(struct reader *r)
-{
-    int n;
-    r->lastactive = now;
-
-    if(r->buf == NULL) /* shouldn't happen */
-       return;
-
-    n = write(r->fd, (char *)(r->buf) + r->bufpos, r->buflen - r->bufpos);
-    if(n <= 0) {
-       if(n < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
-           return;
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-    }
-    r->bufpos += n;
-
-    if(r->bufpos >= r->buflen) {
-       free(r->buf);
-       r->buf = NULL;
-       r->bufpos = r->buflen = 0;
-       r->mode = MODE_READ;
-    }
-}
-
-static void
-newclient(int fd)
-{
-    struct reader *r;
-    int i;
-
-    nonblocking(fd, 1);
-
-    if(numreaders >= readertablen) {
-       readertablen += 50;
-        readertab = xrealloc(readertab, readertablen * sizeof(struct reader));
-        for(i = numreaders; i < readertablen; i++) {
-           readertab[i].mode = MODE_CLOSED;
-           readertab[i].buf = NULL;
-       }
-    }
-
-    r = &(readertab[numreaders]);
-    numreaders++;
-
-    r->fd = fd;
-    r->mode = MODE_WRITE;
-    r->buflen = sizeof(OVDB_SERVER_BANNER);
-    r->bufpos = 0;
-    r->buf = xstrdup(OVDB_SERVER_BANNER);
-    r->lastactive = now;
-    r->currentsearch = NULL;
-
-    handle_write(r);
-}
-
-static void
-delclient(int which)
-{
-    int i;
-    struct reader *r = &(readertab[which]);
-
-    if(r->mode != MODE_CLOSED)
-       close(r->fd);
-
-    if(r->buf != NULL) {
-       free(r->buf);
-    }
-    if(r->currentsearch != NULL) {
-       ovdb_closesearch(r->currentsearch);
-       r->currentsearch = NULL;
-    }
-
-    /* numreaders will get decremented by the calling function */
-    for(i = which; i < numreaders-1; i++)
-       readertab[i] = readertab[i+1];
-
-    readertab[i].mode = MODE_CLOSED;
-    readertab[i].buf = NULL;
-}
-
-static pid_t
-serverproc(int me)
-{
-    fd_set rdset, wrset;
-    int i, ret, count, lastfd, lastnumreaders;
-    socklen_t salen;
-    struct sockaddr_in sa;
-    struct timeval tv;
-    pid_t pid;
-
-    pid = fork();
-    if (pid != 0)
-       return pid;
-
-    if (!ovdb_open(OV_READ|OVDB_SERVER))
-        die("cannot open overview");
-    xsignal_norestart(SIGINT, sigfunc);
-    xsignal_norestart(SIGTERM, sigfunc);
-    xsignal_norestart(SIGHUP, sigfunc);
-    xsignal_norestart(SIGUSR1, childsig);
-    xsignal(SIGPIPE, SIG_IGN);
-
-    numreaders = lastnumreaders = 0;
-    if(ovdb_conf.maxrsconn) {
-       readertablen = ovdb_conf.maxrsconn;
-    } else {
-       readertablen = 50;
-    }
-    readertab = xmalloc(readertablen * sizeof(struct reader));
-    for(i = 0; i < readertablen; i++) {
-       readertab[i].mode = MODE_CLOSED;
-       readertab[i].buf = NULL;
-    }
-
-    setproctitle("0 clients");
-
-    /* main loop */
-    while(!signalled) {
-       FD_ZERO(&rdset);
-       FD_ZERO(&wrset);
-       lastfd = 0;
-       if(wholistens == me) {
-           if(!ovdb_conf.maxrsconn || numreaders < ovdb_conf.maxrsconn) {
-               FD_SET(listensock, &rdset);
-               lastfd = listensock;
-                setproctitle("%d client%s *", numreaders,
-                             numreaders == 1 ? "" : "s");
-           } else {
-               wholistens = -1;
-               kill(parent, SIGUSR1);
-           }
-        }
-
-       for(i = 0; i < numreaders; i++) {
-           switch(readertab[i].mode) {
-           case MODE_READ:
-               FD_SET(readertab[i].fd, &rdset);
-               break;
-           case MODE_WRITE:
-               FD_SET(readertab[i].fd, &wrset);
-               break;
-           default:
-               continue;
-           }
-           if(readertab[i].fd > lastfd)
-               lastfd = readertab[i].fd;
-       }
-       tv.tv_usec = 0;
-       tv.tv_sec = SELECT_TIMEOUT;
-       count = select(lastfd + 1, &rdset, &wrset, NULL, &tv);
-
-       if(signalled)
-           break;
-       if(count <= 0)
-           continue;
-
-       now = time(NULL);
-
-       if(FD_ISSET(listensock, &rdset)) {
-           if(!ovdb_conf.maxrsconn || numreaders < ovdb_conf.maxrsconn) {
-               salen = sizeof(sa);
-               ret = accept(listensock, (struct sockaddr *)&sa, &salen);
-               if(ret >= 0) {
-                   newclient(ret);
-                   wholistens = -1;
-                   children[me].num = numreaders;
-                   kill(parent, SIGUSR1);
-               }
-           }
-       }
-
-       for(i = 0; i < numreaders; i++) {
-           switch(readertab[i].mode) {
-           case MODE_READ:
-               if(FD_ISSET(readertab[i].fd, &rdset))
-                   handle_read(&(readertab[i]));
-               break;
-           case MODE_WRITE:
-               if(FD_ISSET(readertab[i].fd, &wrset))
-                   handle_write(&(readertab[i]));
-               break;
-           }
-       }
-
-       for(i = 0; i < numreaders; i++) {
-           if(readertab[i].mode == MODE_CLOSED
-                 || readertab[i].lastactive + CLIENT_TIMEOUT < now) {
-               delclient(i);
-               numreaders--;
-               i--;
-           }
-       }
-       if(children[me].num != numreaders) {
-           children[me].num = numreaders;
-           kill(parent, SIGUSR1);
-        }
-       if(numreaders != lastnumreaders) {
-           lastnumreaders = numreaders;
-            setproctitle("%d client%s", numreaders,
-                         numreaders == 1 ? "" : "s");
-       }
-    }
-
-    ovdb_close();
-    exit(0);
-}
-
-static int
-reap(void)
-{
-    int i, cs;
-    pid_t c;
-
-    while((c = waitpid(-1, &cs, WNOHANG)) > 0) {
-       for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-           if(c == children[i].pid) {
-               if(children[i].started + 30 > time(NULL))
-                   return 1;
-
-               children[i].num = 0;
-
-               if(wholistens == i)
-                   wholistens = -1;
-
-               if((children[i].pid = serverproc(i)) == -1)
-                   return 1;
-
-               children[i].started = time(NULL);
-               break;
-           }
-       }
-    }
-    if(wholistens == -1)
-       parentsig(SIGUSR1);
-    return 0;
-}
-
-#ifndef MAP_ANON
-#ifdef MAP_ANONYMOUS
-#define MAP_ANON MAP_ANONYMOUS
-#endif
-#endif
-
-static void *
-sharemem(size_t len)
-{
-#ifdef MAP_ANON
-    return mmap(0, len, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
-#else
-    int fd = open("/dev/zero", O_RDWR, 0);
-    char *ptr = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-    close(fd);
-    return ptr;
-#endif
-}
-
-int
-main(int argc, char *argv[])
-{
-    int i, ret;
-    socklen_t salen;
-    char *path, *pidfile;
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    struct sockaddr_un sa;
-#else
-    struct sockaddr_in sa;
-#endif
-    struct timeval tv;
-    fd_set rdset;
-
-    setproctitle_init(argc, argv);
-
-    openlog("ovdb_server", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "ovdb_server";
-
-    if(argc != 2 || strcmp(argv[1], SPACES))
-        die("should be started by ovdb_init");
-    message_handlers_warn(1, message_log_syslog_err);
-    message_handlers_die(1, message_log_syslog_err);
-
-    if (!innconf_read(NULL))
-       exit(1);
-
-    if(strcmp(innconf->ovmethod, "ovdb"))
-        die("ovmethod not set to ovdb in inn.conf");
-
-    read_ovdb_conf();
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    listensock = socket(AF_UNIX, SOCK_STREAM, 0);
-#else
-    listensock = socket(AF_INET, SOCK_STREAM, 0);
-#endif
-    if(listensock < 0)
-        sysdie("cannot create socket");
-
-    nonblocking(listensock, 1);
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    sa.sun_family = AF_UNIX;
-    path = concatpath(innconf->pathrun, OVDB_SERVER_SOCKET);
-    strlcpy(sa.sun_path, path, sizeof(sa.sun_path));
-    unlink(sa.sun_path);
-    free(path);
-    ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-#else
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(OVDB_SERVER_PORT);
-    sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-    
-    ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-
-    if(ret != 0 && errno == EADDRNOTAVAIL) {
-       sa.sin_family = AF_INET;
-       sa.sin_port = htons(OVDB_SERVER_PORT);
-       sa.sin_addr.s_addr = INADDR_ANY;
-       ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-    }
-#endif
-
-    if(ret != 0)
-        sysdie("cannot bind socket");
-    if(listen(listensock, MAXLISTEN) < 0)
-        sysdie("cannot listen on socket");
-
-    pidfile = concatpath(innconf->pathrun, OVDB_SERVER_PIDFILE);
-    if(putpid(pidfile))
-        exit(1);
-
-    xsignal_norestart(SIGINT, sigfunc);
-    xsignal_norestart(SIGTERM, sigfunc);
-    xsignal_norestart(SIGHUP, sigfunc);
-
-    xsignal_norestart(SIGUSR1, parentsig);
-    xsignal_norestart(SIGCHLD, childsig);
-    parent = getpid();
-
-    children = sharemem(sizeof(struct child) * (ovdb_conf.numrsprocs+1));
-
-    if(children == NULL)
-        sysdie("cannot mmap shared memory");
-    for(i = 0; i < ovdb_conf.numrsprocs+1; i++) {
-       children[i].pid = -1;
-       children[i].num = 0;
-    }
-
-    for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-       if((children[i].pid = serverproc(i)) == -1) {
-           for(i--; i >= 0; i--)
-               kill(children[i].pid, SIGTERM);
-           exit(1);
-       }
-       children[i].started = time(NULL);
-       sleep(1);
-    }
-
-    while(!signalled) {
-       if(reap())
-           break;
-
-       if(wholistens == -2) {
-           FD_ZERO(&rdset);
-           FD_SET(listensock, &rdset);
-           tv.tv_usec = 0;
-           tv.tv_sec = SELECT_TIMEOUT;
-           ret = select(listensock+1, &rdset, NULL, NULL, &tv);
-
-           if(ret == 1 && wholistens == -2) {
-               salen = sizeof(sa);
-               ret = accept(listensock, (struct sockaddr *)&sa, &salen);
-               if(ret >= 0)
-                  close(ret);
-           }
-       } else {
-           pause();
-       }
-    }
-
-    for(i = 0; i < ovdb_conf.numrsprocs; i++)
-       if(children[i].pid != -1)
-           kill(children[i].pid, SIGTERM);
-
-    while(wait(&ret) > 0)
-       ;
-
-    unlink(pidfile);
-
-    exit(0);
-}
-
-
-#endif /* USE_BERKELEY_DB */
diff --git a/frontends/ovdb_stat.c b/frontends/ovdb_stat.c
deleted file mode 100644 (file)
index 1166237..0000000
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * ovdb_stat.c
- * print information about ovdb database
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <signal.h>
-#include <syslog.h>
-#include <time.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-#include "storage.h"
-
-#include "../storage/ovdb/ovdb.h"
-#include "../storage/ovdb/ovdb-private.h"
-
-
-#ifndef USE_BERKELEY_DB
-
-int main(int argc UNUSED, char **argv UNUSED)
-{
-    die("BerkeleyDB support not compiled");
-}
-
-#else /* USE_BERKELEY_DB */
-
-static int signalled = 0;
-static void sigfunc(int signum UNUSED)
-{
-    signalled = 1;
-}
-
-static int html = 0;
-
-typedef enum {
-       END,
-       INT32,  /* 'a' points to u_int32_t */
-       HEX32,  /* 'a' printed in hex */
-        DIFF32,        /* 'a' - 'b' - 'c' */
-       PCT32,  /* 100 * 'a' / ('a' + 'b') */
-       FF,     /* 'a' = freebytes, 'b' = npages, 'c' = pagesize */
-       BYTES,  /* 'a' = bytes, 'b' = mbytes, 'c' = gbytes */
-       MODE,   /* 'a' points to int, printed as octal mode */
-       TIME,   /* 'a' points to time_t, printed as date/time */
-       LSN,    /* 'a' points to DB_LSN */
-       STR,    /* 'a' points to char* */
-       SIZE    /* 'a' points to size_t */
-} DATATYPE;
-
-struct datatab {
-    DATATYPE type;
-    ssize_t a;
-    ssize_t b;
-    ssize_t c;
-    const char *desc;
-};
-
-static void display_heading(const char *str)
-{
-    if(html)
-       printf("<h2>%s<h2>\n", str);
-    else
-       printf("%s\n", str);
-}
-
-
-static void getval(int i, void *p, struct datatab *tab, char *val, char *sufx)
-{
-    int mode = 0;
-    u_int32_t a = 0, b = 0, c = 0, bytes = 0, mbytes = 0, gbytes = 0;
-    char *cp = p;
-    char *tmp = NULL;
-    time_t tm = 0;
-    size_t sz = 0;
-    DB_LSN *dl = NULL;
-
-    val[0] = 0;
-    sufx[0] = 0;
-
-    switch(tab[i].type) {
-    case INT32:        /* 'a' points to u_int32_t */
-        memcpy(&a, cp + tab[i].a, sizeof(a));
-       sprintf(val, "%u", a);
-       break;
-    case HEX32:        /* 'a' printed in hex */
-        memcpy(&a, cp + tab[i].a, sizeof(a));
-       sprintf(val, "%x", a);
-       break;
-    case DIFF32:       /* 'a' - 'b' - 'c' */
-        memcpy(&a, cp + tab[i].a, sizeof(a));
-        memcpy(&b, cp + tab[i].b, sizeof(b));
-       if(tab[i].c != -1) {
-            memcpy(&c, cp + tab[i].c, sizeof(c));
-           sprintf(val, "%d", a - b - c);
-       } else {
-           sprintf(val, "%d", a - b);
-       }
-       break;
-    case PCT32:        /* 100 * 'a' / ('a' + 'b') */
-        memcpy(&a, cp + tab[i].a, sizeof(a));
-        memcpy(&b, cp + tab[i].b, sizeof(b));
-       sprintf(val, "%.0f", (double) a / (a + b) * 100.0);
-       strcpy(sufx, "%");
-       break;
-    case FF:   /* 'a' = freebytes, 'b' = npages, 'c' = pagesize */
-        memcpy(&a, cp + tab[i].a, sizeof(a));
-        memcpy(&b, cp + tab[i].b, sizeof(b));
-        memcpy(&c, cp + tab[i].c, sizeof(c));
-       if(b == 0) {
-           sprintf(val, "%.0f", 0.0);
-       } else {
-           sprintf(val, "%.0f", (double)((b * c) - a) / (b * c) * 100);
-       }
-       strcpy(sufx, "%");
-       break;
-    case BYTES:        /* 'a' = bytes, 'b' = mbytes, 'c' = gbytes */
-       if(tab[i].a != -1)
-            memcpy(&bytes, cp + tab[i].a, sizeof(bytes));
-       else
-           bytes = 0;
-       if(tab[i].b != -1)
-            memcpy(&mbytes, cp + tab[i].b, sizeof(mbytes));
-       else
-           mbytes = 0;
-       if(tab[i].c != -1)
-            memcpy(&gbytes, cp + tab[i].c, sizeof(gbytes));
-       else
-           gbytes = 0;
-       if(gbytes > 0 || mbytes > 0) {
-           mbytes += gbytes * 1024;
-           if(bytes > (1024*1024))
-               mbytes += bytes / (1024*1024);
-           sprintf(val, "%u", mbytes);
-           strcpy(sufx, "MB");
-       } else {
-           sprintf(val, "%u", bytes);
-       }
-       break;
-    case MODE: /* 'a' points to int, printed as octal mode */
-        memcpy(&mode, cp + tab[i].a, sizeof(mode));
-       sprintf(val, "%04o", mode);
-       break;  
-    case TIME: /* 'a' points to time_t, printed as date/time */
-        memcpy(&tm, cp + tab[i].a, sizeof(tm));
-       if(tm == 0) {
-           strcpy(val, "none");
-       } else {
-           strftime(val, SMBUF, "%Y-%m-%d %T %Z", localtime(&tm));
-       }
-       break;
-    case LSN:  /* 'a' points to DB_LSN */
-       dl = (DB_LSN *)(cp + tab[i].a);
-       if(dl->file == 0) {
-           strcpy(val, "none");
-       } else {
-           sprintf(val, "%u/%u", dl->file, dl->offset);
-       }
-       break;
-    case STR:  /* 'a' points to char* */
-        memcpy(&tmp, cp + tab[i].a, sizeof(tmp));
-       strcpy(val, tmp);
-       break;
-    case SIZE: /* 'a' points to size_t */
-        memcpy(&sz, cp + tab[i].a, sizeof(sz));
-       sprintf(val, "%lu", (unsigned long) sz);
-       break;
-    case END:
-        break;
-    }
-}
-
-static char *myctime(time_t *tm)
-{
-    static char val[SMBUF];
-    strftime(val, SMBUF, "%Y-%m-%d %T %Z", localtime(tm));
-    return val;
-}
-
-static void display_data(void *p, struct datatab *tab)
-{
-    int i;
-    char val[SMBUF], sufx[SMBUF];
-    if(html)
-       puts("<table border=0 cellpadding=1>");
-    for(i = 0; tab[i].type != END; i++) {
-       getval(i, p, tab, val, sufx);
-       if(html)
-           printf("<tr><td align=right>%s<td>%s<td>%s\n", val, sufx, tab[i].desc);
-       else
-           printf("%16s%-2s %s\n", val, sufx, tab[i].desc);
-    }
-    if(html)
-       puts("</table><p>");
-}
-
-static void start_table(const char *label, struct datatab *tab)
-{
-    int i;
-    if(html) {
-       printf("<h2>%s</h2>\n", label);
-       puts("<table border=0 cellpadding=1>\n<tr bgcolor=#3399aa>");
-       for(i = 0; tab[i].type != END; i++)
-           printf("<th colspan=2>%s\n", tab[i].desc);
-    }
-}
-
-static void display_row(void *p, struct datatab *tab)
-{
-    int i;
-    char val[SMBUF], sufx[SMBUF];
-    if(html) {
-       puts("<tr>");
-       for(i = 0; tab[i].type != END; i++) {
-           getval(i, p, tab, val, sufx);
-           printf("<td align=right>%s<td>%s\n", val, sufx);
-       }
-    } else {
-       puts("---------------------------------------------");
-       display_data(p, tab);
-    }
-}
-
-static void end_table(void)
-{
-    if(html)
-       puts("</table><p>");
-}
-
-#define OFFSETOF(type, f) ((char *)&(((type *)0)->f) - (char *)0)
-
-#define F(f) OFFSETOF(DB_LOCK_STAT, f)
-
-static struct datatab LOCK_tab[] = {
-#if DB_VERSION_MAJOR >= 3
- { INT32,
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-   F(st_id),
-#else
-   F(st_lastid),
-#endif
-   -1, -1,           "Last allocated locker ID" },
-#endif
- { INT32, F(st_maxlocks),      -1, -1,           "Maximum number of locks possible" },
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
- { INT32, F(st_maxlockers),    -1, -1,           "Maximum number of lockers possible" },
- { INT32, F(st_maxobjects),    -1, -1,           "Maximum number of objects possible" },
-#endif
- { INT32, F(st_nmodes),        -1, -1,           "Lock modes" },
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
- { INT32, F(st_nlocks),        -1, -1,           "Current locks" },
- { INT32, F(st_maxnlocks),     -1, -1,           "Maximum locks" },
-#endif
- { INT32, F(st_nlockers),      -1, -1,           "Current lockers" },
-#if DB_VERSION_MAJOR >= 3
- { INT32, F(st_maxnlockers),   -1, -1,           "Maximum lockers" },
-#else
- { INT32, F(st_numobjs),       -1, -1,           "Lock objects" },
-#endif
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
- { INT32, F(st_nobjects),      -1, -1,           "Current objects" },
- { INT32, F(st_maxnobjects),   -1, -1,           "Maximum objects" },
-#endif
-#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 4
- { INT32, F(st_lock_wait),     -1, -1,           "Lock conflicts" },
-#else
- { INT32, F(st_nconflicts),    -1, -1,           "Lock conflicts" },
-#endif
- { INT32, F(st_nrequests),     -1, -1,           "Lock requests" },
- { INT32, F(st_nreleases),     -1, -1,           "Lock releases" },
- { DIFF32, F(st_nrequests), F(st_nreleases), F(st_ndeadlocks), "Outstanding locks" },
-#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 4
- { INT32, F(st_lock_nowait),   -1, -1,           "Lock conflicts w/o subsequent wait" },
-#elif DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 0)
- { INT32, F(st_nnowaits),      -1, -1,           "Lock conflicts w/o subsequent wait" },
-#endif
- { INT32, F(st_ndeadlocks),    -1, -1,           "Deadlocks" },
-#if DB_VERSION_MAJOR >= 4
- { INT32, F(st_nlocktimeouts), -1, -1,           "Lock timeouts" },
- { INT32, F(st_ntxntimeouts),  -1, -1,           "Transaction timeouts" },
-#endif
- { INT32, F(st_region_nowait), -1, -1,           "Region locks granted without waiting" },
- { INT32, F(st_region_wait),   -1, -1,           "Region locks granted after waiting" },
- { BYTES, F(st_regsize),       -1, -1,           "Lock region size" },
- { END, -1, -1, -1, NULL }
-};
-
-static int display_lock(void)
-{
-    DB_LOCK_STAT *sp;
-
-#if DB_VERSION_MAJOR == 2
-    if(lock_stat(OVDBenv->lk_info, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-    if(lock_stat(OVDBenv, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3
-    if(lock_stat(OVDBenv, &sp) != 0)
-#else
-    if(OVDBenv->lock_stat(OVDBenv, &sp, 0) != 0)
-#endif
-       return 1;
-
-    display_heading("Lock Region Statistics");
-    display_data(sp, LOCK_tab);
-
-    free(sp);
-    return 0;
-}
-
-
-#undef F
-#define F(f) OFFSETOF(DB_LOG_STAT, f)
-
-static struct datatab LOG_tab[] = {
- { HEX32, F(st_magic),             -1, -1, "Log magic number" },
- { INT32, F(st_version),           -1, -1, "Log version number" },
- { MODE,  F(st_mode),              -1, -1, "Log file mode" },
-#if DB_VERSION_MAJOR >= 3
- { BYTES, F(st_lg_bsize),          -1, -1, "Log record cache size" },
-#endif
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
- { BYTES, F(st_lg_size),           -1, -1, "The current log file size" },
-#else
- { BYTES, F(st_lg_max),            -1, -1, "Max log file size" },
-#endif
- { BYTES, F(st_w_bytes), F(st_w_mbytes), -1, "Log bytes written" },
- { BYTES, F(st_wc_bytes), F(st_wc_mbytes), -1, "Log bytes written since last checkpoint" },
- { INT32, F(st_wcount),            -1, -1, "Total log writes" },
-#if DB_VERSION_MAJOR >= 3
- { INT32, F(st_wcount_fill),       -1, -1, "Total log writes due to overflow" },
-#endif
- { INT32, F(st_scount),            -1, -1, "Total log flushes" },
- { INT32, F(st_region_nowait),     -1, -1, "Region locks granted without waiting" },
- { INT32, F(st_region_wait),       -1, -1, "Region locks granted after waiting" },
- { INT32, F(st_cur_file),          -1, -1, "Current log file number" },
- { INT32, F(st_cur_offset),        -1, -1, "Current log file offset" },
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3)
- { INT32, F(st_disk_file),         -1, -1, "Known on disk log file number" },
- { INT32, F(st_disk_offset),       -1, -1, "Known on disk log file offset" },
-#endif
- { BYTES, F(st_regsize),           -1, -1, "Log region size" },
-#if DB_VERSION_MAJOR >= 4
-#if DB_VERSION_MINOR < 1
- { INT32, F(st_flushcommit),       -1, -1, "Flushes containing a commit"},
-#endif
- { INT32, F(st_maxcommitperflush), -1, -1, "Max number of commits in a flush"},
- { INT32, F(st_mincommitperflush), -1, -1, "Min number of commits in a flush"},
-#endif
- { END, -1, -1, -1, NULL }
-};
-
-static int display_log(void)
-{
-    DB_LOG_STAT *sp;
-
-#if DB_VERSION_MAJOR == 2
-    if(log_stat(OVDBenv->lg_info, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-    if(log_stat(OVDBenv, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3
-    if(log_stat(OVDBenv, &sp) != 0)
-#else
-    if(OVDBenv->log_stat(OVDBenv, &sp, 0) != 0)
-#endif
-       return 1;
-
-    display_heading("Log Region Statistics");
-    display_data(sp, LOG_tab);
-
-    free(sp);
-    return 0;
-}
-
-
-#undef F
-#define F(f) OFFSETOF(DB_MPOOL_STAT, f)
-
-static struct datatab MEM_tab[] = {
- { INT32, F(st_cache_hit),  -1, -1,       "Cache hits"},
- { INT32, F(st_cache_miss), -1, -1,       "Cache misses"},
- { PCT32, F(st_cache_hit), F(st_cache_miss), -1, "Cache hit percentage"},
-#if DB_VERSION_MAJOR == 2
- { INT32, F(st_cachesize),  -1, -1,       "Total cache size"},
- { INT32, F(st_regsize),    -1, -1,       "Pool region size"},
-#else
- { BYTES, F(st_bytes), -1, F(st_gbytes), "Total cache size"},
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
- { INT32, F(st_regsize),    -1, -1,       "Pool region size"},
-#else
- { INT32, F(st_ncache),     -1, -1,       "Number of caches"},
- { INT32, F(st_regsize),    -1, -1,       "Pool individual cache size"},
-#endif
-#endif
- { INT32, F(st_map),           -1, -1, "Memory mapped pages"},
- { INT32, F(st_page_create),   -1, -1, "Pages created in the cache"},
- { INT32, F(st_page_in),       -1, -1, "Pages read into the cache"},
- { INT32, F(st_page_out),      -1, -1, "Pages written from the cache to the backing file"},
- { INT32, F(st_ro_evict),      -1, -1, "Clean pages forced from the cache"},
- { INT32, F(st_rw_evict),      -1, -1, "Dirty pages forced from the cache"},
- { INT32, F(st_hash_buckets),  -1, -1, "Hash buckets used for page location"},
- { INT32, F(st_hash_searches), -1, -1, "Total hash chain searches"},
- { INT32, F(st_hash_longest),  -1, -1, "Longest hash chain searched"},
- { INT32, F(st_hash_examined), -1, -1, "Total hash entries searched"},
- { INT32, F(st_page_trickle),  -1, -1, "Dirty buffers written by trickle-sync thread"},
- { INT32, F(st_page_clean),    -1, -1, "Current clean buffer count"},
- { INT32, F(st_page_dirty),    -1, -1, "Current dirty buffer count"},
- { INT32, F(st_region_nowait), -1, -1, "Region locks granted without waiting"},
- { INT32, F(st_region_wait),   -1, -1, "Region locks granted after waiting"},
- { END, -1, -1, -1, NULL }
-};
-
-#undef F
-#define F(f) OFFSETOF(DB_MPOOL_FSTAT, f)
-
-static struct datatab MEMF_tab[] = {
- { STR,    F(file_name),        -1, -1, "Database"},
- { SIZE,   F(st_pagesize),      -1, -1, "Page size"},
- { INT32,  F(st_cache_hit),     -1, -1, "Cache hits"},
- { INT32,  F(st_cache_miss),    -1, -1, "Cache misses"},
- { PCT32,  F(st_cache_hit), F(st_cache_miss), -1, "Cache hit percentage"},
- { INT32,  F(st_map),           -1, -1, "Memory mapped pages"},
- { INT32,  F(st_page_create),   -1, -1, "Pages created in the cache"},
- { INT32,  F(st_page_in),       -1, -1, "Pages read into the cache"},
- { INT32,  F(st_page_out),      -1, -1, "Pages written from the cache to the backing file"},
- { END, -1, -1, -1, NULL }
-};
-
-static int display_mem(int all)
-{
-    DB_MPOOL_FSTAT **fsp;
-    DB_MPOOL_STAT *gsp;
-
-#if DB_VERSION_MAJOR == 2
-    if(memp_stat(OVDBenv->mp_info, &gsp, &fsp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-    if(memp_stat(OVDBenv, &gsp, &fsp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3
-    if(memp_stat(OVDBenv, &gsp, &fsp) != 0)
-#else
-    if(OVDBenv->memp_stat(OVDBenv, &gsp, &fsp, 0) != 0)
-#endif
-       return 1;
-
-    display_heading("Memory Pool Statistics");
-    display_data(gsp, MEM_tab);
-
-    if(all) {
-       DB_MPOOL_FSTAT **p = fsp;
-
-       start_table("Per-database Memory Pool Statistics", MEMF_tab);
-       for(; p != NULL && *p != NULL; ++p) {
-           display_row(*p, MEMF_tab);
-       }
-       end_table();
-    }
-
-    free(fsp);
-    free(gsp);
-    return 0;
-}
-
-static int txn_compare(const void *a, const void *b)
-{
-    if (((const DB_TXN_ACTIVE *)a)->txnid > ((const DB_TXN_ACTIVE *)b)->txnid)
-       return 1;
-    if (((const DB_TXN_ACTIVE *)a)->txnid < ((const DB_TXN_ACTIVE *)b)->txnid)
-       return -1;
-    return 0;
-}
-
-#undef F
-#define F(f) OFFSETOF(DB_TXN_STAT, f)
-
-static struct datatab TXN_tab[] = {
- { LSN, F(st_last_ckp),     -1, -1, "File/offset for last checkpoint LSN" },
-#if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
- { LSN, F(st_pending_ckp),  -1, -1, "File/offset for last pending checkpoint LSN" },
-#endif
- { TIME, F(st_time_ckp),    -1, -1, "Checkpoint timestamp" },
- { HEX32, F(st_last_txnid), -1, -1, "Last transaction ID allocated" },
- { INT32, F(st_maxtxns),    -1, -1, "Maximum active transactions possible" },
- { INT32, F(st_nactive),    -1, -1, "Active transactions" },
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3)
- { INT32, F(st_nrestores),  -1, -1, "Restored transactions after recovery" },
-#endif
-#if DB_VERSION_MAJOR >= 3
- { INT32, F(st_maxnactive), -1, -1, "Maximum active transactions" },
-#endif
- { INT32, F(st_nbegins),    -1, -1, "Transactions started" },
- { INT32, F(st_ncommits),   -1, -1, "Transactions committed" },
- { INT32, F(st_naborts),    -1, -1, "Transactions aborted" },
- { INT32, F(st_region_nowait), -1, -1, "Region locks granted without waiting"},
- { INT32, F(st_region_wait),   -1, -1, "Region locks granted after waiting"},
- { BYTES, F(st_regsize),    -1, -1, "Transaction region size" },
- { END, -1, -1, -1, NULL }
-};
-
-#undef F
-#define F(f) OFFSETOF(DB_TXN_ACTIVE, f)
-
-static struct datatab TXNA_tab[] = {
- { INT32, F(txnid),    -1, -1, "Transaction ID" },
-#if DB_VERSION_MAJOR >= 3
- { INT32, F(parentid), -1, -1, "Parent Transaction ID" },
-#endif
- { LSN,   F(lsn),      -1, -1, "Initial LSN file/offset" },
- { END, -1, -1, -1, NULL }
-};
-
-static int display_txn(void)
-{
-    DB_TXN_STAT *sp;
-    u_int32_t i;
-
-#if DB_VERSION_MAJOR == 2
-    if(txn_stat(OVDBenv->tx_info, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-    if(txn_stat(OVDBenv, &sp, NULL) != 0)
-#elif DB_VERSION_MAJOR == 3
-    if(txn_stat(OVDBenv, &sp) != 0)
-#else
-    if(OVDBenv->txn_stat(OVDBenv, &sp, 0) != 0)
-#endif
-        return 1;
-
-    display_heading("Transaction Region Statistics");
-    display_data(sp, TXN_tab);
-
-    if(sp->st_nactive) {
-       qsort(sp->st_txnarray, sp->st_nactive, sizeof(sp->st_txnarray[0]), txn_compare);
-       start_table("Active Transactions", TXNA_tab);
-       for (i = 0; i < sp->st_nactive; ++i)
-           display_row(&(sp->st_txnarray[i]), TXNA_tab);
-       end_table();
-    }
-    free(sp);
-    return 0;
-}
-
-static int display_ver(void)
-{
-    if(html) puts("<p>");
-    printf("ovdb data version: %d\n", DATA_VERSION);
-    if(html) puts("<br>");
-    printf("BerkeleyDB version: %s\n", db_version(NULL,NULL,NULL));
-    if(html) puts("<p>");
-    return 0;
-}
-
-#undef F
-#define F(f) OFFSETOF(DB_BTREE_STAT, f)
-
-static struct datatab BTREE_tab[] = {
- { HEX32, F(bt_magic), -1, -1, "Btree magic number" },
- { INT32, F(bt_version), -1, -1, "Btree version number" },
- { INT32, F(bt_minkey), -1, -1, "Minimum keys per page (minkey)" },
- { INT32, F(bt_pagesize), -1, -1, "Database page size" },
- { INT32, F(bt_levels), -1, -1, "Levels in the tree" },
-#if DB_VERSION_MAJOR == 2 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0)
- { INT32, F(bt_nrecs), -1, -1, "Keys in the tree" },
-#else
- { INT32, F(bt_nkeys), -1, -1, "Unique keys in the tree" },
- { INT32, F(bt_ndata), -1, -1, "Data items in the tree" },
-#endif
- { INT32, F(bt_int_pg), -1, -1, "Tree internal pages" },
- { BYTES, F(bt_int_pgfree), -1, -1, "Bytes free in internal pages" },
- { FF,    F(bt_int_pgfree), F(bt_int_pg), F(bt_pagesize), "Internal page fill factor" },
-
- { INT32, F(bt_leaf_pg), -1, -1, "Tree leaf pages" },
- { BYTES, F(bt_leaf_pgfree), -1, -1, "Bytes free in leaf pages" },
- { FF,    F(bt_leaf_pgfree), F(bt_leaf_pg), F(bt_pagesize), "Leaf page fill factor" },
-
- { INT32, F(bt_dup_pg), -1, -1, "Tree duplicate pages" },
- { BYTES, F(bt_dup_pgfree), -1, -1, "Bytes free in duplicate pages" },
- { FF,    F(bt_dup_pgfree), F(bt_dup_pg), F(bt_pagesize), "Duplicate page fill factor" },
-
- { INT32, F(bt_over_pg), -1, -1, "Tree overflow pages" },
- { BYTES, F(bt_over_pgfree), -1, -1, "Bytes free overflow pages" },
- { FF,    F(bt_over_pgfree), F(bt_over_pg), F(bt_pagesize), "Overflow page fill factor" },
-
-#if DB_VERSION_MAJOR >= 3
- { INT32, F(bt_free), -1, -1, "Pages on the free list" },
-#endif
- { END, -1, -1, -1, NULL }
-};
-
-static int display_btree(DB *db)
-{
-    DB_BTREE_STAT *sp;
-
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
-    if(db->stat(db, NULL, &sp, 0))
-#else
-#if DB_VERSION_MAJOR == 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3)
-    if(db->stat(db, &sp, 0))
-#else
-    if(db->stat(db, &sp, NULL, 0))
-#endif
-#endif
-       return 1;
-
-    display_heading("Btree Statistics");
-    display_data(sp, BTREE_tab);
-
-    free(sp);
-    return 0;
-}
-
-
-#if DB_VERSION_MAJOR >= 3
-
-#undef F
-#define F(f) OFFSETOF(DB_HASH_STAT, f)
-
-static struct datatab HASH_tab[] = {
- { HEX32, F(hash_magic), -1, -1, "Hash magic number" },
- { INT32, F(hash_version), -1, -1, "Hash version number" },
- { INT32, F(hash_pagesize), -1, -1, "Database page size" },
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
- { INT32, F(hash_nrecs), -1, -1, "Keys in the database" },
-#else
- { INT32, F(hash_nkeys), -1, -1, "Keys in the database" },
- { INT32, F(hash_ndata), -1, -1, "Data items in the database" },
-#endif
- { INT32, F(hash_buckets), -1, -1, "Hash buckets" },
- { BYTES, F(hash_bfree), -1, -1, "Bytes free on bucket pages" },
- { FF,    F(hash_buckets), F(hash_bfree), F(hash_pagesize), "Bucket page fill factor" },
-
- { INT32, F(hash_bigpages), -1, -1, "Overflow pages" },
- { BYTES, F(hash_big_bfree), -1, -1, "Bytes free on Overflow pages" },
- { FF,    F(hash_bigpages), F(hash_big_bfree), F(hash_pagesize), "Overflow page fill factor" },
-
- { INT32, F(hash_overflows), -1, -1, "Bucket overflow pages" },
- { BYTES, F(hash_ovfl_free), -1, -1, "Bytes free on bucket overflow pages" },
- { FF,    F(hash_overflows), F(hash_ovfl_free), F(hash_pagesize), "Bucket overflow page fill factor" },
-
- { INT32, F(hash_dup), -1, -1, "Duplicate pages" },
- { BYTES, F(hash_dup_free), -1, -1, "Bytes free in duplicate pages" },
- { FF,    F(hash_dup), F(hash_dup_free), F(hash_pagesize), "Duplicate page fill factor" },
-
- { INT32, F(hash_free), -1, -1, "Pages on the free list"},
- { END, -1, -1, -1, NULL }
-};
-#endif
-
-static int display_hash(DB *db UNUSED)
-{
-#if DB_VERSION_MAJOR == 2
-    printf("Hash statistics not available.\n");
-    return 0;
-#else
-    DB_HASH_STAT *sp;
-
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
-    if(db->stat(db, NULL, &sp, 0))
-#else
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2
-    if(db->stat(db, &sp, NULL, 0))
-#else
-    if(db->stat(db, &sp, 0))
-#endif
-#endif
-       return 1;
-
-    display_heading("Hash Information");
-    display_data(sp, HASH_tab);
-
-    return 0;
-#endif
-}
-
-static int display_db(char *dbfile)
-{
-    int ret;
-    DB *db;
-
-#if DB_VERSION_MAJOR == 2
-    if(db_open(dbfile, DB_UNKNOWN, DB_RDONLY, 0, OVDBenv, NULL, &db))
-       return 1;
-#else
-    if(db_create(&db, OVDBenv, 0))
-       return 1;
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    if(db->open(db, NULL, dbfile, NULL, DB_UNKNOWN, DB_RDONLY, 0))
-#else
-    if(db->open(db, dbfile, NULL, DB_UNKNOWN, DB_RDONLY, 0))
-#endif
-       return 1;
-#endif
-
-    switch(db->type) {
-    case DB_BTREE:
-    case DB_RECNO:
-       ret = display_btree(db);
-       break;
-    case DB_HASH:
-       ret = display_hash(db);
-       break;
-    default:
-        ret = 1;
-        break;
-    }
-    db->close(db, 0);
-    return ret;
-}
-
-static int parse_artrange(char *str, ARTNUM *start, ARTNUM *stop)
-{
-    char *c;
-    int i;
-
-    c = strchr(str, '-');
-    if(c == NULL) {
-       i = atoi(str);
-       if(i == 0) {
-           return 1;
-       }
-       *start = *stop = i;
-       return 0;
-    }
-    if(c == str) {
-       *start = 0;
-       *stop = atoi(str+1);
-       return (*stop == 0);
-    }
-    if (strlen(str) == (size_t)(c - str + 1)) {
-       *start = atoi(str);
-       *stop = 0xffffffff;
-       return (*start == 0);
-    }
-    *start = atoi(str);
-    *stop = atoi(c+1);
-    if(*start == 0 || *stop == 0 || *start > *stop)
-       return 1;
-
-    return 0;
-}
-
-static void htwrite(char *data, int len)
-{
-    int i;
-    for(i = 0; i < len; i++) {
-       switch(data[i]) {
-       case '<':
-       case '>':
-       case '&':
-           printf("&#%d;", (int)data[i]);
-           break;
-       default:
-           putchar(data[i]);
-       }
-    }
-}
-
-int main(int argc, char *argv[])
-{
-    void *s;
-    ARTNUM a, start=0, stop=0, low, high;
-    char *data, *disp_db = NULL;
-    int len, c, count, flag, lowi, highi;
-    int getgs=0, getcount=0, getinfo=0, err=0, gotone=0;
-    int disp_lock=0, disp_log=0, disp_mem=0, disp_mem_all=0, disp_txn=0, disp_ver=0;
-    int needng=0, o;
-
-    openlog("ovdb_stat", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "ovdb_stat";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    if(!ovdb_check_user())
-        die("command must be run as user " NEWSUSER);
-    if(!ovdb_getlock(OVDB_LOCK_ADMIN))
-        sysdie("cannot lock database");
-    if(!ovdb_open(OV_READ|OVDB_SERVER))
-        sysdie("cannot open overview; check syslog for OVDB messages");
-
-    xsignal(SIGINT, sigfunc);
-    xsignal(SIGTERM, sigfunc);
-    xsignal(SIGHUP, sigfunc);
-
-    while((c = getopt(argc, argv, ":Hgcir:klmMtvd:")) != -1) {
-       switch(c) {
-       case 'H':
-           html = 1;
-           break;
-       case 'g':
-           getgs = 1;
-           needng = 1;
-           gotone++;
-           break;
-       case 'c':
-           getcount = 1;
-           needng = 1;
-           gotone++;
-           break;
-       case 'i':
-           getinfo = 1;
-           needng = 1;
-           gotone++;
-           break;
-       case 'r':
-           if(parse_artrange(optarg, &start, &stop))
-               err++;
-           needng = 1;
-           gotone++;
-           break;
-       case 'k':
-           disp_lock = 1;
-           gotone++;
-           break;
-       case 'l':
-           disp_log = 1;
-           gotone++;
-           break;
-       case 'm':
-           disp_mem = 1;
-           gotone++;
-           break;
-       case 'M':
-           disp_mem = 1;
-           disp_mem_all = 1;
-           gotone++;
-           break;
-       case 't':
-           disp_txn = 1;
-           gotone++;
-           break;
-       case 'v':
-           disp_ver = 1;
-           gotone++;
-           break;
-       case 'd':
-           disp_db = optarg;
-           gotone++;
-           break;
-       case ':':
-            warn("option -%c requires an argument", optopt);
-           err++;
-           break;
-       case '?':
-            warn("unrecognized option -%c", optopt);
-           err++;
-           break;
-       }
-    }
-    if(!gotone) {
-       err++;
-    } else if(optind == argc && needng) {
-        warn("missing newsgroup argument(s)");
-       err++;
-    }
-    if(err) {
-       fprintf(stderr, "\
-Usage:\n\
-   ovdb_stat -Hgci [-r artnum] newsgroup [newsgroup ...]\n\
-      -H              : output in HTML\n\
-      -g              : show groupstats info\n\
-      -c              : show groupstats info by counting actual records\n\
-      -i              : show additional group info\n\
-      -r artnum-range : retrieve OV records for article number range\n\
-\n\
-   ovdb_stat -Hklmtv [-d <database>]\n\
-      -H          : output in HTML\n\
-      -k          : Display lock region statistics\n\
-      -l          : Display log region statistics\n\
-      -m          : Display global memory cache statistics\n\
-      -M          : Display all memory cache statistics\n\
-      -t          : Display transaction statistics\n\
-      -v          : Display version information\n\
-      -d database : Display statistics of specified database\n");
-
-       goto out;
-    }
-
-    if(html)
-       puts("<html><head><title>ovdb_stat</title></head><body><p>");
-    if(disp_lock)
-       display_lock();
-    if(disp_log)
-       display_log();
-    if(disp_mem)
-       display_mem(disp_mem_all);
-    if(disp_txn)
-       display_txn();
-    if(disp_ver)
-       display_ver();
-    if(disp_db)
-       display_db(disp_db);
-
-    if(getgs || getcount || getinfo) {
-       if(html) {
-           puts("<table border=0 cellpadding=1 width=90%>\n<tr bgcolor=#3399aa>");
-           puts("<th rowspan=2>Group");
-           if(getgs)
-               puts("<th colspan=4>Groupstats");
-           if(getcount)
-               puts("<th colspan=3>Counted");
-           if(getinfo)
-               puts("<th>Status<th colspan=2>Current<th colspan=2>Pending");
-           puts("<th rowspan=2>Expired<th rowspan=2>Expire PID<tr bgcolor=#3399aa>");
-           if(getgs)
-               puts("<th>Low<th>High<th>Count<th>Flag");
-           if(getcount)
-               puts("<th>Low<th>High<th>Count");
-           if(getinfo)
-               puts("<th>Flags<th>GroupID<th>DB<th>GroupID<th>DB");
-       }
-       for(o = optind ; o < argc; o++) {
-           if(html)
-               printf("<tr><td>%s", argv[o]);
-           if(getgs) {
-               if(ovdb_groupstats(argv[o], &lowi, &highi, &count, &flag)) {
-                   if(html)
-                       printf("<td>%d<td>%d<td>%d<td>%c", lowi, highi, count, flag);
-                   else
-                       printf("%s: groupstats: low: %d, high: %d, count: %d, flag: %c\n",
-                               argv[o], lowi, highi, count, flag);
-               }
-           }
-           if(getcount) {
-               low = high = count = 0;
-                s = ovdb_opensearch(argv[o], 1, 0xffffffff);
-               if (s != NULL) {
-                   while(ovdb_search(s, &a, NULL, NULL, NULL, NULL)) {
-                       if(low == 0 || a < low)
-                           low = a;
-                       if(a > high)
-                           high = a;
-                       count++;
-                       if(signalled)
-                           break;
-                   }
-                   ovdb_closesearch(s);
-                   if(signalled)
-                       goto out;
-                   if(html)
-                       printf("<td>%ld<td>%ld<td>%d", low, high, count);
-                   else
-                       printf("%s:    counted: low: %ld, high: %ld, count: %d\n",
-                               argv[o], low, high, count);
-               }
-           }
-           if(getinfo) {
-               int ret;
-               struct groupinfo gi;
-
-                ret = ovdb_getgroupinfo(argv[o], &gi, false, NULL, 0);
-               if (ret != 0) {
-                    warn("%s: ovdb_getgroupinfo error: %s", argv[o],
-                         db_strerror(ret));
-                   continue;
-               }
-               if(html) {
-                   printf("<td>%s%s%s%s",
-                       (gi.status & GROUPINFO_DELETED) ? "D ":"",
-                       (gi.status & GROUPINFO_EXPIRING) ? "E ":"",
-                       (gi.status & GROUPINFO_MOVING) ? "M":"",
-                       (gi.status == 0) ? "&nbsp;":"");
-                   printf("<td>%d<td>ov%05d", gi.current_gid, gi.current_db);
-                   if(gi.status & GROUPINFO_MOVING)
-                       printf("<td>%d<td>ov%05d", gi.new_gid, gi.new_db);
-                   else
-                       printf("<td>&nbsp;<td>&nbsp;");
-                   if(gi.expired)
-                       printf("<td>%s<td>%lu", myctime(&gi.expired),
-                               (unsigned long) gi.expiregrouppid);
-                   else
-                       printf("<td>&nbsp;<td>&nbsp;");
-                   putchar('\n');
-               } else {
-                   printf("%s: flags: %s%s%s%s\n", argv[o],
-                       (gi.status & GROUPINFO_DELETED) ? "DELETED ":"",
-                       (gi.status & GROUPINFO_EXPIRING) ? "EXPIRING ":"",
-                       (gi.status & GROUPINFO_MOVING) ? "MOVING":"",
-                       (gi.status == 0) ? "none":"");
-
-                   printf("%s: gid: %d;  Stored in: ov%05d\n", argv[o], gi.current_gid, gi.current_db);
-                   if(gi.status & GROUPINFO_MOVING)
-                       printf("%s: pending gid: %d;  pending db: ov%05d\n", argv[o], gi.new_gid, gi.new_db);
-                   if(gi.expired) {
-                       printf("%s: last expired: %s\n", argv[o], myctime(&gi.expired));
-                       printf("%s: by process id: %lu\n", argv[o],
-                               (unsigned long) gi.expiregrouppid);
-                   }
-               }
-           }
-           if(signalled)
-               goto out;
-       }
-       if(html)
-           puts("</table><p>");
-    }
-    if(start || stop) {
-       if(html)
-           puts("<pre>");
-       for(o = optind ; o < argc; o++) {
-            s = ovdb_opensearch(argv[o], start, stop);
-           if (s != NULL) {
-               while(ovdb_search(s, &a, &data, &len, NULL, NULL)) {
-                   if(html)
-                       htwrite(data, len);
-                   else
-                       fwrite(data, len, 1, stdout);
-                   if(signalled)
-                       break;
-               }
-               ovdb_closesearch(s);
-               if(signalled)
-                   goto out;
-           }
-           if(signalled)
-               goto out;
-       }
-       if(html)
-           puts("</pre>");
-    }
-out:
-    if(html)
-       puts("<p></body></html>");
-    ovdb_close();
-    return 0;
-}
-
-#endif /* USE_BERKELEY_DB */
-
diff --git a/frontends/pullnews.in b/frontends/pullnews.in
deleted file mode 100644 (file)
index 5e54080..0000000
+++ /dev/null
@@ -1,822 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Sat, 10 Oct 1998 21:40:11 +0200
-# Project:      INN
-# File:         pullnews.pl
-# RCSId:        $Id: pullnews.in 7862 2008-06-08 09:15:41Z iulius $
-#
-# History:      May 2008:  Geraint A. Edwards greatly improved pullnews, adding
-#               -b, -C, -d, -G, -H, -k, -l, -m, -M, -n, -P, -Q, -R, -t, -T, -w and
-#               improving -s as well as fixing some bugs.
-#               He also integrated the backupfeed contrib script by Kai Henningsen,
-#               adding -f, -F, -N, -S, -z and -Z to pullnews.
-#
-# Description:  A simple pull feeder.  Connects to multiple upstream 
-#               machines (in the guise of a reader), and pulls over articles 
-#               and feeds them to a downstream server (in the guise of a feeder).
-#
-#               Uses a simple configuration file:  $HOME/.pullnews to define
-#               which machines to pull articles from and which groups at each
-#               machine to pull over.  There is also support for more specific
-#               configurations like cross-posted newsgroups to kill, thanks to
-#               the -m flag which allows articles with headers matching regexp
-#               to be dropped.
-#
-#               A configuration file looks like:
-#
-#                       data.pa.vix.com 
-#                               news.software.nntp 0 0
-#                               comp.lang.c 0 0
-#                       news.uu.net username password
-#                               uunet.announce 0 0
-#                               uunet.help 0 0
-#
-#               Hostname lines have no leading space and may have an optional
-#               username and password after the hostname; all the
-#               subsequent group lines for that host must have leading
-#               spaces.  The two integers on the group line will be updated by
-#               the program when it runs.  They are the Unix time the group was
-#               accessed, and the highest numbered article that was pulled
-#               over.
-#
-
-require 5.004;
-
-$0 =~ s!.*/!!;
-
-my $rcsID =<<'EOM';
-$Id: pullnews.in 7862 2008-06-08 09:15:41Z iulius $
-EOM
-
-$SIG{INT} = \&outtaHere;
-$SIG{QUIT} = \&bail;
-
-use Net::NNTP 2.18; # With libnet 1.0606 (10-Dec-1998) because older versions
-                    # issued MODE READER with Net::NNTP::new().
-use Getopt::Std;
-use IO::Handle;
-use POSIX qw(ceil floor);
-use Fcntl;
-use Fcntl qw(:flock);
-use strict;
-
-my $usage = $0;
-my $defaultConfig = "$ENV{HOME}/.pullnews";
-my $defaultPort = 119;
-my $defaultHost = "localhost";
-my $defaultCheckPoint = 0;
-my $defaultRetries = 0;
-my $defaultDebug = 0;
-my $defaultRetryTime = 1;
-my $defaultProgressWidth = 50;
-my $defaultMaxArts;
-
-$usage =~ s!.*/!!;
-$usage .= " [ -hnqRx -b fraction -c config -C width -d level
-        -f fraction -F fakehop -g groups -G newsgroups -H headers
-        -k checkpt -l logfile -m header_pats -M num -N num
-        -p port -P hop_limit -Q level -r file -s host[:port] -S num
-        -t retries -T seconds -w num -z num -Z num ]
-        [ upstream_host ... ]
-
-  -b fraction   backtrack on server numbering reset.  The proportion
-                (0.0 to 1.0) of a group's articles to pull when the
-                server's article number is less than our high for that
-                group.  When fraction is 1.0, pull all the articles on
-                the server.  The default is to do nothing.
-
-  -c config     specify the configuration file instead of the 
-                default of $ENV{HOME}/.pullnews (also called ~/.pullnews).
-
-  -C width      use width characters for progress (default is $defaultProgressWidth).
-
-  -d level      set debugging level to this integer (default is $defaultDebug).
-
-  -f fraction   proportion of articles to get in each group (0.0 to 1.0).
-
-  -F fakehop    prepend fakehop as a host to the Path: header.
-
-  -g groups     specify a collection of groups to get.  The value must be 
-                a single argument with commas between group names:
-
-                        -g comp.lang.c,comp.lang.lisp,comp.lang.python
-
-                The groups must be defined in the config file somewhere. 
-                Only the hosts that carry those groups will be contacted.
-
-  -G newsgroups add these groups to the configuration (see -g and -w).
-
-  -h            print this message.
-
-  -H headers    remove these named headers (colon-separated list).
-
-  -k checkpt    checkpoint the config file every checkpt articles
-                (default is $defaultCheckPoint).  A value of 0 means
-                normally (at end).
-
-  -l logfile    log progress/stats to logfile (default is stdout).
-
-  -m 'Hdr1:regexp1 !Hdr2:regexp2 ...'
-                feed article only if:
-                the Hdr1: header matches regexp1
-                and the Hdr2: header does not match regexp2.
-
-  -M num        maximum number of articles (per group) to process before
-                bailing out.
-
-  -n            do nothing -- just fake it.
-
-  -N num        timeout length when establishing NNTP connection.
-
-  -p port       specify the port to connect to in order to feed articles
-                (default is $defaultPort).
-
-  -P hop_limit  count hops ('!') in the Path: header, feed article only if: 
-                hop_limit is '+num' and hop_count is more than num;
-                or hop_limit is '-num' and hop_count is less than num.
-
-  -q            $0 will normally be verbose about what it is doing.  This 
-                option will make it quiet.
-
-  -Q level      set the quietness level (-Q 2 is equivalent to -q).
-
-  -r file       rather than feeding to a server, $0 will instead
-                create an rnews-compatible file.
-
-  -R            be a reader (use MODE READER and POST)
-
-  -s host[:port]
-                specify the downstream hostname (and optional port)
-                (default is $defaultHost).
-
-  -S num        specify the maximum time (in seconds) to run.
-
-  -t retries    number of attempts to connect to a server
-                (default is $defaultRetries, see also -T).
-
-  -T secs       time (in seconds) to pause between retries
-                (default is $defaultRetryTime, see also -t).
-
-  -w num        set highwater mark to num (if num is negative, use Current+num
-                instead); a num of 0 will re-get all articles on the server;
-                but a num of -0 will get no old articles, set mark to Current.
-
-  -x            insert an Xref: header in any article that lacks one.
-
-  -z num        time (in seconds) to sleep between articles.
-
-  -Z num        time (in seconds) to sleep between groups.
-";
-
-
-use vars qw($opt_b $opt_c $opt_C $opt_d $opt_f $opt_F $opt_g $opt_G
-            $opt_h $opt_H $opt_k $opt_l $opt_m $opt_M $opt_n
-            $opt_N $opt_p $opt_P $opt_q $opt_Q $opt_r $opt_R $opt_s
-            $opt_S $opt_t $opt_T $opt_w $opt_x $opt_z $opt_Z);
-getopts("b:c:C:d:f:F:g:G:hH:k:l:m:M:nN:p:P:qQ:r:Rs:S:t:T:w:xz:Z:") || die $usage;
-
-die $usage if $opt_h;
-
-my @groupsToGet         = ();        # Empty list means all groups in config file.
-my @groupsToAdd         = ();
-my $rnews               = $opt_r;
-my $groupFile           = $opt_c || $defaultConfig;
-my $localServer         = $opt_s || $defaultHost;
-my $localPort           = $opt_p || $defaultPort;
-my $quiet               = $opt_q;
-my $watermark           = $opt_w;
-my $retries             = $opt_t || $defaultRetries;
-my $retryTime           = $opt_T || $defaultRetryTime;
-my $checkPoint          = $opt_k || $defaultCheckPoint;
-my $debug               = $opt_d || $defaultDebug;
-my $progressWidth       = $opt_C || $defaultProgressWidth;
-my $maxArts             = $opt_M || $defaultMaxArts;
-my $no_op               = $opt_n || 0;
-my $reader              = $opt_R || 0;
-my $quietness           = $opt_Q || 0;
-my $skip_headers        = lc($opt_H) || '';
-my $logFile             = '>&STDOUT';
-$logFile                = ">>$opt_l" if $opt_l;
-my @hdr_to_match        = split(/\s+/, $opt_m) if defined $opt_m;
-my $pathSteps           = $opt_P if defined $opt_P;
-my $path_limit;
-
-$localPort = $1 if not defined $opt_p and $localServer =~ s/:(\d+)$//;
-
-die "can\'t have both ``-s'' and ``-r''\n"  if $opt_s && $opt_r;
-
-die "``-b'' value not 0.0-1.0: $opt_b\n"    if defined $opt_b and $opt_b !~ /^([01](\.0*)?|0?\.\d+)$/;
-die "``-C'' value not an integer: $opt_C\n" if $progressWidth !~ m!^\d+$!;
-die "``-d'' value not an integer: $opt_d\n" if $debug !~ m!^\d+$!;
-die "``-f'' value not 0.0-1.0: $opt_f\n"    if defined $opt_f and $opt_f !~ /^([01](\.0*)?|0?\.\d+)$/;
-die "``-F'' value not a hostname: $opt_F\n" if defined $opt_f and $opt_f !~ m!^[\w\-\.]+$!;
-die "``-k'' value not an integer: $opt_k\n" if $checkPoint !~ m!^\d+$!;
-die "``-M'' value not an integer: $opt_M\n" if defined $maxArts and $maxArts !~ m!^\d+$!;
-die "``-N'' value not an integer: $opt_N\n" if defined $opt_N and $opt_N !~ /^\d+$/;
-die "``-p'' value not an integer: $opt_p\n" if $localPort !~ m!^\d+$!;
-if (defined $pathSteps) {
-        die "``-P'' value not a signed integer: $opt_P\n" if $pathSteps !~ /^[-+](\d+)$/;
-        $path_limit = $1;
-}
-die "option ``-r -'' needs ``-l'' option\n" if defined $opt_r and $opt_r eq '-' and not $opt_l;
-die "``-S'' value not an integer: $opt_S\n" if defined $opt_S and $opt_S !~ /^\d+$/;
-die "``-t'' value not an integer: $opt_t\n" if $retries !~ m!^\d+$!;
-die "``-w'' value not an integer: $opt_w\n" if defined $watermark and $watermark !~ /^-?\d+$/;
-die "``-z'' value not an integer: $opt_z\n" if defined $opt_z and $opt_z !~ /^\d+$/;
-die "``-Z'' value not an integer: $opt_Z\n" if defined $opt_Z and $opt_Z !~ /^\d+$/;
-
-$quiet = 1 if $quietness > 1;
-my %NNTP_Args = ();
-$NNTP_Args{'Timeout'} = $opt_N if defined $opt_N;
-
-@groupsToGet = map { s!^\s*(\S+)\s*!$1!; $_ } split (",", $opt_g) if $opt_g;
-@groupsToAdd = map { s!^\s*(\S+)\s*!$1!; $_ } split (",", $opt_G) if $opt_G;
-
-$| = 1;
-
-my $servers = {};
-my $sname = undef;
-my %fed = ();
-my %refused = ();
-my %rejected = ();
-my $pulled = {};
-my %passwd = ();
-my %info        = (
-        fed      => 0,
-        refused  => 0,
-        rejected => 0,
-        bytes    => 0,
-);
-
-if ($rnews) {
-    if ($no_op) {
-        print "Would write to rnews file $rnews\n";
-    } else {
-        open(RNEWS, ">$rnews") ||
-            die "can't open rnews-format output: $rnews: $!\n";
-    }
-}
-open(LOG, $logFile) || die "can't open logfile ($logFile)!: $!\n";
-
-my $oldfh = select;
-$| = 1; select LOG; $| = 1; select $oldfh;
-
-my $lockfile = $ENV{HOME} . "/.pullnews.pid";
-sysopen (LOCK, "$lockfile", O_RDWR | O_CREAT, 0700) ||
-    die "can't create lock file ($lockfile): $!\n";
-$oldfh = select; select LOCK; $| = 1; select $oldfh;
-
-if (!flock (LOCK, LOCK_EX | LOCK_NB)) {
-    seek LOCK, 0, 0;
-    my $otherpid = <LOCK>;
-    chomp $otherpid;
-    die "Another pullnews (pid: $otherpid) seems to be running.\n";
-}
-
-print LOCK "$$\n";
-
-print LOG scalar(localtime(time)), " start\n\n" unless $quiet;
-
-if (@groupsToGet && ! $quiet) {
-    print LOG "Checking for specific groups:\n";
-    map { printf LOG "\t%s\n", $_ } @groupsToGet;
-    print LOG "\n";
-}
-
-open(FILE, "<$groupFile") || die "can't open group file $groupFile\n";
-while (<FILE>) {
-    next if m!^\s*\#! || m!^\s*$!;
-
-    if (m!^(\S+)(\s+(\S+)\s+(\S+))?\s*$!) {
-        $sname = $1;
-        $servers->{$sname} = {};
-        $passwd{$sname} = [ $3, $4 ] if defined $3 and $3 ne "";
-    } elsif (m!^\s+(\S+)\s+(\d+)\s+(\d+)!) {
-        my ($group,$date,$high) = ($1,$2,$3);
-        $servers->{$sname}->{$group} = [ $date, $high ];
-    } elsif (m!^\s+(\S+)\s*$!) {
-        # Assume this is a new group.
-        my ($group,$date,$high) = ($1,0,0);
-        print LOG "Looking for new group $group on $sname\n" unless $quiet;
-        $servers->{$sname}->{$group} = [ $date, $high ]; 
-    } else { 
-        die "Fatal error in $groupFile: $.: $_\n";
-    }
-}
-close FILE;
-
-my @servers = (@ARGV || sort keys %$servers);
-
-die "No servers!\n" if ! @servers;
-
-my $localcxn;
-
-if ( not $rnews ) {
-    print LOG "Connecting to downstream host: $localServer " .
-        "port: $localPort ..."
-        unless $quiet;
-
-    my %localopts = ("Port" => "$localPort", "Reader" => $reader, %NNTP_Args);
-    $localcxn = Net::NNTP->new($localServer, %localopts) ||
-        die "Can't connect to server $localServer\n";
-}
-
-if ( not $quiet and not $quietness ) {
-    print LOG "done.\n\n";
-    print LOG "Legend: ``.'' is an article the downstream server refused\n";
-    print LOG "        ``*'' is an article the downstream server rejected\n";
-    print LOG "        ``+'' is an article the downstream server accepted\n";
-    print LOG "        ``x'' is an article the upstream server couldn't ";
-    print LOG "give out\n";
-    print LOG "        ``m'' is an article skipped due to headers (-m)\n";
-    print LOG "\n";
-    print LOG "Writing to rnews-format output: $rnews\n\n" if $rnews;
-}
-
-foreach my $server (@servers) {
-    my ($username, $passwd);
-
-    foreach my $addGroup (@groupsToAdd) {
-        next if defined $servers->{$server}->{$addGroup};
-        $servers->{$server}->{$addGroup} = [ 0, 0 ];
-    }
-
-    if (@groupsToGet > 0) {
-        my $ok;
-        foreach my $sgroup (keys %{$servers->{$server}}) {
-            $ok = 1 if grep($_ eq $sgroup, @groupsToGet);
-        }
-
-        if (! $ok) {
-            # User gave -g and the server doesn't have those groups.
-            warn "Skipping server $server.  Doesn't have specified groups.\n";
-            next;
-        }
-    }
-
-    if (exists $passwd{$server}) {
-        ($username, $passwd) = @{$passwd{$server}};
-    }
-
-    if (!exists($servers->{$server})) {
-        warn "No such upstream host $server configured.\n";
-        next;
-    }
-
-    my $shash = $servers->{$server};
-
-    my $connectionAttempts = 0;
-    my $upstream;
-    {{
-        print LOG "connecting to upstream server $server..." unless $quiet;
-        $upstream = Net::NNTP->new($server, %NNTP_Args);
-        $connectionAttempts++;
-        if (!$upstream && $connectionAttempts <= $retries) {
-            sleep $retryTime;
-            next;
-        }
-    }}
-
-    if (!$upstream) {
-        print LOG "failed.\n" unless $quiet;
-        warn "can't connect to upstream server $server: $!\n";
-        next;
-    } else {
-        print LOG "done.\n" unless $quiet;
-    }
-
-    if ($username && !$upstream->authinfo($username, $passwd)) {
-        warn sprintf ("failed to authorize: %s %s\n",
-                      $upstream->code(), $upstream->message());
-        next;
-    }
-
-    $info{server}->{$server}->{bytes} = 0;
-    $info{server}->{$server}->{fed} = 0;
-    $info{server}->{$server}->{refused} = 0;
-    $info{server}->{$server}->{rejected} = 0;
-
-    foreach my $group (sort keys %{$servers->{$server}}) {
-        next if (@groupsToGet && !grep ($_ eq $group, @groupsToGet));
-
-        last if !crossFeedGroup ($upstream,$localcxn,$server,$group,$shash);
-        last if defined $opt_S and time >= $^T+$opt_S;
-        sleep $opt_Z if defined $opt_Z;
-    }
-
-    $upstream->quit();
-    last if defined $opt_S and time >= $^T+$opt_S;
-}
-
-saveConfig ();
-stats() unless $quiet;
-
-if ($rnews) {
-    if (not $no_op and not close RNEWS) {
-        print LOG "\nRNEWS close failure: $!";
-    }
-    unlink $rnews if -f $rnews and not -s $rnews;
-}
-
-print LOG "\nDone ", scalar(localtime(time)), "\n" unless $quiet;
-
-cleanLock();
-exit (0);
-
-###############################################################################
-
-sub stats {
-    my $ltotal = 0;
-    my $reftotal = 0;
-    my $rejtotal = 0;
-    my $sum;
-
-    map { $reftotal += $refused{$_} } keys %refused;
-    map { $rejtotal += $rejected{$_} } keys %rejected;
-    map { $ltotal += $fed{$_} } keys %fed;
-
-    $sum = $reftotal + $rejtotal + $ltotal;
-
-    if ($quiet) {
-        printf LOG localtime() . " [$$] %d article%s to $localServer\n",
-            $sum, ($sum != 1 ? "s" : "");
-    } else {
-        printf LOG "\n%d article%s offered to server on $localServer\n",
-            $sum, ($sum != 1 ? "s were" : " was");
-    }
-
-    return if ($sum == 0);
-
-    if ($quiet) {
-        print LOG localtime() . " [$$] $ltotal ok, $reftotal ref, $rejtotal rej\n";
-    } else {
-        printf LOG "%d article%s accepted\n",
-            $ltotal, ($ltotal != 1 ? "s were" : " was") 
-                if ($ltotal != 0);
-        printf LOG "%d article%s refused\n",
-            $reftotal, ($reftotal != 1 ? "s were" : " was") 
-                if ($reftotal != 0);
-        printf LOG "%d article%s rejected\n",
-            $rejtotal, ($rejtotal != 1 ? "s were" : " was") 
-                if ($rejtotal != 0);
-    }
-
-    map { 
-        print LOG "\nUpstream server $_:\n" if not $quiet; 
-        my $server = $_;
-        my $width = 0;
-
-        map {
-            $width = length if length > $width;
-        } sort keys %{$pulled->{$server}} if not $quiet;
-
-        map { 
-            if ($quiet) {
-                printf LOG "%s [$$] from $server $_ %s\n", localtime(), $pulled->{$server}->{$_};
-            } else {
-                printf LOG "\t%${width}s %d\n", $_, $pulled->{$server}->{$_};
-            }
-        } sort keys %{$pulled->{$server}};
-    } sort keys %{$pulled};
-}
-
-sub saveConfig {
-    return if $no_op;
-
-    $SIG{INT} = $SIG{QUIT} = 'IGNORE';
-
-    open(FILE,">$groupFile") || die "can't open $groupFile: $!\n";
-    my $server;
-    my $group;
-
-    print LOG "\nSaving config\n" unless $quiet;
-    print FILE "# Format: (date is epoch seconds)\n";
-    print FILE "# hostname [username password]\n";
-    print FILE "#         group date high\n";
-    foreach $server (sort keys %$servers) {
-        print FILE "$server";
-        if (defined $passwd{$server}) {
-            printf FILE " %s %s", $passwd{$server}->[0], $passwd{$server}->[1];
-        }
-        print FILE "\n";
-        foreach $group (sort keys %{$servers->{$server}}) {
-            my ($date,$high) = @{$servers->{$server}->{$group}};
-            printf FILE "\t%s %d %d\n",$group,$date,$high;
-        }
-    }
-    close FILE;
-}
-
-
-sub outtaHere {
-    saveConfig();
-    cleanLock();
-    exit (0);
-}
-
-sub cleanLock {
-    flock (LOCK, LOCK_UN);
-    unlink $lockfile if defined $lockfile;
-}
-
-sub bail {
-    warn "received QUIT signal.  Not saving config.\n";
-    cleanLock();
-    exit (0);
-}
-
-sub crossFeedGroup {
-    my ($fromServer,$toServer,$server,$group,$shash) = @_;
-    my ($date,$high) = @{$shash->{$group}};
-    my ($prevDate,$prevHigh) = @{$shash->{$group}};
-    my ($narticles,$first,$last,$name) = $fromServer->group($group);
-    my $count = 0;
-    my $code;
-    my $startTime = time;
-    my ($prevRefused, $prevRejected) = ($info{refused}, $info{rejected});
-
-    if (!defined($narticles)) { # Group command failed.
-        warn sprintf ("Group command failed: %s %s\n",
-                      $fromServer->code(), $fromServer->message());
-        return undef;
-    }
-
-    if (not $quiet) {
-        printf LOG "\n%s:\n", $name;
-        printf LOG "\tlast checked: %s\n", scalar(localtime($prevDate));
-        printf LOG "\t%d articles available.  First %d Last %d\n",
-               $narticles, $first, $last;
-    }
-    if (defined $watermark) {
-        printf LOG "\tOur previous highest: %d\n", $prevHigh if not $quiet;
-        $high = $watermark;
-        $high = $last+$watermark if substr($watermark, 0, 1) eq '-';
-        $high = 0 if $high < 0;
-        $shash->{$group} = [ time, $high ];
-    }
-    printf LOG "\tOur current highest: %d", $high if not $quiet;
-
-    return 0 if ! $name;
-    if ($narticles == 0) {
-        print LOG " (nothing to get)\n" unless $quiet;
-        return 1;
-    }
-
-    my $toget = (($last - $high) < $narticles ?
-                     $last - $high : $narticles);
-    $toget = ceil($toget * $opt_f) if defined $opt_f;
-    if ($last < $high and $opt_b) {
-        $high = $first+floor(($last-$first+1)*(1-$opt_b));
-        $toget = $last - $high;
-        print LOG " (reset highwater mark to $high)" unless $quiet;
-    } elsif ($prevHigh == -1 || $last <= $prevHigh) {
-        # We connected OK but there's nothing there, or we just want
-        # to reset our highwater mark.
-        $shash->{$group} = [ time, $high ];
-        print LOG " (nothing to get)\n" unless $quiet;
-        return 1;
-    }
-    print LOG " ($toget to get)\n" unless $quiet;
-
-    my $i;
-    my @warns;
-    for ($i = ($first > $high ? $first : $high + 1) ; $i <= $last ; $i++) {
-        last if defined $maxArts and $count >= $maxArts;
-        last if defined $opt_f and $count >= $toget;
-        $count++;
-        sleep $opt_z if defined $opt_z and $count > 1;
-        my $article = $fromServer->article($i);
-        if ($article) {
-            my $msgid;
-            my $xref = 0;
-            my $headers = 1;
-            my $idx;
-            my $len = 0;                 # Received article length (bytes) (for stats).
-            my $tx_len = 0;              # Transmitted article length (bytes) (for rnews).
-            my @header_nums_to_go = ();
-            my $match_all_hdrs = 1;      # Assume no headers to match.
-            my $skip_due_to_hdrs = 0;
-            my %m_found_hdrs = ();
-            my $curr_hdr = '';
-
-            for ($idx = 0 ; $idx < @{$article} ; $idx++) {
-                $len += length($article->[$idx]);
-                $tx_len += length($article->[$idx]);
-                next if not $headers;
-
-                $curr_hdr = lc($1) if $article->[$idx] =~ /^([^:[:blank:]]+):/;
-                $curr_hdr = '    ' if $article->[$idx] eq "\n";
-
-                if ($match_all_hdrs and @hdr_to_match and $article->[$idx] =~ /^[^[:blank:]]/) {
-                    # Check header matches -m flag if new header.
-
-                    # Unfold this header (with following lines).
-                    my $unfolded_art_hdr = $article->[$idx];
-                    for (my $idx_step = $idx+1;  $article->[$idx_step] =~ /^[[:space:]](.+)/; $idx_step++) {
-                        # While next line is continuation...
-                        my $more_line = $1;
-                        chomp $unfolded_art_hdr;
-                        $unfolded_art_hdr .= $more_line;
-                    }
-
-                    my ($hdr_un, $val_un) = split(':', $unfolded_art_hdr, 2);
-                    $val_un = '' if not defined $val_un;
-                    $val_un =~ s/^\s*//;
-                    for my $tuple_match (@hdr_to_match) {
-                        my ($hdr_m, $val_m) = split(':', $tuple_match, 2);
-                        my $negate_h = ($hdr_m =~ s/^!//);
-                        next if lc($hdr_un) ne lc($hdr_m);
-                        $m_found_hdrs{lc($hdr_m)} = 1;
-                        if ($negate_h) {
-                            if ($val_un =~ /$val_m/i) {
-                                print LOG "\tDEBUGGING $i\t-- $hdr_un [$1]\n" if $debug >= 2;
-                                $match_all_hdrs = 0;
-                            }
-                        } elsif (not $val_un =~ /$val_m/i) {
-                            print LOG "\tDEBUGGING $i\t++ $hdr_un [$1]\n" if $debug >= 2;
-                            $match_all_hdrs = 0;
-                        }
-                        last if not $match_all_hdrs;
-                    }
-                }
-
-                if (grep { $curr_hdr eq $_ } split(':', $skip_headers)) {
-                    print LOG "\tDEBUGGING $i\tskip_hdr $idx\t$curr_hdr\n" if $debug >= 2;
-                    push @header_nums_to_go, $idx;
-                }
-                if ($article->[$idx] =~ m!^message-id:\s*(\S+)!i) {
-                    $msgid = $1;
-                }
-                if (not $skip_due_to_hdrs and defined $pathSteps and $article->[$idx] =~ m!^Path:\s*!i) {
-                    my $path_count = $article->[$idx];
-                    $path_count = ($path_count =~ s@!@@g) || 0;
-                    if (substr($pathSteps, 0, 1) eq '-') {
-                        $skip_due_to_hdrs = 1 if $path_count >= $path_limit;
-                    } elsif (substr($pathSteps, 0, 1) eq '+') {
-                        $skip_due_to_hdrs = 1 if $path_count <= $path_limit;
-                    }
-                    if ($skip_due_to_hdrs) {
-                        print LOG "\tDEBUGGING $i\tNpath_skip_art $i\n" if $debug >= 2;
-                    } elsif (defined $opt_F) {
-                        $tx_len += length($opt_F)+1;
-                        $article->[$idx] =~ s/^Path:\s*/$&$opt_F!/i;
-                    }
-                }
-
-                if ($opt_x && $article->[$idx] =~ m!^xref:!i) {
-                    $xref = 1;
-                }
-
-                # Catch some of the more common problems with articles.
-                if ($article->[$idx] =~ m!^\s+\n$! and $curr_hdr ne 'subject') {
-                    print STDERR "Fixing bad header line[$idx]-1: $article->[$idx-1]" if $idx > 0;
-                    print STDERR "Fixing bad header line[$idx]::: $article->[$idx]";
-                    print STDERR "Fixing bad header line[$idx]+1: $article->[$idx+1]";
-                    $tx_len -= length($article->[$idx])-1;
-                    $article->[$idx] = "\n";
-                }
-
-                $headers = 0 if $article->[$idx] eq "\n";
-            }
-            if (@hdr_to_match and (not $match_all_hdrs or @hdr_to_match != scalar(keys %m_found_hdrs))) {
-                print LOG "\tDEBUGGING $i\thdr_skip_art $i\n" if $debug >= 2;
-                $skip_due_to_hdrs = 1;
-            }
-            while (@header_nums_to_go) {
-                my $idx = pop @header_nums_to_go;  # Start from last.
-                my $cut = join("\n\t", splice(@{$article}, $idx, 1));
-                $tx_len -= length($cut);
-                print LOG "\tDEBUGGING $i\tcut1 $cut" if $debug >= 2;
-                while ($article->[$idx] =~ /^[[:space:]](.+)/) {
-                    # Folded lines.
-                    my $cut = join("\n\t", splice(@{$article}, $idx, 1));
-                    $tx_len -= length($cut);
-                    print LOG "\tDEBUGGING $i\tcut_ $cut" if $debug >= 2;
-                }
-            }
-
-            if (!$msgid) {
-                warn "No Message-ID: header found in article\n";
-                next;
-            } else {
-                print LOG "\tDEBUGGING $i\tMessage-ID: $msgid\n" if $debug >= 2;
-            }
-
-            # Some old servers lack Xref:, which bothers a downstream INN if
-            # it has xrefslave set, so add one just before the blank line.
-            if ($opt_x && !$xref) {
-                warn "No Xref: header found in article, adding\n";
-                my $xref_h = "Xref: $server $group: $i\n";
-                splice(@{$article}, $idx, 0, $xref_h);
-                $tx_len += length($xref_h);
-            }
-
-            $pulled->{$server}->{$group}++;
-            $info{server}->{$server}->{bytes} += $len;
-            $info{bytes} += $len;
-
-            if ($skip_due_to_hdrs) {
-                print LOG "m" unless $quiet;
-            } elsif ($rnews) {
-                printf RNEWS "#! rnews %d\n", $tx_len;
-                map { print RNEWS $_ } @{$article};
-                print LOG "+" unless $quiet;
-            } else {
-                if ($no_op) {
-                    print "Would offer $msgid\n";
-
-                } elsif ($reader and not $toServer->post($article)) {
-                    #   240 article posted ok
-                    #   340 send article to be posted.  End with <CR-LF>.<CR-LF>
-                    #   440 posting not allowed
-                    #   441 posting failed
-                    my $code = $toServer->code();
-                    my $msg = $toServer->message();
-                    print LOG "\tDEBUGGING $i\tPost $code: Msg: <" . join('//', split(/\r?\n/, $msg)) . ">\n" if $debug >= 2;
-                    $msg =~ s/^340 .*?\n(?=.)//o;
-                    if ($msg =~ /^240 /) {
-                        print LOG "+" unless $quiet;
-                        push @warns, "Post $i ok ($code): $msg";
-                        $fed{$group}++;
-                        $info{server}->{$server}->{fed}++;
-                        $info{fed}++;
-                    } elsif ($msg =~ /^435 / or $msg =~ /duplicate message-id/io) {
-                        print LOG "." unless $quiet;
-                        push @warns, "Post $i to server declined ($code): $msg"
-                                            if $msg !~ /^435 $msgid$/
-                                            and $msg !~ /duplicate message-id/io;
-                        $refused{$group}++;
-                        $info{server}->{$server}->{refused}++;
-                        $info{refused}++;
-                    } else {
-                        warn "Post $i to server failed ($code): $msg\n";
-                        $toServer->quit();
-                    }
-
-                } elsif (not $reader and not $toServer->ihave($msgid,$article)) {
-                    #   235 article transferred ok
-                    #   335 send article to be transferred.  End with <CR-LF>.<CR-LF>
-                    #   435 article not wanted -- do not send it
-                    #   436 transfer failed -- try again later
-                    #   437 article rejected -- do not try again
-                    my $code = $toServer->code();
-                    my $msg = $toServer->message();
-                    print LOG "\tDEBUGGING $i\tPost $code: Msg: <" . join('//', split(/\r?\n/, $msg)) . ">\n" if $debug >= 2;
-                    if ($code == 435) {
-                        print LOG "." unless $quiet;
-                        $refused{$group}++;
-                        $info{server}->{$server}->{refused}++;
-                        $info{refused}++;
-                    } elsif ($code == 437) {
-                        print LOG "*" unless $quiet;
-                        $rejected{$group}++;
-                        $info{server}->{$server}->{rejected}++;
-                        $info{rejected}++;
-                    } else {
-                        warn "Transfer to server failed ($code): $msg\n";
-                        $toServer->quit();
-                        saveConfig();
-                        exit (1);
-                    }
-
-                    } else {
-                    my $code = $toServer->code();
-                    my $msg = $toServer->message();
-                    print LOG "\tDEBUGGING $i\tPost $code: Msg: <" . join('//', split(/\r?\n/, $msg)) . ">\n" if $debug >= 2;
-                    print LOG "+" unless $quiet;
-                    $fed{$group}++;
-                    $info{server}->{$server}->{fed}++;
-                    $info{fed}++;
-                    }
-            }
-
-            $shash->{$group} = [ time, $high = $i ];
-        } else {
-            $shash->{$group} = [ time, $high = $i ] if $fromServer->code() == 430;    # no such article, do not retry
-            print LOG "x" unless $quiet;
-            printf LOG ("\nDEBUGGING $i %s %s\n", $fromServer->code(),
-                        $fromServer->message()) if $debug >= 2;
-        }
-        saveConfig() if $checkPoint and ($count % $checkPoint) == 0;
-        print LOG "\n" if (!$quiet && (($count % $progressWidth) == 0));
-        last if defined $opt_S and time >= $^T+$opt_S;
-    }
-    print LOG "\n" unless $quiet;
-    print LOG join("\n\t", '', @warns) . "\n\n" if @warns;
-    my $elapsed_time = time - $startTime + 1;
-    if ($quiet) {
-        my $rejectedDiff = $info{rejected}-$prevRejected;
-        my $refusedDiff = $info{refused}-$prevRefused;
-        my $destServer = ($localServer ne $defaultHost ? " to $localServer" : '');
-        print LOG localtime() . "[$$] $server$destServer $name $narticles $first-$last : $count $prevHigh-" .
-                                ($high == $last ? '' : $high) . " $refusedDiff $rejectedDiff\n"
-                        unless $prevHigh == $high and $count == 0;
-    } else {
-        printf LOG "%s article%s retrieved in %d seconds (%d bytes, %d cps)\n",
-                $count, ($count == 1 ? "" : "s"), $elapsed_time,
-                $info{server}->{$server}->{bytes},
-                int($info{server}->{$server}->{bytes}*100/$elapsed_time)/100;
-    }
-    return 1;
-}
diff --git a/frontends/rnews.c b/frontends/rnews.c
deleted file mode 100644 (file)
index 5ef5f3b..0000000
+++ /dev/null
@@ -1,972 +0,0 @@
-/*  $Id: rnews.c 7424 2005-10-09 05:04:12Z eagle $
-**
-**  A front-end for InterNetNews.
-**
-**  Read UUCP batches and offer them up NNTP-style.  Because we may end
-**  up sending our input down a pipe to uncompress, we have to be careful
-**  to do unbuffered reads.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-#include "storage.h"
-
-
-typedef struct _HEADER {
-    const char *Name;
-    int size;
-} HEADER;
-
-
-static bool    Verbose;
-static const char      *InputFile = "stdin";
-static char    *UUCPHost;
-static char    *PathBadNews = NULL;
-static char    *remoteServer;
-static FILE    *FromServer;
-static FILE    *ToServer;
-static char    UNPACK[] = "gzip";
-static HEADER  RequiredHeaders[] = {
-    { "Message-ID",    10 },
-#define _messageid     0
-    { "Newsgroups",    10 },
-#define _newsgroups    1
-    { "From",           4 },
-#define _from          2
-    { "Date",           4 },
-#define _date          3
-    { "Subject",        7 },
-#define _subject       4
-    { "Path",           4 },
-#define _path          5
-};
-#define IS_MESGID(hp)  ((hp) == &RequiredHeaders[_messageid])
-#define IS_PATH(hp)    ((hp) == &RequiredHeaders[_path])
-
-\f
-
-/*
-**  Open up a pipe to a process with fd tied to its stdin.  Return a
-**  descriptor tied to its stdout or -1 on error.
-*/
-static int
-StartChild(int fd, const char *path, const char *argv[])
-{
-    int                pan[2];
-    int                i;
-    pid_t      pid;
-
-    /* Create a pipe. */
-    if (pipe(pan) < 0)
-        sysdie("cannot pipe for %s", path);
-
-    /* Get a child. */
-    for (i = 0; (pid = fork()) < 0; i++) {
-       if (i == innconf->maxforks) {
-            syswarn("cannot fork %s, spooling", path);
-           return -1;
-       }
-        notice("cannot fork %s, waiting", path);
-       sleep(60);
-    }
-
-    /* Run the child, with redirection. */
-    if (pid == 0) {
-       close(pan[PIPE_READ]);
-
-       /* Stdin comes from our old input. */
-       if (fd != STDIN_FILENO) {
-           if ((i = dup2(fd, STDIN_FILENO)) != STDIN_FILENO) {
-                syswarn("cannot dup2 %d to 0, got %d", fd, i);
-               _exit(1);
-           }
-           close(fd);
-       }
-
-       /* Stdout goes down the pipe. */
-       if (pan[PIPE_WRITE] != STDOUT_FILENO) {
-           if ((i = dup2(pan[PIPE_WRITE], STDOUT_FILENO)) != STDOUT_FILENO) {
-                syswarn("cannot dup2 %d to 1, got %d", pan[PIPE_WRITE], i);
-               _exit(1);
-           }
-           close(pan[PIPE_WRITE]);
-       }
-
-       execv(path, (char * const *)argv);
-        syswarn("cannot execv %s", path);
-       _exit(1);
-    }
-
-    close(pan[PIPE_WRITE]);
-    close(fd);
-    return pan[PIPE_READ];
-}
-
-
-/*
-**  Wait for the specified number of children.
-*/
-static void
-WaitForChildren(int n)
-{
-    pid_t pid;
-
-    while (--n >= 0) {
-        pid = waitpid(-1, NULL, WNOHANG);
-        if (pid == (pid_t) -1 && errno != EINTR) {
-            if (errno != ECHILD)
-                syswarn("cannot wait");
-            break;
-        }
-    }
-}
-
-
-\f
-
-/*
-**  Clean up the NNTP escapes from a line.
-*/
-static char *REMclean(char *buff)
-{
-    char       *p;
-
-    if ((p = strchr(buff, '\r')) != NULL)
-       *p = '\0';
-    if ((p = strchr(buff, '\n')) != NULL)
-       *p = '\0';
-
-    /* The dot-escape is only in text, not command responses. */
-    return buff;
-}
-
-
-/*
-**  Write an article to the rejected directory.
-*/
-static void
-Reject(const char *article, size_t length UNUSED, const char *reason,
-       const char *arg)
-{
-#if    defined(DO_RNEWS_SAVE_BAD)
-    char *filename;
-    FILE *F;
-    int fd;
-#endif /* defined(DO_RNEWS_SAVE_BAD) */
-
-    notice(reason, arg);
-    if (Verbose) {
-       fprintf(stderr, "%s: ", InputFile);
-       fprintf(stderr, reason, arg);
-       fprintf(stderr, " [%.40s...]\n", article);
-    }
-
-#if    defined(DO_RNEWS_SAVE_BAD)
-    filename = concat(PathBadNews, "/XXXXXX", (char *) 0);
-    fd = mkstemp(filename);
-    if (fd < 0) {
-        warn("cannot create temporary file");
-        return;
-    }
-    F = fdopen(fd, "w");
-    if (F == NULL) {
-        warn("cannot fdopen %s", filename);
-       return;
-    }
-    if (fwrite(article, 1, length, F) != length)
-        warn("cannot fwrite to %s", filename);
-    if (fclose(F) == EOF)
-        warn("cannot close %s", filename);
-    free(filename);
-#endif /* defined(DO_RNEWS_SAVE_BAD) */
-}
-
-
-/*
-**  Process one article.  Return true if the article was okay; false if the
-**  whole batch needs to be saved (such as when the server goes down or if
-**  the file is corrupted).
-*/
-static bool
-Process(char *article, size_t artlen)
-{
-    HEADER             *hp;
-    const char         *p;
-    size_t              length;
-    char                *wirefmt, *q;
-    const char         *id = NULL;
-    char                *msgid;
-    char               buff[SMBUF];
-#if    defined(FILE_RNEWS_LOG_DUPS)
-    FILE               *F;
-#endif /* defined(FILE_RNEWS_LOG_DUPS) */
-#if    !defined(DONT_RNEWS_LOG_DUPS)
-    char               path[40];
-#endif /* !defined(DONT_RNEWS_LOG_DUPS) */
-
-    /* Empty article? */
-    if (*article == '\0')
-       return true;
-
-    /* Convert the article to wire format. */
-    wirefmt = ToWireFmt(article, artlen, &length);
-
-    /* Make sure that all the headers are there, note the ID. */
-    for (hp = RequiredHeaders; hp < ARRAY_END(RequiredHeaders); hp++) {
-        p = wire_findheader(wirefmt, length, hp->Name);
-        if (p == NULL) {
-            free(wirefmt);
-           Reject(article, artlen, "bad_article missing %s", hp->Name);
-           return true;
-       }
-       if (IS_MESGID(hp)) {
-           id = p;
-           continue;
-       }
-#if    !defined(DONT_RNEWS_LOG_DUPS)
-       if (IS_PATH(hp)) {
-           strlcpy(path, p, sizeof(path));
-           if ((q = strchr(path, '\r')) != NULL)
-               *q = '\0';
-       }
-#endif /* !defined(DONT_RNEWS_LOG_DUPS) */
-    }
-
-    /* Send the NNTP "ihave" message. */
-    if ((p = strchr(id, '\r')) == NULL) {
-        free(wirefmt);
-       Reject(article, artlen, "bad_article unterminated %s header",
-               "Message-ID");
-       return true;
-    }
-    msgid = xstrndup(id, p - id);
-    fprintf(ToServer, "ihave %s\r\n", msgid);
-    fflush(ToServer);
-    if (UUCPHost)
-        notice("offered %s %s", msgid, UUCPHost);
-    free(msgid);
-
-    /* Get a reply, see if they want the article. */
-    if (fgets(buff, sizeof buff, FromServer) == NULL) {
-        free(wirefmt);
-        if (ferror(FromServer))
-            syswarn("cannot fgets after ihave");
-        else
-            warn("unexpected EOF from server after ihave");
-       return false;
-    }
-    REMclean(buff);
-    if (!CTYPE(isdigit, buff[0])) {
-        free(wirefmt);
-        notice("bad_reply after ihave %s", buff);
-       return false;
-    }
-    switch (atoi(buff)) {
-    default:
-        free(wirefmt);
-       notice("unknown_reply after ihave %s", buff);
-       return false;
-    case NNTP_RESENDIT_VAL:
-        free(wirefmt);
-       return false;
-    case NNTP_SENDIT_VAL:
-       break;
-    case NNTP_HAVEIT_VAL:
-#if    defined(SYSLOG_RNEWS_LOG_DUPS)
-       *p = '\0';
-        notice("duplicate %s %s", id, path);
-#endif /* defined(SYSLOG_RNEWS_LOG_DUPS) */
-#if    defined(FILE_RNEWS_LOG_DUPS)
-       if ((F = fopen(_PATH_RNEWS_DUP_LOG, "a")) != NULL) {
-           *p = '\0';
-           fprintf(F, "duplicate %s %s\n", id, path);
-           fclose(F);
-       }
-#endif /* defined(FILE_RNEWS_LOG_DUPS) */
-        free(wirefmt);
-       return true;
-    }
-
-    /* Send the article to the server. */
-    if (fwrite(wirefmt, length, 1, ToServer) != 1) {
-        free(wirefmt);
-        sysnotice("cant sendarticle");
-       return false;
-    }
-    free(wirefmt);
-
-    /* Flush the server buffer. */
-    if (fflush(ToServer) == EOF) {
-        syswarn("cant fflush after article");
-        return false;
-    }
-
-    /* Process server reply code. */
-    if (fgets(buff, sizeof buff, FromServer) == NULL) {
-        if (ferror(FromServer))
-            syswarn("cannot fgets after article");
-        else
-            warn("unexpected EOF from server after article");
-       return false;
-    }
-    REMclean(buff);
-    if (!CTYPE(isdigit, buff[0])) {
-        notice("bad_reply after article %s", buff);
-       return false;
-    }
-    switch (atoi(buff)) {
-    default:
-        notice("unknown_reply after article %s", buff);
-       /* FALLTHROUGH */
-    case NNTP_RESENDIT_VAL:
-       return false;
-    case NNTP_TOOKIT_VAL:
-       break;
-    case NNTP_REJECTIT_VAL:
-       Reject(article, artlen, "rejected %s", buff);
-       break;
-    }
-    return true;
-}
-
-
-/*
-**  Read the rest of the input as an article.
-*/
-static bool
-ReadRemainder(int fd, char first, char second)
-{
-    char       *article;
-    char       *p;
-    char       buf[BUFSIZ];
-    int                size;
-    int                used;
-    int                left;
-    int                skipnl;
-    int                i, n;
-    bool       ok;
-
-    /* Get an initial allocation, leaving space for the \0. */
-    size = BUFSIZ + 1;
-    article = xmalloc(size + 2);
-    article[0] = first;
-    article[1] = second;
-    used = second ? 2 : 1;
-    left = size - used;
-    skipnl = 0;
-
-    /* Read the input, coverting line ends as we go if necessary. */
-    while ((n = read(fd, buf, sizeof(buf))) > 0) {
-       p = article + used;
-       for (i = 0; i < n; i++) {
-           if (skipnl) {
-               skipnl = 0;
-               if (buf[i] == '\n') continue;
-           }
-           if (buf[i] == '\r') {
-               buf[i] = '\n';
-               skipnl = 1;
-           }
-           *p++ = buf[i];
-           used++;
-           left--;
-           if (left < SMBUF) {
-               size += BUFSIZ;
-               left += BUFSIZ;
-               article = xrealloc(article, size);
-               p = article + used;
-           }
-       }
-    }
-    if (n < 0)
-        sysdie("cannot read after %d bytes", used);
-
-    if (article[used - 1] != '\n')
-       article[used++] = '\n';
-    article[used] = '\0';
-
-    ok = Process(article, used);
-    free(article);
-    return ok;
-}
-
-
-/*
-**  Read an article from the input stream that is artsize bytes long.
-*/
-static bool
-ReadBytecount(int fd, int artsize)
-{
-    static char                *article;
-    static int         oldsize;
-    char       *p;
-    int        left;
-    int        i;
-
-    /* If we haven't gotten any memory before, or we didn't get enough,
-     * then get some. */
-    if (article == NULL) {
-       oldsize = artsize;
-       article = xmalloc(oldsize + 1 + 1);
-    }
-    else if (artsize > oldsize) {
-       oldsize = artsize;
-        article = xrealloc(article, oldsize + 1 + 1);
-    }
-
-    /* Read in the article. */
-    for (p = article, left = artsize; left; p += i, left -= i)
-       if ((i = read(fd, p, left)) <= 0) {
-           i = errno;
-            warn("cannot read, wanted %d got %d", artsize, artsize - left);
-#if    0
-           /* Don't do this -- if the article gets re-processed we
-            * will end up accepting the truncated version. */
-           artsize = p - article;
-           article[artsize] = '\0';
-           Reject(article, "short read (%s?)", strerror(i));
-#endif /* 0 */
-           return true;
-       }
-    if (p[-1] != '\n') {
-       *p++ = '\n';
-        artsize++;
-    }
-    *p = '\0';
-
-    return Process(article, artsize);
-}
-
-\f
-
-/*
-**  Read a single text line; not unlike fgets().  Just more inefficient.
-*/
-static bool
-ReadLine(char *p, int size, int fd)
-{
-    char       *save;
-
-    /* Fill the buffer, a byte at a time. */
-    for (save = p; size > 0; p++, size--) {
-       if (read(fd, p, 1) != 1) {
-           *p = '\0';
-            sysdie("cannot read first line, got %s", save);
-       }
-       if (*p == '\n') {
-           *p = '\0';
-           return true;
-       }
-    }
-    *p = '\0';
-    warn("bad_line too long %s", save);
-    return false;
-}
-
-
-/*
-**  Unpack a single batch.
-*/
-static bool
-UnpackOne(int *fdp, size_t *countp)
-{
-#if    defined(DO_RNEWSPROGS)
-    char       path[(SMBUF * 2) + 1];
-    char       *p;
-#endif /* defined(DO_RNEWSPROGS) */
-    char       buff[SMBUF];
-    const char *cargv[4];
-    int                artsize;
-    int                i;
-    int                gzip = 0;
-    bool       HadCount;
-    bool       SawCunbatch;
-    int                len;
-
-    *countp = 0;
-    for (SawCunbatch = false, HadCount = false; ; ) {
-       /* Get the first character. */
-       if ((i = read(*fdp, &buff[0], 1)) < 0) {
-            syswarn("cannot read first character");
-           return false;
-       }
-       if (i == 0)
-           break;
-
-       if (buff[0] == 0x1f)
-           gzip = 1;
-       else if (buff[0] != '#')
-           /* Not a batch file.  If we already got one count, the batch
-            * is corrupted, else read rest of input as an article. */
-           return HadCount ? false : ReadRemainder(*fdp, buff[0], '\0');
-
-       /* Get the second character. */
-       if ((i = read(*fdp, &buff[1], 1)) < 0) {
-            syswarn("cannot read second character");
-           return false;
-       }
-       if (i == 0)
-           /* A one-byte batch? */
-           return false;
-
-       /* Check second magic character. */
-       /* gzipped ($1f$8b) or compressed ($1f$9d) */
-       if (gzip && ((buff[1] == (char)0x8b) || (buff[1] == (char)0x9d))) {
-           cargv[0] = "gzip";
-           cargv[1] = "-d";
-           cargv[2] = NULL;
-           lseek(*fdp, 0, 0); /* Back to the beginning */
-           *fdp = StartChild(*fdp, _PATH_GZIP, cargv);
-           if (*fdp < 0)
-               return false;
-           (*countp)++;
-           SawCunbatch = true;
-           continue;
-       }
-       if (buff[1] != '!')
-           return HadCount ? false : ReadRemainder(*fdp, buff[0], buff[1]);
-
-       /* Some kind of batch -- get the command. */
-       if (!ReadLine(&buff[2], (int)(sizeof buff - 3), *fdp))
-           return false;
-
-       if (strncmp(buff, "#! rnews ", 9) == 0) {
-           artsize = atoi(&buff[9]);
-           if (artsize <= 0) {
-                syswarn("bad_line bad count %s", buff);
-               return false;
-           }
-           HadCount = true;
-           if (ReadBytecount(*fdp, artsize))
-               continue;
-           return false;
-       }
-
-       if (HadCount)
-           /* Already saw a bytecount -- probably corrupted. */
-           return false;
-
-       if (strcmp(buff, "#! cunbatch") == 0) {
-           if (SawCunbatch) {
-                syswarn("nested_cunbatch");
-               return false;
-           }
-           cargv[0] = UNPACK;
-           cargv[1] = "-d";
-           cargv[2] = NULL;
-           *fdp = StartChild(*fdp, _PATH_GZIP, cargv);
-           if (*fdp < 0)
-               return false;
-           (*countp)++;
-           SawCunbatch = true;
-           continue;
-       }
-
-#if    defined(DO_RNEWSPROGS)
-       cargv[0] = UNPACK;
-       cargv[1] = NULL;
-       /* Ignore any possible leading pathnames, to avoid trouble. */
-       if ((p = strrchr(&buff[3], '/')) != NULL)
-           p++;
-       else
-           p = &buff[3];
-       if (strchr(_PATH_RNEWSPROGS, '/') == NULL) {
-           snprintf(path, sizeof(path), "%s/%s/%s", innconf->pathbin,
-                     _PATH_RNEWSPROGS, p);
-           len = strlen(innconf->pathbin) + 1 + sizeof _PATH_RNEWSPROGS;
-       } else {
-           snprintf(path, sizeof(path), "%s/%s", _PATH_RNEWSPROGS, p);
-           len = sizeof _PATH_RNEWSPROGS;
-       }
-       for (p = &path[len]; *p; p++)
-           if (ISWHITE(*p)) {
-               *p = '\0';
-               break;
-           }
-       *fdp = StartChild(*fdp, path, cargv);
-       if (*fdp < 0)
-           return false;
-       (*countp)++;
-       continue;
-#else
-        warn("bad_format unknown command %s", buff);
-       return false;
-#endif /* defined(DO_RNEWSPROGS) */
-    }
-    return true;
-}
-
-
-/*
-**  Read all articles in the spool directory and unpack them.  Print all
-**  errors with xperror as well as syslog, since we're probably being run
-**  interactively.
-*/
-static void
-Unspool(void)
-{
-    DIR        *dp;
-    struct dirent       *ep;
-    bool       ok;
-    struct stat                Sb;
-    char               hostname[10];
-    int                        fd;
-    size_t             i;
-    char                *uuhost;
-
-    message_handlers_die(2, message_log_stderr, message_log_syslog_err);
-    message_handlers_warn(2, message_log_stderr, message_log_syslog_err);
-
-    /* Go to the spool directory, get ready to scan it. */
-    if (chdir(innconf->pathincoming) < 0)
-        sysdie("cannot chdir to %s", innconf->pathincoming);
-    if ((dp = opendir(".")) == NULL)
-        sysdie("cannot open spool directory");
-
-    /* Loop over all files, and parse them. */
-    while ((ep = readdir(dp)) != NULL) {
-       InputFile = ep->d_name;
-       if (InputFile[0] == '.')
-           continue;
-       if (stat(InputFile, &Sb) < 0 && errno != ENOENT) {
-            syswarn("cannot stat %s", InputFile);
-           continue;
-       }
-
-       if (!S_ISREG(Sb.st_mode))
-           continue;
-
-       if ((fd = open(InputFile, O_RDWR)) < 0) {
-           if (errno != ENOENT)
-                syswarn("cannot open %s", InputFile);
-           continue;
-       }
-
-       /* Make sure multiple Unspools don't stomp on eachother. */
-       if (!inn_lock_file(fd, INN_LOCK_WRITE, 0)) {
-           close(fd);
-           continue;
-       }
-
-       /* Get UUCP host from spool file, deleting the mktemp XXXXXX suffix. */
-       uuhost = UUCPHost;
-       hostname[0] = 0;
-       if ((i = strlen(InputFile)) > 6) {
-           i -= 6;
-           if (i > sizeof hostname - 1)
-               /* Just in case someone wrote their own spooled file. */
-               i = sizeof hostname - 1;
-           strlcpy(hostname, InputFile, i + 1);
-           UUCPHost = hostname;
-       }
-       ok = UnpackOne(&fd, &i);
-       WaitForChildren(i);
-       UUCPHost = uuhost;
-
-        /* If UnpackOne returned true, the article has been dealt with one way
-           or the other, so remove it.  Otherwise, leave it in place; either
-           we got an unknown error from the server or we got a deferral, and
-           for both we want to try later. */
-       if (ok) {
-            if (unlink(InputFile) < 0)
-                syswarn("cannot remove %s", InputFile);
-        }
-
-       close(fd);
-    }
-    closedir(dp);
-
-    message_handlers_die(1, message_log_syslog_err);
-    message_handlers_warn(1, message_log_syslog_err);
-}
-
-\f
-
-/*
-**  Can't connect to the server, so spool our input.  There isn't much
-**  we can do if this routine fails, unfortunately.  Perhaps try to use
-**  an alternate filesystem?
-*/
-static void
-Spool(int fd, int mode)
-{
-    int spfd;
-    int i;
-    int j;
-    char *tmpspool, *spoolfile, *p;
-    char buff[BUFSIZ];
-    int count;
-    int status;
-
-    if (mode == 'N')
-       exit(9);
-    tmpspool = concat(innconf->pathincoming, "/.",
-               UUCPHost ? UUCPHost : "", "XXXXXX", (char *)0);
-    spfd = mkstemp(tmpspool);
-    if (spfd < 0)
-        sysdie("cannot create temporary batch file %s", tmpspool);
-    if (fchmod(spfd, BATCHFILE_MODE) < 0)
-        sysdie("cannot chmod temporary batch file %s", tmpspool);
-
-    /* Read until we there is nothing left. */
-    for (status = 0, count = 0; (i = read(fd, buff, sizeof buff)) != 0; ) {
-       /* Break out on error. */
-       if (i < 0) {
-            syswarn("cannot read after %d", count);
-           status++;
-           break;
-       }
-       /* Write out what we read. */
-       for (count += i, p = buff; i; p += j, i -= j)
-           if ((j = write(spfd, p, i)) <= 0) {
-                syswarn("cannot write around %d", count);
-               status++;
-               break;
-           }
-    }
-
-    /* Close the file. */
-    if (close(spfd) < 0) {
-        syswarn("cannot close spooled article %s", tmpspool);
-       status++;
-    }
-
-    /* Move temp file into the spool area, and exit appropriately. */
-    spoolfile = concat(innconf->pathincoming, "/",
-               UUCPHost ? UUCPHost : "", "XXXXXX", (char *)0);
-    spfd = mkstemp(spoolfile);
-    if (spfd < 0) {
-        syswarn("cannot create spool file %s", spoolfile);
-        status++;
-    } else {
-        close(spfd);
-        if (rename(tmpspool, spoolfile) < 0) {
-            syswarn("cannot rename %s to %s", tmpspool, spoolfile);
-            status++;
-        }
-    }
-    free(tmpspool);
-    free(spoolfile);
-    exit(status);
-    /* NOTREACHED */
-}
-
-
-/*
-**  Try to read the password file and open a connection to a remote
-**  NNTP server.
-*/
-static bool OpenRemote(char *server, int port, char *buff)
-{
-    int                i;
-
-    /* Open the remote connection. */
-    if (server)
-       i = NNTPconnect(server, port, &FromServer, &ToServer, buff);
-    else
-       i = NNTPremoteopen(port, &FromServer, &ToServer, buff);
-    if (i < 0)
-       return false;
-
-    *buff = '\0';
-    if (NNTPsendpassword(server, FromServer, ToServer) < 0) {
-       int oerrno = errno;
-       fclose(FromServer);
-       fclose(ToServer);
-       errno = oerrno;
-       return false;
-    }
-    return true;
-}
-
-
-/*
-**  Can't connect to server; print message and spool if necessary.
-*/
-static void
-CantConnect(char *buff, int mode, int fd)
-{
-    if (buff[0])
-        notice("rejected connection %s", REMclean(buff));
-    else
-        syswarn("cant open_remote");
-    if (mode != 'U')
-       Spool(fd, mode);
-    exit(1);
-}
-
-
-int main(int ac, char *av[])
-{
-    int                fd;
-    int                i;
-    size_t     count;
-    int                mode;
-    char       buff[SMBUF];
-    int         port = NNTP_PORT;
-
-    /* First thing, set up logging and our identity. */
-    openlog("rnews", L_OPENLOG_FLAGS, LOG_INN_PROG);
-    message_program_name = "rnews";
-    message_handlers_notice(1, message_log_syslog_notice);
-    message_handlers_warn(1, message_log_syslog_err);
-    message_handlers_die(1, message_log_syslog_err);
-
-    /* The reason for the following is somewhat obscure and is done only
-       because rnews is sometimes installed setuid.
-
-       The stderr stream used by message_log_syslog_err is associated with
-       file descriptor 2, generally even if that file descriptor is closed.
-       Someone running rnews may close all of the standard file descriptors
-       before running it, in which case, later in its operations, one of the
-       article files or network connections it has open could be file
-       descriptor 2.  If an error occurs at that point, the error message may
-       be written to that file or network connection instead of to stderr,
-       with unpredictable results.
-
-       We avoid this by burning three file descriptors if the real and
-       effective user IDs don't match, or if we're running as root.  (If they
-       do match, there is no escalation of privileges and at worst the user is
-       just managing to produce a strange bug.) */
-    if (getuid() != geteuid() || geteuid() == 0) {
-        if (open("/dev/null", O_RDONLY) < 0)
-            sysdie("cannot open /dev/null");
-        if (open("/dev/null", O_RDONLY) < 0)
-            sysdie("cannot open /dev/null");
-        if (open("/dev/null", O_RDONLY) < 0)
-            sysdie("cannot open /dev/null");
-    }
-
-    /* Make sure that we switch to the news user if we're running as root,
-       since we may spool files and don't want those files owned by root.
-       Don't require that we be running as the news user, though; there are
-       other setups where rnews might be setuid news or be run by other
-       processes in the news group. */
-    if (getuid() == 0 || geteuid() == 0) {
-        struct passwd *pwd;
-
-        pwd = getpwnam(NEWSUSER);
-        if (pwd == NULL)
-            die("can't resolve %s to a UID (account doesn't exist?)",
-                NEWSUSER);
-        setuid(pwd->pw_uid);
-    }
-
-    if (!innconf_read(NULL))
-        exit(1);
-    UUCPHost = getenv(_ENV_UUCPHOST);
-    PathBadNews = concatpath(innconf->pathincoming, _PATH_BADNEWS);
-    port = innconf->nnrpdpostport;
-
-    umask(NEWSUMASK);
-
-    /* Parse JCL. */
-    fd = STDIN_FILENO;
-    mode = '\0';
-    while ((i = getopt(ac, av, "h:P:NUvr:S:")) != EOF)
-       switch (i) {
-       default:
-           die("usage error");
-           /* NOTRTEACHED */
-       case 'h':
-           UUCPHost = *optarg ? optarg : NULL;
-           break;
-       case 'N':
-       case 'U':
-           mode = i;
-           break;
-       case 'P':
-           port = atoi(optarg);
-           break;
-       case 'v':
-           Verbose = true;
-           break;
-       case 'r':
-       case 'S':
-           remoteServer = optarg;
-           break;
-       }
-    ac -= optind;
-    av += optind;
-
-    /* Parse arguments.  At most one, the input file. */
-    switch (ac) {
-    default:
-        die("usage error");
-       /* NOTREACHED */
-    case 0:
-       break;
-    case 1:
-       if (mode == 'U')
-            die("usage error");
-       if (freopen(av[0], "r", stdin) == NULL)
-            sysdie("cannot freopen %s", av[0]);
-       fd = fileno(stdin);
-       InputFile = av[0];
-       break;
-    }
-
-    /* Open the link to the server. */
-    if (remoteServer != NULL) {
-       if (!OpenRemote(remoteServer,port,buff))
-               CantConnect(buff,mode,fd);
-    } else if (innconf->nnrpdposthost != NULL) {
-       if (!OpenRemote(innconf->nnrpdposthost,
-           (port != NNTP_PORT) ? port : innconf->nnrpdpostport, buff))
-               CantConnect(buff, mode, fd);
-    }
-    else {
-#if    defined(DO_RNEWSLOCALCONNECT)
-       if (NNTPlocalopen(&FromServer, &ToServer, buff) < 0) {
-           /* If server rejected us, no point in continuing. */
-           if (buff[0])
-               CantConnect(buff, mode, fd);
-           if (!OpenRemote((char *)NULL,
-               (port != NNTP_PORT) ? port : innconf->port, buff))
-                       CantConnect(buff, mode, fd);
-       }
-#else
-       if (!OpenRemote((char *)NULL, 
-           (port != NNTP_PORT) ? port : innconf->port, buff))
-               CantConnect(buff, mode, fd);
-#endif /* defined(DO_RNEWSLOCALCONNECT) */
-    }
-    close_on_exec(fileno(FromServer), true);
-    close_on_exec(fileno(ToServer), true);
-
-    /* Execute the command. */
-    if (mode == 'U')
-       Unspool();
-    else {
-       if (!UnpackOne(&fd, &count)) {
-           lseek(fd, 0, 0);
-           Spool(fd, mode);
-       }
-       close(fd);
-       WaitForChildren(count);
-    }
-
-    /* Tell the server we're quitting, get his okay message. */
-    fprintf(ToServer, "quit\r\n");
-    fflush(ToServer);
-    fgets(buff, sizeof buff, FromServer);
-
-    /* Return the appropriate status. */
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/frontends/scanspool.in b/frontends/scanspool.in
deleted file mode 100644 (file)
index 1381c9c..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# @(#)scanspool.pl     1.20 4/6/92 00:47:35
-#
-# Written by:  Landon Curt Noll                (chongo was here  /\../\)
-#
-# This code is placed in the public domain.
-#
-# scanspool - perform a big scan over all articles in /usr/spool/news
-#
-# usage:
-#    scanspool [-a active_file] [-s spool_dir] [-v] [-c] [-n]
-#
-#    -a active_file    active file to use (default /usr/lib/news/active)
-#    -s spool_dir      spool tree (default /usr/spool/news)
-#    -v                verbose mode
-#                      verbose messages begin with a tab
-#                      show articles found in non-active directories
-#    -c                        check article filenames, don't scan the articles
-#    -n                        don't throttle innd
-#
-# NOTE: This take a while, -v is a good thing if you want to know
-#      how far this program has progressed.
-#
-# This program will scan first the active file, noting problems such as:
-#
-#      malformed line
-#      group aliased to a non-existent group
-#      group aliased to a group tat is also aliased
-#
-# Then it will examine all articles under your news spool directory,
-# looking for articles that:
-#
-#      basename that starts with a leading 0
-#      basename that is out of range with the active file
-#      does not contain a Newsgroups: line
-#      article that is all header and no text
-#      is in a directory for which there is no active group
-#      article that is in a group to which it does not belong
-#
-# Scanspool understands aliased groups.  Thus, if an article is posted
-# to foo.old.name that is aliases to foo.bar, it will be expected to
-# be found under foo.bar and not foo.old.name.
-#
-# Any group that is of type 'j' or 'x' (4th field of the active file)
-# will be allowed to show up under the junk group.
-#
-# Scanspool assumes that the path of a valid newsgroup's directory
-# from the top of the spool tree will not contain any "." character.
-# Thus, directories such as out.going, tmp.dir, in.coming and
-# news.archive will not be searched.  This program also assumes that
-# article basenames contain only decimal digits.  Last, files under
-# the top level directory "lost+found" are not scanned.
-#
-# The output of scanspool will start with one of 4 forms:
-#
-#    FATAL:        fatal or internal error                     (to stderr)
-#
-#    WARN:         active or article format problem,           (to stderr)
-#                  group alias problem, find error,
-#                  article open error
-#
-#    path/123:     basename starts with 0,                     (to stdout)
-#                  article number out of range,
-#                  article in the wrong directory,
-#                  article in directory not related to
-#                      an active non-aliases newsgroup
-#
-#    \t ...        verbose message starting with a tab         (to stdout)
-
-
-# Data structures
-#
-# $gname2type{$name}
-#    $name     - newsgroup name in foo.dot.form
-#    produces  => 4th active field  (y, n, x, ...)
-#                alias type is "=", not "=foo.bar"
-#
-# $realgname{$name}
-#    $name      - newsgroup name in foo.dot.form
-#    produces  => newsgroup name in foo.dot.form
-#                if type is =, this will be a.b, not $name
-#
-# $lowart{$name}
-#    $name      - newsgroup name in foo.dot.form
-#    produces  => lowest article allowed in the group
-#                if type is =, this is not valid
-#
-# $highart{$name}
-#    $name      - newsgroup name in foo.dot.form
-#    produces  => highest article allowed in the group
-#                if type is =, this is not valid
-#                If $highart{$name} < $lowart{$name},
-#                then the group should be empty
-
-# perl requirements
-#
-require "getopts.pl";
-
-# setup non-buffered stdout and stderr
-#
-select(STDERR);
-$|=1;
-select(STDOUT);
-$|=1;
-
-# global constants
-#
-$prog = $0;                            # our name
-$spool = "$inn::patharticles";
-$active = "$inn::pathdb/active";
-$ctlinnd = "$inn::pathbin/ctlinnd";
-$reason = "running scanspool";         # throttle reason
-
-# parse args
-#
-&Getopts("a:s:vcn");
-$active = $opt_a if (defined($opt_a));
-$spool = $opt_s if (defined($opt_s));
-
-# throttle innd unless -n
-#
-if (! defined($opt_n)) {
-    system("$ctlinnd throttle '$reason' >/dev/null 2>&1");
-}
-
-# process the active file
-#
-&parse_active($active);
-
-# check the spool directory
-#
-&check_spool($spool);
-
-# unthrottle innd unless -n
-#
-if (! defined($opt_n)) {
-    system("$ctlinnd go '$reason' >/dev/null 2>&1");
-}
-
-# all done
-exit(0);
-
-
-# parse_active - parse the active file
-#
-# From the active file, fill out the @gname2type (type of newsgroup)
-# and @realgname (real/non-aliased name of group), @lowart & @highart
-# (low and high article numbers).  This routine will also check for
-# aliases to missing groups or groups that are also aliases.
-#
-sub parse_active
-{
-    local ($active) = $_[0];   # the name of the active file to use
-    local (*ACTIVE);           # active file handle
-    local ($line);             # active file line
-    local ($name);             # name of newsgroup
-    local ($low);              # low article number
-    local ($high);             # high article number
-    local ($type);             # type of newsgroup (4th active field)
-    local ($field5);           # 5th active field (should not exist)
-    local ($dir);              # directory path of group from $spool
-    local ($alias);            # realname of an aliased group
-    local ($linenum);          # active file line number
-
-    # if verbose (-v), say what we are doing
-    print "\tscanning $active\n" if defined($opt_v);
-
-    # open the active file
-    open (ACTIVE, $active) || &fatal(1, "cannot open $active");
-
-    # parse each line
-    $linenum = 0;
-    while ($line = <ACTIVE>) {
-
-       # count the line
-       ++$linenum;
-
-       # verify that we have a correct number of tokens
-       if ($line !~ /^\S+ 0*(\d+) 0*(\d+) \S+$/o) {
-           &problem("WARNING: active line is mal-formed at line $linenum");
-           next;
-       }
-       ($name, $high, $low, $type) = $line =~ /^(\S+) 0*(\d+) 0*(\d+) (\S+)$/o;
-
-       # watch for duplicate entries
-       if (defined($realgname{$name})) {
-           &problem("WARNING: ignoring dup group: $name, at line $linenum");
-           next;
-       }
-
-       # record which type it is
-       $gname2type{$name} = $type;
-
-       # record the low and high article numbers
-       $lowart{$name} = $low;
-       $highart{$name} = $high;
-
-       # determine the directory and real group name
-       if ($type eq "j" || $type eq "x") {
-           $dir = "junk";
-           $alias = $name;
-       } elsif ($type =~ /^=(.+)/o) {
-           $alias = $1;
-           ($dir = $alias) =~ s#\.#/#go;
-           $gname2type{$name} = "=";   # rename type to be just =
-       } else {
-           $dir = $name;
-           $dir =~ s#\.#/#go;
-           $alias = $name;
-       }
-       $realgname{$name} = $alias;
-    }
-
-    # close the active file
-    close (ACTIVE);
-
-    # be sure that any alias type is aliased to a real group
-    foreach $name (keys %realgname) {
-
-       # skip if not an alias type
-       next if $gname2type{$name} ne "=";
-
-       # be sure that the alias exists
-       $alias = $realgname{$name};
-       if (! defined($realgname{$alias})) {
-           &problem("WARNING: alias for $name: $alias, is not a group");
-           next;
-       }
-
-       # be sure that the alias is not an alias of something else
-       if ($gname2type{$alias} eq "=") {
-           &problem("WARNING: alias for $name: $alias, is also an alias");
-           next;
-       }
-    }
-}
-
-
-# problem - report a problem to stdout
-#
-# Print a message to stdout.  Parameters are space separated.
-# A final newline is appended to it.
-#
-# usage:
-#      &problem(arg, arg2, ...)
-#
-sub problem
-{
-    local ($line);             # the line to write
-
-    # print the line with the header and newline
-    $line = join(" ", @_);
-    print STDERR $line, "\n";
-}
-
-
-# fatal - report a fatal error to stderr and exit
-#
-# Print a message to stderr.  The message has the program name prepended
-# to it.  Parameters are space separated.  A final newline is appended
-# to it.  This function exists with the code of exitval.
-#
-# usage:
-#      &fatal(exitval, arg, arg2, ...)
-#
-sub fatal
-{
-    local ($exitval) = $_[0];  # what to exit with
-
-    # firewall
-    if ($#_ < 1) {
-       print STDERR "FATAL: fatal called with only ", $#_-1, " arguments\n";
-       if ($#_ < 0) {
-           $exitval = -1;
-       }
-    }
-
-    # print the error message
-    shift(@_);
-    $line = join(" ", @_);
-    print STDERR "$prog: ", $line, "\n";
-
-    # unthrottle innd unless -n
-    #
-    if (! defined($opt_n)) {
-       system("$ctlinnd go '$reason' >/dev/null 2>&1");
-    }
-
-    # exit
-    exit($exitval);
-}
-
-
-# check_spool - check the articles found in the spool directory
-#
-# This subroutine will check all articles found under the $spool directory.
-# It will examine only file path that do not contain any "." or whitespace
-# character, and whose basename is completely numeric.  Files under
-# lost+found will also be ignored.
-#
-# given:
-#      $spooldir  - top of /usr/spool/news article tree
-#
-sub check_spool
-{
-    local ($spooldir) = $_[0]; # top of article tree
-    local (*FILEFILE);         # pipe from the find files process
-    local ($filename);         # article pathname under $spool
-    local ($artgrp);           # group of an article
-    local ($artnum);           # article number in a group
-    local ($prevgrp);          # previous different value of $artgrp
-    local ($preverrgrp);       # previous non-active $artgrp
-    local (*ARTICLE);          # article handle
-    local ($aline);            # header line from an article
-    local (@group);            # array of groups from the Newsgroup header
-    local ($j);
-
-    # if verbose, say what we are doing
-    print "\tfinding articles under $spooldir\n" if defined($opt_v);
-
-    # move to the $spool directory
-    chdir $spooldir || &fatal(2, "cannot chdir to $spool");
-
-    # start finding files
-    #
-    if (!open (FINDFILE,
-         "find . \\( -type f -o -type l \\) -name '[0-9]*' -print 2>&1 |")) {
-       &fatal(3, "cannot start find in $spool");
-    }
-
-    # process each history line
-    #
-    while ($filename = <FINDFILE>) {
-
-       # if the line contains find:, assume it is a find error and print it
-       chop($filename);
-       if ($filename =~ /find:\s/o) {
-           &problem("WARNING:", $filename);
-           next;
-       }
-
-       # remove the \n and ./ that find put in our path
-       $filename =~ s#^\./##o;
-
-       # skip is this path has a . in it (beyond a leading ./)
-       next if ($filename =~ /\./o);
-
-       # skip if lost+found
-       next if ($filename =~ m:^lost+found/:o);
-
-       # skip if not a numeric basename
-       next if ($filename !~ m:/\d+$:o);
-
-       # get the article's newsgroup name (based on its path from $spool)
-       $artgrp = $filename;
-       $artgrp =~ s#/\d+$##o;
-       $artgrp =~ s#/#.#go;
-
-       # if verbose (-v), then note if our group changed
-       if (defined($opt_v) && $artgrp ne $prevgrp) {
-           print "\t$artgrp\n";
-           $prevgrp = $artgrp;
-       }
-
-       # note if the article is not in a directory that is used by
-       # a real (non-aliased) group in the active file
-       #
-       # If we complained about this dgroup before, don't complain again.
-       # If verbose, note files that could be removed.
-       #
-       if (!defined($gname2type{$artgrp}) || $gname2type{$artgrp} =~ /[=jx]/o){
-           if ($preverrgrp ne $artgrp) {
-               &problem("$artgrp: not an active group directory");
-               $preverrgrp = $artgrp;
-           }
-           if (defined($opt_v)) {
-               &problem("$filename: article found in non-active directory");
-           }
-           next;
-       }
-
-       # check on the article number
-       $artnum = $filename;
-       $artnum =~ s#^.+/##o;
-       if ($artnum =~ m/^0/o) {
-           &problem("$filename: article basename starts with a 0");
-       }
-       if (defined($gname2type{$artgrp})) {
-           if ($lowart{$artgrp} > $highart{$artgrp}) {
-               &problem("$filename: active indicates group should be empty");
-           } elsif ($artnum < $lowart{$artgrp}) {
-               &problem("$filename: article number is too low");
-           } elsif ($artnum > $highart{$artgrp}) {
-               &problem("$filename: article number is too high");
-           }
-       }
-
-       # if check filenames only (-c), then do nothing else with the file
-       next if (defined($opt_c));
-
-       # don't open a control or junk, they can be from anywhere
-       next if ($artgrp eq "control" || $artgrp eq "junk");
-
-       # try open the file
-       if (!open(ARTICLE, $filename)) {
-
-           # the find is now gone (expired?), give up on it
-           &problem("WARNING: cannot open $filename");
-           next;
-       }
-
-       # read until the Newsgroup header line is found
-       AREADLINE:
-       while ($aline = <ARTICLE>) {
-
-           # catch the newsgroup: header
-           if ($aline =~ /^Newsgroups:\w*\W/io) {
-
-               # convert $aline into a comma separated list of groups
-               $aline =~ s/^Newsgroups://io;
-               $aline =~ tr/ \t\n//d;
-
-               # form an array of news groups
-               @group = split(",", $aline);
-
-               # see if any groups in the Newsgroup list are our group
-               for ($j=0; $j <= $#group; ++$j) {
-
-                   # look at the group
-                   if ($realgname{$group[$j]} eq $artgrp) {
-                       # this article was posted to this group
-                       last AREADLINE;
-                   }
-               }
-
-               # no group or group alias was found
-               &problem("$filename: does not belong in $artgrp");
-               last;
-
-           # else watch for the end of the header
-           } elsif ($aline =~ /^\s*$/o) {
-
-               # no Newsgroup: header found
-               &problem("WARNING: $filename: no Newsgroup header");
-               last;
-           }
-           if (eof(ARTICLE)) {
-               &problem("WARNING: $filename: EOF found while reading header");
-           }
-       }
-
-       # close the article
-       close(ARTICLE);
-    }
-
-    # all done with the find
-    close(FINDFILE);
-}
diff --git a/frontends/sm.c b/frontends/sm.c
deleted file mode 100644 (file)
index a3017c4..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*  $Id: sm.c 6682 2004-03-06 18:31:15Z rra $
-**
-**  Provide a command line interface to the storage manager
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "storage.h"
-
-static const char usage[] = "\
-Usage: sm [-dHiqrRS] [token ...]\n\
-\n\
-Command-line interface to the INN storage manager.  The default action is\n\
-to display the complete article associated with each token given.  If no\n\
-tokens are specified on the command line, they're read from stdin, one per\n\
-line.\n\
-\n\
-    -d, -r      Delete the articles associated with the given tokens\n\
-    -H          Display the headers of articles only\n\
-    -i          Translate tokens into newsgroup names and article numbers\n\
-    -q          Suppress all error messages except usage\n\
-    -R          Display the raw article rather than undoing wire format\n\
-    -S          Output articles in rnews batch file format\n";
-
-/* The options that can be set on the command line, used to determine what to
-   do with each token. */
-struct options {
-    bool artinfo;               /* Show newsgroup and article number. */
-    bool delete;                /* Delete articles instead of showing them. */
-    bool header;                /* Display article headers only. */
-    bool raw;                   /* Show the raw wire-format articles. */
-    bool rnews;                 /* Output articles as rnews batch files. */
-};
-
-
-/*
-**  Process a single token, performing the operations specified in the given
-**  options struct.  Calls warn and die to display error messages; -q is
-**  implemented by removing all the warn and die error handlers.
-*/
-static bool
-process_token(const char *id, const struct options *options)
-{
-    TOKEN token;
-    struct artngnum artinfo;
-    ARTHANDLE *article;
-    size_t length;
-    char *text;
-
-    if (!IsToken(id)) {
-        warn("%s is not a storage token", id);
-        return false;
-    }
-    token = TextToToken(id);
-
-    if (options->artinfo) {
-        if (!SMprobe(SMARTNGNUM, &token, &artinfo)) {
-            warn("could not get article information for %s", id);
-            return false;
-        } else {
-            printf("%s: %lu\n", artinfo.groupname, artinfo.artnum);
-            free(artinfo.groupname);
-        }
-    } else if (options->delete) {
-        if (!SMcancel(token)) {
-            warn("could not remove %s: %s", id, SMerrorstr);
-            return false;
-        }
-    } else {
-        article = SMretrieve(token, options->header ? RETR_HEAD : RETR_ALL);
-        if (article == NULL) {
-            warn("could not retrieve %s", id);
-            return false;
-        }
-        if (options->raw) {
-            if (fwrite(article->data, article->len, 1, stdout) != 1)
-                die("output failed");
-        } else {
-            text = FromWireFmt(article->data, article->len, &length);
-            if (options->rnews)
-                printf("#! rnews %lu\n", (unsigned long) length);
-            if (fwrite(text, length, 1, stdout) != 1)
-                die("output failed");
-            free(text);
-        }
-        SMfreearticle(article);
-    }
-    return true;
-}
-
-
-int
-main(int argc, char *argv[])
-{
-    int option;
-    bool okay, status;
-    struct options options = { false, false, false, false, false };
-
-    message_program_name = "sm";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    while ((option = getopt(argc, argv, "iqrdRSH")) != EOF) {
-        switch (option) {
-        case 'd':
-        case 'r':
-            options.delete = true;
-            break;
-        case 'H':
-            options.header = true;
-            break;
-        case 'i':
-            options.artinfo = true;
-            break;
-        case 'q':
-            message_handlers_warn(0);
-            message_handlers_die(0);
-            break;
-        case 'R':
-            options.raw = true;
-            break;
-        case 'S':
-            options.rnews = true;
-            break;
-        default:
-            fprintf(stderr, usage);
-            exit(1);
-        }
-    }
-
-    /* Check options for consistency. */
-    if (options.artinfo && options.delete)
-        die("-i cannot be used with -r, -d");
-    if (options.artinfo && (options.header || options.raw || options.rnews))
-        die("-i cannot be used with -H, -R, or -S");
-    if (options.delete && (options.header || options.rnews))
-        die("-r or -d cannot be used with -H or -S");
-    if (options.raw && options.rnews)
-        die("-R cannot be used with -S");
-    if (options.header && options.rnews)
-        die("-H cannot be used with -S");
-
-    /* Initialize the storage manager.  If we're doing article deletions, we
-       need to open it read/write. */
-    if (options.delete) {
-        bool value = true;
-
-        if (!SMsetup(SM_RDWR, &value))
-            die("cannot set up storage manager");
-    }
-    if (!SMinit())
-        die("cannot initialize storage manager: %s", SMerrorstr);
-
-    /* Process tokens.  If no arguments were given on the command line,
-       process tokens from stdin.  Otherwise, walk through the remaining
-       command line arguments. */
-    okay = true;
-    if (optind == argc) {
-        QIOSTATE *qp;
-        char *line;
-
-        qp = QIOfdopen(fileno(stdin));
-        for (line = QIOread(qp); line != NULL; line = QIOread(qp)) {
-            status = process_token(line, &options);
-            okay = okay && status;
-        }
-        if (QIOerror(qp)) {
-            if (QIOtoolong(qp))
-                die("input line too long");
-            sysdie("error reading stdin");
-        }
-        QIOclose(qp);
-    } else {
-        int i;
-
-        for (i = optind; i < argc; i++) {
-            status = process_token(argv[i], &options);
-            okay = okay && status;
-        }
-    }
-
-    SMshutdown();
-    exit(okay ? 0 : 1);
-}
diff --git a/frontends/sys2nf.c b/frontends/sys2nf.c
deleted file mode 100644 (file)
index 2d949a9..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*  $Id: sys2nf.c 7741 2008-04-06 09:51:47Z iulius $
-**
-**  Read a C news "sys" file and split it up into a set of INN
-**  newsfeeds entries.  Also works with B news.
-**
-**  Once done, edit all files that have HELP or all in them.
-**  Review all files, anyway.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-
-#define TEMPFILE       ":tmp"
-static char            **Groups;
-
-
-/*
-**  Fill in the Groups array with the names of all active newsgroups.
-*/
-static void
-ReadActive(act)
-    char       *act;
-{
-    FILE       *F;
-    int                i;
-    char       buff[BUFSIZ];
-    char       *p;
-
-    /* Open file, count lines. */
-    if ((F = fopen(act, "r")) == NULL) {
-       perror(act);
-       exit(1);
-    }
-    for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
-       continue;
-    Groups = xmalloc((i + 2) * sizeof(char *));
-
-    /* Fill in each word. */
-    rewind(F);
-    for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++) {
-       if ((p = strchr(buff, ' ')) != NULL)
-           *p = '\0';
-       Groups[i] = xstrdup(buff);
-    }
-    Groups[i] = NULL;
-    fclose(F);
-}
-
-
-/*
-**  Read in the sys file and turn it into an array of strings, one
-**  per continued line.
-*/
-char **
-ReadSys(sys)
-    char               *sys;
-{
-    char       *p;
-    char       *to;
-    char       *site;
-    int        i;
-    char               *data;
-    char               **strings;
-
-    /* Read in the file, get rough count. */
-    if ((data = ReadInFile(sys, (struct stat *)NULL)) == NULL) {
-       perror(sys);
-       exit(1);
-    }
-    for (p = data, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
-       continue;
-
-    /* Scan the file, glue all multi-line entries. */
-    for (strings = xmalloc((i + 1) * sizeof(char *)), i = 0, to = p = data; *p; ) {
-       for (site = to; *p; ) {
-           if (*p == '\n') {
-               p++;
-               *to = '\0';
-               break;
-           }
-           if (*p == '\\' && p[1] == '\n')
-               while (*++p && CTYPE(isspace, *p))
-                   continue;
-           else
-               *to++ = *p++;
-       }
-       *to++ = '\0';
-       if (*site == '\0')
-           continue;
-       strings[i++] = xstrdup(site);
-    }
-    strings[i] = NULL;
-    free(data);
-    return strings;
-}
-
-
-/*
-**  Is this the name of a top-level group?  We want a simple name, "foo",
-**  and should find a "foo." in the group list.
-*/
-static bool
-Toplevel(p)
-    char       *p;
-{
-    char       **gp;
-    char       *g;
-    int                i;
-
-    if (strchr(p, '.') != NULL)
-       return false;
-    for (i = strlen(p) - 1, gp = Groups; (g = *gp++) != NULL; )
-       if (strncmp(p, g, i) == 0 && g[i + 1] == '.')
-           return true;
-    return false;
-}
-
-
-/*
-**  Do we have a name that's a prefix for more then one newsgroup?
-**  For "foo.bar", we must find more then one "foo.bar" or "foo.bar."
-*/
-static bool
-GroupPrefix(p)
-    char       *p;
-{
-    char       **gp;
-    char       *g;
-    int                count;
-    int                i;
-
-    if (strchr(p, '.') == NULL)
-       return false;
-    for (i = strlen(p), count = 0, gp = Groups; (g = *gp++) != NULL; )
-       if (strcmp(p, g) == 0 || (strncmp(p, g, i) == 0 && g[i] == '.'))
-           count++;
-    return count > 1;
-}
-
-
-/*
-**  Step through the old subscription list, try to update each one in
-**  turn.
-*/
-static void
-DoSub(F, p)
-    FILE       *F;
-    char               *p;
-{
-    char       *s;
-    int        len, i;
-    bool matched;
-    bool       SawBang;
-    bool       SawAll;
-
-    /* Distributions, not newsgroups. */
-    static const char * const distributions[] = {
-        "world", "na", "usa", "inet", "mod", "net", "local"
-    };
-
-    /* Newsgroup hierarchies. */
-    static const char * const hierarchies[] = {
-        "comp", "misc", "news", "rec", "sci", "soc", "talk", "alt", "bionet",
-        "bit", "biz", "clari", "ddn", "gnu", "ieee", "k12", "pubnet", "trial",
-        "u3b", "vmsnet",
-
-        "ba", "ca", "dc", "ne", "ny", "tx",
-
-        "info", "mail", "opinions", "uunet"
-    }
-
-    if ((s = strtok(p, ",")) == NULL)
-       return;
-
-    fprintf(F, "!*");
-    len = 8 + 1 + 2;
-    do {
-        for (matched = false, i = 0; i < ARRAY_SIZE(distributions); i++)
-            if (strcmp(s, distributions[i]) == 0) {
-                matched = true;
-                break;
-            }
-        if (matched)
-            continue;
-
-       if (innconf->mergetogroups)
-           if (strcmp(s, "!to") == 0 || strncmp(s, "to.", 3) == 0)
-               continue;
-
-       putc(',', F);
-       len++;
-
-       if (len + strlen(s) + 3 > 72) {
-           fprintf(F,"\\\n\t    ");
-           len = 12;
-       }
-
-       SawBang = *s == '!';
-       if (SawBang) {
-           putc('!', F);
-           len++;
-           s++;
-       }
-
-       SawAll = (strcmp(s, "all") == 0);
-       if (SawAll)
-           s = SawBang ? "*" : "*,!control,!control.*";
-       len += strlen(s);
-       fprintf(F, "%s", s);
-
-       if (SawAll)
-           ;
-       else {
-            for (matched = false, i = 0; i < ARRAY_SIZE(distributions); i++)
-                if (strcmp(s, hierarchies[i]) == 0) {
-                    matched = true;
-                    break;
-                }
-
-            if (matched) {
-                fprintf(F, ".*");
-                len += 2;
-            } else if (GroupPrefix(s)) {
-                putc('*', F);
-                len++;
-            }
-        }
-    } while ((s = strtok((char *)NULL, ",")) != NULL);
-}
-
-
-int
-main(ac, av)
-    int                 ac;
-    char       *av[];
-{
-    FILE       *F;
-    FILE       *out;
-    char       **sites;
-    char       *f2;
-    char       *f3;
-    char       *f4;
-    char       *p;
-    char       *q;
-    char       *site;
-    char       buff[256];
-    char       *act;
-    char       *dir;
-    char       *sys;
-    int                i;
-
-    if (!innconf_read(NULL))
-        exit(1);
-    /* Set defaults. */
-    act = "/usr/local/lib/newslib/active";
-    sys = "sys";
-    dir = "feeds";
-    while ((i = getopt(ac, av, "a:s:d:")) != EOF)
-    switch (i) {
-    default:
-       exit(1);
-       /* NOTREACHED */
-    case 'a':  act = optarg;   break;
-    case 'd':  dir = optarg;   break;
-    case 's':  sys = optarg;   break;
-    }
-
-    sites = ReadSys(sys);
-    ReadActive(act);
-    if (mkdir(dir, 0777) < 0 && errno != EEXIST)
-       perror(dir), exit(1);
-    if (chdir(dir) < 0)
-       perror("chdir"), exit(1);
-    for ( ; ; ) {
-       /* Get next non-comment ilne. */
-       if ((p = *sites++) == NULL)
-           break;
-       for (F = fopen(TEMPFILE, "w"); p && *p == '#'; p = *sites++)
-           fprintf(F, "%s\n", p);
-       if (p == NULL) {
-           fclose(F);
-           break;
-       }
-       site = xstrdup(p);
-       if ((f2 = strchr(site, ':')) == NULL)
-           f2 = "HELP";
-       else
-           *f2++ = '\0';
-       if ((f3 = strchr(f2, ':')) == NULL)
-           f3 = "HELP";
-       else
-           *f3++ = '\0';
-       if ((f4 = strchr(f3, ':')) == NULL)
-           f4 = "HELP";
-       else
-           *f4++ = '\0';
-
-       /* Write the fields. */
-       fprintf(F, "%s\\\n", site);
-       fprintf(F, "\t:");
-       DoSub(F, f2);
-       fprintf(F, "\\\n");
-       if (strcmp(f3, "n") == 0)
-           fprintf(F, "\t:Tf,Wnm\\\n", f3);
-       else
-           fprintf(F, "\t:HELP%s\\\n", f3);
-       fprintf(F, "\t:%s\n", f4);
-       if (ferror(F) || fclose(F) == EOF)
-           perror(TEMPFILE), exit(1);
-
-       free(site);
-
-       /* Find the sitename. */
-       for (q = p; *q && *q != '/' && *q != ':'; q++)
-           continue;
-       *q = '\0';
-
-       /* Append temp file to site file. */
-       if ((F = fopen(TEMPFILE, "r")) == NULL)
-           perror(TEMPFILE), exit(1);
-       if ((out = xfopena(p)) == NULL)
-           perror(p), exit(1);
-       while ((i = fread(buff, 1, sizeof buff, F)) > 0)
-           if (fwrite(buff, 1, i, out) != i)
-               perror(p), exit(1);
-       fclose(F);
-       if (fclose(out) == EOF)
-           perror(p), exit(1);
-
-       if (unlink(TEMPFILE) < 0)
-           perror("can't unlink temp file");
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
diff --git a/history/Make.methods b/history/Make.methods
deleted file mode 100644 (file)
index f422c81..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is automatically generated by buildconfig
-
-METHOD_SOURCES  = hisv6/hisv6.c
-EXTRA_SOURCES   =
-PROGRAMS        =
diff --git a/history/Makefile b/history/Makefile
deleted file mode 100644 (file)
index 404cc24..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top           = ..
-CFLAGS        = $(GCFLAGS) -I.
-
-SOURCES       = his.c hismethods.c $(METHOD_SOURCES)
-OBJECTS       = $(SOURCES:.c=.o)
-LOBJECTS      = $(OBJECTS:.o=.lo)
-
-.SUFFIXES: .lo
-
-all: library programs
-
-# Included here after the all target, since additional rules are defined in
-# Make.methods to be sure that we recurse properly to build the methods.
-include Make.methods
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPUB) libinnhist.$(EXTLIB) $(D)$(PATHLIB)/libinnhist.$(EXTLIB)
-
-library: libinnhist.$(EXTLIB)
-
-programs: $(PROGRAMS)
-
-clobber clean distclean:
-       rm -f *.o *.lo */*.o */*.lo libinnhist.la libinnhist.a
-       rm -f libinnhist_pure_*.a .pure $(PROGRAMS)
-       rm -f buildconfig hismethods.c hismethods.h
-       rm -f profiled libinnhist$(PROFSUFFIX).a
-       rm -rf .libs */.libs
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES) ../include/*.h
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-libinnhist.la: $(OBJECTS) $(LIBSTORAGE) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(LOBJECTS) \
-           $(LIBSTORAGE) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS) \
-           -rpath $(PATHLIB) -version-info 2:0:0
-
-libinnhist.a: $(OBJECTS)
-       ar r $@ $(OBJECTS)
-       $(RANLIB) libinnhist.a
-
-# Try to set up these rules so that buildconfig is only run once.
-# Make.methods is included in the distribution tarball since some non-GNU
-# makes can't deal with including a non-existent file, so don't depend on
-# it.  The dependencies aren't entirely accurate; you really want to re-run
-# buildconfig each time a new subdirectory is added to the directory.  But
-# adding a dependency on . is a bit too non-portable for my taste and causes
-# too many rebuilds.
-Make.methods hismethods.h: hismethods.c buildconfig
-hismethods.c: buildconfig
-       ./buildconfig
-
-buildconfig: buildconfig.in $(FIXSCRIPT)
-       $(FIXSCRIPT) -i buildconfig.in
-
-.c.o .c.lo:
-       $(LIBCC) $(CFLAGS) $(CCOUTPUT)
-
-$(LIBINN):      ; (cd ../lib ; $(MAKE))
-$(LIBSTORAGE): ; (cd ../storage ; $(MAKE) library)
-
-
-##  Profiling.  The rules are a bit brute-force, but good enough.
-
-profiled: libinnhist$(PROFSUFFIX).a
-       date >$@
-
-libinnhist$(PROFSUFFIX).a: $(SOURCES)
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) libinnhist.a
-       mv libinnhist.a libinnhist$(PROFSUFFIX).a
-       $(RANLIB) libinnhist$(PROFSUFFIX).a
-       rm -f $(OBJECTS)
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend:        $(SOURCES) $(EXTRA_SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES) $(EXTRA_SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-his.o: his.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h ../include/inn/history.h \
-  ../include/inn/defines.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/storage.h \
-  hisinterface.h hismethods.h
-hismethods.o: hismethods.c hisinterface.h ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h hismethods.h \
-  hisv6/hisv6.h
-hisv6/hisv6.o: hisv6/hisv6.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  hisinterface.h ../include/config.h hisv6/hisv6.h hisv6/hisv6-private.h \
-  ../include/inn/history.h ../include/inn/defines.h ../include/storage.h \
-  ../include/libinn.h ../include/dbz.h ../include/libinn.h \
-  ../include/inn/innconf.h ../include/inn/timer.h ../include/inn/qio.h \
-  ../include/inn/sequence.h ../include/inndcomm.h
diff --git a/history/buildconfig.in b/history/buildconfig.in
deleted file mode 100644 (file)
index 24ae7d5..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-#! /usr/bin/perl
-
-##  $Id: buildconfig.in 6806 2004-05-18 01:18:57Z rra $
-##
-##  Generate linkage code and makefiles for storage and overview methods.
-##
-##  Goes through all subdirectories of the current directory and finds
-##  directories that history methods or overview methods.  Builds
-##  hismethods.[ch] as well as makefile stubs.
-
-require 5.003;
-
-use strict;
-use vars qw(@HISTORY);
-
-# History API functions.
-@HISTORY = qw(open close sync lookup check write replace expire walk remember
-              ctl);
-
-# Used to make heredocs more readable.
-sub unquote { my ($string) = @_; $string =~ s/^:( {0,7}|\t)//gm; $string }
-
-# Parse a hismethod.config file for a history method, putting information
-# about that history method into the given hash ref.
-sub parse_config {
-    my ($dir, $file, $config) = @_;
-    local $_;
-    $$config{sources} ||= [];
-    $$config{extra} ||= [];
-    $$config{programs} ||= [];
-    $$config{makefiles} ||= [];
-    open (CONFIG, "$dir/$file") or die "Can't open $dir/$file: $!\n";
-    while (<CONFIG>) {
-        s/^\s+//;
-        s/\s+$//;
-        if (/^name\s*=\s*(\S+)$/) {
-            my $method = $1;
-            die "$dir/$file: $method has already been defined\n"
-                if (defined $$config{method}{$method});
-            $$config{method}{$method} = $dir;
-        } elsif (/^number\s*=\s*(\d+)$/) {
-            my $number = $1;
-            if (defined $$config{number}{$number}) {
-                die "$dir/$file: method number $number was already "
-                    . "allocated in $$config{number}{$number}\n";
-            }
-            $$config{number}{$dir} = $number;
-        } elsif (/^sources\s*=\s*(.*)/) {
-            my $sources = $1;
-            my @sources = split (' ', $sources);
-            push (@{ $$config{sources} }, map { "$dir/$_" } @sources);
-        } elsif (/^extra-sources\s*=\s*(.*)/) {
-            my $extra = $1;
-            my @extra = split (' ', $extra);
-            push (@{ $$config{extra} }, map { "$dir/$_" } @extra);
-        } elsif (/^programs\s*=\s*(.*)/) {
-            my $programs = $1;
-            my @programs = split (' ', $programs);
-            push (@{ $$config{programs} }, map { "$dir/$_" } @programs);
-        } else {
-            warn "$dir/$file: ignoring unknown line: $_\n";
-        }
-    }
-
-    # If there is a makefile fragment in the directory, note it.
-    if (-f "$dir/hismethod.mk") {
-        push (@{ $$config{makefiles} }, "$dir/hismethod.mk");
-    }
-}
-
-# Write out include directives for a list of files.
-sub write_includes {
-    my ($fh, $config) = @_;
-    my $method;
-    for $method (sort keys %{ $$config{method} }) {
-        my $path = $$config{method}{$method};
-        print $fh qq(\#include "$path/$method.h"\n);
-    }
-}
-
-# Write out the method struct.
-sub write_methods {
-    my ($fh, $config, $prefix, @funcs) = @_;
-    my ($notfirst, $method);
-    for $method (sort keys %{ $$config{method} }) {
-        print $fh "\n},\n" if $notfirst;
-        print $fh qq(\{\n    "$method");
-        print $fh ', ', $prefix, '_', uc ($method) if $prefix;
-        for (@funcs) {
-            print $fh ",\n    ${method}_$_";
-        }
-        $notfirst++;
-    }
-    print $fh "\n}\n};\n\n";
-}
-
-# Write out hismethods.c and hismethods.h for the interface to the history
-# methods.
-sub write_history {
-    my $history = shift;
-    open (DEF, '> hismethods.c.new')
-        or die "Can't create hismethods.c.new: $!\n";
-    print DEF unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig. */
-:
-:       #include "hisinterface.h"
-:       #include "hismethods.h"
-EOE
-    my $method;
-    write_includes (\*DEF, $history);
-    print DEF "\nHIS_METHOD his_methods[",
-        scalar (keys %{ $$history{method} }), "] = {\n";
-    write_methods (\*DEF, $history, undef, @HISTORY);
-    close DEF;
-    rename ('hismethods.c.new', 'hismethods.c');
-
-    open (H, '> hismethods.h.new') or die "Can't open hismethods.h.new: $!\n";
-    print H unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig */
-:
-:       #ifndef HISMETHODS_H
-:       #define HISMETHODS_H 1
-:
-:       #include "hisinterface.h"
-:
-EOE
-    print H '#define NUM_HIS_METHODS ',
-        scalar (keys %{ $$history{method} }), "\n";
-    print H unquote (<<'EOE');
-:
-:       extern HIS_METHOD his_methods[NUM_HIS_METHODS];
-:
-:       #endif /* HISMETHODS_H */
-EOE
-    close H;
-    rename ('hismethods.h.new', 'hismethods.h');
-}
-
-# Return a string setting a makefile variable.  Tab over the = properly and
-# wrap to fit our coding standards.
-sub makefile_var {
-    my ($variable, @values) = @_;
-    my $output;
-    $output = sprintf ("%-15s =", $variable);
-    my $column = 17;
-    for (@values) {
-        if ($column > 17 && 77 - $column < length ($_)) {
-            $output .= " \\\n" . ' ' x 17;
-            $column = 17;
-        }
-        $output .= " $_";
-        $column += 1 + length ($_);
-    }
-    $output .= "\n";
-    return $output;
-}
-
-# Write out the makefile fragment for history methods.
-sub write_makefile {
-    my ($dirs, $sources, $extra, $programs, $makefiles) = @_;
-    open (MAKE, '> Make.methods.new')
-        or die "Can't create Make.methods.new: $!\n";
-    print MAKE "# This file is automatically generated by buildconfig\n\n";
-    print MAKE makefile_var ('METHOD_SOURCES', @$sources);
-    print MAKE makefile_var ('EXTRA_SOURCES', @$extra);
-    print MAKE makefile_var ('PROGRAMS', @$programs);
-    for (@$makefiles) {
-        print MAKE "\n\n##  Included from $_\n\n";
-        open (FRAG, $_) or die "Can't open $_: $!\n";
-        print MAKE <FRAG>;
-        close FRAG;
-    }
-    rename ('Make.methods.new', 'Make.methods');
-}
-
-my ($dir, %history);
-if (!-d 'hisv6') {
-    if (-d 'history/cnfs') {
-        chdir 'history' or die "Can't chdir to history: $!\n";
-    } else {
-        die "Can't find history directory (looking for history/hisv6)\n";
-    }
-}
-opendir (D, ".") or die "Can't open current directory: $!\n";
-my @dirs = sort readdir D;
-for $dir (@dirs) {
-    if (-e "$dir/hismethod.config") {
-        parse_config ($dir, 'hismethod.config', \%history);
-    }
-}
-write_history (\%history);
-@dirs = sort values %{ $history{method} };
-my @sources = sort @{ $history{sources} };
-my @extra = sort @{ $history{extra} };
-my @programs = sort @{ $history{programs} };
-my @makefiles = sort @{ $history{makefiles} };
-write_makefile (\@dirs, \@sources, \@extra, \@programs, \@makefiles);
diff --git a/history/his.c b/history/his.c
deleted file mode 100644 (file)
index aafd14f..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/*  $Id: his.c 6351 2003-05-19 02:00:06Z rra $
-**
-**  API to history routines 
-**
-**  Copyright (c) 2001, Thus plc 
-**  
-**  Redistribution and use of the source code in source and binary 
-**  forms, with or without modification, are permitted provided that
-**  the following 3 conditions are met:
-**  
-**  1. Redistributions of the source code must retain the above 
-**  copyright notice, this list of conditions and the disclaimer 
-**  set out below. 
-**  
-**  2. Redistributions of the source code in binary form must 
-**  reproduce the above copyright notice, this list of conditions 
-**  and the disclaimer set out below in the documentation and/or 
-**  other materials provided with the distribution. 
-**  
-**  3. Neither the name of the Thus plc nor the names of its 
-**  contributors may be used to endorse or promote products 
-**  derived from this software without specific prior written 
-**  permission from Thus plc. 
-**  
-**  Disclaimer:
-**  
-**  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-**  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DIRECTORS
-**  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-**  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-**  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-**  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-**  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <errno.h>
-#include <syslog.h>
-
-#include "inn/history.h"
-#include "inn/messages.h"
-#include "inn/timer.h"
-#include "libinn.h"
-#include "storage.h"
-
-#include "hisinterface.h"
-#include "hismethods.h"
-
-struct hiscache {
-    HASH Hash; /* Hash value of the message-id using Hash() */
-    bool Found;        /* Whether this entry is in the dbz file yet */
-};
-
-struct history {
-    struct hismethod *methods;
-    void *sub;
-    struct hiscache *cache;
-    size_t cachesize;
-    const char *error;
-    struct histstats stats;
-};
-
-enum HISRESULT {HIScachehit, HIScachemiss, HIScachedne};
-
-static const struct histstats nullhist = {0};
-
-/*
-** Put an entry into the history cache 
-*/
-static void
-his_cacheadd(struct history *h, HASH MessageID, bool Found)
-{
-    unsigned int  i, loc;
-
-    his_logger("HIScacheadd begin", S_HIScacheadd);
-    if (h->cache != NULL) {
-       memcpy(&loc, ((char *)&MessageID) + (sizeof(HASH) - sizeof(loc)),
-              sizeof(loc));
-       i = loc % h->cachesize;
-       memcpy((char *)&h->cache[i].Hash, (char *)&MessageID, sizeof(HASH));
-       h->cache[i].Found = Found;
-    }
-    his_logger("HIScacheadd end", S_HIScacheadd);
-}
-
-/*
-** Lookup an entry in the history cache
-*/
-static enum HISRESULT
-his_cachelookup(struct history *h, HASH MessageID)
-{
-    unsigned int i, loc;
-
-    if (h->cache == NULL)
-       return HIScachedne;
-    his_logger("HIScachelookup begin", S_HIScachelookup);
-    memcpy(&loc, ((char *)&MessageID) + (sizeof(HASH) - sizeof(loc)), sizeof(loc));
-    i = loc % h->cachesize;
-    if (memcmp((char *)&h->cache[i].Hash, (char *)&MessageID, sizeof(HASH)) == 0) {
-       his_logger("HIScachelookup end", S_HIScachelookup);
-        if (h->cache[i].Found) {
-            return HIScachehit;
-        } else {
-            return HIScachemiss;
-        }
-    } else {
-       his_logger("HIScachelookup end", S_HIScachelookup);
-        return HIScachedne;
-    }
-}
-
-/*
-**  set error status to that indicated by s; doesn't copy the string,
-**  assumes the caller did that for us
-*/
-void
-his_seterror(struct history *h, const char *s)
-{
-    if (h != NULL) {
-       if (h->error)
-           free((void *)h->error);
-       h->error = s;
-    }
-    if (s != NULL)
-       warn("%s", s);
-}
-
-struct history *
-HISopen(const char *path, const char *method, int flags)
-{
-    struct history *h;
-    int i;
-
-    for (i = 0; i < NUM_HIS_METHODS; ++i) {
-       if (strcmp(method, his_methods[i].name) == 0)
-           break;
-    }
-    if (i == NUM_HIS_METHODS) {
-       warn("`%s' isn't a valid history method", method);
-       return NULL;
-    }
-
-    /* allocate up our structure and start subordinate history
-     * manager */
-    h = xmalloc(sizeof *h);
-    h->methods = &his_methods[i];
-    h->cache = NULL;
-    h->error = NULL;
-    h->cachesize = 0;
-    h->stats = nullhist;
-    h->sub = (*h->methods->open)(path, flags, h);
-    if (h->sub == NULL) {
-       free(h);
-       h = NULL;
-    }
-    return h;
-}
-
-static bool
-his_checknull(struct history *h)
-{
-    if (h != NULL)
-       return false;
-    errno = EBADF;
-    return true;
-
-}
-
-bool 
-HISclose(struct history *h)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    r = (*h->methods->close)(h->sub);
-    if (h->cache) {
-       free(h->cache);
-       h->cache = NULL;
-    }
-    if (h->error) {
-       free((void *)h->error);
-       h->error = NULL;
-    }
-    free(h);
-    return r;
-}
-
-bool
-HISsync(struct history *h)
-{
-    bool r = false;
-
-    if (his_checknull(h))
-       return false;
-    TMRstart(TMR_HISSYNC);
-    r = (*h->methods->sync)(h->sub);
-    TMRstop(TMR_HISSYNC);
-    return r;
-}
-
-bool
-HISlookup(struct history *h, const char *key, time_t *arrived,
-         time_t *posted, time_t *expires, TOKEN *token)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    TMRstart(TMR_HISGREP);
-    r = (*h->methods->lookup)(h->sub, key, arrived, posted, expires, token);
-    TMRstop(TMR_HISGREP);
-    return r;
-}
-
-bool
-HIScheck(struct history *h, const char *key)
-{
-    bool r = false;
-    HASH hash;
-
-    if (his_checknull(h))
-       return false;
-    TMRstart(TMR_HISHAVE);
-    hash = HashMessageID(key);
-    switch (his_cachelookup(h, hash)) {
-    case HIScachehit:
-       h->stats.hitpos++;
-       r = true;
-       break;
-
-    case HIScachemiss:
-       h->stats.hitneg++;
-       r = false;
-       break;
-
-    case HIScachedne:
-       r = (*h->methods->check)(h->sub, key);
-       his_cacheadd(h, hash, r);
-       if (r)
-           h->stats.misses++;
-       else
-           h->stats.dne++;
-       break;
-    }
-    TMRstop(TMR_HISHAVE);
-    return r;
-}
-
-bool
-HISwrite(struct history *h, const char *key, time_t arrived,
-        time_t posted, time_t expires, const TOKEN *token)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    TMRstart(TMR_HISWRITE);
-    r = (*h->methods->write)(h->sub, key, arrived, posted, expires, token);
-    if (r == true) {
-       HASH hash;
-
-       /* if we successfully wrote it, add it to the cache */
-       hash = HashMessageID(key);
-       his_cacheadd(h, hash, true);
-    }
-    TMRstop(TMR_HISWRITE);
-
-    return r;
-}
-
-bool
-HISremember(struct history *h, const char *key, time_t arrived)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    TMRstart(TMR_HISWRITE);
-    r = (*h->methods->remember)(h->sub, key, arrived);
-    if (r == true) {
-       HASH hash;
-
-       /* if we successfully wrote it, add it to the cache */
-       hash = HashMessageID(key);
-       his_cacheadd(h, hash, true);
-    }
-    TMRstop(TMR_HISWRITE);
-
-    return r;
-}
-
-bool
-HISreplace(struct history *h, const char *key, time_t arrived,
-          time_t posted, time_t expires, const TOKEN *token)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    r = (*h->methods->replace)(h->sub, key, arrived, posted, expires, token);
-    if (r == true) {
-       HASH hash;
-
-       /* if we successfully wrote it, add it to the cache */
-       hash = HashMessageID(key);
-       his_cacheadd(h, hash, true);
-    }
-    return r;
-}
-
-bool
-HISwalk(struct history *h, const char *reason, void *cookie,
-       bool (*callback)(void *, time_t, time_t, time_t, const TOKEN *))
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    r = (*h->methods->walk)(h->sub, reason, cookie, callback);
-    return r;
-}
-
-bool
-HISexpire(struct history *h, const char *path, const char *reason,
-         bool writing, void *cookie, time_t threshold,
-         bool (*exists)(void *, time_t, time_t, time_t, TOKEN *))
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    r = (*h->methods->expire)(h->sub, path, reason, writing,
-                             cookie, threshold, exists);
-    return r;
-}
-
-void
-HISsetcache(struct history *h, size_t size)
-{
-    if (h == NULL)
-       return;
-    if (h->cache) {
-       free(h->cache);
-       h->cache = NULL;
-    }
-    h->cachesize = size / sizeof(struct hiscache);
-    if (h->cachesize != 0)
-       h->cache = xcalloc(h->cachesize, sizeof(struct hiscache));
-    h->stats = nullhist;
-}
-
-
-/*
-**  return current history cache stats and zero the counters
-*/
-struct histstats
-HISstats(struct history *h)
-{
-    struct histstats r;
-
-    if (h == NULL)
-       return nullhist;
-    r = h->stats;
-    h->stats = nullhist;
-    return r;
-}
-
-
-/*
-**  return current error status to caller
-*/
-const char *
-HISerror(struct history *h)
-{
-    if (h == NULL)
-       return NULL;
-    return h->error;
-}
-
-
-/*
-**  control interface to underlying method
-*/
-bool
-HISctl(struct history *h, int selector, void *val)
-{
-    bool r;
-
-    if (his_checknull(h))
-       return false;
-    r = (*h->methods->ctl)(h->sub, selector, val);
-    return r;
-}
-
-
-/*
-**  This code doesn't fit well with the generic history API, it really
-**  needs migrating to use the new nested timers
-*/
-
-FILE             *HISfdlog = NULL; /* filehandle for history logging purpose */
-
-static struct timeval HISstat_start[S_HIS_MAX];
-static struct timeval HISstat_total[S_HIS_MAX];
-static unsigned long  HISstat_count[S_HIS_MAX];
-
-void HISlogclose(void) {
-   if (HISfdlog != NULL)
-       Fclose(HISfdlog);
-   HISfdlog = NULL;
-}
-
-void HISlogto(const char *s) {
-   int i;
-
-   HISlogclose();
-   if ((HISfdlog = Fopen(s, "a", INND_HISLOG)) == NULL)
-       syslog(L_FATAL, "cant open %s %m", s);
-   /* initialize our counters */
-   for (i = 0; i < S_HIS_MAX; i++) {
-       HISstat_start[i].tv_sec = 0;
-       HISstat_start[i].tv_usec = 0;
-       HISstat_total[i].tv_sec = 0;
-       HISstat_total[i].tv_usec = 0;
-       HISstat_count[i] = 0;
-   }
-}
-
-void
-his_logger(char *s, int code)
-{
-    struct timeval tv;
-    struct tm *tm;
-
-    if (HISfdlog == NULL) /* do nothing unless HISlogto() has been called */
-       return;
-
-    gettimeofday(&tv, NULL);
-    tm = localtime((const time_t *)&(tv.tv_sec));
-    if (HISstat_start[code].tv_sec != 0) {
-       fprintf(HISfdlog, "%d/%d/%d %02d:%02d:%02d.%06d: [%d] %s (%.6f)\n",
-               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
-               tm->tm_min, tm->tm_sec, (int)tv.tv_usec, code, s, (float) tv.tv_sec +
-               (float) tv.tv_usec / 1000000 - (float) HISstat_start[code].tv_sec -
-               (float) HISstat_start[code].tv_usec / 1000000);
-       if (tv.tv_usec < HISstat_start[code].tv_usec) {
-           HISstat_total[code].tv_sec++;
-           HISstat_total[code].tv_usec +=
-               tv.tv_usec - HISstat_start[code].tv_usec + 1000000;
-      }
-      else
-          HISstat_total[code].tv_usec +=
-              tv.tv_usec - HISstat_start[code].tv_usec;
-       HISstat_total[code].tv_sec += tv.tv_sec - HISstat_start[code].tv_sec;
-       HISstat_count[code]++;
-       HISstat_start[code].tv_sec = 0;
-       HISstat_start[code].tv_usec = 0;
-    }
-    else {
-       fprintf(HISfdlog, "%d/%d/%d %02d:%02d:%02d.%06d: [%d] %s\n",
-               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
-               tm->tm_min, tm->tm_sec, (int)tv.tv_usec, code, s);
-       HISstat_start[code].tv_sec = tv.tv_sec;
-       HISstat_start[code].tv_usec = tv.tv_usec;
-    }
-}
diff --git a/history/hisinterface.h b/history/hisinterface.h
deleted file mode 100644 (file)
index 8fa5390..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id: hisinterface.h 5745 2002-09-08 19:52:12Z rra $
-**
-** Interface to history API modules
-*/
-
-#ifndef HISINTERFACE_H
-#define HISINTERFACE_H
-
-#include "config.h"
-#include <sys/types.h>
-
-struct token;
-struct histopts;
-struct history;
-
-typedef struct hismethod {
-    const char *name;
-    void *(*open)(const char *path, int flags, struct history *);
-    bool (*close)(void *);
-    bool (*sync)(void *);
-    bool (*lookup)(void *, const char *, time_t *, time_t *, time_t *,
-                  struct token *);
-    bool (*check)(void *, const char *);
-    bool (*write)(void *, const char *, time_t, time_t, time_t,
-                 const struct token *);
-    bool (*replace)(void *, const char *, time_t, time_t, time_t,
-                   const struct token *);
-    bool (*expire)(void *, const char *, const char *, bool, void *, time_t,
-                  bool (*)(void *, time_t, time_t, time_t,
-                           struct token *));
-    bool (*walk)(void *, const char *, void *,
-                bool (*)(void *, time_t, time_t, time_t,
-                         const struct token *));
-    bool (*remember)(void *, const char *, time_t);
-    bool (*ctl)(void *, int, void *);
-} HIS_METHOD;
-
-/* subordinate history manager private methods */
-void his_seterror(struct history *, const char *);
-
-enum { S_HIScacheadd, S_HIScachelookup, S_HISsetup, S_HISsync,
-       S_HISlogstats, S_HISclose, S_HISfilesfor, S_HIShavearticle,
-       S_HISwrite, S_HISremember, S_HIS_MAX };
-
-/* fine grained history logging */
-void his_logger(char *s, int code);
-#endif
diff --git a/history/hisv6/hismethod.config b/history/hisv6/hismethod.config
deleted file mode 100644 (file)
index 4182ab0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = hisv6
-number  = 0
-sources = hisv6.c
diff --git a/history/hisv6/hisv6-private.h b/history/hisv6/hisv6-private.h
deleted file mode 100644 (file)
index 51398ea..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef HISV6_PRIVATE_H
-#define HISV6_PRIVATE_H
-
-#include "config.h"
-#include <stdio.h>
-#include <time.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include "inn/history.h"
-#include "storage.h"
-#include "libinn.h"
-
-/* Used by lots of stuff that parses history file entries.  Should be moved
-   into a header specifically for history parsing. */
-#define HISV6_BADCHAR             '_'
-#define HISV6_FIELDSEP            '\t'
-#define HISV6_NOEXP               '-'
-#define HISV6_SUBFIELDSEP         '~'
-
-/* maximum length of a history line:
-   34 - hash
-    1 - \t
-   20 - arrived
-    1 - ~
-   20 - expires
-    1 - ~
-   20 - posted
-    1 - tab
-   38 - token
-    1 - \n */
-#define HISV6_MAXLINE 137
-
-/* minimum length of a history line:
-   34 - hash
-    1 - \t
-    1 - arrived
-    1 - \n */
-#define HISV6_MINLINE 37
-
-struct hisv6 {
-    char *histpath;
-    FILE *writefp;
-    off_t offset;               /* Offset into writefp. */
-    unsigned long nextcheck;
-    struct history *history;
-    time_t statinterval;
-    size_t synccount;
-    size_t dirty;
-    ssize_t npairs;
-    int readfd;
-    int flags;
-    struct stat st;
-};
-
-/* values in the bitmap returned from hisv6_splitline */
-#define HISV6_HAVE_HASH (1<<0)
-#define HISV6_HAVE_ARRIVED (1<<1)
-#define HISV6_HAVE_POSTED (1<<2)
-#define HISV6_HAVE_EXPIRES (1<<3)
-#define HISV6_HAVE_TOKEN (1<<4)
-
-/* structure used to hold the callback and cookie so we don't try
- * passing too many parameters into the callers callback */
-struct hisv6_walkstate {
-    union {
-       bool (*expire)(void *, time_t, time_t, time_t, TOKEN *);
-       bool (*walk)(void *, time_t, time_t, time_t, const TOKEN *);
-    } cb;
-    void *cookie;
-    bool paused;
-    bool ignore;
-    /* the next two fields are only used during expire... they should
-     * probably be linked off of cookie, but I've been lazy */
-    struct hisv6 *new;
-    time_t threshold;
-};
-
-/* maximum length of the string from hisv6_errloc */
-#define HISV6_MAX_LOCATION 22
-
-#endif
diff --git a/history/hisv6/hisv6.c b/history/hisv6/hisv6.c
deleted file mode 100644 (file)
index edcb965..0000000
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*  $Id: hisv6.c 7339 2005-06-20 03:16:41Z eagle $
-**
-**  History v6 implementation against the history API.
-**
-**  Copyright (c) 2001, Thus plc 
-**  
-**  Redistribution and use of the source code in source and binary 
-**  forms, with or without modification, are permitted provided that
-**  the following 3 conditions are met:
-**  
-**  1. Redistributions of the source code must retain the above 
-**  copyright notice, this list of conditions and the disclaimer 
-**  set out below. 
-**  
-**  2. Redistributions of the source code in binary form must 
-**  reproduce the above copyright notice, this list of conditions 
-**  and the disclaimer set out below in the documentation and/or 
-**  other materials provided with the distribution. 
-**  
-**  3. Neither the name of the Thus plc nor the names of its 
-**  contributors may be used to endorse or promote products 
-**  derived from this software without specific prior written 
-**  permission from Thus plc. 
-**  
-**  Disclaimer:
-**  
-**  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-**  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-**  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-**  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DIRECTORS
-**  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-**  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-**  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-**  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-**  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-#include "hisinterface.h"
-#include "hisv6.h"
-#include "hisv6-private.h"
-#include "dbz.h"
-#include "inn/innconf.h"
-#include "inn/timer.h"
-#include "inn/qio.h"
-#include "inn/sequence.h"
-#include "inndcomm.h"
-
-/*
-**  because we can only have one open dbz per process, we keep a
-**  pointer to which of the current history structures owns it
-*/
-static struct hisv6 *hisv6_dbzowner;
-
-
-/*
-**  set error status to that indicated by s; doesn't copy the string,
-**  assumes the caller did that for us
-*/
-static void
-hisv6_seterror(struct hisv6 *h, const char *s)
-{
-    his_seterror(h->history, s);
-}
-
-
-/*
-**  format line or offset into a string for error reporting
-*/
-static void
-hisv6_errloc(char *s, size_t line, off_t offset)
-{
-    if (offset != -1) {
-       /* really we want an autoconf test for %ll/%L/%I64, sigh */
-       sprintf(s, "@%.0f", (double)offset);
-    } else {
-       sprintf(s, ":%lu", (unsigned long)line);
-    }
-}
-
-
-/*
-**  split a history line into its constituent components; return a
-**  bitmap indicating which components we're returning are valid (or
-**  would be valid if a NULL pointer is passed for that component) or
-**  -1 for error.  *error is set to a string which describes the
-**  failure.
-*/
-static int
-hisv6_splitline(const char *line, const char **error, HASH *hash,
-                time_t *arrived, time_t *posted, time_t *expires,
-                TOKEN *token)
-{
-    char *p = (char *)line;
-    unsigned long l;
-    int r = 0;
-
-    /* parse the [...] hash field */
-    if (*p != '[') {
-       *error = "`[' missing from history line";
-       return -1;
-    }
-    ++p;
-    if (hash)
-       *hash = TextToHash(p);
-    p += 32;
-    if (*p != ']') {
-       *error = "`]' missing from history line";
-       return -1;
-    }
-    ++p;
-    r |= HISV6_HAVE_HASH;
-    if (*p != HISV6_FIELDSEP) {
-       *error = "field separator missing from history line";
-       return -1;
-    }
-
-    /* parse the arrived field */
-    l = strtoul(p + 1, &p, 10);
-    if (l == ULONG_MAX) {
-       *error = "arrived timestamp out of range";
-       return -1;
-    }
-    r |= HISV6_HAVE_ARRIVED;
-    if (arrived)
-       *arrived = (time_t)l;
-    if (*p != HISV6_SUBFIELDSEP) {
-       /* no expires or posted time */
-       if (posted)
-           *posted = 0;
-       if (expires)
-           *expires = 0;
-    } else {
-       /* parse out the expires field */
-       ++p;
-       if (*p == HISV6_NOEXP) {
-           ++p;
-           if (expires)
-               *expires = 0;
-       } else {
-           l = strtoul(p, &p, 10);
-           if (l == ULONG_MAX) {
-               *error = "expires timestamp out of range";
-               return -1;
-           }
-           r |= HISV6_HAVE_EXPIRES;
-           if (expires)
-               *expires = (time_t)l;
-       }
-       /* parse out the posted field */
-       if (*p != HISV6_SUBFIELDSEP) {
-           /* no posted time */
-           if (posted)
-               *posted = 0;
-       } else {
-           ++p;
-           l = strtoul(p, &p, 10);
-           if (l == ULONG_MAX) {
-               *error = "posted timestamp out of range";
-               return -1;
-           }
-           r |= HISV6_HAVE_POSTED;
-           if (posted)
-               *posted = (time_t)l;
-       }
-    }
-
-    /* parse the token */
-    if (*p == HISV6_FIELDSEP)
-       ++p;
-    else if (*p != '\0') {
-       *error = "field separator missing from history line";
-       return -1;
-    }
-    /* IsToken false would imply a remembered line, or where someone's
-     * used prunehistory */
-    if (IsToken(p)) {
-       r |= HISV6_HAVE_TOKEN;
-       if (token)
-           *token = TextToToken(p);
-    }
-    return r;
-}
-
-
-/*
-**  Given the time, now, return the time at which we should next check
-**  the history file
-*/
-static unsigned long
-hisv6_nextcheck(struct hisv6 *h, unsigned long now)
-{
-    return now + h->statinterval;
-}
-
-
-/*
-**  close any dbz structures associated with h; we also manage the
-**  single dbz instance voodoo
-*/
-static bool
-hisv6_dbzclose(struct hisv6 *h)
-{
-    bool r = true;
-
-    if (h == hisv6_dbzowner) {
-       if (!hisv6_sync(h))
-           r = false;
-       if (!dbzclose()) {
-           hisv6_seterror(h, concat("can't dbzclose ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           r = false;
-       }
-       hisv6_dbzowner = NULL;
-    }
-    return r;
-}
-
-
-/*
-**  close an existing history structure, cleaning it to the point
-**  where we can reopon without leaking resources
-*/
-static bool
-hisv6_closefiles(struct hisv6 *h)
-{
-    bool r = true;
-
-    if (!hisv6_dbzclose(h))
-       r = false;
-
-    if (h->readfd != -1) {
-       if (close(h->readfd) != 0 && errno != EINTR) {
-           hisv6_seterror(h, concat("can't close history ",
-                                     h->histpath, " ",
-                                     strerror(errno),NULL));
-           r = false;
-       }
-       h->readfd = -1;
-    }
-
-    if (h->writefp != NULL) {
-       if (ferror(h->writefp) || fflush(h->writefp) == EOF) {
-           hisv6_seterror(h, concat("error on history ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           r = false;
-       }
-       if (Fclose(h->writefp) == EOF) {
-           hisv6_seterror(h, concat("can't fclose history ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           r = false;
-       }
-       h->writefp = NULL;
-        h->offset = 0;
-    }
-
-    h->nextcheck = 0;
-    h->st.st_ino = (ino_t)-1;
-    h->st.st_dev = (dev_t)-1;
-    return r;
-}
-
-
-/*
-**  Reopen (or open from fresh) a history structure; assumes the flags
-**  & path are all set up, ready to roll. If we don't own the dbz, we
-**  suppress the dbz code; this is needed during expiry (since the dbz
-**  code doesn't yet understand multiple open contexts... yes its a
-**  hack)
-*/
-static bool
-hisv6_reopen(struct hisv6 *h)
-{
-    bool r = false;
-
-    if (h->flags & HIS_RDWR) {
-       const char *mode;
-
-       if (h->flags & HIS_CREAT)
-           mode = "w";
-       else
-           mode = "r+";
-       if ((h->writefp = Fopen(h->histpath, mode, INND_HISTORY)) == NULL) {
-           hisv6_seterror(h, concat("can't fopen history ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           hisv6_closefiles(h);
-           goto fail;
-       }
-       if (fseeko(h->writefp, 0, SEEK_END) == -1) {
-           hisv6_seterror(h, concat("can't fseek to end of ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           hisv6_closefiles(h);
-           goto fail;
-       }
-        h->offset = ftello(h->writefp);
-       if (h->offset == -1) {
-           hisv6_seterror(h, concat("can't ftello ", h->histpath, " ",
-                                     strerror(errno), NULL));
-           hisv6_closefiles(h);
-           goto fail;
-       }
-       close_on_exec(fileno(h->writefp), true);
-    }
-
-    /* Open the history file for reading. */
-    if ((h->readfd = open(h->histpath, O_RDONLY)) < 0) {
-       hisv6_seterror(h, concat("can't open ", h->histpath, " ",
-                                 strerror(errno), NULL));
-       hisv6_closefiles(h);
-       goto fail;
-    }
-    close_on_exec(h->readfd, true);
-    
-    /* if there's no current dbz owner, claim it here */
-    if (hisv6_dbzowner == NULL) {
-       hisv6_dbzowner = h;
-    }
-
-    /* During expiry we need two history structures in place, so we
-       have to select which one gets the dbz file */
-    if (h == hisv6_dbzowner) {
-       dbzoptions opt;
-
-       /* Open the DBZ file. */
-       dbzgetoptions(&opt);
-
-       /* HIS_INCORE usually means we're rebuilding from scratch, so
-          keep the whole lot in core until we flush */
-       if (h->flags & HIS_INCORE) {
-           opt.writethrough = false;
-           opt.pag_incore = INCORE_MEM;
-#ifndef        DO_TAGGED_HASH
-           opt.exists_incore = INCORE_MEM;
-#endif
-       } else {
-           opt.writethrough = true;
-#ifdef DO_TAGGED_HASH
-           opt.pag_incore = INCORE_MMAP;
-#else
-           /*opt.pag_incore = INCORE_NO;*/
-           opt.pag_incore = (h->flags & HIS_MMAP) ? INCORE_MMAP : INCORE_NO;
-           opt.exists_incore = (h->flags & HIS_MMAP) ? INCORE_MMAP : INCORE_NO;
-
-# if defined(MMAP_NEEDS_MSYNC) && INND_DBZINCORE == 1
-           /* Systems that have MMAP_NEEDS_MSYNC defined will have their
-              on-disk copies out of sync with the mmap'ed copies most of
-              the time.  So if innd is using INCORE_MMAP, then we force
-              everything else to use it, too (unless we're on NFS) */
-           if(!innconf->nfsreader) {
-               opt.pag_incore = INCORE_MMAP;
-               opt.exists_incore = INCORE_MMAP;
-           }
-# endif
-#endif
-       }
-       dbzsetoptions(opt);
-       if (h->flags & HIS_CREAT) {
-           size_t npairs;
-               
-           /* must only do this once! */
-           h->flags &= ~HIS_CREAT;
-           npairs = (h->npairs == -1) ? 0 : h->npairs;
-           if (!dbzfresh(h->histpath, dbzsize(npairs))) {
-               hisv6_seterror(h, concat("can't dbzfresh ", h->histpath, " ",
-                                         strerror(errno), NULL));
-               hisv6_closefiles(h);
-               goto fail;
-           }
-       } else if (!dbzinit(h->histpath)) {
-           hisv6_seterror(h, concat("can't dbzinit ", h->histpath, " ",
-                                     strerror(errno), NULL));
-           hisv6_closefiles(h);
-           goto fail;
-       }
-    }
-    h->nextcheck = hisv6_nextcheck(h, TMRnow());
-    r = true;
- fail:
-    return r;
-}
-
-
-/*
-** check if the history file has changed, if so rotate to the new
-** history file. Returns false on failure (which is probably fatal as
-** we'll have closed the files)
-*/
-static bool
-hisv6_checkfiles(struct hisv6 *h)
-{
-    unsigned long t = TMRnow();
-
-    if (h->statinterval == 0)
-       return true;
-
-    if (h->readfd == -1) {
-       /* this can happen if a previous checkfiles() has failed to
-        * reopen the handles, but our caller hasn't realised... */
-       hisv6_closefiles(h);
-       if (!hisv6_reopen(h)) {
-           hisv6_closefiles(h);
-           return false;
-       }
-    }
-    if (seq_lcompare(t, h->nextcheck) == 1) {
-       struct stat st;
-
-       if (stat(h->histpath, &st) == 0 &&
-           (st.st_ino != h->st.st_ino ||
-            st.st_dev != h->st.st_dev)) {
-           /* there's a possible race on the history file here... */
-           hisv6_closefiles(h);
-           if (!hisv6_reopen(h)) {
-               hisv6_closefiles(h);
-               return false;
-           }
-           h->st = st;
-       }
-       h->nextcheck = hisv6_nextcheck(h, t);
-    }
-    return true;
-}
-
-
-/*
-**  dispose (and clean up) an existing history structure
-*/
-static bool
-hisv6_dispose(struct hisv6 *h)
-{
-    bool r;
-
-    r = hisv6_closefiles(h);
-    if (h->histpath) {
-       free(h->histpath);
-       h->histpath = NULL;
-    }
-
-    free(h);
-    return r;
-}
-
-
-/*
-**  return a newly constructed, but empty, history structure
-*/
-static struct hisv6 *
-hisv6_new(const char *path, int flags, struct history *history)
-{
-    struct hisv6 *h;
-
-    h = xmalloc(sizeof *h);
-    h->histpath = path ? xstrdup(path) : NULL;
-    h->flags = flags;
-    h->writefp = NULL;
-    h->offset = 0;
-    h->history = history;
-    h->readfd = -1;
-    h->nextcheck = 0;
-    h->statinterval = 0;
-    h->npairs = 0;
-    h->dirty = 0;
-    h->synccount = 0;
-    h->st.st_ino = (ino_t)-1;
-    h->st.st_dev = (dev_t)-1;
-    return h;
-}
-
-
-/*
-**  open the history database identified by path in mode flags
-*/
-void *
-hisv6_open(const char *path, int flags, struct history *history)
-{
-    struct hisv6 *h;
-
-    his_logger("HISsetup begin", S_HISsetup);
-
-    h = hisv6_new(path, flags, history);
-    if (path) {
-       if (!hisv6_reopen(h)) {
-           hisv6_dispose(h);
-           h = NULL;
-       }
-    }
-    his_logger("HISsetup end", S_HISsetup);
-    return h;
-}
-
-
-/*
-**  close and free a history handle
-*/
-bool
-hisv6_close(void *history)
-{
-    struct hisv6 *h = history;
-    bool r;
-
-    his_logger("HISclose begin", S_HISclose);
-    r = hisv6_dispose(h);
-    his_logger("HISclose end", S_HISclose);
-    return r;
-}
-
-
-/*
-**  synchronise any outstanding history changes to disk
-*/
-bool
-hisv6_sync(void *history)
-{
-    struct hisv6 *h = history;
-    bool r = true;
-
-    if (h->writefp != NULL) {
-       his_logger("HISsync begin", S_HISsync);
-       if (fflush(h->writefp) == EOF) {
-           hisv6_seterror(h, concat("error on history ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           r = false;
-       }
-       if (h->dirty && h == hisv6_dbzowner) {
-           if (!dbzsync()) {
-               hisv6_seterror(h, concat("can't dbzsync ", h->histpath,
-                                         " ", strerror(errno), NULL));
-               r = false;
-           } else {
-               h->dirty = 0;
-           }
-       }
-       his_logger("HISsync end", S_HISsync);
-    }
-    return r;
-}
-
-
-/*
-**  fetch the line associated with `hash' in the history database into
-**  buf; buf must be at least HISV6_MAXLINE+1 bytes. `poff' is filled
-**  with the offset of the line in the history file.
-*/
-static bool
-hisv6_fetchline(struct hisv6 *h, const HASH *hash, char *buf, off_t *poff)
-{
-    off_t offset;
-    bool r;
-
-    if (h != hisv6_dbzowner) {
-       hisv6_seterror(h, concat("dbz not open for this history file ",
-                                 h->histpath, NULL));
-       return false;
-    }
-    if ((h->flags & (HIS_RDWR | HIS_INCORE)) == (HIS_RDWR | HIS_INCORE)) {
-       /* need to fflush as we may be reading uncommitted data
-          written via writefp */
-       if (fflush(h->writefp) == EOF) {
-           hisv6_seterror(h, concat("error on history ",
-                                     h->histpath, " ",
-                                     strerror(errno), NULL));
-           r = false;
-           goto fail;
-       }
-    }
-
-    /* Get the seek value into the history file. */
-    errno = 0;
-    r = dbzfetch(*hash, &offset);
-#ifdef ESTALE
-    /* If your history is on NFS need to deal with stale NFS
-     * handles */
-    if (!r && errno == ESTALE) {
-       hisv6_closefiles(h);
-       if (!hisv6_reopen(h)) {
-           hisv6_closefiles(h);
-           r = false;
-           goto fail;
-       }
-    }
-#endif
-    if (r) {
-       ssize_t n;
-
-       do {
-           n = pread(h->readfd, buf, HISV6_MAXLINE, offset);
-#ifdef ESTALE
-           if (n == -1 && errno == ESTALE) {
-               hisv6_closefiles(h);
-               if (!hisv6_reopen(h)) {
-                   hisv6_closefiles(h);
-                   r = false;
-                   goto fail;
-               }
-           }
-#endif
-       } while (n == -1 && errno == EINTR);
-       if (n >= HISV6_MINLINE) {
-           char *p;
-
-           buf[n] = '\0';
-           p = strchr(buf, '\n');
-           if (!p) {
-               char location[HISV6_MAX_LOCATION];
-
-               hisv6_errloc(location, (size_t)-1, offset);
-               hisv6_seterror(h,
-                               concat("can't locate end of line in history ",
-                                      h->histpath, location,
-                                      NULL));
-               r = false;
-           } else {
-               *p = '\0';
-               *poff = offset;
-               r = true;
-           }
-       } else {
-           char location[HISV6_MAX_LOCATION];
-
-           hisv6_errloc(location, (size_t)-1, offset);
-           hisv6_seterror(h, concat("line too short in history ",
-                                     h->histpath, location,
-                                     NULL));
-           r = false;
-
-       }
-    } else {
-       /* not found */
-       r = false;
-    }
- fail:
-    return r;
-}
-
-
-/*
-**  lookup up the entry `key' in the history database, returning
-**  arrived, posted and expires (for those which aren't NULL
-**  pointers), and any storage token associated with the entry.
-**
-**  If any of arrived, posted or expires aren't available, return zero
-**  for that component.
-*/
-bool
-hisv6_lookup(void *history, const char *key, time_t *arrived,
-            time_t *posted, time_t *expires, TOKEN *token)
-{
-    struct hisv6 *h = history;
-    HASH messageid;
-    bool r;
-    off_t offset;
-    char buf[HISV6_MAXLINE + 1];
-
-    his_logger("HISfilesfor begin", S_HISfilesfor);
-    hisv6_checkfiles(h);
-
-    messageid = HashMessageID(key);
-    r = hisv6_fetchline(h, &messageid, buf, &offset);
-    if (r == true) {
-       int status;
-       const char *error;
-
-       status = hisv6_splitline(buf, &error, NULL,
-                                 arrived, posted, expires, token);
-       if (status < 0) {
-           char location[HISV6_MAX_LOCATION];
-
-           hisv6_errloc(location, (size_t)-1, offset);
-           hisv6_seterror(h, concat(error, " ",
-                                     h->histpath, location,
-                                     NULL));
-           r = false;
-       } else {
-           /* if we have a token then we have the article */
-           r = !!(status & HISV6_HAVE_TOKEN);
-       }
-    }
-    his_logger("HISfilesfor end", S_HISfilesfor);
-    return r;
-}
-
-
-/*
-**  check `key' has been seen in this history database
-*/
-bool
-hisv6_check(void *history, const char *key)
-{
-    struct hisv6 *h = history;
-    bool r;    
-    HASH hash;
-    
-    if (h != hisv6_dbzowner) {
-       hisv6_seterror(h, concat("dbz not open for this history file ",
-                                 h->histpath, NULL));
-       return false;
-    }
-
-    his_logger("HIShavearticle begin", S_HIShavearticle);
-    hisv6_checkfiles(h);
-    hash = HashMessageID(key);
-    r = dbzexists(hash);
-    his_logger("HIShavearticle end", S_HIShavearticle);
-    return r;
-}
-
-
-/*
-**  Format a history line.  s should hold at least HISV6_MAXLINE + 1
-**  characters (to allow for the nul).  Returns the length of the data
-**  written, 0 if there was some error or if the data was too long to write.
-*/
-static int
-hisv6_formatline(char *s, const HASH *hash, time_t arrived,
-                 time_t posted, time_t expires, const TOKEN *token)
-{
-    int i;
-    const char *hashtext = HashToText(*hash);
-
-    if (token == NULL) {
-       i = snprintf(s, HISV6_MAXLINE, "[%s]%c%lu%c%c\n",
-                    hashtext, HISV6_FIELDSEP,
-                    (unsigned long)arrived, HISV6_SUBFIELDSEP, HISV6_NOEXP);
-    } else {
-       const char *texttok;
-
-       texttok = TokenToText(*token);
-       if (expires <= 0) {
-           i = snprintf(s, HISV6_MAXLINE, "[%s]%c%lu%c%c%c%lu%c%s\n",
-                        hashtext, HISV6_FIELDSEP,
-                        (unsigned long)arrived, HISV6_SUBFIELDSEP,
-                        HISV6_NOEXP, HISV6_SUBFIELDSEP,
-                        (unsigned long)posted, HISV6_FIELDSEP,
-                        texttok);
-       } else {
-           i = snprintf(s, HISV6_MAXLINE, "[%s]%c%lu%c%lu%c%lu%c%s\n",
-                        hashtext, HISV6_FIELDSEP,
-                        (unsigned long)arrived, HISV6_SUBFIELDSEP,
-                        (unsigned long)expires, HISV6_SUBFIELDSEP,
-                        (unsigned long)posted, HISV6_FIELDSEP,
-                        texttok);
-       }
-    }
-    if (i < 0 || i >= HISV6_MAXLINE)
-       return 0;
-    return i;
-}
-
-
-/*
-**  write the hash and offset to the dbz
-*/
-static bool
-hisv6_writedbz(struct hisv6 *h, const HASH *hash, off_t offset)
-{
-    bool r;
-    char location[HISV6_MAX_LOCATION];
-    const char *error;
-
-    /* store the offset in the database */
-    switch (dbzstore(*hash, offset)) {
-    case DBZSTORE_EXISTS:
-       error = "dbzstore duplicate message-id ";
-       /* not `false' so that we duplicate the pre-existing
-          behaviour */
-       r = true;
-       break;
-
-    case DBZSTORE_ERROR:
-       error = "dbzstore error ";
-       r = false;
-       break;
-
-    default:
-       error = NULL;
-       r = true;
-       break;
-    }
-    if (error) {
-       hisv6_errloc(location, (size_t)-1, offset);
-       hisv6_seterror(h, concat(error, h->histpath,
-                                 ":[", HashToText(*hash), "]",
-                                 location, " ", strerror(errno), NULL));
-    }
-    if (r && h->synccount != 0 && ++h->dirty >= h->synccount)
-       r = hisv6_sync(h);
-
-    return r;
-}
-
-
-/*
-**  write a history entry, hash, with times arrived, posted and
-**  expires, and storage token.
-*/
-static bool
-hisv6_writeline(struct hisv6 *h, const HASH *hash, time_t arrived,
-               time_t posted, time_t expires, const TOKEN *token)
-{
-    bool r;
-    size_t i, length;
-    char hisline[HISV6_MAXLINE + 1];
-    char location[HISV6_MAX_LOCATION];
-
-    if (h != hisv6_dbzowner) {
-       hisv6_seterror(h, concat("dbz not open for this history file ",
-                                 h->histpath, NULL));
-       return false;
-    }
-
-    if (!(h->flags & HIS_RDWR)) {
-       hisv6_seterror(h, concat("history not open for writing ",
-                                 h->histpath, NULL));
-       return false;
-    }
-
-    length = hisv6_formatline(hisline, hash, arrived, posted, expires, token);
-    if (length == 0) {
-       hisv6_seterror(h, concat("error formatting history line ",
-                                 h->histpath, NULL));
-       return false;
-    }  
-
-    i = fwrite(hisline, 1, length, h->writefp);
-
-    /* If the write failed, the history line is now an orphan.  Attempt to
-       rewind the write pointer to our offset to avoid leaving behind a
-       partial write and desyncing the offset from our file position. */
-    if (i < length ||
-        (!(h->flags & HIS_INCORE) && fflush(h->writefp) == EOF)) {
-       hisv6_errloc(location, (size_t)-1, h->offset);
-       hisv6_seterror(h, concat("can't write history ", h->histpath,
-                                 location, " ", strerror(errno), NULL));
-        if (fseeko(h->writefp, h->offset, SEEK_SET) == -1)
-            h->offset += i;
-       r = false;
-       goto fail;
-    }
-
-    r = hisv6_writedbz(h, hash, h->offset);
-    h->offset += length;     /* increment regardless of error from writedbz */
- fail:
-    return r;
-}
-
-
-/*
-**  write a history entry, key, with times arrived, posted and
-**  expires, and storage token.
-*/
-bool
-hisv6_write(void *history, const char *key, time_t arrived,
-           time_t posted, time_t expires, const TOKEN *token)
-{
-    struct hisv6 *h = history;
-    HASH hash;
-    bool r;
-
-    his_logger("HISwrite begin", S_HISwrite);
-    hash = HashMessageID(key);
-    r = hisv6_writeline(h, &hash, arrived, posted, expires, token);
-    his_logger("HISwrite end", S_HISwrite);
-    return r;
-}
-
-
-/*
-**  remember a history entry, key, with arrival time arrived.
-*/
-bool
-hisv6_remember(void *history, const char *key, time_t arrived)
-{
-    struct hisv6 *h = history;
-    HASH hash;
-    bool r;
-
-    his_logger("HISwrite begin", S_HISwrite);
-    hash = HashMessageID(key);
-    r = hisv6_writeline(h, &hash, arrived, 0, 0, NULL);
-    his_logger("HISwrite end", S_HISwrite);
-    return r;
-}
-
-
-/*
-**  replace an existing history entry, `key', with times arrived,
-**  posted and expires, and (optionally) storage token `token'. The
-**  new history line must fit in the space allocated for the old one -
-**  if it had previously just been HISremember()ed you'll almost
-**  certainly lose.
-*/
-bool
-hisv6_replace(void *history, const char *key, time_t arrived,
-             time_t posted, time_t expires, const TOKEN *token)
-{
-    struct hisv6 *h = history;
-    HASH hash;
-    bool r;
-    off_t offset;
-    char old[HISV6_MAXLINE + 1];
-
-    if (!(h->flags & HIS_RDWR)) {
-       hisv6_seterror(h, concat("history not open for writing ",
-                                 h->histpath, NULL));
-       return false;
-    }
-
-    hash = HashMessageID(key);
-    r = hisv6_fetchline(h, &hash, old, &offset);
-    if (r == true) {
-       char new[HISV6_MAXLINE + 1];
-
-       if (hisv6_formatline(new, &hash, arrived, posted, expires,
-                             token) == 0) {
-           hisv6_seterror(h, concat("error formatting history line ",
-                                     h->histpath, NULL));
-           r = false;
-       } else {
-           size_t oldlen, newlen;
-
-           oldlen = strlen(old);
-           newlen = strlen(new);
-           if (new[newlen - 1] == '\n')
-                newlen--;
-           if (newlen > oldlen) {
-               hisv6_seterror(h, concat("new history line too long ",
-                                         h->histpath, NULL));
-               r = false;
-           } else {
-               ssize_t n;
-
-               /* space fill any excess in the tail of new */
-               memset(new + newlen, ' ', oldlen - newlen);
-
-               do {
-                   n = pwrite(fileno(h->writefp), new, oldlen, offset);
-               } while (n == -1 && errno == EINTR);
-               if (n != oldlen) {
-                   char location[HISV6_MAX_LOCATION];
-
-                   hisv6_errloc(location, (size_t)-1, offset);
-                   hisv6_seterror(h, concat("can't write history ",
-                                             h->histpath, location, " ",
-                                             strerror(errno), NULL));
-                   r = false;
-               }
-           }
-       }
-    }
-    return r;
-}
-
-
-/*
-**  traverse a history database, passing the pieces through a
-**  callback; note that we have more parameters in the callback than
-**  the public interface, we add the internal history struct and the
-**  message hash so we can use those if we need them. If the callback
-**  returns false we abort the traversal.
-**/
-static bool
-hisv6_traverse(struct hisv6 *h, struct hisv6_walkstate *cookie,
-              const char *reason,
-              bool (*callback)(struct hisv6 *, void *, const HASH *hash,
-                               time_t, time_t, time_t,
-                               const TOKEN *))
-{
-    bool r = false;
-    QIOSTATE *qp;
-    void *p;
-    size_t line;
-    char location[HISV6_MAX_LOCATION];
-
-    if ((qp = QIOopen(h->histpath)) == NULL) {
-       hisv6_seterror(h, concat("can't QIOopen history file ",
-                                 h->histpath, strerror(errno), NULL));
-       return false;
-    }
-
-    line = 1;
-    /* we come back to again after we hit EOF for the first time, when
-       we pause the server & clean up any lines which sneak through in
-       the interim */
- again:
-    while ((p = QIOread(qp)) != NULL) {
-       time_t arrived, posted, expires;
-       int status;
-       TOKEN token;
-       HASH hash;
-       const char *error;
-
-       status = hisv6_splitline(p, &error, &hash,
-                                 &arrived, &posted, &expires, &token);
-       if (status > 0) {
-           r = (*callback)(h, cookie, &hash, arrived, posted, expires,
-                           (status & HISV6_HAVE_TOKEN) ? &token : NULL);
-           if (r == false)
-               hisv6_seterror(h, concat("callback failed ",
-                                         h->histpath, NULL));
-       } else {
-           hisv6_errloc(location, line, (off_t)-1);
-           hisv6_seterror(h, concat(error, " ", h->histpath, location,
-                                     NULL));
-           /* if we're not ignoring errors set the status */
-           if (!cookie->ignore)
-               r = false;
-       }
-       if (r == false)
-           goto fail;
-       ++line;
-    }
-
-    if (p == NULL) {
-       /* read or line-format error? */
-       if (QIOerror(qp) || QIOtoolong(qp)) {
-           hisv6_errloc(location, line, (off_t)-1);
-           if (QIOtoolong(qp)) {
-               hisv6_seterror(h, concat("line too long ",
-                                        h->histpath, location, NULL));
-               /* if we're not ignoring errors set the status */
-               if (!cookie->ignore)
-                   r = false;
-           } else {
-               hisv6_seterror(h, concat("can't read line ",
-                                        h->histpath, location, " ",
-                                        strerror(errno), NULL));
-               r = false;
-           }
-           if (r == false)
-               goto fail;
-       }
-
-       /* must have been EOF, pause the server & clean up any
-        * stragglers */
-       if (reason && !cookie->paused) {
-           if (ICCpause(reason) != 0) {
-               hisv6_seterror(h, concat("can't pause server ",
-                                         h->histpath, strerror(errno), NULL));
-               r = false;
-               goto fail;
-           }
-           cookie->paused = true;
-           goto again;
-       }
-    }
- fail:
-    QIOclose(qp);
-    return r;
-}
-
-
-/*
-**  internal callback used during hisv6_traverse; we just pass on the
-**  parameters the user callback expects
-**/
-static bool
-hisv6_traversecb(struct hisv6 *h UNUSED, void *cookie, const HASH *hash UNUSED,
-                time_t arrived, time_t posted, time_t expires,
-                const TOKEN *token)
-{
-    struct hisv6_walkstate *hiscookie = cookie;
-
-    return (*hiscookie->cb.walk)(hiscookie->cookie,
-                                arrived, posted, expires,
-                                token);
-}
-
-
-/*
-**  history API interface to the database traversal routine
-*/
-bool
-hisv6_walk(void *history, const char *reason, void *cookie,
-          bool (*callback)(void *, time_t, time_t, time_t,
-                           const TOKEN *))
-{
-    struct hisv6 *h = history;
-    struct hisv6_walkstate hiscookie;
-    bool r;
-
-    /* our internal walk routine passes too many parameters, so add a
-       wrapper */
-    hiscookie.cb.walk = callback;
-    hiscookie.cookie = cookie;
-    hiscookie.new = NULL;
-    hiscookie.paused = false;
-    hiscookie.ignore = false;
-
-    r = hisv6_traverse(h, &hiscookie, reason, hisv6_traversecb);
-
-    return r;
-}
-
-
-/*
-**  internal callback used during expire
-**/
-static bool
-hisv6_expirecb(struct hisv6 *h, void *cookie, const HASH *hash,
-               time_t arrived, time_t posted, time_t expires,
-               const TOKEN *token)
-{
-    struct hisv6_walkstate *hiscookie = cookie;
-    bool r = true;
-
-    /* check if we've seen this message id already */
-    if (hiscookie->new && dbzexists(*hash)) {
-       /* continue after duplicates, it serious, but not fatal */
-       hisv6_seterror(h, concat("duplicate message-id [",
-                                HashToText(*hash), "] in history ",
-                                hiscookie->new->histpath, NULL));
-    } else {
-       struct hisv6_walkstate *hiscookie = cookie;
-       TOKEN ltoken, *t;
-
-       /* if we have a token pass it to the discrimination function */
-       if (token) {
-           bool keep;
-
-           /* make a local copy of the token so the callback can
-            * modify it */
-           ltoken = *token;
-           t = &ltoken;
-           keep = (*hiscookie->cb.expire)(hiscookie->cookie,
-                                          arrived, posted, expires,
-                                          t);
-           /* if the callback returns true, we should keep the
-              token for the time being, else we just remember
-              it */
-           if (keep == false) {
-               t = NULL;
-               posted = expires = 0;
-           }
-       } else {
-           t = NULL;
-       }
-       if (hiscookie->new &&
-           (t != NULL || arrived >= hiscookie->threshold)) {
-           r = hisv6_writeline(hiscookie->new, hash,
-                                arrived, posted, expires, t);
-       }
-    }
-    return r;
-}
-
-
-/*
-**  unlink files associated with the history structure h
-*/
-static bool
-hisv6_unlink(struct hisv6 *h)
-{
-    bool r = true;
-    char *p;
-
-#ifdef DO_TAGGED_HASH
-    p = concat(h->histpath, ".pag", NULL);
-    r = (unlink(p) == 0) && r;
-    free(p);
-#else
-    p = concat(h->histpath, ".index", NULL);
-    r = (unlink(p) == 0) && r;
-    free(p);
-
-    p = concat(h->histpath, ".hash", NULL);
-    r = (unlink(p) == 0) && r;
-    free(p);
-#endif
-    
-    p = concat(h->histpath, ".dir", NULL);
-    r = (unlink(p) == 0) && r;
-    free(p);
-
-    r = (unlink(h->histpath) == 0) && r;
-    return r;
-}
-
-
-/*
-**  rename files associated with hold to hnew
-*/
-static bool
-hisv6_rename(struct hisv6 *hold, struct hisv6 *hnew)
-{
-    bool r = true;
-    char *old, *new;
-
-#ifdef DO_TAGGED_HASH
-    old = concat(hold->histpath, ".pag", NULL);
-    new = concat(hnew->histpath, ".pag", NULL);
-    r = (rename(old, new) == 0) && r;
-    free(old);
-    free(new);
-#else
-    old = concat(hold->histpath, ".index", NULL);
-    new = concat(hnew->histpath, ".index", NULL);
-    r = (rename(old, new) == 0) && r;
-    free(old);
-    free(new);
-
-    old = concat(hold->histpath, ".hash", NULL);
-    new = concat(hnew->histpath, ".hash", NULL);
-    r = (rename(old, new) == 0) && r;
-    free(old);
-    free(new);
-#endif
-    
-    old = concat(hold->histpath, ".dir", NULL);
-    new = concat(hnew->histpath, ".dir", NULL);
-    r = (rename(old, new) == 0) && r;
-    free(old);
-    free(new);
-
-    r = (rename(hold->histpath, hnew->histpath) == 0) && r;
-    return r;
-}
-
-
-/*
-**  expire the history database, history.
-*/
-bool
-hisv6_expire(void *history, const char *path, const char *reason,
-            bool writing, void *cookie, time_t threshold,
-            bool (*exists)(void *, time_t, time_t, time_t, TOKEN *))
-{
-    struct hisv6 *h = history, *hnew = NULL;
-    const char *nhistory = NULL;
-    dbzoptions opt;
-    bool r;
-    struct hisv6_walkstate hiscookie;
-
-    /* this flag is always tested in the fail clause, so initialise it
-       now */
-    hiscookie.paused = false;
-
-    /* during expire we ignore errors whilst reading the history file
-     * so any errors in it get fixed automagically */
-    hiscookie.ignore = true;
-
-    if (writing && (h->flags & HIS_RDWR)) {
-       hisv6_seterror(h, concat("can't expire from read/write history ",
-                                h->histpath, NULL));
-       r = false;
-       goto fail;
-    }
-
-    if (writing) {
-       /* form base name for new history file */
-       if (path != NULL) {
-           nhistory = concat(path, ".n", NULL);
-       } else {
-           nhistory = concat(h->histpath, ".n", NULL);
-       }
-
-       hnew = hisv6_new(nhistory, HIS_CREAT | HIS_RDWR | HIS_INCORE,
-                         h->history);
-       if (!hisv6_reopen(hnew)) {
-           hisv6_dispose(hnew);
-           hnew = NULL;
-           r = false;
-           goto fail;
-       }
-
-       /* this is icky... we can only have one dbz open at a time; we
-          really want to make dbz take a state structure. For now we'll
-          just close the existing one and create our new one they way we
-          need it */
-       if (!hisv6_dbzclose(h)) {
-           r = false;
-           goto fail;
-       }
-
-       dbzgetoptions(&opt);
-       opt.writethrough = false;
-       opt.pag_incore = INCORE_MEM;
-#ifndef        DO_TAGGED_HASH
-       opt.exists_incore = INCORE_MEM;
-#endif
-       dbzsetoptions(opt);
-
-       if (h->npairs == 0) {
-           if (!dbzagain(hnew->histpath, h->histpath)) {
-               hisv6_seterror(h, concat("can't dbzagain ",
-                                        hnew->histpath, ":", h->histpath, 
-                                        strerror(errno), NULL));
-               r = false;
-               goto fail;
-           }
-       } else {
-           size_t npairs;
-
-           npairs = (h->npairs == -1) ? 0 : h->npairs;
-           if (!dbzfresh(hnew->histpath, dbzsize(npairs))) {
-               hisv6_seterror(h, concat("can't dbzfresh ",
-                                        hnew->histpath, ":", h->histpath, 
-                                        strerror(errno), NULL));
-               r = false;
-               goto fail;
-           }
-       }
-       hisv6_dbzowner = hnew;
-    }
-
-    /* set up the callback handler */
-    hiscookie.cb.expire = exists;
-    hiscookie.cookie = cookie;
-    hiscookie.new = hnew;
-    hiscookie.threshold = threshold;
-    r = hisv6_traverse(h, &hiscookie, reason, hisv6_expirecb);
-
- fail:
-    if (writing) {
-       if (hnew && !hisv6_closefiles(hnew)) {
-           /* error will already have been set */
-           r = false;
-       }
-
-       /* reopen will synchronise the dbz stuff for us */
-       if (!hisv6_closefiles(h)) {
-           /* error will already have been set */
-           r = false;
-       }
-
-       if (r) {
-           /* if the new path was explicitly specified don't move the
-              files around, our caller is planning to do it out of
-              band */
-           if (path == NULL) {
-               /* unlink the old files */
-               r = hisv6_unlink(h);
-           
-               if (r) {
-                   r = hisv6_rename(hnew, h);
-               }
-           }
-       } else if (hnew) {
-           /* something went pear shaped, unlink the new files */
-           hisv6_unlink(hnew);
-       }
-
-       /* re-enable dbz on the old history file */
-       if (!hisv6_reopen(h)) {
-           hisv6_closefiles(h);
-       }
-    }
-
-    if (hnew && !hisv6_dispose(hnew))
-       r = false;
-    if (nhistory && nhistory != path)
-       free((char *)nhistory);
-    if (r == false && hiscookie.paused)
-       ICCgo(reason);
-    return r;
-}
-
-
-/*
-**  control interface
-*/
-bool
-hisv6_ctl(void *history, int selector, void *val)
-{
-    struct hisv6 *h = history;
-    bool r = true;
-
-    switch (selector) {
-    case HISCTLG_PATH:
-       *(char **)val = h->histpath;
-       break;
-
-    case HISCTLS_PATH:
-       if (h->histpath) {
-           hisv6_seterror(h, concat("path already set in handle", NULL));
-           r = false;
-       } else {
-           h->histpath = xstrdup((char *)val);
-           if (!hisv6_reopen(h)) {
-               free(h->histpath);
-               h->histpath = NULL;
-               r = false;
-           }
-       }
-       break;
-
-    case HISCTLS_STATINTERVAL:
-       h->statinterval = *(time_t *)val * 1000;
-       break;
-
-    case HISCTLS_SYNCCOUNT:
-       h->synccount = *(size_t *)val;
-       break;
-
-    case HISCTLS_NPAIRS:
-       h->npairs = (ssize_t)*(size_t *)val;
-       break;
-
-    case HISCTLS_IGNOREOLD:
-       if (h->npairs == 0 && *(bool *)val) {
-           h->npairs = -1;
-       } else if (h->npairs == -1 && !*(bool *)val) {
-           h->npairs = 0;
-       }
-       break;
-
-    default:
-       /* deliberately doesn't call hisv6_seterror as we don't want
-        * to spam the error log if someone's passing in stuff which
-        * would be relevant to a different history manager */
-       r = false;
-       break;
-    }
-    return r;
-}
diff --git a/history/hisv6/hisv6.h b/history/hisv6/hisv6.h
deleted file mode 100644 (file)
index 6c132bf..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* $Id: hisv6.h 4959 2001-07-25 12:23:32Z alexk $
-**
-** Internal history API interface exposed to HISxxx
-*/
-
-#ifndef HISV6_H
-#define HISV6_H
-
-struct token;
-struct histopts;
-struct history;
-
-void *hisv6_open(const char *path, int flags, struct history *);
-
-bool hisv6_close(void *);
-
-bool hisv6_sync(void *);
-
-bool hisv6_lookup(void *, const char *key, time_t *arrived,
-                 time_t *posted, time_t *expires, struct token *token);
-
-bool hisv6_check(void *, const char *key);
-
-bool hisv6_write(void *, const char *key, time_t arrived,
-                time_t posted, time_t expires, const struct token *token);
-
-bool hisv6_replace(void *, const char *key, time_t arrived,
-                time_t posted, time_t expires, const struct token *token);
-
-bool hisv6_expire(void *, const char *, const char *, bool,
-                 void *, time_t threshold,
-                 bool (*exists)(void *, time_t, time_t, time_t,
-                                struct token *));
-
-bool hisv6_walk(void *, const char *, void *,
-               bool (*)(void *, time_t, time_t, time_t,
-                        const struct token *));
-
-const char *hisv6_error(void *);
-
-bool hisv6_remember(void *, const char *key, time_t arrived);
-
-bool hisv6_ctl(void *, int, void *);
-
-#endif
diff --git a/include/Makefile b/include/Makefile
deleted file mode 100644 (file)
index fed5549..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-##  $Id: Makefile 6326 2003-05-05 21:47:43Z rra $
-##
-##  Currently just handles creation of the automatically generated header
-##  files.  Eventually, rules for installing INN's header files will go
-##  here.
-
-include ../Makefile.global
-
-top          = ..
-
-ALL          = inn/system.h inn/version.h
-
-EXTRA        = config.h paths.h
-
-PUBLIC       = config.h conffile.h dbz.h inndcomm.h libinn.h nntp.h ov.h \
-               paths.h storage.h
-
-all: $(ALL) $(EXTRA)
-
-clean:
-       rm -f $(ALL)
-
-clobber distclean: clean
-       rm -f $(EXTRA)
-
-depend tags ctags:
-
-profiled: all
-
-$(EXTRA) $(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Build rules.
-
-inn/system.h: config.h $(top)/support/mksystem
-       $(top)/support/mksystem $(AWK) config.h > $@
-
-inn/version.h: $(top)/support/mkversion $(top)/Makefile.global
-       $(top)/support/mkversion '$(VERSION)' '$(VERSION_EXTRA)' > $@
-
-
-##  Installation rules.
-
-install:
-       for F in $(PUBLIC) ; do \
-           $(CP_RPUB) $$F $D$(PATHINCLUDE)/$$F ; \
-       done
-       $(top)/support/install-sh $(OWNER) -m 0755 -d $D$(PATHINCLUDE)/inn
-       for F in inn/*.h ; do \
-           $(CP_RPUB) $$F $D$(PATHINCLUDE)/$$F ; \
-       done
diff --git a/include/acconfig.h b/include/acconfig.h
deleted file mode 100644 (file)
index 1b9cbf1..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*  $Id: acconfig.h 6717 2004-05-16 20:48:51Z rra $
-**
-**  Here be configuration data used by various InterNetNews programs.  This
-**  file is used as source for the autoheader script, which from it and
-**  configure.in generates a config.h.in file that will be used by autoconf
-**  as the repository of all wisdom.
-**
-**  Stuff before TOP and after BOTTOM is copied verbatim to config.h.in;
-**  the rest of this file is in the desired form for autoconfiscation.
-**  Only stuff that autoconf 2.13 couldn't figure out for itself or that
-**  needs a larger comment is included here.
-*/
-
-#ifndef CONFIG_H
-#define CONFIG_H 1
-
-/* Portable defines that don't rely on autoconf results come from here. */
-#include "inn/defines.h"
-
-/*
-**  GENERAL SETTINGS
-**
-**  Look over these settings and make sure they're correct for your site.
-**  These values don't come from configure and therefore may need manual
-**  editing.  The defaults normally should be fine.
-**
-**  For boolean #defines, uncomment and change #undef to #define to enable,
-**  do the reverse to disable.
-*/
-
-/* A null-terminated list of uwildmat(3) patterns matching illegal
-   distributions.  inews and nnrpd will reject posts with a distribution
-   matching one of these patterns. */
-#define BAD_DISTRIBS            "*.*", NULL
-
-/* Default timeout period for ctlinnd, overridden by the -t flag.  If set to
-   zero, ctlinnd will never time out, but will check every two minutes to
-   see if the server is still running so it won't hang forever on a dead
-   server. */
-#define CTLINND_TIMEOUT         0
-
-/* Reject articles posted more than this many seconds in the future. */
-#define DATE_FUZZ               (24L * 60L * 60L)
-
-/* innd will flush the history and active file after this many seconds. */
-#define DEFAULT_TIMEOUT         300
-
-/* Define if inews should put hostnames into the Path header itself. */
-#define DO_INEWS_PATH
-
-/* Define if inews should munge the GECOS entry of the passwd file when
-   attempting to determine a poster's real name.  Use this if your GECOS
-   entries have other stuff after trailing commas or before dashes, things
-   in parentheses that aren't part of the name, etc.  See frontends/inews.c
-   for the full algorithm. */
-#define DO_MUNGE_GECOS
-
-/* Define if rnews should try to connect to the local host. */
-#define DO_RNEWSLOCALCONNECT
-
-/* Define if rnews should syslog articles rejected as duplicates. */
-/* #undef DO_RNEWS_LOG_DUPS */
-
-/* Define if rnews should look in _PATH_RNEWSPROGS for batch unpackers. */
-#define DO_RNEWSPROGS
-
-/* Define if rnews should save articles rejected by the server. */
-/* #undef DO_RNEWS_SAVE_BAD */
-
-/* Value to pass to dbzincore() inside innd.  Under some bizarre low memory
-   circumstance you may want this not to be 1, but normally you always want
-   to load the full history indexes into innd's memory.  Has no effect if
-   using tagged hash (which is always in core). */
-#define INND_DBZINCORE          1
-
-/* A null-terminated list of unknown commands that, when seen by innd,
-   shouldn't be logged to syslog.  Normally innd logs all unknown commands,
-   but sometimes some are so frequent that it's not worth it. */
-#define INND_QUIET_BADLIST      NULL
-
-/* innd will throttle itself after this many I/O errors.  The count is reset
-   on a ctlinnd go.  (ENOSPC is special and will always cause an immediate
-   throttle.) */
-#define IO_ERROR_COUNT          50
-
-/* Length of listen queue for innd. */
-#define MAXLISTEN               25
-
-/* The standard NNTP port. */
-#define NNTP_PORT               119
-
-/* What to use for a Path tail for local posts. */
-#define PATHMASTER              "not-for-mail"
-
-
-/*
-**  CONFIGURE RESULTS
-**
-**  Things determined automatically by autoconf.  Nothing below this point
-**  should require manual editing; if anything here is wrong, see if you
-**  should be passing a flag to configure to set it correctly for your
-**  system.
-**
-**  Be aware that success of some tests will cause other tests to be skipped
-**  since their results aren't then needed.  For example, if you have
-**  standard C headers, INN won't bother looking for stdlib.h, and
-**  HAVE_STDLIB_H will be false whether you have it or not.  This is normal.
-**
-**  Fodder for autoheader is provided in sort -df order (alphabetical,
-**  case-insensitive, ignoring punctuation) to make it easier to check
-**  whether a given entry is in the file.
-*/
-@TOP@
-
-/* Define to a suitable 32-bit type if standard headers don't define.  */
-#undef int32_t
-
-/* Define to `long' if <sys/types.h> doesn't define.  */
-#undef ptrdiff_t
-
-/* Define to `int' if <signal.h> doesn't define.  */
-#undef sig_atomic_t
-
-/* Define to `int' if <sys/socket.h> doesn't define.  */
-#undef socklen_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef ssize_t
-
-/* Define to a suitable 32-bit type if standard headers don't define.  */
-#undef uint32_t
-
-@BOTTOM@
-
-
-/*
-**  BUFFER SIZES AND DATA LENGTHS
-**
-**  You shouldn't need to change any of the following, and changing some of
-**  them may cause other things to break.  Some standard buffer sizes and
-**  lengths of data types for various different things.
-*/
-
-/* The data type to use for article numbers.  This probably can't be
-   increased without a lot of work due to assumptions about the active file
-   format, etc. */
-typedef unsigned long           ARTNUM;
-
-/* Input buffers start at START_BUFF_SIZE.  While reading input, if we have
-   less than LOW_WATER bytes left free in the buffer, use the current
-   buffersize as input to GROW_AMOUNT to determine how much to realloc.
-   Growth must be at least NNTP_STRLEN bytes!  The default settings provide
-   aggressive, exponential buffer growth. */
-#define START_BUFF_SIZE         (4 * 1024)
-#define LOW_WATER               (1 * 1024)
-#define GROW_AMOUNT(x)          ((x) < 128 * 1024 ? (x) : 128 * 1024)
-
-/* The size of a large buffer.  Free dynamically allocated buffers larger
-   than this when we're done with them. */
-#define BIG_BUFFER              (2 * START_BUFF_SIZE)
-
-/* The maximum length of a single header, used as a good guess at a buffer
-   size for some header parsing code.  This is currently also used by innd
-   to determine whether to reject a message for an excessively long header;
-   this behavior should be fixed. */
-#define MAXHEADERSIZE           1024
-
-/* Default buffer size for outgoing feeds from innd. */
-#define SITE_BUFFER_SIZE        (16 * 1024)
-
-/* The size of a small buffer. */
-#define SMBUF                   256
-
-/* Maximum size of a pathname in the spool directory. */
-#define SPOOLNAMEBUFF           512
-
-
-/*
-**  LEGACY
-**
-**  Everything below this point is here so that parts of INN that haven't
-**  been tweaked to use more standard constructs don't break.  Don't count
-**  on any of this staying in this file.  If you have a chance, consider
-**  following the comments before each item and fixing it.
-*/
-
-/* Used to send commands to exploders.  Should be moved into a more specific
-   header file; used by innd/site.c and backends/buffchan.c. */
-#define EXP_CONTROL             '!'
-
-/* Only used by innd and cvtbatch, should be moved to a more specific header
-   file. */
-#define FEED_BYTESIZE           'b'
-#define FEED_FULLNAME           'f'
-#define FEED_HASH               'h'
-#define FEED_HDR_DISTRIB        'D'
-#define FEED_HDR_NEWSGROUP      'N'
-#define FEED_MESSAGEID          'm'
-#define FEED_FNLNAMES           '*'
-#define FEED_HEADERS            'H'
-#define FEED_NAME               'n'
-#define FEED_STOREDGROUP        'G'
-#define FEED_NEWSGROUP          'g'
-#define FEED_OVERVIEW           'O'
-#define FEED_PATH               'P'
-#define FEED_REPLIC             'R'
-#define FEED_SITE               's'
-#define FEED_TIMEEXPIRED        'e'
-#define FEED_TIMERECEIVED       't'
-#define FEED_TIMEPOSTED         'p'
-
-/* Maximum number of flags for a feed in newsfeeds.  Only used in innd,
-   should be moved there (or made dynamic). */
-#define FEED_MAXFLAGS           20
-
-/* Maximum length of argv vectors used in innd/site.c.  This should be moved
-   out of here into that file, or even better hard-coded rather than
-   defined; this value isn't affected by user data and the right value can
-   be determined by looking at the code and seeing how big of an argv it
-   will attempt to construct. */
-#define MAX_BUILTIN_ARGV        20
-
-/* active file flags.  Should be moved to a more specific header file. */
-#define NF_FLAG_ALIAS          '='
-#define NF_FLAG_EXCLUDED       'j'
-#define NF_FLAG_MODERATED      'm'
-#define NF_FLAG_OK             'y'
-#define NF_FLAG_NOLOCAL                'n'
-#define NF_FLAG_IGNORE         'x'
-
-/* Used for parsing the Newsgroups header.  Should be rolled into a library
-   for parsing headers, combining all the code that's currently scattered
-   all over INN for doing that. */
-#define NG_SEPARATOR            ","
-#define NG_ISSEP(c)             ((c) == ',')
-
-/* There's no reason to make all of these #defines except possibly for
-   L_CC_CMD and even that's a stretch.  Since we're logging to our own
-   distinguished log facility, provided that we spread things out between a
-   reasonable variety of log levels, the sysadmin shouldn't have to change
-   any of this.  (Some of this is arguably wrong; L_NOTICE should be
-   LOG_NOTICE, for example.) */
-
-/* Flags to use in opening the logs; some programs add LOG_PID. */
-#define L_OPENLOG_FLAGS         (LOG_CONS | LOG_NDELAY)
-
-/* Fatal error, program is about to exit. */
-#define L_FATAL                 LOG_CRIT
-
-/* Log an error that might mean one or more articles get lost. */
-#define L_ERROR                 LOG_ERR
-
-/* Informational notice, usually not worth caring about. */
-#define L_NOTICE                LOG_WARNING
-
-/* A protocol trace. */
-#define L_TRACE                 LOG_DEBUG
-
-/* All incoming control commands (ctlinnd, etc). */
-#define L_CC_CMD                LOG_INFO
-
-#endif /* !CONFIG_H */
diff --git a/include/clibrary.h b/include/clibrary.h
deleted file mode 100644 (file)
index d57c6d1..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*  $Id: clibrary.h 6704 2004-05-16 19:46:20Z rra $
-**
-**  Here be declarations of routines and variables in the C library.
-**  Including this file is the equivalent of including all of the following
-**  headers, portably:
-**
-**      #include <sys/types.h>
-**      #include <stdarg.h>
-**      #include <stdio.h>
-**      #include <stdlib.h>
-**      #include <stddef.h>
-**      #include <stdint.h>
-**      #include <string.h>
-**      #include <unistd.h>
-**
-**  Missing functions are provided via #define or prototyped if we'll be
-**  adding them to INN's library.  If the system doesn't define a SUN_LEN
-**  macro, one will be provided.  Also provides some standard #defines.
-*/
-
-#ifndef CLIBRARY_H
-#define CLIBRARY_H 1
-
-/* Make sure we have our configuration information. */
-#include "config.h"
-
-/* Assume stdarg is available; don't bother with varargs support any more.
-   We need this to be able to declare vsnprintf. */
-#include <stdarg.h>
-
-/* This is the same method used by autoconf as of 2000-07-29 for including
-   the basic system headers with the addition of handling of strchr,
-   strrchr, and memcpy.  Note that we don't attempt to declare any of the
-   functions; the number of systems left without ANSI-compatible function
-   prototypes isn't high enough to be worth the trouble.  */
-#include <stdio.h>
-#include <sys/types.h>
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# if HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-# if !HAVE_STRCHR
-#  define strchr index
-#  define strrchr rindex
-# endif
-# if !HAVE_MEMCPY
-#  define memcpy(d, s, n)  bcopy((s), (d), (n))
-# endif
-#endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#else
-# if HAVE_STRINGS_H
-#  include <strings.h>
-# endif
-#endif
-
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-/* SCO OpenServer gets int32_t from here. */
-#if HAVE_SYS_BITYPES_H
-# include <sys/bitypes.h>
-#endif
-
-BEGIN_DECLS
-
-/* Provide prototypes for functions not declared in system headers.  Use the
-   NEED_DECLARATION macros for those functions that may be prototyped but
-   implemented incorrectly. */
-#if !HAVE_FSEEKO
-extern int              fseeko(FILE *, off_t, int);
-#endif
-#if !HAVE_FTELLO
-extern off_t            ftello(FILE *);
-#endif
-#if !HAVE_HSTRERROR
-extern const char *     hstrerror(int);
-#endif
-#if !HAVE_MKSTEMP
-extern int              mkstemp(char *);
-#endif
-#if !HAVE_PREAD
-extern ssize_t          pread(int, void *, size_t, off_t);
-#endif
-#if !HAVE_PWRITE
-extern ssize_t          pwrite(int, const void *, size_t, off_t);
-#endif
-#if !HAVE_SETENV
-extern int              setenv(const char *, const char *, int);
-#endif
-#if !HAVE_SETEUID
-extern int              seteuid(uid_t);
-#endif
-#if NEED_DECLARATION_SNPRINTF
-extern int              snprintf(char *, size_t, const char *, ...)
-    __attribute__((__format__(printf, 3, 4)));
-#endif
-#if !HAVE_STRERROR
-extern const char *     strerror(int);
-#endif
-#if !HAVE_STRLCAT
-extern size_t           strlcat(char *, const char *, size_t);
-#endif
-#if !HAVE_STRLCPY
-extern size_t           strlcpy(char *, const char *, size_t);
-#endif
-#if NEED_DECLARATION_VSNPRINTF
-extern int              vsnprintf(char *, size_t, const char *, va_list);
-#endif
-
-END_DECLS
-
-/* "Good enough" replacements for standard functions. */
-#if !HAVE_ATEXIT
-# define atexit(arg) on_exit((arg), 0)
-#endif
-#if !HAVE_STRTOUL
-# define strtoul(a, b, c) (unsigned long) strtol((a), (b), (c))
-#endif
-
-/* This almost certainly isn't necessary, but it's not hurting anything.
-   gcc assumes that if SEEK_SET isn't defined none of the rest are either,
-   so we certainly can as well. */
-#ifndef SEEK_SET
-# define SEEK_SET 0
-# define SEEK_CUR 1
-# define SEEK_END 2
-#endif
-
-/* POSIX requires that these be defined in <unistd.h>.  If one of them has
-   been defined, all the rest almost certainly have. */
-#ifndef STDIN_FILENO
-# define STDIN_FILENO   0
-# define STDOUT_FILENO  1
-# define STDERR_FILENO  2
-#endif
-
-/* On some systems, the macros defined by <ctype.h> are only vaild on ASCII
-   characters (those characters that isascii() says are ASCII).  This comes
-   into play when applying <ctype.h> macros to eight-bit data.  autoconf
-   checks for this with as part of AC_HEADER_STDC, so if autoconf doesn't
-   think our headers are standard, check isascii() first. */
-#if STDC_HEADERS
-# define CTYPE(isXXXXX, c) (isXXXXX((unsigned char)(c)))
-#else
-# define CTYPE(isXXXXX, c) \
-    (isascii((unsigned char)(c)) && isXXXXX((unsigned char)(c)))
-#endif
-
-/* POSIX.1g requires <sys/un.h> to define a SUN_LEN macro for determining
-   the real length of a struct sockaddr_un, but it's not available
-   everywhere yet.  If autoconf couldn't find it, define our own.  This
-   definition is from 4.4BSD by way of Stevens, Unix Network Programming
-   (2nd edition), vol. 1, pg. 917. */
-#if !HAVE_SUN_LEN
-# define SUN_LEN(sun) \
-    (sizeof(*(sun)) - sizeof((sun)->sun_path) + strlen((sun)->sun_path))
-#endif
-
-/* Used to name the elements of the array passed to pipe(). */
-#define PIPE_READ       0
-#define PIPE_WRITE      1
-
-/* Used for iterating through arrays.  ARRAY_SIZE returns the number of
-   elements in the array (useful for a < upper bound in a for loop) and
-   ARRAY_END returns a pointer to the element past the end (ISO C99 makes it
-   legal to refer to such a pointer as long as it's never dereferenced). */
-#define ARRAY_SIZE(array)       (sizeof(array) / sizeof((array)[0]))
-#define ARRAY_END(array)        (&(array)[ARRAY_SIZE(array)])
-
-
-#endif /* !CLIBRARY_H */
diff --git a/include/conffile.h b/include/conffile.h
deleted file mode 100644 (file)
index 78bc972..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*  $Revision: 5086 $
-**
-**  Data structures, functions and cetera used for config file parsing.
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
-    FILE *f;
-    char *buf;
-    unsigned int sbuf;
-    int lineno;
-    int array_len;
-    char **array;
-    char *filename;
-} CONFFILE;
-
-typedef struct {
-    int type;
-#define CONFstring     -1
-    char *name;
-} CONFTOKEN;
-
-extern char CONFerror[];
-
-extern CONFFILE *CONFfopen(char*);
-extern void CONFfclose(CONFFILE*);
-
-extern CONFTOKEN *CONFgettoken(CONFTOKEN*, CONFFILE*);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/include/dbz.h b/include/dbz.h
deleted file mode 100644 (file)
index f8390b6..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __DBZ_H__
-#define __DBZ_H__
-
-/* Need the definition of HASH. */
-#include "libinn.h"
-
-BEGIN_DECLS
-
-/* This is the number of bytes of the md5 to actually store in
- * the .pag file.  This number directly effects the collision
- * rate and memory usage.  You can probably set this number as
- * low as 5 w/o problems and some sites may want to set it as
- * high as 8.  Anything higher than that is probably not useful.
- * Note at the internal hash size isn't the only factor that
- * effects collision rate.  The table index is used as an implicit
- * part of the hash value stored also.
- */
-#ifdef DO_TAGGED_HASH
-#define DBZMAXKEY      255
-#define DBZ_INTERNAL_HASH_SIZE   4
-#else
-#define DBZ_INTERNAL_HASH_SIZE   6
-#endif
-
-typedef enum {DBZSTORE_OK, DBZSTORE_EXISTS, DBZSTORE_ERROR} DBZSTORE_RESULT;
-typedef enum {INCORE_NO, INCORE_MEM, INCORE_MMAP} dbz_incore_val;
-
-typedef struct {
-    /* Whether to write to the filesystem in addition to updating the incore
-       copy.  This will replace a single large write to disk when dbzsync is
-       called.  */
-    bool             writethrough;
-    /* Whether to do hash lookups from disk, memory or a mmap'ed file */
-    dbz_incore_val   pag_incore;
-    dbz_incore_val   exists_incore;
-    /* Whether dbzstore should update the database async or sync.  This
-       is only applicable if you're not mmaping the database */
-    bool             nonblock;
-} dbzoptions;
-
-#ifdef __GNUC__
-#define PACKED __attribute__ ((packed))
-#else
-#if !defined(PACKED)
-#define PACKED
-#endif
-#endif
-
-#if !defined(lint) && (defined(__SUNPRO_C) || defined(_nec_ews))
-#pragma pack(1)
-#endif /* nor lint, nor __SUNPRO_C, nor sgi, nor _nec_ews */
-typedef struct {
-    char               hash[DBZ_INTERNAL_HASH_SIZE];
-} PACKED erec;
-#if !defined(lint) && (defined(__SUNPRO_C) || defined(_nec_ews))
-#pragma pack()
-#endif /* nor lint, nor__SUNPRO_C, nor _nec_ews */
-
-/* standard dbm functions */
-extern bool dbzinit(const char *name);
-extern bool dbzclose(void);
-
-/* new stuff for dbz */
-extern bool dbzfresh(const char *name, off_t size);
-extern bool dbzagain(const char *name, const char *oldname);
-extern bool dbzexists(const HASH key);
-extern bool dbzfetch(const HASH key, off_t *value);
-extern DBZSTORE_RESULT dbzstore(const HASH key, off_t data);
-extern bool dbzsync(void);
-extern long dbzsize(off_t contents);
-extern void dbzsetoptions(const dbzoptions options);
-extern void dbzgetoptions(dbzoptions *options);
-
-END_DECLS
-
-#endif /* __DBZ_H__ */
diff --git a/include/inn/buffer.h b/include/inn/buffer.h
deleted file mode 100644 (file)
index e9deb2b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*  $Id: buffer.h 6295 2003-04-16 05:46:38Z rra $
-**
-**  Counted, reusable memory buffer.
-**
-**  A buffer is an allocated bit of memory with a known size and a separate
-**  data length.  It's intended to store strings and can be reused repeatedly
-**  to minimize the number of memory allocations.  Buffers increase in
-**  increments of 1K.
-**
-**  A buffer contains a notion of the data that's been used and the data
-**  that's been left, used when the buffer is an I/O buffer where lots of data
-**  is buffered and then slowly processed out of the buffer.  The total length
-**  of the data is used + left.  If a buffer is just used to store some data,
-**  used can be set to 0 and left stores the length of the data.
-*/
-
-#ifndef INN_BUFFER_H
-#define INN_BUFFER_H 1
-
-#include <inn/defines.h>
-
-struct buffer {
-    size_t size;                /* Total allocated length. */
-    size_t used;                /* Data already used. */
-    size_t left;                /* Remaining unused data. */
-    char *data;                 /* Pointer to allocated memory. */
-};
-
-BEGIN_DECLS
-
-/* Allocate a new buffer and initialize its contents. */
-struct buffer *buffer_new(void);
-
-/* Resize a buffer to be at least as large as the provided size. */
-void buffer_resize(struct buffer *, size_t);
-
-/* Set the buffer contents, ignoring anything currently there. */
-void buffer_set(struct buffer *, const char *data, size_t length);
-
-/* Append data to the buffer. */
-void buffer_append(struct buffer *, const char *data, size_t length);
-
-/* Swap the contents of two buffers. */
-void buffer_swap(struct buffer *, struct buffer *);
-
-END_DECLS
-
-#endif /* INN_BUFFER_H */
diff --git a/include/inn/confparse.h b/include/inn/confparse.h
deleted file mode 100644 (file)
index 5c2aa1c..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*  $Id: confparse.h 5114 2002-02-18 01:17:24Z rra $
-**
-**  Configuration file parsing interface.
-*/
-
-#ifndef INN_CONFPARSE_H
-#define INN_CONFPARSE_H 1
-
-#include <inn/defines.h>
-
-/* Avoid including <inn/vector.h> unless the client needs it. */
-struct vector;
-
-/* The opaque data type representing a configuration tree. */
-struct config_group;
-
-BEGIN_DECLS
-
-/* Parse the given file and build a configuration tree.  This does purely
-   syntactic parsing; no semantic checking is done.  After the file name, a
-   NULL-terminated list of const char * pointers should be given, naming the
-   top-level group types that the caller is interested in.  If none are given
-   (if the second argument is NULL), the entire file is parsed.  (This is
-   purely for efficiency reasons; if one doesn't care about speed, everything
-   will work the same if no types are given.)
-
-   Returns a config_group for the top-level group representing the entire
-   file.  Generally one never wants to query parameters in this group;
-   instead, the client should then call config_find_group for the group type
-   of interest.  Returns NULL on failure to read the file or on a parse
-   failure; errors are reported via warn. */
-struct config_group *config_parse_file(const char *filename, /* types */ ...);
-
-/* config_find_group returns the first group of the given type found in the
-   tree rooted at its argument.  config_next_group returns the next group in
-   the tree of the same type as the given group (or NULL if none is found).
-   This can be used to do such things as enumerate all "peer" groups in a
-   configuration file. */
-struct config_group *config_find_group(struct config_group *,
-                                       const char *type);
-struct config_group *config_next_group(struct config_group *);
-
-/* Accessor functions for group information. */
-const char *config_group_type(struct config_group *);
-const char *config_group_tag(struct config_group *);
-
-/* Look up a parameter in a given config tree.  The second argument is the
-   name of the parameter, and the result will be stored in the third argument
-   if the function returns true.  If it returns false, the third argument is
-   unchanged and that parameter wasn't set (or was set to an invalid value for
-   the expected type). */
-bool config_param_boolean(struct config_group *, const char *, bool *);
-bool config_param_integer(struct config_group *, const char *, long *);
-bool config_param_real(struct config_group *, const char *, double *);
-bool config_param_string(struct config_group *, const char *, const char **);
-bool config_param_list(struct config_group *, const char *, struct vector *);
-
-/* Used for checking a configuration file, returns a vector of all parameters
-   set for the given config_group, including inherited ones. */
-struct vector *config_params(struct config_group *);
-
-/* Used for reporting semantic errors, config_error_param reports the given
-   error at a particular parameter in a config_group and config_error_group
-   reports an error at the definition of that group.  The error is reported
-   using warn. */
-void config_error_group(struct config_group *, const char *format, ...);
-void config_error_param(struct config_group *, const char *key,
-                        const char *format, ...);
-
-/* Free all space allocated by the tree rooted at config_group.  One normally
-   never wants to do this.  WARNING: This includes the storage allocated for
-   all strings returned by config_param_string and config_param_list for any
-   configuration groups in this tree. */
-void config_free(struct config_group *);
-
-END_DECLS
-
-#endif /* INN_CONFPARSE_H */
diff --git a/include/inn/defines.h b/include/inn/defines.h
deleted file mode 100644 (file)
index 74f4969..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*  $Id: defines.h 6124 2003-01-14 06:03:29Z rra $
-**
-**  Portable defines used by other INN header files.
-**
-**  In order to make the libraries built by INN usable by other software,
-**  INN needs to install several header files.  Installing autoconf-
-**  generated header files, however, is a bad idea, since the defines will
-**  conflict with other software that uses autoconf.
-**
-**  This header contains common definitions, such as internal typedefs and
-**  macros, common to INN's header files but not based on autoconf probes.
-**  As such, it's limited in what it can do; if compiling software against
-**  INN's header files on a system not supporting basic ANSI C features
-**  (such as const) or standard types (like size_t), the software may need
-**  to duplicate the tests that INN itself performs, generate a config.h,
-**  and make sure that config.h is included before any INN header files.
-*/
-
-#ifndef INN_DEFINES_H
-#define INN_DEFINES_H 1
-
-#include <inn/system.h>
-
-/* BEGIN_DECLS is used at the beginning of declarations so that C++
-   compilers don't mangle their names.  END_DECLS is used at the end. */
-#undef BEGIN_DECLS
-#undef END_DECLS
-#ifdef __cplusplus
-# define BEGIN_DECLS    extern "C" {
-# define END_DECLS      }
-#else
-# define BEGIN_DECLS    /* empty */
-# define END_DECLS      /* empty */
-#endif
-
-/* __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
-   could you use the __format__ form of the attributes, which is what we use
-   (to avoid confusion with other macros). */
-#ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-#  define __attribute__(spec)   /* empty */
-# endif
-#endif
-
-/* Used for unused parameters to silence gcc warnings. */
-#define UNUSED  __attribute__((__unused__))
-
-/* Make available the bool type. */
-#if INN_HAVE_STDBOOL_H
-# include <stdbool.h>
-#else
-# undef true
-# undef false
-# define true   (1)
-# define false  (0)
-# ifndef __cplusplus
-#  define bool int
-# endif
-#endif /* INN_HAVE_STDBOOL_H */
-
-/* Tell Perl that we have a bool type. */
-#ifndef HAS_BOOL
-# define HAS_BOOL 1
-#endif
-
-#endif /* !INN_DEFINES_H */
diff --git a/include/inn/hashtab.h b/include/inn/hashtab.h
deleted file mode 100644 (file)
index 8d9f31e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*  $Id: hashtab.h 5944 2002-12-08 02:33:08Z rra $
-**
-**  Generic hash table interface.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  A hash table takes a hash function that acts on keys, a function to
-**  extract the key from a data item stored in a hash, a function that takes
-**  a key and a data item and returns true if the key matches, and a
-**  function to be called on any data item being deleted from the hash.
-**
-**  hash_create creates a hash and hash_free frees all the space allocated
-**  by one.  hash_insert, hash_replace, and hash_delete modify it, and
-**  hash_lookup extracts values.  hash_traverse can be used to walk the
-**  hash, and hash_count returns the number of elements currently stored in
-**  the hash.  hash_searches, hash_collisions, and hash_expansions extract
-**  performance and debugging statistics.
-*/
-
-#ifndef INN_HASHTAB_H
-#define INN_HASHTAB_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/* The layout of this struct is entirely internal to the implementation. */
-struct hash;
-
-/* Data types for function pointers used by the hash table interface. */
-typedef unsigned long (*hash_func)(const void *);
-typedef const void * (*hash_key_func)(const void *);
-typedef bool (*hash_equal_func)(const void *, const void *);
-typedef void (*hash_delete_func)(void *);
-typedef void (*hash_traverse_func)(void *, void *);
-
-/* Generic hash table interface. */
-struct hash *   hash_create(size_t, hash_func, hash_key_func,
-                            hash_equal_func, hash_delete_func);
-void            hash_free(struct hash *);
-void *          hash_lookup(struct hash *, const void *key);
-bool            hash_insert(struct hash *, const void *key, void *datum);
-bool            hash_replace(struct hash *, const void *key, void *datum);
-bool            hash_delete(struct hash *, const void *key);
-void            hash_traverse(struct hash *, hash_traverse_func, void *);
-unsigned long   hash_count(struct hash *);
-unsigned long   hash_searches(struct hash *);
-unsigned long   hash_collisions(struct hash *);
-unsigned long   hash_expansions(struct hash *);
-
-/* Hash functions available for callers. */
-unsigned long   hash_string(const void *);
-
-/* Functions useful for constructing new hashes. */
-unsigned long   hash_lookup2(const char *, size_t, unsigned long partial);
-
-END_DECLS
-
-#endif /* INN_HASHTAB_H */
diff --git a/include/inn/history.h b/include/inn/history.h
deleted file mode 100644 (file)
index 48c6e25..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*  $Id: history.h 4916 2001-07-18 12:33:01Z alexk $
-**
-**  Interface to history API
-*/
-
-#ifndef INN_HISTORY_H
-#define INN_HISTORY_H
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/*
-**  ensure appropriate scoping; we don't pull inn/storage.h as we
-**  don't need; our caller then has the option
-*/
-struct history;
-struct token;
-
-/*
-**  structure giving cache statistics returned from HISstats
-*/
-struct histstats {
-    /* number of positive hits */
-    int hitpos;
-    /* number of negative hits */
-    int hitneg;
-    /* number of misses (positive hit, but not in cache) */
-    int misses;
-    /* number of does not exists (negative hit, but not in cache) */
-    int dne;
-};
-
-
-/*
-**  flags passed to HISopen
-*/
-
-/* open database read only */
-#define HIS_RDONLY (0)
-
-/* open database read/write */
-#define HIS_RDWR (1<<0)
-
-/* create on open */
-#define HIS_CREAT (1<<1)
-
-/* hint that the data should be kept on disk */
-#define HIS_ONDISK (1<<2)
-
-/* hint that the data should be kept in core */
-#define HIS_INCORE (1<<3)
-
-/* hint that the data should be kept mmap()ed */
-#define HIS_MMAP (1<<4)
-
-/*
-**  values passed to HISctl
-*/
-enum {
-    /* (char **) get history path */
-    HISCTLG_PATH,
-
-    /* (char *) set history path */
-    HISCTLS_PATH,
-
-    /* (int) how many history writes may be outstanding */
-    HISCTLS_SYNCCOUNT,
-
-    /* (size_t) number of pairs for which the database should be sized */
-    HISCTLS_NPAIRS,
-
-    /* (bool) Ignore old database during expire */
-    HISCTLS_IGNOREOLD,
-    
-    /* (time_t) interval, in s, between stats of the history database
-     * for * detecting a replacement, or 0 to disable (no checks);
-     * defaults {hisv6, taggedhash} */
-    HISCTLS_STATINTERVAL
-
-};
-
-struct history *        HISopen(const char *, const char *, int);
-bool                    HISclose(struct history *);
-bool                    HISsync(struct history *);
-void                    HISsetcache(struct history *, size_t);
-bool                    HISlookup(struct history *, const char *, time_t *,
-                                 time_t *, time_t *, struct token *);
-bool                    HIScheck(struct history *, const char *);
-bool                    HISwrite(struct history *, const char *, time_t,
-                                time_t, time_t, const struct token *);
-bool                    HISremember(struct history *, const char *, time_t);
-bool                    HISreplace(struct history *, const char *, time_t,
-                                  time_t, time_t, const struct token *);
-bool                    HISexpire(struct history *, const char *, const char *,
-                                 bool, void *, time_t,
-                                 bool (*)(void *, time_t, time_t, time_t,
-                                          struct token *));
-bool                    HISwalk(struct history *, const char *, void *,
-                               bool (*)(void *, time_t, time_t, time_t,
-                                        const struct token *));
-struct histstats        HISstats(struct history *);
-const char *            HISerror(struct history *);
-bool                    HISctl(struct history *, int, void *);
-void                    HISlogclose(void);
-void                    HISlogto(const char *s);
-
-END_DECLS
-
-#endif
diff --git a/include/inn/innconf.h b/include/inn/innconf.h
deleted file mode 100644 (file)
index 8cd24d2..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*  $Id: innconf.h 7751 2008-04-06 14:35:40Z iulius $
-**
-**  inn.conf parser interface.
-**
-**  The interface to reading inn.conf configuration files and managing the
-**  resulting innconf struct.
-*/
-
-#ifndef INN_INNCONF_H
-#define INN_INNCONF_H 1
-
-#include <inn/defines.h>
-#include <stdio.h>
-
-/*
-**  This structure is organized in the same order as the variables contained
-**  in it are mentioned in the inn.conf documentation, and broken down into
-**  the same sections.  Note that due to the implementation, only three types
-**  of variables are permissible here:  char *, bool, and long.
-*/
-struct innconf {
-    /* General Settings */
-    char *domain;               /* Default domain of local host */
-    char *innflags;             /* Flags to pass to innd on startup */
-    char *mailcmd;              /* Command to send report/control type mail */
-    char *mta;                  /* MTA for mailing to moderators, innmail */
-    char *pathhost;             /* Entry for the Path line */
-    char *server;               /* Default server to connect to */
-
-    /* Feed Configuration */
-    long artcutoff;             /* Max accepted article age */
-    char *bindaddress;          /* Which interface IP to bind to */
-    char *bindaddress6;         /* Which interface IPv6 to bind to */
-    bool dontrejectfiltered;    /* Don't reject filtered article? */
-    long hiscachesize;          /* Size of the history cache in kB */
-    bool ignorenewsgroups;      /* Propagate cmsgs by affected group? */
-    bool immediatecancel;       /* Immediately cancel timecaf messages? */
-    long linecountfuzz;         /* Check linecount and reject if off by more */
-    long maxartsize;            /* Reject articles bigger than this */
-    long maxconnections;        /* Max number of incoming NNTP connections */
-    char *pathalias;            /* Prepended Host for the Path line */
-    char *pathcluster;          /* Appended Host for the Path line */
-    bool pgpverify;             /* Verify control messages with pgpverify? */
-    long port;                  /* Which port innd should listen on */
-    bool refusecybercancels;    /* Reject message IDs with "<cancel."? */
-    bool remembertrash;         /* Put unwanted article IDs into history */
-    char *sourceaddress;        /* Source IP for outgoing NNTP connections */
-    char *sourceaddress6;       /* Source IPv6 for outgoing NNTP connections */
-    bool verifycancels;         /* Verify cancels against article author */
-    bool wanttrash;             /* Put unwanted articles in junk */
-    long wipcheck;              /* How long to defer other copies of article */
-    long wipexpire;             /* How long to keep pending article record */
-
-    /* History settings */
-    char *hismethod;            /* Which history method to use */
-    
-    /* Article Storage */
-    long cnfscheckfudgesize;    /* Additional CNFS integrity checking */
-    bool enableoverview;        /* Store overview info for articles? */
-    bool groupbaseexpiry;       /* Do expiry by newsgroup? */
-    bool mergetogroups;         /* Refile articles from to.* into to */
-    bool nfswriter;            /* Use NFS writer functionality */
-    long overcachesize;         /* fd size cache for tradindexed */
-    char *ovgrouppat;           /* Newsgroups to store overview for */
-    char *ovmethod;             /* Which overview method to use */
-    bool storeonxref;           /* SMstore use Xref to detemine class? */
-    bool useoverchan;           /* overchan write the overview, not innd? */
-    bool wireformat;            /* Store tradspool artilces in wire format? */
-    bool xrefslave;             /* Act as a slave of another server? */
-
-    /* Reading */
-    bool allownewnews;          /* Allow use of the NEWNEWS command */
-    bool articlemmap;           /* Use mmap to read articles? */
-    long clienttimeout;         /* How long nnrpd can be inactive */
-    long initialtimeout;        /* How long nnrpd waits for first command */
-    long msgidcachesize;        /* Number of entries in the message ID cache */
-    bool nfsreader;             /* Use NFS reader functionality */
-    long nfsreaderdelay;        /* Delay applied to article arrival */
-    bool nnrpdcheckart;         /* Check article existence before returning? */
-    char *nnrpdflags;           /* Arguments to pass when spawning nnrpd */
-    long nnrpdloadlimit;       /* Maximum getloadvg() we allow */
-    bool noreader;              /* Refuse to fork nnrpd for readers? */
-    bool readerswhenstopped;    /* Allow nnrpd when server is paused */
-    bool readertrack;           /* Use the reader tracking system? */
-    bool tradindexedmmap;       /* Whether to mmap for tradindexed */
-
-    /* Reading -- Keyword Support */
-    bool keywords;              /* Generate keywords in overview? */
-    long keyartlimit;           /* Max article size for keyword generation */
-    long keylimit;              /* Max allocated space for keywords */
-    long keymaxwords;           /* Max count of interesting works */
-
-    /* Posting */
-    bool addnntppostingdate;    /* Add NNTP-Posting-Date: to posts */
-    bool addnntppostinghost;    /* Add NNTP-Posting-Host: to posts */
-    bool checkincludedtext;     /* Reject if too much included text */
-    char *complaints;           /* Address for X-Complaints-To: */
-    char *fromhost;             /* Host for the From: line */
-    long localmaxartsize;       /* Max article size of local postings */
-    char *moderatormailer;      /* Default host to mail moderated articles */
-    bool nnrpdauthsender;       /* Add authenticated Sender: header? */
-    char *nnrpdposthost;        /* Host postings should be forwarded to */
-    long nnrpdpostport;         /* Port postings should be forwarded to */
-    char *organization;         /* Data for the Organization: header */
-    bool spoolfirst;            /* Spool all posted articles? */
-    bool strippostcc;           /* Strip To:, Cc: and Bcc: from posts */
-
-    /* Posting -- Exponential Backoff */
-    bool backoffauth;           /* Backoff by user, not IP address */
-    char *backoffdb;            /* Directory for backoff databases */
-    long backoffk;              /* Multiple for the sleep time */
-    long backoffpostfast;       /* Upper time limit for fast posting */
-    long backoffpostslow;       /* Lower time limit for slow posting */
-    long backofftrigger;        /* Number of postings before triggered */
-
-    /* Monitoring */
-    bool doinnwatch;            /* Start innwatch from rc.news? */
-    long innwatchbatchspace;    /* Minimum free space in pathoutgoing */
-    long innwatchlibspace;      /* Minimum free space in pathdb */
-    long innwatchloload;        /* Load times 100 at which to restart */
-    long innwatchhiload;        /* Load times 100 at which to throttle */
-    long innwatchpauseload;     /* Load times 100 at which to pause */
-    long innwatchsleeptime;     /* Seconds to wait between checks */
-    long innwatchspoolnodes;    /* Minimum free inodes in patharticles */
-    long innwatchspoolspace;    /* Minimum free space in patharticles */
-
-    /* Logging */
-    bool docnfsstat;            /* Run cnfsstat in the background? */
-    bool logartsize;            /* Log article sizes? */
-    bool logcancelcomm;         /* Log ctlinnd cancel commands to syslog? */
-    long logcycles;             /* How many old logs scanlogs should keep */
-    bool logipaddr;             /* Log by host IP address? */
-    bool logsitename;           /* Log outgoing site names? */
-    bool nnrpdoverstats;        /* Log overview statistics? */
-    long nntpactsync;           /* Checkpoint log after this many articles */
-    bool nntplinklog;           /* Put storage token into the log? */
-    long status;                /* Status file update interval */
-    long timer;                 /* Performance monitoring interval */
-    char *stathist;            /* Filename for history profiler outputs */
-
-    /* System Tuning */
-    long badiocount;            /* Failure count before dropping channel */
-    long blockbackoff;          /* Multiplier for sleep in EAGAIN writes */
-    long chaninacttime;         /* Wait before noticing inactive channels */
-    long chanretrytime;         /* How long before channel restarts */
-    long icdsynccount;          /* Articles between active & history updates */
-    long keepmmappedthreshold;  /* Threshold for keeping mmap in buffindexed */
-    long maxforks;              /* Give up after this many fork failure */
-    long nicekids;              /* Child processes get niced to this */
-    long nicenewnews;           /* If NEWNEWS command is used, nice to this */
-    long nicennrpd;             /* nnrpd is niced to this */
-    long pauseretrytime;        /* Seconds before seeing if pause is ended */
-    long peertimeout;           /* How long peers can be inactive */
-    long rlimitnofile;          /* File descriptor limit to set */
-    long maxcmdreadsize;        /* max NNTP command read size used by innd */
-    long datamovethreshold;     /* threshold no to extend buffer for ever */
-
-    /* Paths */
-    char *patharchive;          /* Archived news. */
-    char *patharticles;         /* Articles. */
-    char *pathbin;              /* News binaries. */
-    char *pathcontrol;          /* Path to control message handlers */
-    char *pathdb;               /* News database files */
-    char *pathetc;              /* News configuration files */
-    char *pathfilter;           /* Filtering code */
-    char *pathhttp;             /* HTML files */
-    char *pathincoming;         /* Incoming spooled news */
-    char *pathlog;              /* Log files */
-    char *pathnews;             /* Home directory for news user */
-    char *pathoutgoing;         /* Outgoing news batch files */
-    char *pathoverview;         /* Overview infomation */
-    char *pathrun;              /* Runtime state and sockets */
-    char *pathspool;            /* Root of news spool hierarchy */
-    char *pathtmp;              /* Temporary files for the news system */
-};
-
-/* The global innconf variable used in programs. */
-extern struct innconf *innconf;
-
-/* Used to request various types of quoting when printing out values. */
-enum innconf_quoting {
-    INNCONF_QUOTE_NONE,
-    INNCONF_QUOTE_SHELL,
-    INNCONF_QUOTE_PERL,
-    INNCONF_QUOTE_TCL
-};
-
-BEGIN_DECLS
-
-/* Parse the given file into innconf, using the default path if NULL. */
-bool innconf_read(const char *path);
-
-/* Free an innconf struct and all allocated memory for it. */
-void innconf_free(struct innconf *);
-
-/* Print a single value with appropriate quoting, return whether found. */
-bool innconf_print_value(FILE *, const char *key, enum innconf_quoting);
-
-/* Dump the entire configuration with appropriate quoting. */
-void innconf_dump(FILE *, enum innconf_quoting);
-
-/* Compare two instances of an innconf struct, for testing. */
-bool innconf_compare(struct innconf *, struct innconf *);
-
-/* Check the validity of an inn.conf file.  Does innconf_read plus checking
-   for any unknown parameters that are set. */
-bool innconf_check(const char *path);
-
-END_DECLS
-
-#endif /* INN_INNCONF_H */
diff --git a/include/inn/list.h b/include/inn/list.h
deleted file mode 100644 (file)
index 99004e4..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*  $Id: list.h 6168 2003-01-21 06:27:32Z alexk $
-**
-*/
-
-#ifndef INN_LIST_H
-#define INN_LIST_H 1
-
-#include <inn/defines.h>
-
-struct node {
-    struct node *succ;
-    struct node *pred;
-};
-
-struct list {
-    struct node *head;
-    struct node *tail;
-    struct node *tailpred;
-};
-
-BEGIN_DECLS
-
-/* initialise a new list */
-void list_new(struct list *list);
-
-/* add a node to the head of the list */
-struct node *list_addhead(struct list *list, struct node *node);
-
-/* add a node to the tail of the list */
-struct node *list_addtail(struct list *list, struct node *node);
-
-/* return a pointer to the first node on the list */
-struct node *list_head(struct list *list);
-
-/* return a pointer to the last node on the list */
-struct node *list_tail(struct list *list);
-
-struct node *list_succ(struct node *node);
-struct node *list_pred(struct node *node);
-
-struct node *list_remhead(struct list *list);
-struct node *list_remove(struct node *node);
-struct node *list_remtail(struct list *list);
-struct node *list_insert(struct list *list, struct node *node,
-                        struct node *pred);
-
-bool list_isempty(struct list *list);
-
-END_DECLS
-
-#endif /* INN_LIST_H */
diff --git a/include/inn/md5.h b/include/inn/md5.h
deleted file mode 100644 (file)
index f0b1584..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*  $Id: md5.h 4567 2001-02-24 08:10:16Z rra $
-**
-**  RSA Data Security, Inc. MD5 Message-Digest Algorithm
-**
-**  LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-**  INCLUDING ALL IMPLIED WARRANTIES OF MER- CHANTABILITY AND FITNESS.  IN
-**  NO EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-**  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-**  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-**  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-**  PERFORMANCE OF THIS SOFTWARE.
-**
-**  Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
-**
-**  License to copy and use this software is granted provided that it is
-**  identified as the "RSA Data Security, Inc. MD5 Message-Digest
-**  Algorithm" in all material mentioning or referencing this software or
-**  this function.
-**
-**  License is also granted to make and use derivative works provided that
-**  such works are identified as "derived from the RSA Data Security,
-**  Inc. MD5 Message-Digest Algorithm" in all material mentioning or
-**  referencing the derived work.
-**
-**  RSA Data Security, Inc. makes no representations concerning either the
-**  merchantability of this software or the suitability of this software for
-**  any particular purpose.  It is provided "as is" without express or
-**  implied warranty of any kind.
-**
-**  These notices must be retained in any copies of any part of this
-**  documentation and/or software.
-*/
-
-#ifndef INN_MD5_H
-#define INN_MD5_H 1
-
-#include <inn/defines.h>
-
-/* Make sure we have uint32_t. */
-#include <sys/types.h>
-#if INN_HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-
-/* SCO OpenServer gets int32_t from here. */
-#if INN_HAVE_SYS_BITYPES_H
-# include <sys/bitypes.h>
-#endif
-
-/* Bytes to process at once, defined by the algorithm. */ 
-#define MD5_CHUNKSIZE   (1 << 6)
-#define MD5_CHUNKWORDS  (MD5_CHUNKSIZE / sizeof(uint32_t))
-
-/* Length of the digest, defined by the algorithm. */
-#define MD5_DIGESTSIZE  16
-#define MD5_DIGESTWORDS (MD5_DIGESTSIZE / sizeof(uint32_t))
-
-BEGIN_DECLS
-
-/* Data structure for MD5 message-digest computation. */
-struct md5_context {
-    uint32_t count[2];                          /* A 64-bit byte count. */
-    uint32_t buf[MD5_DIGESTWORDS];              /* Scratch buffer. */
-    union {
-        unsigned char byte[MD5_CHUNKSIZE];      /* Byte chunk buffer. */
-        uint32_t word[MD5_CHUNKWORDS];          /* Word chunk buffer. */
-    } in;
-    unsigned int datalen;                       /* Length of data in in. */
-    unsigned char digest[MD5_DIGESTSIZE];       /* Final digest. */
-};
-
-extern void md5_hash(const unsigned char *, size_t, unsigned char *);
-extern void md5_init(struct md5_context *);
-extern void md5_update(struct md5_context *, const unsigned char *, size_t);
-extern void md5_final(struct md5_context *);
-
-END_DECLS
-
-#endif /* !INN_MD5_H */
diff --git a/include/inn/messages.h b/include/inn/messages.h
deleted file mode 100644 (file)
index 22297fa..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*  $Id: messages.h 5496 2002-06-07 13:59:06Z alexk $
-**
-**  Logging, debugging, and error reporting functions.
-**
-**  This collection of functions facilitate logging, debugging, and error
-**  reporting in a flexible manner that can be used by libraries as well as by
-**  programs.  The functions are based around the idea of handlers, which take
-**  a message and do something appropriate with it.  The program can set the
-**  appropriate handlers for all the message reporting functions, and then
-**  library code can use them with impunity and know the right thing will
-**  happen with the messages.
-*/
-
-#ifndef INN_MESSAGES_H
-#define INN_MESSAGES_H 1
-
-#include <inn/defines.h>
-#include <stdarg.h>
-
-BEGIN_DECLS
-
-/* These are the currently-supported types of traces. */
-enum message_trace {
-    TRACE_NETWORK,              /* Network traffic. */
-    TRACE_PROGRAM,              /* Stages of program execution. */
-    TRACE_ALL                   /* All traces; this must be last. */
-};
-
-/* The reporting functions.  The ones prefaced by "sys" add a colon, a space,
-   and the results of strerror(errno) to the output and are intended for
-   reporting failures of system calls. */
-extern void trace(enum message_trace, const char *, ...)
-    __attribute__((__format__(printf, 2, 3)));
-extern void notice(const char *, ...)
-    __attribute__((__format__(printf, 1, 2)));
-extern void sysnotice(const char *, ...)
-    __attribute__((__format__(printf, 1, 2)));
-extern void warn(const char *, ...)
-    __attribute__((__format__(printf, 1, 2)));
-extern void syswarn(const char *, ...)
-    __attribute__((__format__(printf, 1, 2)));
-extern void die(const char *, ...)
-    __attribute__((__noreturn__, __format__(printf, 1, 2)));
-extern void sysdie(const char *, ...)
-    __attribute__((__noreturn__, __format__(printf, 1, 2)));
-
-/* Debug is handled specially, since we want to make the code disappear
-   completely unless we're built with -DDEBUG.  We can only do that with
-   support for variadic macros, though; otherwise, the function just won't do
-   anything. */
-#if !defined(DEBUG) && (INN_HAVE_C99_VAMACROS || INN_HAVE_GNU_VAMACROS)
-# if INN_HAVE_C99_VAMACROS
-#  define debug(format, ...)            /* empty */
-# elif INN_HAVE_GNU_VAMACROS
-#  define debug(format, args...)        /* empty */
-# endif
-#else
-extern void debug(const char *, ...)
-    __attribute__((__format__(printf, 1, 2)));
-#endif
-
-/* Set the handlers for various message functions.  All of these functions
-   take a count of the number of handlers and then function pointers for each
-   of those handlers.  These functions are not thread-safe; they set global
-   variables. */
-extern void message_handlers_debug(int count, ...);
-extern void message_handlers_trace(int count, ...);
-extern void message_handlers_notice(int count, ...);
-extern void message_handlers_warn(int count, ...);
-extern void message_handlers_die(int count, ...);
-
-/* Enable or disable tracing for particular classes of messages. */
-extern void message_trace_enable(enum message_trace, bool);
-
-/* Some useful handlers, intended to be passed to message_handlers_*.  All
-   handlers take the length of the formatted message, the format, a variadic
-   argument list, and the errno setting if any. */
-extern void message_log_stdout(int, const char *, va_list, int);
-extern void message_log_stderr(int, const char *, va_list, int);
-extern void message_log_syslog_debug(int, const char *, va_list, int);
-extern void message_log_syslog_info(int, const char *, va_list, int);
-extern void message_log_syslog_notice(int, const char *, va_list, int);
-extern void message_log_syslog_warning(int, const char *, va_list, int);
-extern void message_log_syslog_err(int, const char *, va_list, int);
-extern void message_log_syslog_crit(int, const char *, va_list, int);
-
-/* The type of a message handler. */
-typedef void (*message_handler_func)(int, const char *, va_list, int);
-
-/* If non-NULL, called before exit and its return value passed to exit. */
-extern int (*message_fatal_cleanup)(void);
-
-/* If non-NULL, prepended (followed by ": ") to all messages printed by either
-   message_log_stdout or message_log_stderr. */
-extern const char *message_program_name;
-
-END_DECLS
-
-#endif /* INN_MESSAGE_H */
diff --git a/include/inn/mmap.h b/include/inn/mmap.h
deleted file mode 100644 (file)
index 3769d51..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*  $Id: mmap.h 7598 2007-02-09 02:40:51Z eagle $
-**
-**  MMap manipulation routines
-**
-**  Written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  These routines work with mmap()ed memory
-*/
-
-#ifndef INN_MMAP_H
-#define INN_MMAP_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/* Figure out what page an address is in and flush those pages.  This is the
-   internal function, which we wrap with a define below. */
-void inn__mapcntl(void *, size_t, int);
-
-/* Some platforms only support two arguments to msync.  On those platforms,
-   make the third argument to mapcntl always be zero, getting rid of whatever
-   the caller tried to pass.  This avoids undefined symbols for MS_ASYNC and
-   friends on platforms with two-argument msync functions. */
-#ifdef INN_HAVE_MSYNC_3_ARG
-# define inn_mapcntl inn__mapcntl
-#else
-# define inn_mapcntl(p, l, f) inn__mapcntl((p), (l), 0)
-#endif
-
-END_DECLS
-
-#endif /* INN_MMAP_H */
diff --git a/include/inn/qio.h b/include/inn/qio.h
deleted file mode 100644 (file)
index 132da6f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*  $Id: qio.h 3653 2000-07-29 02:57:50Z rra $
-**
-**  Quick I/O package.
-**
-**  The interface to the Quick I/O package, optimized for reading through
-**  files line by line.  This package uses internal buffering like stdio,
-**  but is even more aggressive about its buffering.
-*/
-
-#ifndef INN_QIO_H
-#define INN_QIO_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/*
-**  State for a quick open file, equivalent to FILE for stdio.  All callers
-**  should treat this structure as opaque and instead use the functions and
-**  macros defined below.
-*/
-enum QIOflag { QIO_ok, QIO_error, QIO_long };
-
-typedef struct {
-    int         _fd;
-    size_t      _length;        /* Length of the current string. */
-    size_t      _size;          /* Size of the internal buffer. */
-    char *      _buffer;
-    char *      _start;         /* Start of the unread data. */
-    char *      _end;           /* End of the available data. */
-    off_t       _count;         /* Number of bytes read so far. */
-    enum QIOflag _flag;
-} QIOSTATE;
-
-#define QIOerror(qp)    ((qp)->_flag != QIO_ok)
-#define QIOtoolong(qp)  ((qp)->_flag == QIO_long)
-#define QIOfileno(qp)   ((qp)->_fd)
-#define QIOlength(qp)   ((qp)->_length)
-#define QIOtell(qp)     ((qp)->_count - ((qp)->_end - (qp)->_start))
-
-extern QIOSTATE *       QIOopen(const char *name);
-extern QIOSTATE *       QIOfdopen(int fd);
-extern char *           QIOread(QIOSTATE *qp);
-extern void             QIOclose(QIOSTATE *qp);
-extern int              QIOrewind(QIOSTATE *qp);
-
-END_DECLS
-
-#endif /* !INN_QIO_H */
diff --git a/include/inn/sequence.h b/include/inn/sequence.h
deleted file mode 100644 (file)
index d7bfa33..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*  $Id: sequence.h 4871 2001-07-09 08:09:58Z alexk $
-**
-**  Sequence space arithmetic routines.
-**
-**  This is a set of routines for implementing so called sequence
-**  space arithmetic (typically used for DNS serial numbers). The
-**  implementation here is taken from RFC 1982.
-*/
-
-#ifndef INN_SEQUENCE_H
-#define INN_SEQUENCE_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-int seq_lcompare(unsigned long, unsigned long);
-
-END_DECLS
-
-#endif /* INN_SEQUENCE_H */
diff --git a/include/inn/timer.h b/include/inn/timer.h
deleted file mode 100644 (file)
index 0cc611f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*  $Id: timer.h 6129 2003-01-19 00:39:49Z rra $
-**
-**  Timer library interface.
-**
-**  An interface to a simple profiling library.  An application can declare
-**  its intent to use n timers by calling TMRinit(n), and then start and
-**  stop numbered timers with TMRstart and TMRstop.  TMRsummary logs the
-**  results to syslog given labels for each numbered timer.
-*/
-
-#ifndef INN_TIMER_H
-#define INN_TIMER_H
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-enum {
-    TMR_HISHAVE,                /* Looking up ID in history (yes/no). */
-    TMR_HISGREP,                /* Looking up ID in history (data). */
-    TMR_HISWRITE,               /* Writing to history. */
-    TMR_HISSYNC,                /* Syncing history to disk. */
-    TMR_APPLICATION             /* Application numbering starts here. */
-};
-
-void            TMRinit(unsigned int);
-void            TMRstart(unsigned int);
-void            TMRstop(unsigned int);
-void            TMRsummary(const char *prefix, const char *const *labels);
-unsigned long   TMRnow(void);
-void            TMRfree(void);
-
-/* Return the current time as a double of seconds and fractional sections. */
-double TMRnow_double(void);
-
-END_DECLS
-
-#endif /* INN_TIMER_H */
diff --git a/include/inn/tst.h b/include/inn/tst.h
deleted file mode 100644 (file)
index 44bfff6..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*  $Id: tst.h 6083 2002-12-27 07:24:36Z rra $
-**
-**  Ternary search trie implementation.
-**
-**  This implementation is based on the implementation by Peter A. Friend
-**  (version 1.3), but has been assimilated into INN and modified to use INN
-**  formatting conventions.
-**
-**  Copyright (c) 2002, Peter A. Friend 
-**  All rights reserved. 
-**
-**  Redistribution and use in source and binary forms, with or without
-**  modification, are permitted provided that the following conditions are
-**  met:
-**
-**  Redistributions of source code must retain the above copyright notice,
-**  this list of conditions and the following disclaimer.
-**
-**  Redistributions in binary form must reproduce the above copyright notice,
-**  this list of conditions and the following disclaimer in the documentation
-**  and/or other materials provided with the distribution.
-**
-**  Neither the name of Peter A. Friend nor the names of its contributors may
-**  be used to endorse or promote products derived from this software without
-**  specific prior written permission.
-**
-**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-**  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-**  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-**  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-**  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-**  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-**  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-**  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-**  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-**  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef INN_TST_H
-#define INN_TST_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/* Constants used for return values and options. */
-enum tst_constants {
-    TST_OK,
-    TST_NULL_KEY,
-    TST_NULL_DATA,
-    TST_DUPLICATE_KEY,
-    TST_REPLACE
-};
-
-/* Opaque data type returned by and used by ternary search trie functions. */
-struct tst;
-
-/* Allocate a new ternary search trie.  width is the number of nodes allocated
-   at a time and should be chosen carefully.  One node is required for every
-   character in the tree.  If you choose a value that is too small, your
-   application will spend too much time calling malloc and your node space
-   will be too spread out.  Too large a value is just a waste of space. */
-struct tst *tst_init(int width);
-
-/* Insert a value into the tree.  If the key already exists in the tree,
-   option determiens the behavior.  If set to TST_REPLACE, the data for that
-   key is replaced with the new data value and the old value is returned in
-   exist_ptr.  Otherwise, TST_DUPLICATE_KEY is returned.  If key is zero
-   length, TST_NULL_KEY is returned.  If data is NULL, TST_NULL_DATA is
-   returned.  On success, TST_OK is returned.
-
-   The data argument may not be NULL.  For a simple existence tree, use the
-   struct tst pointer as the data. */
-int tst_insert(struct tst *, const unsigned char *key, void *data, int option,
-               void **exist_ptr);
-
-/* Search for a key and return the associated data, or NULL if not found. */
-void *tst_search(struct tst *, const unsigned char *key);
-
-/* Delete the given key out of the trie, returning the data that it pointed
-   to.  If the key was not found, returns NULL. */
-void *tst_delete(struct tst *, const unsigned char *key);
-
-/* Free the given ternary search trie and all resources it uses. */
-void tst_cleanup(struct tst *);
-
-#endif /* !INN_TST_H */
diff --git a/include/inn/vector.h b/include/inn/vector.h
deleted file mode 100644 (file)
index ed63e32..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*  $Id: vector.h 5450 2002-04-23 06:06:10Z rra $
-**
-**  Vector handling (counted lists of char *'s).
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  A vector is a simple array of char *'s combined with a count.  It's a
-**  convenient way of managing a list of strings, as well as a reasonable
-**  output data structure for functions that split up a string.  There are
-**  two basic types of vectors, regular vectors (in which case strings are
-**  copied when put into a vector and freed when the vector is freed) and
-**  cvectors or const vectors (where each pointer is a const char * to some
-**  external string that isn't freed when the vector is freed).
-**
-**  There are two interfaces here, one for vectors and one for cvectors,
-**  with the basic operations being the same between the two.
-*/
-
-#ifndef INN_VECTOR_H
-#define INN_VECTOR_H 1
-
-#include <inn/defines.h>
-
-struct vector {
-    size_t count;
-    size_t allocated;
-    char **strings;
-};
-
-struct cvector {
-    size_t count;
-    size_t allocated;
-    const char **strings;
-};
-
-BEGIN_DECLS
-
-/* Create a new, empty vector. */
-struct vector *vector_new(void);
-struct cvector *cvector_new(void);
-
-/* Add a string to a vector.  Resizes the vector if necessary. */
-void vector_add(struct vector *, const char *string);
-void cvector_add(struct cvector *, const char *string);
-
-/* Resize the array of strings to hold size entries.  Saves reallocation work
-   in vector_add if it's known in advance how many entries there will be. */
-void vector_resize(struct vector *, size_t size);
-void cvector_resize(struct cvector *, size_t size);
-
-/* Reset the number of elements to zero, freeing all of the strings for a
-   regular vector, but not freeing the strings array (to cut down on memory
-   allocations if the vector will be reused). */
-void vector_clear(struct vector *);
-void cvector_clear(struct cvector *);
-
-/* Free the vector and all resources allocated for it. */
-void vector_free(struct vector *);
-void cvector_free(struct cvector *);
-
-/* Split functions build a vector from a string.  vector_split splits on a
-   specified character, while vector_split_space splits on any sequence of
-   spaces or tabs (not any sequence of whitespace, as just spaces or tabs is
-   more useful for INN).  The cvector versions destructively modify the
-   provided string in-place to insert nul characters between the strings.  If
-   the vector argument is NULL, a new vector is allocated; otherwise, the
-   provided one is reused.
-
-   Empty strings will yield zero-length vectors.  Adjacent delimiters are
-   treated as a single delimiter by *_split_space, but *not* by *_split, so
-   callers of *_split should be prepared for zero-length strings in the
-   vector. */
-struct vector *vector_split(const char *string, char sep, struct vector *);
-struct vector *vector_split_space(const char *string, struct vector *);
-struct cvector *cvector_split(char *string, char sep, struct cvector *);
-struct cvector *cvector_split_space(char *string, struct cvector *);
-
-/* Build a string from a vector by joining its components together with the
-   specified string as separator.  Returns a newly allocated string; caller is
-   responsible for freeing. */
-char *vector_join(const struct vector *, const char *seperator);
-char *cvector_join(const struct cvector *, const char *separator);
-
-END_DECLS
-
-#endif /* INN_VECTOR_H */
diff --git a/include/inn/wire.h b/include/inn/wire.h
deleted file mode 100644 (file)
index bafae0b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*  $Id: wire.h 6028 2002-12-24 05:10:39Z rra $
-**
-**  Wire format article utilities.
-**
-**  Originally written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  These routines manipulate wire format articles; in particular, they should
-**  be safe in the presence of embedded NULs and UTF-8 characters.
-*/
-
-#ifndef INN_WIRE_H
-#define INN_WIRE_H 1
-
-#include <inn/defines.h>
-
-BEGIN_DECLS
-
-/* Given a pointer to the start of an article, locate the first octet
-   of the body (which may be the octet beyond the end of the buffer if
-   your article is bodyless). */
-char *wire_findbody(const char *, size_t);
-
-/* Given a pointer into an article and a pointer to the end of the article,
-   find the start of the next line or return NULL if there are no more lines
-   remaining in the article. */
-char *wire_nextline(const char *, const char *end);
-
-/* Given a pointer to the start of an article and the name of a header, find
-   the beginning of the value of the given header (the returned pointer will
-   be after the name of the header and any initial whitespace).  Headers whose
-   only content is whitespace are ignored.  If the header isn't found, returns
-   NULL.
-
-   WARNING: This function does not comply with RFC 2822's idea of header
-   content, particularly in its skipping of initial whitespace. */
-char *wire_findheader(const char *article, size_t, const char *header);
-
-/* Given a pointer inside a header's value and a pointer to the end of the
-   article, returns a pointer to the end of the header value (the \n at the
-   end of the terminating \r\n with folding taken into account), or NULL if no
-   such terminator was found before the end of the article. */
-char *wire_endheader(const char *header, const char *end);
-
-END_DECLS
-
-#endif /* INN_WIRE_H */
diff --git a/include/inndcomm.h b/include/inndcomm.h
deleted file mode 100644 (file)
index 98e63d6..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*  $Revision: 6786 $
-**
-**  Here be values used for communicating with the server once it is
-**  running.
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* The header for the ICC protocol is a one-byte protocol version followed
-   by a 2 byte messages length*/
-#define HEADER_SIZE (sizeof (ICC_PROTOCOLTYPE) + sizeof (ICC_MSGLENTYPE))
-
-typedef unsigned short ICC_MSGLENTYPE; /* Length code to prefix commands to
-                                       ** the server. */
-typedef char ICC_PROTOCOLTYPE ;
-
-/* Values for the protocol version field of the message. 8 bits wide. */
-#define ICC_PROTOCOL_1 'a'
-
-
-
-#define SC_SEP         '\001'
-#define SC_MAXFIELDS   6
-
-#define SC_ADDHIST     'a'
-#define SC_ALLOW       'D'
-#define SC_BEGIN       'b'
-#define SC_CANCEL      'c'
-#define SC_CHANGEGROUP 'u'
-#define SC_CHECKFILE   'd'
-#define SC_DROP                'e'
-#define SC_FEEDINFO    'F'
-#define SC_FILTER      'T'
-#define SC_FLUSH       'f'
-#define SC_FLUSHLOGS   'g'
-#define SC_GO          'h'
-#define SC_HANGUP      'i'
-#define SC_LOGMODE     'E'
-#define SC_LOWMARK     'L'
-#define SC_MODE                's'
-#define SC_NAME                'j'
-#define SC_NEWGROUP    'k'
-#define SC_PARAM       'l'
-#define SC_PAUSE       'm'
-#define SC_PERL                'P'
-#define SC_PYTHON      'Y'
-#define SC_READERS     'v'
-#define SC_REJECT      'C'
-#define SC_RELOAD      'o'
-#define SC_RENUMBER    'n'
-#define SC_RESERVE     'z'
-#define SC_RMGROUP     'p'
-#define SC_SEND                'A'
-#define SC_SHUTDOWN    'q'
-#define SC_STATHIST    'H'
-#define SC_STATUS      'S'
-#define SC_SIGNAL      'B'
-#define SC_THROTTLE    'r'
-#define SC_TIMER       'Z'
-#define SC_TRACE       'w'
-#define SC_XABORT      'x'
-#define SC_XEXEC       'y'
-
-    /* Yes, we don't want anyone to use this. */
-#define SC_FIRSTFREE   G
-
-#define MAX_REASON_LEN 80
-
-
-extern void            ICCsettimeout(int i);
-extern int             ICCopen(void);
-extern int             ICCclose(void);
-extern int             ICCcommand(char cmd, const char *argv[], char **replyp);
-extern int             ICCcancel(const char *msgid);
-extern int             ICCgo(const char *why);
-extern int             ICCpause(const char *why);
-extern int             ICCreserve(const char *why);
-
-extern const char      *ICCfailure;
-
-/* Use a read or recv call to read a descriptor. */
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# define RECVorREAD(fd, p, s)   recv((fd), (p), (s), 0)
-#else
-# define RECVorREAD(fd, p, s)   read((fd), (p), (s))
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
diff --git a/include/innperl.h b/include/innperl.h
deleted file mode 100644 (file)
index 84ff112..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*  $Id: innperl.h 5302 2002-03-12 20:10:46Z rra $
-**
-**  Declarations for embedded Perl.
-*/
-
-#ifndef INNPERL_H
-#define INNPERL_H 1
-
-/* Skip this entire file if DO_PERL (./configure --with-perl) isn't set. */
-#if DO_PERL
-
-#include "config.h"
-
-BEGIN_DECLS
-
-extern bool PerlFilterActive;
-
-extern bool PerlFilter(bool value);
-extern void PerlClose(void);
-extern void PERLsetup(char *startupfile, char *filterfile,
-                      const char *function);
-extern int  PERLreadfilter(char *filterfile, const char *function);
-
-END_DECLS
-
-#endif /* DO_PERL */
-#endif /* !INNPERL_H */
diff --git a/include/libinn.h b/include/libinn.h
deleted file mode 100644 (file)
index 166372b..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*  $Id: libinn.h 6135 2003-01-19 01:15:40Z rra $
-**
-**  Here be declarations of functions in the InterNetNews library.
-*/
-
-#ifndef LIBINN_H
-#define LIBINN_H 1
-
-#include "inn/defines.h"
-
-/* Eventually we don't want to include this, since this will be an installed
-   header and we don't want to install config.h. */
-#include "config.h"
-
-#include <stdio.h>              /* FILE */
-#include <sys/types.h>          /* size_t and ssize_t */
-
-/* Forward declarations to avoid unnecessary includes. */
-struct stat;
-struct iovec;
-struct sockaddr;
-struct sockaddr_in;
-struct in_addr;
-
-BEGIN_DECLS
-
-/*
-**  MEMORY MANAGEMENT
-*/
-
-/* The functions are actually macros so that we can pick up the file and line
-   number information for debugging error messages without the user having to
-   pass those in every time. */
-#define xcalloc(n, size)        x_calloc((n), (size), __FILE__, __LINE__)
-#define xmalloc(size)           x_malloc((size), __FILE__, __LINE__)
-#define xrealloc(p, size)       x_realloc((p), (size), __FILE__, __LINE__)
-#define xstrdup(p)              x_strdup((p), __FILE__, __LINE__)
-#define xstrndup(p, size)       x_strndup((p), (size), __FILE__, __LINE__)
-
-/* Last two arguments are always file and line number.  These are internal
-   implementations that should not be called directly.  ISO C99 says that
-   identifiers beginning with _ and a lowercase letter are reserved for
-   identifiers of file scope, so while the position of libraries in the
-   standard isn't clear, it's probably not entirely kosher to use _xmalloc
-   here.  Use x_malloc instead. */
-extern void *x_calloc(size_t, size_t, const char *, int);
-extern void *x_malloc(size_t, const char *, int);
-extern void *x_realloc(void *, size_t, const char *, int);
-extern char *x_strdup(const char *, const char *, int);
-extern char *x_strndup(const char *, size_t, const char *, int);
-
-/* Failure handler takes the function, the size, the file, and the line. */
-typedef void (*xmalloc_handler_t)(const char *, size_t, const char *, int);
-
-/* The default error handler. */
-void xmalloc_fail(const char *, size_t, const char *, int);
-
-/* Assign to this variable to choose a handler other than the default, which
-   just calls sysdie. */
-extern xmalloc_handler_t xmalloc_error_handler;
-
-
-/*
-**  TIME AND DATE PARSING, GENERATION, AND HANDLING
-*/
-typedef struct _TIMEINFO {
-    time_t      time;
-    long        usec;
-    long        tzone;
-} TIMEINFO;
-
-extern int      GetTimeInfo(TIMEINFO *Now);
-extern bool     makedate(time_t, bool local, char *buff, size_t buflen);
-extern time_t   parsedate(char *p, TIMEINFO *now);
-extern time_t   parsedate_nntp(const char *, const char *, bool local);
-extern time_t   parsedate_rfc2822(const char *);
-
-
-/*
-**  VERSION INFORMATION
-*/
-extern const int        inn_version[3];
-extern const char       inn_version_extra[];
-extern const char       inn_version_string[];
-
-/* Earlier versions of INN didn't have <inn/version.h> and some source is
-   intended to be portable to different INN versions; it can use this macro
-   to determine whether <inn/version.h> is available. */
-#define HAVE_INN_VERSION_H 1
-
-
-/*
-**  WILDMAT MATCHING
-*/
-enum uwildmat {
-    UWILDMAT_FAIL   = 0,
-    UWILDMAT_MATCH  = 1,
-    UWILDMAT_POISON
-};
-
-extern bool             uwildmat(const char *text, const char *pat);
-extern bool             uwildmat_simple(const char *text, const char *pat);
-extern enum uwildmat    uwildmat_poison(const char *text, const char *pat);
-
-
-/*
-**  FILE LOCKING
-*/
-enum inn_locktype {
-    INN_LOCK_READ,
-    INN_LOCK_WRITE,
-    INN_LOCK_UNLOCK
-};
-
-extern bool     inn_lock_file(int fd, enum inn_locktype type, bool block);
-extern bool     inn_lock_range(int fd, enum inn_locktype type, bool block,
-                              off_t offset, off_t size);
-
-
-/*
-**  MISCELLANEOUS UTILITY FUNCTIONS
-*/
-extern void     close_on_exec(int fd, bool flag);
-extern char *   concat(const char *first, ...);
-extern char *   concatpath(const char *base, const char *name);
-extern void     daemonize(const char *path);
-extern int      getfdlimit(void);
-extern int      nonblocking(int fd, bool flag);
-extern int      setfdlimit(unsigned int limit);
-extern ssize_t  xpwrite(int fd, const void *buffer, size_t size, off_t offset);
-extern void     (*xsignal(int signum, void (*sigfunc)(int)))(int);
-extern void     (*xsignal_norestart(int signum, void (*sigfunc)(int)))(int);
-extern ssize_t  xwrite(int fd, const void *buffer, size_t size);
-extern ssize_t  xwritev(int fd, const struct iovec *iov, int iovcnt);
-
-
-/* Headers. */
-extern char *           GenerateMessageID(char *domain);
-extern void             HeaderCleanFrom(char *from);
-extern struct _DDHANDLE * DDstart(FILE *FromServer, FILE *ToServer);
-extern void               DDcheck(struct _DDHANDLE *h, char *group);
-extern char *             DDend(struct _DDHANDLE *h);
-
-/* NNTP functions. */
-extern int      NNTPlocalopen(FILE **FromServerp, FILE **ToServerp,
-                              char *errbuff);
-extern int      NNTPremoteopen(int port, FILE **FromServerp,
-                               FILE **ToServerp, char *errbuff);
-extern int      NNTPconnect(char *host, int port, FILE **FromServerp,
-                            FILE **ToServerp, char *errbuff);
-extern int      NNTPsendarticle(char *, FILE *F, bool Terminate);
-extern int      NNTPsendpassword(char *server, FILE *FromServer,
-                                 FILE *ToServer);
-
-/* clientlib compatibility functions. */
-extern char *   getserverbyfile(char *file);
-extern int      server_init(char *host, int port);
-extern int      handle_server_response(int response, char *host);
-extern void     put_server(const char *text);
-extern int      get_server(char *buff, int buffsize);
-extern void     close_server(void);
-
-/* Opening the active file on a client. */
-extern FILE *   CAopen(FILE *FromServer, FILE *ToServer);
-extern FILE *   CAlistopen(FILE *FromServer, FILE *ToServer,
-                          const char *request);
-extern FILE *   CA_listopen(char *pathname, FILE *FromServer, FILE *ToServer,
-                           const char *request);
-extern void     CAclose(void);
-
-extern char *    GetFQDN(char *domain);
-extern char *    GetModeratorAddress(FILE *FromServer, FILE *ToServer,
-                                     char *group, char *moderatormailer); 
-
-#define TEMPORARYOPEN   0
-#define INND_HISTORY    1
-#define INND_HISLOG     2
-#define DBZ_DIR         3
-#define DBZ_BASE        4
-
-/* Hash functions */
-typedef struct {
-    char        hash[16];
-} HASH;
-extern HASH     Hash(const void *value, const size_t len);
-/* Return the hash of a case mapped message-id */
-extern HASH     HashMessageID(const char *MessageID);
-extern bool     HashEmpty(const HASH hash);
-extern void     HashClear(HASH *hash);
-extern char *   HashToText(const HASH hash);
-extern HASH     TextToHash(const char *text);
-extern int      HashCompare(const HASH *h1, const HASH *h2);
-
-/* Miscellaneous. */
-extern int      dbzneedfilecount(void);
-extern bool     MakeDirectory(char *Name, bool Recurse);
-extern int      xread(int fd, char *p, off_t i);
-extern int      GetResourceUsage(double *usertime, double *systime);
-extern void     Radix32(unsigned long, char *buff);
-extern char *   ReadInDescriptor(int fd, struct stat *Sbp);
-extern char *   ReadInFile(const char *name, struct stat *Sbp);
-extern FILE *   xfopena(const char *p);
-extern bool     fdreserve(int fdnum);
-extern FILE *   Fopen(const char *p, const char *type, int fd);
-extern int      Fclose(FILE *fp);
-extern char *  sprint_sockaddr(const struct sockaddr *sa);
-extern void    make_sin(struct sockaddr_in *s, const struct in_addr *src);
-
-END_DECLS
-
-/* <ctype.h>'s isspace includes \n, which is not what we want. */
-#define ISWHITE(c)              ((c) == ' ' || (c) == '\t')
-
-#endif /* LIBINN_H */
diff --git a/include/nntp.h b/include/nntp.h
deleted file mode 100644 (file)
index 158a941..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*  $Id: nntp.h 6070 2002-12-26 07:10:10Z rra $
-**
-**  Here be a set of NNTP response codes as defined in RFC977 and elsewhere.
-**  The reponse codes are three digits, RFI, defined like this:
-**     R, Response:
-**             1xx     Informative message
-**             2xx     Command ok
-**             3xx     Command ok so far, send the rest of it.
-**             4xx     Command was correct, but couldn't be performed for
-**                     some reason.
-**             5xx     Command unimplemented, or incorrect, or a serious
-**                     program error occurred.
-**     F, Function:
-**             x0x     Connection, setup, and miscellaneous messages
-**             x1x     Newsgroup selection
-**             x2x     Article selection
-**             x3x     Distribution functions
-**             x4x     Posting
-**             x8x     Nonstandard extensions (AUTHINFO, XGTITLE)
-**             x9x     Debugging output
-**     I, Information:
-**             No defined semantics
-*/
-#define NNTP_HELPOK_VAL                        100
-#define NNTP_BAD_COMMAND_VAL           500
-#define NNTP_BAD_COMMAND               "500 Syntax error or bad command"
-#define NNTP_TEMPERR_VAL               503
-#define NNTP_ACCESS                    "502 Permission denied"
-#define NNTP_ACCESS_VAL                        502
-#define NNTP_GOODBYE_ACK               "205 ."
-#define NNTP_GOODBYE_ACK_VAL           205
-#define NNTP_GOODBYE                   "400"
-#define NNTP_GOODBYE_VAL               400
-#define NNTP_HAVEIT                    "435 Duplicate"
-#define NNTP_HAVEIT_BADID              "435 Bad Message-ID"
-#define NNTP_HAVEIT_VAL                        435
-#define NNTP_LIST_FOLLOWS              "215"
-#define NNTP_LIST_FOLLOWS_VAL          215
-#define NNTP_HELP_FOLLOWS              "100 Legal commands"
-#define NNTP_HELP_FOLLOWS_VAL          100
-#define NNTP_NOTHING_FOLLOWS_VAL       223
-#define NNTP_ARTICLE_FOLLOWS           "220"
-#define NNTP_ARTICLE_FOLLOWS_VAL       220
-#define NNTP_NEWGROUPS_FOLLOWS_VAL     231
-#define NNTP_HEAD_FOLLOWS              "221"
-#define NNTP_HEAD_FOLLOWS_VAL          221
-#define NNTP_BODY_FOLLOWS_VAL          222
-#define NNTP_OVERVIEW_FOLLOWS_VAL      224
-#define NNTP_DATE_FOLLOWS_VAL          111
-#define NNTP_POSTOK                    "200"
-#define NNTP_POSTOK_VAL                        200
-#define NNTP_START_POST_VAL            340
-#define NNTP_NOPOSTOK_VAL              201
-#define NNTP_SLAVEOK_VAL               202
-#define NNTP_REJECTIT_VAL              437
-#define NNTP_REJECTIT_EMPTY            "437 Empty article"
-#define NNTP_DONTHAVEIT                        "430"
-#define NNTP_DONTHAVEIT_VAL            430
-#define NNTP_RESENDIT_LATER             "436 Retry later"
-#define NNTP_RESENDIT_VAL              436
-#define NNTP_POSTEDOK                  "240 Article posted"
-#define NNTP_POSTEDOK_VAL              240
-#define NNTP_POSTFAIL_VAL              441
-#define NNTP_GROUPOK_VAL               211
-#define NNTP_SENDIT                    "335"
-#define NNTP_SENDIT_VAL                        335
-#define NNTP_SYNTAX_USE                        "501 Bad command use"
-#define NNTP_SYNTAX_VAL                        501
-#define NNTP_BAD_SUBCMD                        "501 Bad subcommand"
-#define NNTP_TOOKIT                    "235"
-#define NNTP_TOOKIT_VAL                        235
-#define NNTP_NOTINGROUP                        "412 Not in a newsgroup"
-#define NNTP_NOTINGROUP_VAL            412
-#define NNTP_NOSUCHGROUP               "411 No such group"
-#define NNTP_NOSUCHGROUP_VAL           411
-#define NNTP_NEWNEWSOK                 "230 New news follows"
-#define NNTP_NOARTINGRP                        "423 Bad article number"
-#define NNTP_NOARTINGRP_VAL            423
-#define NNTP_NOCURRART                 "420 No current article"
-#define NNTP_NOCURRART_VAL             420
-#define NNTP_NONEXT_VAL                        421
-#define NNTP_NOPREV_VAL                        422
-#define NNTP_CANTPOST                  "440 Posting not allowed"
-#define NNTP_CANTPOST_VAL              440
-
-/* new entries for the "streaming" protocol */
-/* response to "mode stream" else 500 if stream not supported */
-#define NNTP_OK_STREAM_VAL             203     /* Streaming supported */
-
-/* response to "check <id>".  Must include ID of article.
-** Example: "431 <1234@host.domain>"
-*/
-#define NNTP_OK_SENDID_VAL             238     /* I want article <id> */
-#define NNTP_RESENDID_VAL              431     /* try <id> again later */
-#define NNTP_ERR_GOTID_VAL             438     /* Got <id>, don't send */
-
-/* responses to "takethis <id>.  Must include ID of article */
-#define NNTP_OK_RECID_VAL              239     /* Article <id> received OK */
-#define NNTP_ERR_FAILID_VAL            439     /* Transfer of <id> failed */
-
-/* End of new entries for the "streaming" protocol */
-
-/*
-**  The first character of an NNTP reply can be used as a category class.
-*/
-#define NNTP_CLASS_OK                  '2'
-#define NNTP_CLASS_ERROR               '4'
-#define NNTP_CLASS_FATAL               '5'
-
-
-/*
-**  Authentication commands from the RFC update (not official).
-*/
-#define NNTP_AUTH_NEEDED               "480"
-#define NNTP_AUTH_NEEDED_VAL           480
-#define NNTP_AUTH_BAD                  "481"
-#define NNTP_AUTH_NEXT                 "381"
-#define NNTP_AUTH_NEXT_VAL             381
-#define NNTP_AUTH_OK                   "281"
-#define NNTP_AUTH_OK_VAL               281
-#define NNTP_AUTH_REJECT_VAL           482
-
-/*
-**  Starttls commands (not official).
-*/
-#define NNTP_STARTTLS_NEXT             "382"
-#define NNTP_STARTTLS_NEXT_VAL 382
-#define NNTP_STARTTLS_DONE             "483"
-#define NNTP_STARTTLS_DONE_VAL 483
-#define NNTP_STARTTLS_BAD              "580"
-#define NNTP_STARTTLS_BAD_VAL  580
-
-/*
-**  XGTITLE, from ANU news.
-*/
-#define NNTP_XGTITLE_BAD               481     /* Yes, 481. */
-#define NNTP_XGTITLE_OK                        282
-
-/*
-**  MODE CANCEL extension.
-*/
-#define NNTP_OK_CANCEL_VAL      284
-#define NNTP_OK_CANCELLED       "289"
-#define NNTP_ERR_CANCEL_VAL     484
-
-/*
-**  XBATCH feed extension.
-*/
-#define NNTP_OK_XBATCHED_VAL   239     /* Batch transferred successfully */
-#define NNTP_OK_XBATCHED       "239"
-#define NNTP_CONT_XBATCH_VAL   339     /* Continue to send batch */
-#define NNTP_CONT_XBATCH       "339"
-/* and one more meaning for the 436 code NNTP_RESENDIT_VAL */
-#define NNTP_RESENDIT_XBATCHERR        "436 xbatch failed: "
-/* and one more meaning for the 501 code NNTP_SYNTAX_USE */
-#define NNTP_XBATCH_BADSIZE    "501 Invalid or missing size for xbatch"
-
-#define NNTP_STRLEN                    512
-
-/* Consensus on the USEFOR mailing list in June of 2000 indicates that the
-   next revision of the Usenet article standard will limit the length of the
-   message ID to 250 characters.  This is also the limit recommended by
-   son-of-1036.
-
-   You can increase this limit if you want, but don't increase it above 497.
-   RFC 977 limits each line of the NNTP protocol to 512 octets, including
-   the terminating CRLF.  For a message ID to be passed using the TAKETHIS
-   command, it can therefore be a maximum of 501 octets.  The November 1999
-   draft of the replacement RFC limits it to 497 octets.
-
-   Both Cyclone and DNews are known to reject message IDs longer than 500
-   octets as of June of 2000.  DNews has been reported to have problems with
-   message IDs of 494 octets. */
-
-#define NNTP_MSGID_MAXLEN       250
diff --git a/include/ov.h b/include/ov.h
deleted file mode 100644 (file)
index 5e9b935..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _OV_H_
-#define _OV_H_
-
-#include "storage.h"
-#include "inn/history.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define OV_READ  1
-#define OV_WRITE 2
-
-typedef enum {OVSPACE, OVSORT, OVCUTOFFLOW, OVGROUPBASEDEXPIRE, OVSTATICSEARCH, OVSTATALL, OVCACHEKEEP, OVCACHEFREE} OVCTLTYPE;
-#define OV_NOSPACE 100
-typedef enum {OVNEWSGROUP, OVARRIVED, OVNOSORT} OVSORTTYPE;
-typedef enum {OVADDCOMPLETED, OVADDFAILED, OVADDGROUPNOMATCH} OVADDRESULT;
-
-typedef struct _OVGE {
-    bool       delayrm;          /* append tokens to filename if true */
-    bool       usepost;          /* posting date is used to determine expiry
-                                    time if true */
-    bool       quiet;            /* statistics will be suppressed if true */
-    bool       keep;             /* keep article so long as any of crossposted
-                                    newsgroups is not expired if true */
-    bool       earliest;         /* purge article any of crossposted
-                                    newsgroups is expired if true */
-    bool       ignoreselfexpire; /* purge article even if storing method has
-                                    self expiry */
-    char       *filename;        /* used to append tokens to this file if
-                                    delayrm is true */
-    time_t     now;              /* used as current time */
-    float      timewarp;         /* used to bias expiry time */
-} OVGE;
-
-extern bool    OVstatall;
-bool OVopen(int mode);
-bool OVgroupstats(char *group, int *lo, int *hi, int *count, int *flag);
-bool OVgroupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag);
-bool OVgroupdel(char *group);
-OVADDRESULT OVadd(TOKEN token, char *data, int len, time_t arrived, time_t expires);
-bool OVcancel(TOKEN token);
-void *OVopensearch(char *group, int low, int high);
-bool OVsearch(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived);
-void OVclosesearch(void *handle);
-bool OVgetartinfo(char *group, ARTNUM artnum, TOKEN *token);
-bool OVexpiregroup(char *group, int *lo, struct history *h);
-bool OVctl(OVCTLTYPE type, void *val);
-void OVclose(void);
-
-/* Overview data manipulation functions. */
-const struct cvector *overview_fields(void);
-struct vector *overview_extra_fields(void);
-struct buffer *overview_build(ARTNUM number, const char *article,
-                              size_t length, const struct vector *extra,
-                              struct buffer *);
-bool overview_check(const char *data, size_t length, ARTNUM article);
-int overview_index(const char *field, const struct vector *extra);
-struct cvector *overview_split(const char *line, size_t length,
-                              ARTNUM *number, struct cvector *vector);
-char *overview_getheader(const struct cvector *vector, int element,
-                        const struct vector *extra);
-
-/* offsets into vectors for standard overview headers */
-enum {
-    OVERVIEW_SUBJECT,
-    OVERVIEW_FROM,
-    OVERVIEW_DATE,
-    OVERVIEW_MESSAGE_ID,
-    OVERVIEW_REFERENCES,
-    OVERVIEW_BYTES,
-    OVERVIEW_LINES,
-    OVERVIEW_MAX
-};
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _OV_H_ */
diff --git a/include/paths.h.in b/include/paths.h.in
deleted file mode 100644 (file)
index 27e78c3..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*  $Id: paths.h.in 4844 2001-06-30 03:54:06Z rra $ -*- c -*-
-**  @configure_input@
-**
-**  Here be #define's for filenames, socket names, environment variables,
-**  and so on.
-*/
-
-/*
-**  PATHS TO FILES AND SOCKETS
-**
-**  Default prefixes can be overridden by defining the constant to a full
-**  path.  That magic is handled by concatpath.  At some point all of these
-**  defines will change to start with INN_PATH_ instead of _PATH_ because
-**  identifiers beginning with an underscore and an uppercase letter are
-**  reserved by the C standard.  New ones should use INN_PATH_ for this
-**  reason, to save eventual work.
-*/
-
-/* Default prefix path is pathbin. */
-#define _PATH_NNRPD            "nnrpd"
-#define _PATH_NNTPD            "nnrpd"
-#define _PATH_AUTHDIR          "auth"
-#define _PATH_AUTHDIR_GENERIC  "generic"
-#define _PATH_AUTHDIR_NOPASS   "resolv"
-#define _PATH_AUTHDIR_PASSWD   "passwd"
-#define _PATH_CTLINND          "ctlinnd"
-#define _PATH_RNEWSPROGS       "rnews.libexec"
-
-/* Default prefix path is pathfilter. */
-#define _PATH_TCL_STARTUP      "startup.tcl"
-#define _PATH_TCL_FILTER       "filter.tcl"
-#define _PATH_PERL_STARTUP_INND        "startup_innd.pl"
-#define _PATH_PERL_FILTER_INND "filter_innd.pl"
-#define _PATH_PERL_FILTER_NNRPD        "filter_nnrpd.pl"
-#define _PATH_PERL_AUTH                "nnrpd_auth.pl"
-#define _PATH_PYTHON_STARTUP   "filter_innd.py"
-#define _PATH_PYTHON_STARTUP_M  "filter_innd"
-#define _PATH_PYTHON_AUTH_M    "nnrpd_auth"
-
-/* Default prefix path is pathrun. */
-#define _PATH_NNTPCONNECT      "nntpin"
-#define _PATH_NEWSCONTROL      "control"
-#define _PATH_TEMPSOCK         "ctlinndXXXXXX"
-#define _PATH_SERVERPID                "innd.pid"
-
-/* Default prefix path is pathdb. */
-#define _PATH_HISTORY          "history"
-#define _PATH_ACTIVE           "active"
-#define _PATH_NEWACTIVE                "active.tmp"
-#define _PATH_OLDACTIVE                "active.old"
-#define _PATH_ACTIVETIMES      "active.times"
-#define _PATH_NEWSGROUPS       "newsgroups"
-
-/* Default prefix path is pathetc. */
-#define _PATH_NEWSFEEDS                "newsfeeds"
-#define _PATH_INNDHOSTS                "incoming.conf"
-#define _PATH_DISTPATS         "distrib.pats"
-#define _PATH_NNRPDIST         "distributions"
-#define _PATH_NNRPSUBS         "subscriptions"
-#define _PATH_CONFIG           "@ETCDIR@/inn.conf"
-#define _PATH_CLIENTACTIVE     "active"
-#define _PATH_MODERATORS       "moderators"
-#define _PATH_SERVER           "server"
-#define _PATH_NNTPPASS         "passwd.nntp"
-#define _PATH_NNRPACCESS       "readers.conf"
-#define _PATH_EXPIRECTL                "expire.ctl"
-#define _PATH_SCHEMA           "overview.fmt"
-#define _PATH_MOTD             "motd.news"
-#define _PATH_STORAGECTL       "storage.conf"
-#define _PATH_RADIUS_CONFIG    "radius.conf"
-#define _PATH_SASL_CONFIG      "sasl.conf"
-#define INN_PATH_FILESYSTEMS    "filesystems"
-
-/* Default prefix path is pathspool. */
-#define _PATH_SPOOL            "articles"
-#define _PATH_BADNEWS          "bad"
-
-/* Default prefix path is pathlog. */
-#define _PATH_LOGFILE          "news"
-#define _PATH_ERRLOG           "errlog"
-
-/* Paths to various programs. */
-#define _PATH_COMPRESS         "@COMPRESS@"
-#define _PATH_GZIP             "@GZIP@"
-#define _PATH_SH               "@_PATH_SH@"
-#define _PATH_SORT              "@_PATH_SORT@"
-
-/* Absolute paths. */
-#define _PATH_TMP              "@tmpdir@"
-#define _PATH_RNEWS_DUP_LOG    "/dev/null"
-
-/* Always relative to pathtmp. */
-#define _PATH_TEMPACTIVE       "activeXXXXXX"
-#define _PATH_TEMPMODERATORS   "moderatorsXXXXXX"
-
-/*
-**  ENVIRONMENT VARIABLES
-*/
-
-/* The host name of the NNTP server, for client posting. */
-#define _ENV_NNTPSERVER                "NNTPSERVER"
-
-/* The Organization header line, for client posting. */
-#define _ENV_ORGANIZATION      "ORGANIZATION"
-
-/* What to put in the From line, for client posting. */
-#define _ENV_FROMHOST          "FROMHOST"
-
-/* UUCP host, for rnews. */
-#define _ENV_UUCPHOST           "UU_MACHINE"
-
-/* Interface to bind as, for sockets. */
-#define _ENV_INNBINDADDR       "INND_BIND_ADDRESS"
diff --git a/include/portable/mmap.h b/include/portable/mmap.h
deleted file mode 100644 (file)
index 3d0bbe2..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*  $Id: mmap.h 6012 2002-12-16 11:19:21Z alexk $
-**
-**  Portability wrapper around <sys/mman.h>.
-**
-**  This header file includes <sys/mman.h> and then sets up various
-**  additional defines and macros to permit a uniform API across platforms
-**  with varying mmap implementations.
-*/
-
-#ifndef PORTABLE_MMAP_H
-#define PORTABLE_MMAP_H 1
-
-#include "config.h"
-#include <sys/mman.h>
-
-/* Make sure that the symbolic constant for the error return from mmap is
-   defined (some platforms don't define it). */
-#ifndef MAP_FAILED
-# define MAP_FAILED     ((void *) -1)
-#endif
-
-/* Solaris 8 (at least) prototypes munmap, msync, and madvise as taking char *
-   (actually a caddr_t, which is a typedef for a char *) instead of void * as
-   is required by the standard.  This macro adds a cast that silences compiler
-   warnings on Solaris 8 without adversely affecting other platforms.  (ISO C
-   allows macro definitions of this sort; this macro is not recursive.) */
-#define munmap(p, l)            munmap((void *)(p), (l))
-
-/* On some platforms, msync only takes two arguments.  (ANSI C allows macro
-   definitions of this sort; this macro is not recursive.) */
-#if HAVE_MSYNC_3_ARG
-# define msync(p, l, f)         msync((void *)(p), (l), (f))
-#else
-# define msync(p, l, f)         msync((void *)(p), (l))
-#endif
-
-/* Turn calls to madvise into a no-op if that call isn't available. */
-#if HAVE_MADVISE
-# define madvise(p, l, o)       madvise((void *)(p), (l), (o))
-#else
-# define madvise(p, l, o)       /* empty */
-#endif
-
-/* Some platforms don't flush data written to a memory mapped region until
-   msync or munmap; on those platforms, we sometimes need to force an msync
-   so that other parts of INN will see the changed data.  Some other
-   platforms don't see writes to a file that's memory-mapped until the
-   memory mappings have been flushed.
-
-   These platforms can use mmap_flush to schedule a flush to disk and
-   mmap_invalidate to force re-reading from disk.  Note that all platforms
-   should still periodically call msync so that data is written out in case
-   of a crash. */
-#if MMAP_NEEDS_MSYNC
-# define mmap_flush(p, l)       msync((p), (l), MS_ASYNC)
-#else
-# define mmap_flush(p, l)       /* empty */
-#endif
-
-#if MMAP_MISSES_WRITES
-# define mmap_invalidate(p, l)  msync((p), (l), MS_INVALIDATE)
-#else
-# define mmap_invalidate(p, l)  /* empty */
-#endif
-
-#endif /* PORTABLE_MMAP_H */
diff --git a/include/portable/setproctitle.h b/include/portable/setproctitle.h
deleted file mode 100644 (file)
index e15e591..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*  $Id: setproctitle.h 5682 2002-08-29 05:17:56Z rra $
-**
-**  Set things up for setproctitle portably.
-**
-**  If the system supports setproctitle, we need to define away
-**  setproctitle_init.  Otherwise, we have to prototype setproctitle (which is
-**  normally prototyped in stdlib.h).
-*/
-
-#ifndef PORTABLE_SETPROCTITLE_H
-#define PORTABLE_SETPROCTITLE_H 1
-
-#include "config.h"
-
-#if !HAVE_SETPROCTITLE
-void setproctitle(const char *format, ...);
-#endif
-
-#if HAVE_SETPROCTITLE || HAVE_PSTAT
-# define setproctitle_init(argc, argv)   /* empty */
-#else
-void setproctitle_init(int argc, char *argv[]);
-#endif
-
-#endif /* !PORTABLE_SETPROCTITLE_H */
diff --git a/include/portable/socket.h b/include/portable/socket.h
deleted file mode 100644 (file)
index 804a203..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*  $Id: socket.h 5388 2002-04-01 07:03:01Z rra $
-**
-**  Portability wrapper around <sys/socket.h> and friends.
-**
-**  This header file is the equivalent of:
-**
-**      #include <arpa/inet.h>
-**      #include <netinet/in.h>
-**      #include <sys/socket.h>
-**
-**  but also cleans up various messes, mostly related to IPv6 support.  It
-**  ensures that inet_aton and inet_ntoa are available and properly
-**  prototyped.
-*/
-
-#ifndef PORTABLE_SOCKET_H
-#define PORTABLE_SOCKET_H 1
-
-#include "config.h"
-#include <sys/types.h>
-
-/* BSDI needs <netinet/in.h> before <arpa/inet.h>. */
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-/* Provide prototypes for inet_aton and inet_ntoa if not prototyped in the
-   system header files since they're occasionally available without proper
-   prototypes. */
-#if NEED_DECLARATION_INET_ATON
-extern int              inet_aton(const char *, struct in_addr *);
-#endif
-#if NEED_DECLARATION_INET_NTOA
-extern const char *     inet_ntoa(const struct in_addr);
-#endif
-
-/* Defined by RFC 2553, used to store a generic address.  Note that this
-   doesn't do the alignment mangling that RFC 2553 does; it's not clear if
-   that should be added.... */
-#if !HAVE_SOCKADDR_STORAGE
-# if HAVE_SOCKADDR_LEN
-struct sockaddr_storage {
-    unsigned char ss_len;
-    unsigned char ss_family;
-    unsigned char __padding[128 - 2];
-};
-# else
-struct sockaddr_storage {
-    unsigned short ss_family;
-    unsigned char __padding[128 - 2];
-};
-# endif
-#endif
-
-/* Use convenient, non-uglified names for the fields since we use them quite a
-   bit in code. */
-#if HAVE_2553_STYLE_SS_FAMILY
-# define ss_family __ss_family
-# define ss_len    __ss_len
-#endif
-
-/* Define an SA_LEN macro that gives us the length of a sockaddr. */
-#if !HAVE_SA_LEN_MACRO
-# if HAVE_SOCKADDR_LEN
-#  define SA_LEN(s)     ((s)->sa_len)
-# else
-/* Hack courtesy of the USAGI project. */
-#  if HAVE_INET6
-#   define SA_LEN(s) \
-    ((((struct sockaddr *)(s))->sa_family == AF_INET6)          \
-        ? sizeof(struct sockaddr_in6)                           \
-        : ((((struct sockaddr *)(s))->sa_family == AF_INET)     \
-            ? sizeof(struct sockaddr_in)                        \
-            : sizeof(struct sockaddr)))
-#  else
-#   define SA_LEN(s) \
-    ((((struct sockaddr *)(s))->sa_family == AF_INET)           \
-        ? sizeof(struct sockaddr_in)                            \
-        : sizeof(struct sockaddr))
-#  endif
-# endif /* HAVE_SOCKADDR_LEN */
-#endif /* !HAVE_SA_LEN_MACRO */
-
-#endif /* PORTABLE_SOCKET_H */
diff --git a/include/portable/time.h b/include/portable/time.h
deleted file mode 100644 (file)
index 42d4961..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*  $Id: time.h 4020 2000-10-03 01:27:13Z rra $
-**
-**  Portability wrapper around <time.h> and <sys/time.h>.
-**
-**  This header includes <time.h> and <sys/time.h> as applicable, handling
-**  systems where one can't include both headers (per the autoconf manual).
-*/
-
-#ifndef PORTABLE_TIME_H
-#define PORTABLE_TIME_H 1
-
-#include "config.h"
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#endif /* PORTABLE_TIME_H */
diff --git a/include/portable/wait.h b/include/portable/wait.h
deleted file mode 100644 (file)
index b6f5109..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*  $Id: wait.h 5398 2002-04-09 07:21:58Z rra $
-**
-**  Portability wrapper around <sys/wait.h>.
-**
-**  This header includes <sys/wait.h> if it's available, and then makes sure
-**  that the standard wait macros are defined and defines them if they
-**  aren't.
-*/
-
-#ifndef PORTABLE_WAIT_H
-#define PORTABLE_WAIT_H 1
-
-#include "config.h"
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-/* Per the autoconf documentation, just always check to see if the various
-   macros are defined and define them ourselves if they aren't.  These
-   definitions are based on the approach taken by BSDI. */
-#ifndef WCOREDUMP
-# define WCOREDUMP(status)      ((unsigned)(status) & 0x80)
-#endif
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(status)    (((unsigned)(status) >> 8) & 0xff)
-#endif
-#ifndef WTERMSIG
-# define WTERMSIG(status)       ((unsigned)(status) & 0x7f)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(status)      (((unsigned)(status) & 0xff) == 0)
-#endif
-#ifndef WIFSTOPPED
-# define WIFSTOPPED(status)     (((unsigned)(status) & 0xff) == 0x7f)
-#endif
-#ifndef WIFSIGNALED
-# define WIFSIGNALED(status)    (!WIFSTOPPED(status) && !WIFEXITED(status))
-#endif
-
-#endif /* PORTABLE_WAIT_H */
diff --git a/include/ppport.h b/include/ppport.h
deleted file mode 100644 (file)
index 2387f00..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-
-#ifndef PPPORT_H
-#define PPPORT_H 1
-
-/* Perl/Pollution/Portability Version 1.0003 */
-
-/* Copyright (C) 1999, Kenneth Albanowski. This code may be used and
-   distributed under the same license as any version of Perl. */
-   
-/* For the latest version of this code, please contact the author at
-   <kjahds@kjahds.com>, or check with the Perl maintainers. */
-   
-/* If you needed to customize this file for your project, please mention
-   your changes. */
-
-/*
-   Modified for Perl 5.6.0 by Russ Allbery (use PERL_VERSION instead of
-   PERL_PATCHLEVEL).
-*/
-
-
-/*
-   In order for a Perl extension module to be as portable as possible
-   across differing versions of Perl itself, certain steps need to be taken.
-   Including this header is the first major one, then using dTHR is all the
-   appropriate places and using a PL_ prefix to refer to global Perl
-   variables is the second.
-*/
-
-
-/* If you use one of a few functions that were not present in earlier
-   versions of Perl, please add a define before the inclusion of ppport.h
-   for a static include, or use the GLOBAL request in a single module to
-   produce a global definition that can be referenced from the other
-   modules.
-   
-   Function:            Static define:           Extern define:
-   newCONSTSUB()        NEED_newCONSTSUB         NEED_newCONSTSUB_GLOBAL
-
-*/
-
-/* To verify whether ppport.h is needed for your module, and whether any
-   special defines should be used, ppport.h can be run through Perl to check
-   your source code. Simply say:
-   
-       perl -x ppport.h *.c *.h *.xs foo/perl.c [etc]
-   
-   The result will be a list of patches suggesting changes that should at
-   least be acceptable, if not necessarily the most efficient solution, or a
-   fix for all possible problems. It won't catch where dTHR is needed, and
-   doesn't attempt to account for global macro or function definitions,
-   nested includes, typemaps, etc.
-   
-   In order to test for the need of dTHR, please try your module under a
-   recent version of Perl that has threading compiled-in.
-*/ 
-
-
-/*
-#!/usr/bin/perl
-@ARGV = ("*.xs") if !@ARGV;
-%badmacros = %funcs = %macros = ();
-foreach (<DATA>) {
-       $funcs{$1} = 1 if /Provide:\s+(\S+)/;
-       $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/;
-       $badmacros{$2}=$1 if /^#\s*define\s+(PL_\S+)\s+(\S+)/;
-}
-foreach $filename (map(glob($_),@ARGV)) {
-       unless (open(IN, "<$filename")) {
-               warn "Unable to read from $file: $!\n";
-               next;
-       }
-       print "Scanning $filename...\n";
-       $c = ""; while (<IN>) { $c .= $_; } close(IN);
-       $need_include = 0; %add_func = (); $changes = 0;
-       $has_include = ($c =~ /#.*include.*ppport/m);
-
-       foreach $func (keys %funcs) {
-               if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) {
-                       if ($c !~ /\b$func\b/m) {
-                               print "If $func isn't needed, you don't need to request it.\n" if
-                               $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m);
-                       } else {
-                               print "Uses $func\n";
-                               $need_include = 1;
-                       }
-               } else {
-                       if ($c =~ /\b$func\b/m) {
-                               $add_func{$func} =1 ;
-                               print "Uses $func\n";
-                               $need_include = 1;
-                       }
-               }
-       }
-
-       if (not $need_include) {
-               foreach $macro (keys %macros) {
-                       if ($c =~ /\b$macro\b/m) {
-                               print "Uses $macro\n";
-                               $need_include = 1;
-                       }
-               }
-       }
-
-       foreach $badmacro (keys %badmacros) {
-               if ($c =~ /\b$badmacro\b/m) {
-                       $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm);
-                       print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
-                       $need_include = 1;
-               }
-       }
-       
-       if (scalar(keys %add_func) or $need_include != $has_include) {
-               if (!$has_include) {
-                       $inc = join('',map("#define NEED_$_\n", sort keys %add_func)).
-                              "#include \"ppport.h\"\n";
-                       $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
-               } elsif (keys %add_func) {
-                       $inc = join('',map("#define NEED_$_\n", sort keys %add_func));
-                       $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m;
-               }
-               if (!$need_include) {
-                       print "Doesn't seem to need ppport.h.\n";
-                       $c =~ s/^.*#.*include.*ppport.*\n//m;
-               }
-               $changes++;
-       }
-       
-       if ($changes) {
-               open(OUT,">/tmp/ppport.h.$$");
-               print OUT $c;
-               close(OUT);
-               open(DIFF, "diff -u $filename /tmp/ppport.h.$$|");
-               while (<DIFF>) { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; }
-               close(DIFF);
-               unlink("/tmp/ppport.h.$$");
-       } else {
-               print "Looks OK\n";
-       }
-}
-__DATA__
-*/
-
-
-#if !defined(PERL_VERSION) && !defined(PERL_PATCHLEVEL)
-#      ifndef __PATCHLEVEL_H_INCLUDED__
-#              include <patchlevel.h>
-#      endif
-#endif
-#ifndef PERL_VERSION
-#       define PERL_REVISION (5)
-#       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_REVISION == 5) && ((PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 4)))
-#      define PL_sv_undef      sv_undef
-#      define PL_sv_yes        sv_yes
-#      define PL_sv_no         sv_no
-#      define PL_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_REVISION == 5) && (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/innd/Makefile b/innd/Makefile
deleted file mode 100644 (file)
index 61ebcae..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-##  $Id: Makefile 7837 2008-05-19 17:14:15Z iulius $
-
-include ../Makefile.global
-
-top            = ..
-CFLAGS         = $(GCFLAGS) $(TCLINC)
-
-ALL            = innd inndstart
-
-SOURCES                = art.c cc.c chan.c icd.c innd.c inndstart.c keywords.c lc.c \
-                 nc.c newsfeeds.c ng.c perl.c proc.c python.c rc.c site.c \
-                 status.c tcl.c util.c wip.c
-
-# The objects that are linked into innd.  All SOURCES except inndstart.
-OBJECTS                = art.o cc.o chan.o icd.o innd.o keywords.o lc.o nc.o \
-                 newsfeeds.o ng.o perl.o proc.o python.o rc.o site.o \
-                 status.o tcl.o util.o wip.o
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPRI) innd $D$(PATHBIN)/innd
-       @ME=`$(WHOAMI)` ; \
-       if [ x"$$ME" = xroot ] ; then \
-           echo $(LI_SPRI) inndstart $D$(PATHBIN)/inndstart ; \
-           $(LI_SPRI) inndstart $D$(PATHBIN)/inndstart ; \
-       else \
-           echo $(LI_XPRI) inndstart $D$(PATHBIN)/inndstart ; \
-           $(LI_XPRI) inndstart $D$(PATHBIN)/inndstart ; \
-           echo '' ; \
-           echo '========================' ; \
-           echo 'NOTE NOTE NOTE NOTE NOTE' ; \
-           ls -l $D$(PATHBIN)/inndstart ; \
-           echo '$D$(PATHBIN)/inndstart needs to be installed setuid root' ; \
-           echo '' ; echo ; \
-       fi
-
-clean:
-       rm -f *.o $(ALL) inndp profiled
-       rm -rf .libs
-
-clobber distclean: clean
-       rm -f tags
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES) ../lib/*.c innd.h ../include/*.h
-
-
-##  Compilation rules.
-
-INNDLIBS       = $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) \
-                 $(PERLLIB) $(TCLLIB) $(PYTHONLIB) $(REGEXLIB) $(LIBS)
-
-perl.o:                perl.c          ; $(CC) $(CFLAGS) $(PERLINC) -c perl.c
-python.o:      python.c        ; $(CC) $(CFLAGS) $(PYTHONINC) -c python.c
-
-innd: $(OBJECTS) $(LIBSTORAGE) $(LIBHIST) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(OBJECTS) $(INNDLIBS)
-
-inndstart: inndstart.o $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ inndstart.o $(LIBINN) $(LIBS)
-
-$(LIBINN):     ; (cd ../lib ; $(MAKE))
-$(LIBSTORAGE): ; (cd ../storage ; $(MAKE))
-$(LIBHIST):    ; (cd ../history ; $(MAKE))
-
-
-##  Profiling.  These rules have not been checked for a while and may need
-##  some work.
-
-profiled:      inndp
-       date >$@
-
-inndp:         $(SOURCES)
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) innd
-       mv innd inndp
-       rm -f $(OBJECTS)
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend: Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS) $(PERLINC) $(PYTHONINC) $(TCLINC)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-art.o: art.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/wire.h \
-  ../include/inn/md5.h innd.h ../include/portable/time.h \
-  ../include/config.h ../include/portable/socket.h \
-  ../include/inn/buffer.h ../include/inn/history.h \
-  ../include/inn/messages.h ../include/inn/timer.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h
-cc.o: cc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/qio.h \
-  innd.h ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/inndcomm.h \
-  ../include/innperl.h
-chan.o: chan.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-icd.o: icd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h ../include/inn/innconf.h \
-  ../include/inn/defines.h innd.h ../include/portable/time.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h
-innd.o: innd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/innperl.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/timer.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h
-inndstart.o: inndstart.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/paths.h
-keywords.o: keywords.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h ../include/inn/innconf.h ../include/inn/defines.h \
-  innd.h ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/nntp.h ../include/paths.h \
-  ../include/storage.h
-lc.o: lc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-nc.o: nc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-newsfeeds.o: newsfeeds.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-ng.o: ng.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h
-perl.o: perl.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h
-proc.o: proc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/wait.h ../include/config.h innd.h \
-  ../include/portable/time.h ../include/portable/socket.h \
-  ../include/inn/buffer.h ../include/inn/defines.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-python.o: python.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-rc.o: rc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/vector.h innd.h ../include/portable/time.h \
-  ../include/inn/buffer.h ../include/inn/history.h \
-  ../include/inn/messages.h ../include/inn/timer.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h
-site.o: site.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-status.o: status.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/innperl.h
-tcl.o: tcl.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
-util.o: util.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  innd.h ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/nntp.h ../include/paths.h \
-  ../include/storage.h
-wip.o: wip.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h innd.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/buffer.h \
-  ../include/inn/history.h ../include/inn/messages.h \
-  ../include/inn/timer.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h
diff --git a/innd/art.c b/innd/art.c
deleted file mode 100644 (file)
index bef61f7..0000000
+++ /dev/null
@@ -1,2545 +0,0 @@
-/*  $Id: art.c 7748 2008-04-06 13:49:56Z iulius $
-**
-**  Article-processing.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <sys/uio.h>
-
-#include "inn/innconf.h"
-#include "inn/wire.h"
-#include "inn/md5.h"
-#include "innd.h"
-#include "ov.h"
-#include "storage.h"
-
-typedef struct iovec   IOVEC;
-
-#define        ARTIOVCNT       16
-
-extern bool DoCancels;
-
-#if    defined(S_IXUSR)
-#define EXECUTE_BITS   (S_IXUSR | S_IXGRP | S_IXOTH)
-#else
-#define EXECUTE_BITS   0111
-#endif /* defined(S_IXUSR) */
-
-/* Characters used in log messages indicating the disposition of messages. */
-#define ART_ACCEPT              '+'
-#define ART_CANC                'c'
-#define ART_STRSTR              '?'
-#define ART_JUNK                'j'
-#define ART_REJECT              '-'
-
-/*
-**  used to sort Xref, Bytes and Path pointers
-*/
-typedef struct _HEADERP {
-  int   index;                          
-  char  *p;
-} HEADERP;
-  
-#define HPCOUNT                4
-
-/*
-**  For speed we build a binary tree of the headers, sorted by their
-**  name.  We also store the header's Name fields in the tree to avoid
-**  doing an extra indirection.
-*/
-typedef struct _TREE {
-  const char   *Name;
-  const ARTHEADER *Header;
-  struct _TREE *Before;
-  struct _TREE *After;
-} TREE;
-
-static TREE    *ARTheadertree;
-
-/*
-**  For doing the overview database, we keep a list of the headers and
-**  a flag saying if they're written in brief or full format.
-*/
-typedef struct _ARTOVERFIELD {
-  const ARTHEADER *Header;
-  bool         NeedHeader;
-} ARTOVERFIELD;
-
-static ARTOVERFIELD    *ARTfields;
-
-/*
-**  General newsgroup we care about, and what we put in the Path line.
-*/
-static char    ARTctl[] = "control";
-static char    ARTjnk[] = "junk";
-static char    *ARTpathme;
-
-/*
-**  Different types of rejected articles.
-*/
-typedef enum {REJECT_DUPLICATE, REJECT_SITE, REJECT_FILTER, REJECT_DISTRIB,
-             REJECT_GROUP, REJECT_UNAPP, REJECT_OTHER} Reject_type;
-
-/*
-**  Flag array, indexed by character.  Character classes for Message-ID's.
-*/
-static char            ARTcclass[256];
-#define CC_MSGID_ATOM  01
-#define CC_MSGID_NORM  02
-#define CC_HOSTNAME    04
-#define ARTnormchar(c) ((ARTcclass[(unsigned char)(c)] & CC_MSGID_NORM) != 0)
-#define ARTatomchar(c) ((ARTcclass[(unsigned char)(c)] & CC_MSGID_ATOM) != 0)
-#define ARThostchar(c) ((ARTcclass[(unsigned char)(c)] & CC_HOSTNAME) != 0)
-
-#if defined(DO_PERL) || defined(DO_PYTHON)
-const char     *filterPath;
-#endif /* DO_PERL || DO_PYTHON */
-
-
-\f
-/*
-**  Trim '\r' from buffer.
-*/
-static void
-buffer_trimcr(struct buffer *bp)
-{
-    char *p, *q;
-    int trimmed = 0;
-
-    for (p = q = bp->data ; p < bp->data + bp->left ; p++) {
-       if (*p == '\r' && p+1 < bp->data + bp->left && p[1] == '\n') {
-           trimmed++;
-           continue;
-       }
-       *q++ = *p;
-    }
-    bp->left -= trimmed;
-}
-
-/*
-**  Mark that the site gets this article.
-*/
-static void
-SITEmark(SITE *sp, NEWSGROUP *ngp)
-{
-  SITE *funnel;
-
-  sp->Sendit = true;
-  if (sp->ng == NULL)
-    sp->ng = ngp;
-  if (sp->Funnel != NOSITE) {
-    funnel = &Sites[sp->Funnel];
-    if (funnel->ng == NULL)
-      funnel->ng = ngp;
-  }
-}
-
-/*
-**
-*/
-bool
-ARTreadschema(void)
-{
-  static char  *SCHEMA = NULL;
-  FILE         *F;
-  int          i;
-  char         *p;
-  ARTOVERFIELD *fp;
-  const ARTHEADER *hp;
-  bool         ok;
-  char         buff[SMBUF];
-  bool         foundxref = false;
-  bool         foundxreffull = false;
-
-  if (ARTfields != NULL) {
-    free(ARTfields);
-    ARTfields = NULL;
-  }
-
-  /* Open file, count lines. */
-  if (SCHEMA == NULL)
-    SCHEMA = concatpath(innconf->pathetc, _PATH_SCHEMA);
-  if ((F = Fopen(SCHEMA, "r", TEMPORARYOPEN)) == NULL)
-    return false;
-  for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
-    continue;
-  fseeko(F, 0, SEEK_SET);
-  ARTfields = xmalloc((i + 1) * sizeof(ARTOVERFIELD));
-
-  /* Parse each field. */
-  for (ok = true, fp = ARTfields ; fgets(buff, sizeof buff, F) != NULL ;) {
-    /* Ignore blank and comment lines. */
-    if ((p = strchr(buff, '\n')) != NULL)
-      *p = '\0';
-    if ((p = strchr(buff, '#')) != NULL)
-      *p = '\0';
-    if (buff[0] == '\0')
-      continue;
-    if ((p = strchr(buff, ':')) != NULL) {
-      *p++ = '\0';
-      fp->NeedHeader = (strcmp(p, "full") == 0);
-    } else
-      fp->NeedHeader = false;
-    if (strcasecmp(buff, "Xref") == 0) {
-      foundxref = true;
-      foundxreffull = fp->NeedHeader;
-    }
-    for (hp = ARTheaders; hp < ARRAY_END(ARTheaders); hp++) {
-      if (strcasecmp(buff, hp->Name) == 0) {
-       fp->Header = hp;
-       break;
-      }
-    }
-    if (hp == ARRAY_END(ARTheaders)) {
-      syslog(L_ERROR, "%s bad_schema unknown header \"%s\"",
-               LogName, buff);
-      ok = false;
-      continue;
-    }
-    fp++;
-  }
-  fp->Header = NULL;
-
-  Fclose(F);
-  if (!foundxref || !foundxreffull) {
-    syslog(L_FATAL, "%s 'Xref:full' must be included in %s", LogName, SCHEMA);
-    exit(1);
-  }
-  return ok;
-}
-
-
-/*
-**  Build a balanced tree for the headers in subscript range [lo..hi).
-**  This only gets called once, and the tree only has about 37 entries,
-**  so we don't bother to unroll the recursion.
-*/
-static TREE *
-ARTbuildtree(const ARTHEADER **Table, int lo, int hi)
-{
-  int  mid;
-  TREE *tp;
-
-  mid = lo + (hi - lo) / 2;
-  tp = xmalloc(sizeof(TREE));
-  tp->Header = Table[mid];
-  tp->Name = tp->Header->Name;
-  if (mid == lo)
-    tp->Before = NULL;
-  else
-    tp->Before = ARTbuildtree(Table, lo, mid);
-  if (mid == hi - 1)
-    tp->After = NULL;
-  else
-    tp->After = ARTbuildtree(Table, mid + 1, hi);
-  return tp;
-}
-
-
-/*
-**  Sorting predicate for qsort call in ARTsetup.
-*/
-static int
-ARTcompare(const void *p1, const void *p2)
-{
-  return strcasecmp(((const ARTHEADER **)p1)[0]->Name,
-    ((const ARTHEADER **)p2)[0]->Name);
-}
-
-
-/*
-**  Setup the article processing.
-*/
-void
-ARTsetup(void)
-{
-  const char * p;
-  const ARTHEADER **   table;
-  unsigned int i;
-
-  /* Set up the character class tables.  These are written a
-   * little strangely to work around a GCC2.0 bug. */
-  memset(ARTcclass, 0, sizeof ARTcclass);
-  p = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-  while ((i = *p++) != 0) {
-    ARTcclass[i] = CC_HOSTNAME | CC_MSGID_ATOM | CC_MSGID_NORM;
-  }
-  p = "!#$%&'*+-/=?^_`{|}~";
-  while ((i = *p++) != 0) {
-    ARTcclass[i] = CC_MSGID_ATOM | CC_MSGID_NORM;
-  }
-  p = "\"(),.:;<@[\\]";
-  while ((i = *p++) != 0) {
-    ARTcclass[i] = CC_MSGID_NORM;
-  }
-
-  /* The RFC's don't require it, but we add underscore to the list of valid
-   * hostname characters. */
-  ARTcclass['.'] |= CC_HOSTNAME;
-  ARTcclass['-'] |= CC_HOSTNAME;
-  ARTcclass['_'] |= CC_HOSTNAME;
-
-  /* Build the header tree. */
-  table = xmalloc(ARRAY_SIZE(ARTheaders) * sizeof(ARTHEADER *));
-  for (i = 0; i < ARRAY_SIZE(ARTheaders); i++)
-    table[i] = &ARTheaders[i];
-  qsort(table, ARRAY_SIZE(ARTheaders), sizeof *table, ARTcompare);
-  ARTheadertree = ARTbuildtree(table, 0, ARRAY_SIZE(ARTheaders));
-  free(table);
-
-  /* Get our Path name, kill trailing !. */
-  ARTpathme = xstrdup(Path.data);
-  ARTpathme[Path.used - 1] = '\0';
-
-  /* Set up database; ignore errors. */
-  ARTreadschema();
-}
-
-
-static void
-ARTfreetree(TREE *tp)
-{
-  TREE *next;
-
-  for ( ; tp != NULL; tp = next) {
-    if (tp->Before)
-      ARTfreetree(tp->Before);
-    next = tp->After;
-    free(tp);
-  }
-}
-
-
-void
-ARTclose(void)
-{
-  if (ARTfields != NULL) {
-    free(ARTfields);
-    ARTfields = NULL;
-  }
-  ARTfreetree(ARTheadertree);
-}
-
-/*
-**  Start a log message about an article.
-*/
-static void
-ARTlog(const ARTDATA *data, char code, const char *text)
-{
-  const HDRCONTENT *hc = data->HdrContent;
-  int i;
-  bool Done;
-
-  TMRstart(TMR_ARTLOG);
-  /* We could be a bit faster by not dividing Now.usec by 1000,
-   * but who really wants to log at the Microsec level? */
-  Done = code == ART_ACCEPT || code == ART_JUNK;
-  if (text)
-    i = fprintf(Log, "%.15s.%03d %c %s %s %s%s",
-      ctime(&Now.time) + 4, (int)(Now.usec / 1000), code, data->Feedsite,
-      HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "(null)",
-      text, Done ? "" : "\n");
-  else
-    i = fprintf(Log, "%.15s.%03d %c %s %s%s",
-      ctime(&Now.time) + 4, (int)(Now.usec / 1000), code, data->Feedsite,
-      HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "(null)",
-      Done ? "" : "\n");
-  if (i == EOF || (Done && !BufferedLogs && fflush(Log)) || ferror(Log)) {
-    i = errno;
-    syslog(L_ERROR, "%s cant write log_start %m", LogName);
-    IOError("logging article", i);
-    clearerr(Log);
-  }
-  TMRstop(TMR_ARTLOG);
-}
-
-/*
-**  Parse a Path line, splitting it up into NULL-terminated array of strings.
-*/
-static int
-ARTparsepath(const char *p, int size, LISTBUFFER *list)
-{
-  int  i;
-  char *q, **hp;
-
-  /* setup buffer */ 
-  SetupListBuffer(size, list);
-
-  /* loop over text and copy */
-  for (i = 0, q = list->Data, hp = list->List ; *p ; p++, *q++ = '\0') { 
-    /* skip leading separators. */
-    for (; *p && !ARThostchar(*p) && ISWHITE(*p) ; p++)
-      continue;
-    if (*p == '\0')
-      break;
-
-    if (list->ListLength <= i) {
-      list->ListLength += DEFAULTNGBOXSIZE;
-      list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-      hp = &list->List[i];
-    }
-    /* mark the start of the host, move to the end of it while copying */  
-    for (*hp++ = q, i++ ; *p && ARThostchar(*p) && !ISWHITE(*p) ;)
-      *q++ = *p++;
-    if (*p == '\0')
-      break;
-  }
-  *q = '\0';
-  if (i == list->ListLength) {
-    list->ListLength += DEFAULTNGBOXSIZE;
-    list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-    hp = &list->List[i];
-  }
-  *hp = NULL;
-  return i;
-}
-
-/*
-**  Sorting pointer where header starts
-*/
-static int
-ARTheaderpcmp(const void *p1, const void *p2)
-{
-  return (((const HEADERP *)p1)->p - ((const HEADERP *)p2)->p);
-}
-
-/* Write an article using the storage api.  Put it together in memory and
-   call out to the api. */
-static TOKEN
-ARTstore(CHANNEL *cp)
-{
-  struct buffer        *Article = &cp->In;
-  ARTDATA      *data = &cp->Data;
-  HDRCONTENT   *hc = data->HdrContent;
-  const char   *p;
-  ARTHANDLE    arth;
-  int          i, j, iovcnt = 0;
-  long         headersize = 0;
-  TOKEN                result;
-  struct buffer        *headers = &data->Headers;
-  struct iovec iov[ARTIOVCNT];
-  HEADERP      hp[HPCOUNT];
-
-  /* find Path, Bytes and Xref to be prepended/dropped/replaced */
-  arth.len = i = 0;
-  /* assumes Path header is required header */
-  hp[i].p = HDR(HDR__PATH);
-  hp[i++].index = HDR__PATH;
-  if (HDR_FOUND(HDR__XREF)) {
-    hp[i].p = HDR(HDR__XREF);
-    hp[i++].index = HDR__XREF;
-  }
-  if (HDR_FOUND(HDR__BYTES)) {
-    hp[i].p = HDR(HDR__BYTES);
-    hp[i++].index = HDR__BYTES;
-  }
-  /* get the order of header appearance */
-  qsort(hp, i, sizeof(HEADERP), ARTheaderpcmp);
-  /* p always points where the next data should be written from */
-  for (p = Article->data + cp->Start, j = 0 ; j < i ; j++) {
-    switch (hp[j].index) {
-      case HDR__PATH:
-       if (!data->Hassamepath || data->AddAlias || Pathcluster.used) {
-         /* write heading data */
-         iov[iovcnt].iov_base = (char *) p;
-         iov[iovcnt++].iov_len = HDR(HDR__PATH) - p;
-         arth.len += HDR(HDR__PATH) - p;
-          /* append clusterpath */
-          if (Pathcluster.used) {
-            iov[iovcnt].iov_base = Pathcluster.data;
-            iov[iovcnt++].iov_len = Pathcluster.used;
-            arth.len += Pathcluster.used;
-          }
-         /* now append new one */
-         iov[iovcnt].iov_base = Path.data;
-         iov[iovcnt++].iov_len = Path.used;
-         arth.len += Path.used;
-         if (data->AddAlias) {
-           iov[iovcnt].iov_base = Pathalias.data;
-           iov[iovcnt++].iov_len = Pathalias.used;
-           arth.len += Pathalias.used;
-         }
-         /* next to write */
-         p = HDR(HDR__PATH);
-          if (data->Hassamecluster)
-            p += Pathcluster.used;
-       }
-       break;
-      case HDR__XREF:
-       if (!innconf->xrefslave) {
-         /* write heading data */
-         iov[iovcnt].iov_base = (char *) p;
-         iov[iovcnt++].iov_len = HDR(HDR__XREF) - p;
-         arth.len += HDR(HDR__XREF) - p;
-         /* replace with new one */
-         iov[iovcnt].iov_base = data->Xref;
-         iov[iovcnt++].iov_len = data->XrefLength - 2;
-         arth.len += data->XrefLength - 2;
-         /* next to write */
-         /* this points where trailing "\r\n" of orginal Xref header exists */
-         p = HDR(HDR__XREF) + HDR_LEN(HDR__XREF);
-       }
-       break;
-      case HDR__BYTES:
-       /* ditch whole Byte header */
-       /* write heading data */
-       iov[iovcnt].iov_base = (char *) p;
-       iov[iovcnt++].iov_len = data->BytesHeader - p;
-       arth.len += data->BytesHeader - p;
-       /* next to write */
-       /* need to skip trailing "\r\n" of Bytes header */
-       p = HDR(HDR__BYTES) + HDR_LEN(HDR__BYTES) + 2;
-       break;
-      default:
-       result.type = TOKEN_EMPTY;
-       return result;
-    }
-  }
-  /* in case Xref is not included in orignal article */
-  if (!HDR_FOUND(HDR__XREF)) {
-    /* write heading data */
-    iov[iovcnt].iov_base = (char *) p;
-    iov[iovcnt++].iov_len = Article->data + (data->Body - 2) - p;
-    arth.len += Article->data + (data->Body - 2) - p;
-    /* Xref needs to be inserted */
-    iov[iovcnt].iov_base = (char *) "Xref: ";
-    iov[iovcnt++].iov_len = sizeof("Xref: ") - 1;
-    arth.len += sizeof("Xref: ") - 1;
-    iov[iovcnt].iov_base = data->Xref;
-    iov[iovcnt++].iov_len = data->XrefLength;
-    arth.len += data->XrefLength;
-    p = Article->data + (data->Body - 2);
-  }
-  /* write rest of data */
-  iov[iovcnt].iov_base = (char *) p;
-  iov[iovcnt++].iov_len = Article->data + cp->Next - p;
-  arth.len += Article->data + cp->Next - p;
-
-  /* revert trailing '\0\n' to '\r\n' of all system header */
-  for (i = 0 ; i < MAX_ARTHEADER ; i++) {
-    if (HDR_FOUND(i))
-      HDR_PARSE_END(i);
-  }
-
-  arth.iov = iov;
-  arth.iovcnt = iovcnt;
-  arth.arrived = (time_t)0;
-  arth.token = (TOKEN *)NULL;
-  arth.expires = data->Expires;
-  if (innconf->storeonxref) {
-    arth.groups = data->Replic;
-    arth.groupslen = data->ReplicLength;
-  } else {
-    arth.groups = HDR(HDR__NEWSGROUPS);
-    arth.groupslen = HDR_LEN(HDR__NEWSGROUPS);
-  }
-
-  SMerrno = SMERR_NOERROR;
-  result = SMstore(arth);
-  if (result.type == TOKEN_EMPTY) {
-    if (SMerrno == SMERR_NOMATCH)
-      ThrottleNoMatchError();
-    else if (SMerrno != SMERR_NOERROR)
-      IOError("SMstore", SMerrno);
-    return result;
-  }
-
-  /* calculate stored size */
-  for (data->BytesValue = i = 0 ; i < iovcnt ; i++) {
-    if (NeedHeaders && (i + 1 == iovcnt)) {
-      /* body begins at last iov */
-      headersize = data->BytesValue +
-       Article->data + data->Body - (char *) iov[i].iov_base;
-    }
-    data->BytesValue += iov[i].iov_len;
-  }
-  /* "\r\n" is counted as 1 byte.  trailing ".\r\n" and body delimitor are also
-     substituted */
-  data->BytesValue -= (data->HeaderLines + data->Lines + 4);
-  /* Figure out how much space we'll need and get it. */
-  snprintf(data->Bytes, sizeof(data->Bytes), "Bytes: %ld\r\n",
-           data->BytesValue);
-  /* does not include strlen("Bytes: \r\n") */
-  data->BytesLength = strlen(data->Bytes) - 9;
-
-  if (!NeedHeaders)
-    return result;
-
-  /* Add the data. */
-  buffer_resize(headers, headersize);
-  buffer_set(headers, data->Bytes, strlen(data->Bytes));
-  for (i = 0 ; i < iovcnt ; i++) {
-    if (i + 1 == iovcnt)
-      buffer_append(headers, iov[i].iov_base,
-       Article->data + data->Body - (char *) iov[i].iov_base);
-    else
-      buffer_append(headers, iov[i].iov_base, iov[i].iov_len);
-  }
-  buffer_trimcr(headers);
-
-  return result;
-}
-
-/*
-**  Parse a header that starts at header.  size includes trailing "\r\n"
-*/
-static void
-ARTparseheader(CHANNEL *cp, int size)
-{
-  ARTDATA      *data = &cp->Data;
-  char         *header = cp->In.data + data->CurHeader;
-  HDRCONTENT   *hc = cp->Data.HdrContent;
-  TREE         *tp;
-  const ARTHEADER *hp;
-  char         c, *p, *colon;
-  int          i;
-
-  /* Find first colon */
-  if ((colon = memchr(header, ':', size)) == NULL || !ISWHITE(colon[1])) {
-    if ((p = memchr(header, '\r', size)) != NULL)
-      *p = '\0';
-    snprintf(cp->Error, sizeof(cp->Error),
-             "%d No colon-space in \"%s\" header",
-             NNTP_REJECTIT_VAL, MaxLength(header, header));
-    if (p != NULL)
-      *p = '\r';
-    return;
-  }
-
-  /* See if this is a system header.  A fairly tightly-coded binary search. */
-  c = CTYPE(islower, *header) ? toupper(*header) : *header;
-  for (*colon = '\0', tp = ARTheadertree; tp; ) {
-    if ((i = c - tp->Name[0]) == 0 && (i = strcasecmp(header, tp->Name)) == 0)
-      break;
-    if (i < 0)
-      tp = tp->Before;
-    else
-      tp = tp->After;
-  }
-  *colon = ':';
-
-  if (tp == NULL) {
-    /* Not a system header, make sure we have <word><colon><space>. */
-    for (p = colon; --p > header; ) {
-      if (ISWHITE(*p)) {
-       c = *p;
-       *p = '\0';
-       snprintf(cp->Error, sizeof(cp->Error),
-                 "%d Space before colon in \"%s\" header",
-                 NNTP_REJECTIT_VAL, MaxLength(header, header));
-       *p = c;
-       return;
-      }
-    }
-    return;
-  }
-  hp = tp->Header;
-  i = hp - ARTheaders;
-  /* remember to ditch if it's Bytes: */
-  if (i == HDR__BYTES)
-    cp->Data.BytesHeader = header;
-  hc = &hc[i];
-  if (hc->Length != 0) {
-    /* duplicated */
-    hc->Length = -1;
-  } else {
-    for (p = colon + 1 ; (p < header + size - 2) &&
-      (ISWHITE(*p) || *p == '\r' || *p == '\n'); p++);
-    if (p < header + size - 2) {
-      hc->Value = p;
-      /* HDR_LEN() does not include trailing "\r\n" */
-      hc->Length = header + size - 2 - p;
-    } else {
-      snprintf(cp->Error, sizeof(cp->Error),
-               "%d Body of header is all blanks in \"%s\" header",
-               NNTP_REJECTIT_VAL, MaxLength(hp->Name, hp->Name));
-    }
-  }
-  return;
-}
-
-/*
-**  Check Message-ID format based on RFC 822 grammar, except that (as per
-**  RFC 1036) whitespace, non-printing, and '>' characters are excluded.
-**  Based on code by Paul Eggert posted to news.software.b on 22-Nov-90
-**  in <#*tyo2'~n@twinsun.com>, with additional email discussion.
-**  Thanks, Paul.
-*/
-bool
-ARTidok(const char *MessageID)
-{
-  int          c;
-  const char   *p;
-
-  /* Check the length of the message ID. */
-  if (MessageID == NULL || strlen(MessageID) > NNTP_MSGID_MAXLEN)
-    return false;
-
-  /* Scan local-part:  "< atom|quoted [ . atom|quoted]" */
-  p = MessageID;
-  if (*p++ != '<')
-    return false;
-  for (; ; p++) {
-    if (ARTatomchar(*p))
-      while (ARTatomchar(*++p))
-       continue;
-    else {
-      if (*p++ != '"')
-       return false;
-      for ( ; ; ) {
-       switch (c = *p++) {
-       case '\\':
-         c = *p++;
-         /* FALLTHROUGH */
-       default:
-         if (ARTnormchar(c))
-           continue;
-         return false;
-       case '"':
-         break;
-       }
-       break;
-      }
-    }
-    if (*p != '.')
-      break;
-  }
-
-  /* Scan domain part:  "@ atom|domain [ . atom|domain] > \0" */
-  if (*p++ != '@')
-    return false;
-  for ( ; ; p++) {
-    if (ARTatomchar(*p))
-      while (ARTatomchar(*++p))
-       continue;
-    else {
-      if (*p++ != '[')
-       return false;
-      for ( ; ; ) {
-       switch (c = *p++) {
-       case '\\':
-         c = *p++;
-         /* FALLTHROUGH */
-       default:
-         if (ARTnormchar(c))
-           continue;
-         /* FALLTHROUGH */
-       case '[':
-         return false;
-       case ']':
-         break;
-       }
-       break;
-      }
-    }
-    if (*p != '.')
-      break;
-  }
-
-  return *p == '>' && *++p == '\0';
-}
-
-/*
-**  Clean up data field where article informations are stored.
-**  This must be called before article processing.
-*/
-void
-ARTprepare(CHANNEL *cp)
-{
-  ARTDATA      *data = &cp->Data;
-  HDRCONTENT   *hc = data->HdrContent;
-  int          i;
-
-  for (i = 0 ; i < MAX_ARTHEADER ; i++, hc++) {
-    hc->Value = NULL;
-    hc->Length = 0;
-  }
-  data->Lines = data->HeaderLines = data->CRwithoutLF = data->LFwithoutCR = 0;
-  data->CurHeader = data->LastTerminator = data->LastCR = cp->Start - 1;
-  data->LastCRLF = data->Body = cp->Start - 1;
-  data->BytesHeader = NULL;
-  data->Feedsite = "?";
-  *cp->Error = '\0';
-}
-
-/*
-**  Clean up an article.  This is mainly copying in-place, stripping bad
-**  headers.  Also fill in the article data block with what we can find.
-**  Return NULL if the article is okay, or a string describing the error.
-**  Parse headers and end of article
-**  This is called by NCproc().
-*/
-void
-ARTparse(CHANNEL *cp)
-{
-  struct buffer        *bp = &cp->In;
-  ARTDATA      *data = &cp->Data;
-  long          i, limit, fudge, size;
-  int          hopcount;
-  char         **hops;
-  HDRCONTENT   *hc = data->HdrContent;
-
-  /* Read through the buffer to find header, body and end of article */
-  /* this routine is designed not to refer data so long as possible for
-     performance reason, so the code may look redundant at a glance */
-  limit = bp->used;
-  i = cp->Next;
-  if (cp->State == CSgetheader) {
-    /* header processing */
-    for (; i < limit ;) {
-      if (data->LastCRLF + 1 == i) {
-       /* begining of the line */
-       switch (bp->data[i]) {
-         case '.':
-           data->LastTerminator = i;
-           data->NullHeader = false;
-           break;
-         case '\r':
-           data->LastCR = i;
-           data->NullHeader = false;
-           break;
-         case '\n':
-           data->LFwithoutCR++;
-           data->NullHeader = false;
-           break;
-         case '\t':
-         case ' ':
-           /* header is folded.  NullHeader is untouched */
-           break;
-         case '\0':
-           snprintf(cp->Error, sizeof(cp->Error), "%d Null Header",
-                     NNTP_REJECTIT_VAL);
-           data->NullHeader = true;
-           break;
-         default:
-           if (data->CurHeader >= cp->Start) {
-             /* parse previous header */
-             if (!data->NullHeader && (*cp->Error == '\0'))
-               /* skip if already got an error */
-               ARTparseheader(cp, i - data->CurHeader);
-           }
-           data->CurHeader = i;
-           data->NullHeader = false;
-           break;
-       }
-       i++;
-      }
-      for (; i < limit ;) {
-       /* rest of the line */
-       switch (bp->data[i]) {
-         case '\0':
-           snprintf(cp->Error, sizeof(cp->Error), "%d Null Header",
-                     NNTP_REJECTIT_VAL);
-           data->NullHeader = true;
-           break;
-         case '\r':
-            if (data->LastCR >= cp->Start)
-             data->CRwithoutLF++;
-           data->LastCR = i;
-           break;
-         case '\n':
-           if (data->LastCR + 1 == i) {
-             /* found CRLF */
-             data->LastCR = cp->Start - 1;
-             if (data->LastTerminator + 2 == i) {
-               /* terminated still in header */
-               if (cp->Start + 3 == i) {
-                 snprintf(cp->Error, sizeof(cp->Error), "%d Empty article",
-                           NNTP_REJECTIT_VAL);
-                 cp->State = CSnoarticle;
-               } else {
-                 snprintf(cp->Error, sizeof(cp->Error), "%d No body",
-                           NNTP_REJECTIT_VAL);
-                 cp->State = CSgotarticle;
-               }
-               cp->Next = ++i;
-               goto sizecheck;
-             }
-             if (data->LastCRLF + MAXHEADERSIZE < i)
-               snprintf(cp->Error, sizeof(cp->Error),
-                         "%d Too long line in header %ld bytes",
-                         NNTP_REJECTIT_VAL, i - data->LastCRLF);
-             else if (data->LastCRLF + 2 == i) {
-               /* header ends */
-               /* parse previous header */
-               if (data->CurHeader >= cp->Start) {
-                 if (!data->NullHeader && (*cp->Error == '\0'))
-                   /* skip if already got an error */
-                   ARTparseheader(cp, i - 1 - data->CurHeader);
-               } else {
-                 snprintf(cp->Error, sizeof(cp->Error), "%d No header",
-                           NNTP_REJECTIT_VAL);
-               }
-               data->LastCRLF = i++;
-               data->Body = i;
-               cp->State = CSgetbody;
-               goto bodyprocessing;
-             }
-             data->HeaderLines++;
-             data->LastCRLF = i++;
-             goto endofheaderline;
-           } else {
-             data->LFwithoutCR++;
-           }
-           break;
-         default:
-           break;
-       }
-       i++;
-      }
-endofheaderline:
-      ;
-    }
-  } else {
-bodyprocessing:
-    /* body processing, or eating huge article */
-    for (; i < limit ;) {
-      if (data->LastCRLF + 1 == i) {
-        /* begining of the line */
-        switch (bp->data[i]) {
-         case '.':
-           data->LastTerminator = i;
-           break;
-         case '\r':
-           data->LastCR = i;
-           break;
-         case '\n':
-           data->LFwithoutCR++;
-           break;
-         default:
-           break;
-        }
-        i++;
-      }
-      for (; i < limit ;) {
-       /* rest of the line */
-       switch (bp->data[i]) {
-         case '\r':
-            if (data->LastCR >= cp->Start)
-             data->CRwithoutLF++;
-           data->LastCR = i;
-           break;
-         case '\n':
-           if (data->LastCR + 1 == i) {
-             /* found CRLF */
-             data->LastCR = cp->Start - 1;
-             if (data->LastTerminator + 2 == i) {
-               /* found end of article */
-               if (cp->State == CSeatarticle) {
-                 cp->State = CSgotlargearticle;
-                 cp->Next = ++i;
-                 snprintf(cp->Error, sizeof(cp->Error),
-                   "%d Article of %ld bytes exceeds local limit of %ld bytes",
-                   NNTP_REJECTIT_VAL, (unsigned long) i - cp->Start,
-                    innconf->maxartsize);
-               } else {
-                 cp->State = CSgotarticle;
-                 i++;
-               }
-               if (*cp->Error != '\0' && HDR_FOUND(HDR__MESSAGE_ID)) {
-                 HDR_PARSE_START(HDR__MESSAGE_ID);
-                 if (HDR_FOUND(HDR__PATH)) {
-                   /* to record path into news log */
-                   HDR_PARSE_START(HDR__PATH);
-                   hopcount = ARTparsepath(HDR(HDR__PATH), HDR_LEN(HDR__PATH),
-                     &data->Path);
-                   HDR_PARSE_END(HDR__PATH);
-                   if (hopcount > 0) {
-                     hops = data->Path.List;
-                     if (innconf->logipaddr) {
-                       data->Feedsite = RChostname(cp);
-                       if (data->Feedsite == NULL)
-                         data->Feedsite = CHANname(cp);
-                       if (strcmp("0.0.0.0", data->Feedsite) == 0 ||
-                         data->Feedsite[0] == '\0')
-                         data->Feedsite =
-                           hops && hops[0] ? hops[0] : CHANname(cp);
-                     } else {
-                       data->Feedsite =
-                         hops && hops[0] ? hops[0] : CHANname(cp);
-                     }
-                   }
-                 }
-                 ARTlog(data, ART_REJECT, cp->Error);
-                 HDR_PARSE_END(HDR__MESSAGE_ID);
-               }
-               if (cp->State == CSgotlargearticle)
-                 return;
-               goto sizecheck;
-             }
-#if 0 /* this may be examined in the future */
-             if (data->LastCRLF + MAXHEADERSIZE < i)
-               snprintf(cp->Error, sizeof(cp->Error),
-                         "%d Too long line in body %d bytes",
-                         NNTP_REJECTIT_VAL, i);
-#endif
-             data->Lines++;
-             data->LastCRLF = i++;
-             goto endofline;
-           } else {
-             data->LFwithoutCR++;
-           }
-           break;
-         default:
-           break;
-       }
-       i++;
-      }
-endofline:
-      ;
-    }
-  }
-sizecheck:
-  size = i - cp->Start;
-  fudge = data->HeaderLines + data->Lines + 4;
-  if (innconf->maxartsize > 0)
-    if (size > fudge && size - fudge > innconf->maxartsize)
-        cp->State = CSeatarticle;
-  cp->Next = i;
-  return;
-}
-
-/*
-**  Clean up an article.  This is mainly copying in-place, stripping bad
-**  headers.  Also fill in the article data block with what we can find.
-**  Return true if the article has no error, or false which means the error.
-*/
-static bool
-ARTclean(ARTDATA *data, char *buff)
-{
-  HDRCONTENT   *hc = data->HdrContent;
-  const ARTHEADER *hp = ARTheaders;
-  int          i;
-  char         *p;
-  int          delta;
-
-  TMRstart(TMR_ARTCLEAN);
-  data->Arrived = Now.time;
-  data->Expires = 0;
-
-  /* replace trailing '\r\n' with '\0\n' of all system header to be handled
-     easily by str*() functions */
-  for (i = 0 ; i < MAX_ARTHEADER ; i++) {
-    if (HDR_FOUND(i))
-      HDR_PARSE_START(i);
-  }
-
-  /* Make sure all the headers we need are there */
-  for (i = 0; i < MAX_ARTHEADER ; i++) {
-    if (hp[i].Type == HTreq) {
-      if (HDR_FOUND(i))
-        continue;
-      if (hc[i].Length < 0) {
-        sprintf(buff, "%d Duplicate \"%s\" header", NNTP_REJECTIT_VAL,
-                hp[1].Name);
-      } else {
-       sprintf(buff, "%d Missing \"%s\" header", NNTP_REJECTIT_VAL,
-                hp[i].Name);
-      }
-      TMRstop(TMR_ARTCLEAN);
-      return false;
-    }
-  }
-
-  /* assumes Message-ID header is required header */
-  if (!ARTidok(HDR(HDR__MESSAGE_ID))) {
-    HDR_LEN(HDR__MESSAGE_ID) = 0;
-    sprintf(buff, "%d Bad \"Message-ID\" header", NNTP_REJECTIT_VAL);
-    TMRstop(TMR_ARTCLEAN);
-    return false;
-  }
-
-  if (innconf->linecountfuzz && HDR_FOUND(HDR__LINES)) {
-    p = HDR(HDR__LINES);
-    i = data->Lines;
-    if ((delta = i - atoi(p)) != 0 && abs(delta) > innconf->linecountfuzz) {
-      sprintf(buff, "%d Linecount %s != %d +- %ld", NNTP_REJECTIT_VAL,
-       MaxLength(p, p), i, innconf->linecountfuzz);
-      TMRstop(TMR_ARTCLEAN);
-      return false;
-    }
-  }
-
-  /* Is article too old? */
-  /* assumes Date header is required header */
-  p = HDR(HDR__DATE);
-  if ((data->Posted = parsedate(p, &Now)) == -1) {
-    sprintf(buff, "%d Bad \"Date\" header -- \"%s\"", NNTP_REJECTIT_VAL,
-      MaxLength(p, p));
-    TMRstop(TMR_ARTCLEAN);
-    return false;
-  }
-  if (innconf->artcutoff) {
-      long cutoff = innconf->artcutoff * 24 * 60 * 60;
-
-      if (data->Posted < Now.time - cutoff) {
-          sprintf(buff, "%d Too old -- \"%s\"", NNTP_REJECTIT_VAL,
-                  MaxLength(p, p));
-          TMRstop(TMR_ARTCLEAN);
-          return false;
-      }
-  }
-  if (data->Posted > Now.time + DATE_FUZZ) {
-    sprintf(buff, "%d Article posted in the future -- \"%s\"",
-      NNTP_REJECTIT_VAL, MaxLength(p, p));
-    TMRstop(TMR_ARTCLEAN);
-    return false;
-  }
-  if (HDR_FOUND(HDR__EXPIRES)) {
-    p = HDR(HDR__EXPIRES);
-    data->Expires = parsedate(p, &Now);
-  }
-
-  /* Colon or whitespace in the Newsgroups header? */
-  /* assumes Newsgroups header is required header */
-  if ((data->Groupcount =
-    NGsplit(HDR(HDR__NEWSGROUPS), HDR_LEN(HDR__NEWSGROUPS),
-    &data->Newsgroups)) == 0) {
-    TMRstop(TMR_ARTCLEAN);
-    sprintf(buff, "%d Unwanted character in \"Newsgroups\" header",
-      NNTP_REJECTIT_VAL);
-    return false;
-  }
-
-  /* Fill in other Data fields. */
-  if (HDR_FOUND(HDR__SENDER))
-    data->Poster = HDR(HDR__SENDER);
-  else
-    data->Poster = HDR(HDR__FROM);
-  if (HDR_FOUND(HDR__REPLY_TO))
-    data->Replyto = HDR(HDR__REPLY_TO);
-  else
-    data->Replyto = HDR(HDR__FROM);
-
-  TMRstop(TMR_ARTCLEAN);
-  return true;
-}
-
-/*
-**  We are going to reject an article, record the reason and
-**  and the article.
-*/
-static void
-ARTreject(Reject_type code, CHANNEL *cp, struct buffer *article UNUSED)
-{
-  /* Remember why the article was rejected (for the status file) */
-
-  switch (code) {
-    case REJECT_DUPLICATE:
-      cp->Duplicate++;
-      cp->DuplicateSize += cp->Next - cp->Start;
-      break;
-    case REJECT_SITE:
-      cp->Unwanted_s++;
-      break;
-    case REJECT_FILTER:
-      cp->Unwanted_f++;
-      break;
-    case REJECT_DISTRIB:
-      cp->Unwanted_d++;
-      break;
-    case REJECT_GROUP:
-      cp->Unwanted_g++;
-      break;
-    case REJECT_UNAPP:
-      cp->Unwanted_u++;
-      break;
-    case REJECT_OTHER:
-      cp->Unwanted_o++;
-      break;
-    default:
-      /* should never be here */
-      syslog(L_NOTICE, "%s unknown reject type received by ARTreject()",
-            LogName);
-      break;
-  }
-      /* error */
-}
-
-/*
-**  Verify if a cancel message is valid.  If the user posting the cancel
-**  matches the user who posted the article, return the list of filenames
-**  otherwise return NULL.
-*/
-static bool
-ARTcancelverify(const ARTDATA *data, const char *MessageID, TOKEN *token)
-{
-  const char   *p;
-  char         *q, *q1;
-  const char   *local;
-  char         buff[SMBUF];
-  ARTHANDLE    *art;
-  bool         r;
-
-  if (!HISlookup(History, MessageID, NULL, NULL, NULL, token))
-    return false;
-  if ((art = SMretrieve(*token, RETR_HEAD)) == NULL)
-    return false;
-  local = wire_findheader(art->data, art->len, "Sender");
-  if (local == NULL) {
-    local = wire_findheader(art->data, art->len, "From");
-    if (local == NULL) {
-      SMfreearticle(art);
-      return false;
-    }
-  }
-  for (p = local; p < art->data + art->len; p++) {
-    if (*p == '\r' || *p == '\n')
-      break;
-  }
-  if (p == art->data + art->len) {
-    SMfreearticle(art);
-    return false;
-  }
-  q = xmalloc(p - local + 1);
-  memcpy(q, local, p - local);
-  SMfreearticle(art);
-  q[p - local] = '\0';
-  HeaderCleanFrom(q);
-
-  /* Compare canonical forms. */
-  q1 = xstrdup(data->Poster);
-  HeaderCleanFrom(q1);
-  if (strcmp(q, q1) != 0) {
-    r = false;
-    sprintf(buff, "\"%.50s\" wants to cancel %s by \"%.50s\"",
-      q1, MaxLength(MessageID, MessageID), q);
-    ARTlog(data, ART_REJECT, buff);
-  }
-  else {
-    r = true;
-  }
-  free(q1);
-  free(q);
-  return r;
-}
-
-/*
-**  Process a cancel message.
-*/
-void
-ARTcancel(const ARTDATA *data, const char *MessageID, const bool Trusted)
-{
-  char buff[SMBUF+16];
-  TOKEN        token;
-  bool r;
-
-  TMRstart(TMR_ARTCNCL);
-  if (!DoCancels && !Trusted) {
-    TMRstop(TMR_ARTCNCL);
-    return;
-  }
-
-  if (!ARTidok(MessageID)) {
-    syslog(L_NOTICE, "%s bad cancel Message-ID %s", data->Feedsite,
-      MaxLength(MessageID, MessageID));
-    TMRstop(TMR_ARTCNCL);
-    return;
-  }
-
-  if (!HIScheck(History, MessageID)) {
-    /* Article hasn't arrived here, so write a fake entry using
-     * most of the information from the cancel message. */
-    if (innconf->verifycancels && !Trusted) {
-      TMRstop(TMR_ARTCNCL);
-      return;
-    }
-    InndHisRemember(MessageID);
-    snprintf(buff, sizeof(buff), "Cancelling %s",
-             MaxLength(MessageID, MessageID));
-    ARTlog(data, ART_CANC, buff);
-    TMRstop(TMR_ARTCNCL);
-    return;
-  }
-  if (Trusted || !innconf->verifycancels)
-      r = HISlookup(History, MessageID, NULL, NULL, NULL, &token);
-  else
-      r = ARTcancelverify(data, MessageID, &token);
-  if (r == false) {
-    TMRstop(TMR_ARTCNCL);
-    return;
-  }
-
-  /* Get stored message and zap them. */
-  if (!SMcancel(token) && SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT)
-    syslog(L_ERROR, "%s cant cancel %s (SMerrno %d)", LogName,
-       TokenToText(token), SMerrno);
-  if (innconf->immediatecancel && !SMflushcacheddata(SM_CANCELEDART))
-    syslog(L_ERROR, "%s cant cancel cached %s", LogName, TokenToText(token));
-  snprintf(buff, sizeof(buff), "Cancelling %s",
-           MaxLength(MessageID, MessageID));
-  ARTlog(data, ART_CANC, buff);
-  TMRstop(TMR_ARTCNCL);
-}
-
-/*
-**  Process a control message.  Cancels are handled here, but any others
-**  are passed out to an external program in a specific directory that
-**  has the same name as the first word of the control message.
-*/
-static void
-ARTcontrol(ARTDATA *data, char *Control, CHANNEL *cp UNUSED)
-{
-  char *p, c;
-
-  /* See if it's a cancel message. */
-  c = *Control;
-  if (c == 'c' && strncmp(Control, "cancel", 6) == 0) {
-    for (p = &Control[6]; ISWHITE(*p); p++)
-      continue;
-    if (*p && ARTidok(p))
-      ARTcancel(data, p, false);
-    return;
-  }
-}
-
-/*
-**  Parse a Distribution line, splitting it up into NULL-terminated array of
-**  strings.
-*/
-static void
-ARTparsedist(const char *p, int size, LISTBUFFER *list)
-{
-  int  i;
-  char *q, **dp;
-
-  /* setup buffer */ 
-  SetupListBuffer(size, list);
-
-  /* loop over text and copy */
-  for (i = 0, q = list->Data, dp = list->List ; *p ; p++, *q++ = '\0') { 
-    /* skip leading separators. */
-    for (; *p && ((*p == ',') || ISWHITE(*p)) ; p++)
-      continue;
-    if (*p == '\0')
-      break;
-
-    if (list->ListLength <= i) {
-      list->ListLength += DEFAULTNGBOXSIZE;
-      list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-      dp = &list->List[i];
-    }
-    /* mark the start of the host, move to the end of it while copying */  
-    for (*dp++ = q, i++ ; *p && (*p != ',') && !ISWHITE(*p) ;)
-      *q++ = *p++;
-    if (*p == '\0')
-      break;
-  }
-  *q = '\0';
-  if (i == list->ListLength) {
-    list->ListLength += DEFAULTNGBOXSIZE;
-    list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-    dp = &list->List[i];
-  }
-  *dp = NULL;
-  return;
-}
-
-/*
-**  A somewhat similar routine, except that this handles negated entries
-**  in the list and is used to check the distribution sub-field.
-*/
-static bool
-DISTwanted(char **list, char *p)
-{
-  char *q;
-  char c;
-  bool sawbang;
-
-  for (sawbang = false, c = *p; (q = *list) != NULL; list++) {
-    if (*q == '!') {
-      sawbang = true;
-      if (c == *++q && strcmp(p, q) == 0)
-       return false;
-    } else if (c == *q && strcmp(p, q) == 0)
-      return true;
-  }
-
-  /* If we saw any !foo's and didn't match, then assume they are all negated
-     distributions and return true, else return false. */
-  return sawbang;
-}
-
-/*
-**  See if any of the distributions in the article are wanted by the site.
-*/
-static bool
-DISTwantany(char **site, char **article)
-{
-  for ( ; *article; article++)
-    if (DISTwanted(site, *article))
-      return true;
-  return false;
-}
-
-/*
-**  Send the current article to all sites that would get it if the
-**  group were created.
-*/
-static void
-ARTsendthegroup(char *name)
-{
-  SITE         *sp;
-  int          i;
-  NEWSGROUP    *ngp;
-
-  for (ngp = NGfind(ARTctl), sp = Sites, i = nSites; --i >= 0; sp++) {
-    if (sp->Name != NULL && SITEwantsgroup(sp, name)) {
-      SITEmark(sp, ngp);
-    }
-  }
-}
-
-/*
-**  Check if site doesn't want this group even if it's crossposted
-**  to a wanted group.
-*/
-static void
-ARTpoisongroup(char *name)
-{
-  SITE *sp;
-  int  i;
-
-  for (sp = Sites, i = nSites; --i >= 0; sp++) {
-    if (sp->Name != NULL && (sp->PoisonEntry || ME.PoisonEntry) &&
-      SITEpoisongroup(sp, name))
-      sp->Poison = true;
-  }
-}
-
-/*
-** Assign article numbers to the article and create the Xref line.
-** If we end up not being able to write the article, we'll get "holes"
-** in the directory and active file.
-*/
-static void
-ARTassignnumbers(ARTDATA *data)
-{
-  char         *p, *q;
-  int          i, len, linelen, buflen;
-  NEWSGROUP    *ngp;
-
-  if (data->XrefBufLength == 0) {
-    data->XrefBufLength = MAXHEADERSIZE * 2 + 1;
-    data->Xref = xmalloc(data->XrefBufLength);
-    strncpy(data->Xref, Path.data, Path.used - 1);
-  }
-  len = Path.used - 1;
-  p = q = data->Xref + len;
-  for (linelen = i = 0; (ngp = GroupPointers[i]) != NULL; i++) {
-    /* If already went to this group (i.e., multiple groups are aliased
-     * into it), then skip it. */
-    if (ngp->PostCount > 0)
-      continue;
-
-    /* Bump the number. */
-    ngp->PostCount++;
-    ngp->Last++;
-    if (!FormatLong(ngp->LastString, (long)ngp->Last, ngp->Lastwidth)) {
-      syslog(L_ERROR, "%s cant update_active %s", LogName, ngp->Name);
-      continue;
-    }
-    ngp->Filenum = ngp->Last;
-    /*  len  ' ' "news_groupname"  ':' "#" "\r\n" */
-    if (len + 1 + ngp->NameLength + 1 + 10 + 2 > data->XrefBufLength) {
-      data->XrefBufLength += MAXHEADERSIZE;
-      data->Xref = xrealloc(data->Xref, data->XrefBufLength);
-      p = data->Xref + len;
-    }
-    if (linelen + 1 + ngp->NameLength + 1 + 10 > MAXHEADERSIZE) {
-      /* line exceeded */
-      sprintf(p, "\r\n %s:%lu", ngp->Name, ngp->Filenum);
-      buflen = strlen(p);
-      linelen = buflen - 2;
-    } else {
-      sprintf(p, " %s:%lu", ngp->Name, ngp->Filenum);
-      buflen = strlen(p);
-      linelen += buflen;
-    }
-    len += buflen;
-    p += buflen;
-  }
-  /* p[0] is replaced with '\r' to be wireformatted when stored.  p[1] needs to
-     be '\n' */
-  p[0] = '\r';
-  p[1] = '\n';
-  /* data->XrefLength includes trailing "\r\n" */
-  data->XrefLength = len + 2;
-  data->Replic = q + 1;
-  data->ReplicLength = len - (q + 1 - data->Xref);
-}
-
-/*
-**  Parse the data from the xref header and assign the numbers.
-**  This involves replacing the GroupPointers entries.
-*/
-static bool
-ARTxrefslave(ARTDATA *data)
-{
-  char         *p, *q, *name, *next, c = 0;
-  NEWSGROUP    *ngp;
-  int          i;
-  bool         nogroup = true;
-  HDRCONTENT   *hc = data->HdrContent;
-
-  if (!HDR_FOUND(HDR__XREF))
-    return false;
-  /* skip server name */
-  if ((p = strpbrk(HDR(HDR__XREF), " \t\r\n")) == NULL)
-    return false;
-  /* in case Xref is folded */
-  while (*++p == ' ' || *p == '\t' || *p == '\r' || *p == '\n');
-  if (*p == '\0')
-    return false;
-  data->Replic = p;
-  data->ReplicLength = HDR_LEN(HDR__XREF) - (p - HDR(HDR__XREF));
-  for (i = 0; (*p != '\0') && (p < HDR(HDR__XREF) + HDR_LEN(HDR__XREF)) ; p = next) {
-    /* Mark end of this entry and where next one starts. */
-    name = p;
-    if ((q = next = strpbrk(p, " \t\r\n")) != NULL) {
-      c = *q;
-      *q = '\0';
-      while (*++next == ' ' || *next == '\t' || *next == '\r' || *next == '\n');
-    } else {
-      q = NULL;
-      next = "";
-    }
-
-    /* Split into news.group:# */
-    if ((p = strchr(p, ':')) == NULL) {
-      syslog(L_ERROR, "%s bad_format %s", LogName, name);
-      if (q != NULL)
-       *q = c;
-      continue;
-    }
-    *p = '\0';
-    if ((ngp = NGfind(name)) == NULL) {
-      syslog(L_ERROR, "%s bad_newsgroup %s", LogName, name);
-      *p = ':';
-      if (q != NULL)
-       *q = c;
-      continue;
-    }
-    *p = ':';
-    ngp->Filenum = atol(p + 1);
-    if (q != NULL)
-      *q = c;
-
-    /* Update active file if we got a new high-water mark. */
-    if (ngp->Last < ngp->Filenum) {
-      ngp->Last = ngp->Filenum;
-      if (!FormatLong(ngp->LastString, (long)ngp->Last, ngp->Lastwidth)) {
-       syslog(L_ERROR, "%s cant update_active %s", LogName, ngp->Name);
-       continue;
-      }
-    }
-    /* Mark that this group gets the article. */
-    ngp->PostCount++;
-    GroupPointers[i++] = ngp;
-    nogroup = false;
-  }
-  GroupPointers[i] = NULL;
-  if (nogroup)
-    return false;
-  return true;
-}
-
-/*
-**  Return true if a list of strings has a specific one.  This is a
-**  generic routine, but is used for seeing if a host is in the Path line.
-*/
-static bool
-ListHas(const char **list, const char *p)
-{
-  const char   *q;
-  char         c;
-
-  for (c = *p; (q = *list) != NULL; list++)
-    if (strcasecmp(p, q) == 0)
-      return true;
-  return false;
-}
-
-/*
-**  Even though we have already calculated the Message-ID MD5sum,
-**  we have to do it again since unfortunately HashMessageID()
-**  lowercases the Message-ID first.  We also need to remain
-**  compatible with Diablo's hashfeed.
-*/
-
-static unsigned int
-HashFeedMD5(char *MessageID, unsigned int offset)
-{
-  static char LastMessageID[128];
-  static char *LastMessageIDPtr;
-  static struct md5_context context;
-  unsigned int ret;
-
-  if (offset > 12)
-    return 0;
-
-  /* Some light caching. */
-  if (MessageID != LastMessageIDPtr ||
-    strcmp(MessageID, LastMessageID) != 0) {
-    md5_init(&context);
-    md5_update(&context, (unsigned char *)MessageID, strlen(MessageID));
-    md5_final(&context);
-    LastMessageIDPtr = MessageID;
-    strncpy(LastMessageID, MessageID, sizeof(LastMessageID) - 1);
-    LastMessageID[sizeof(LastMessageID) - 1] = 0;
-  }
-
-  memcpy(&ret, &context.digest[12 - offset], 4);
-
-  return ntohl(ret);
-}
-
-/*
-** Old-style Diablo (< 5.1) quickhash.
-**
-*/
-static unsigned int
-HashFeedQH(char *MessageID, unsigned int *tmp)
-{
-  unsigned char *p;
-  int n;
-
-  if (*tmp != (unsigned int)-1)
-    return *tmp;
-
-  p = (unsigned char *)MessageID;
-  n = 0;
-  while (*p)
-    n += *p++;
-  *tmp = (unsigned int)n;
-
-  return *tmp;
-}
-
-/*
-**  Return true if an element of the HASHFEEDLIST matches
-**  the hash of the Message-ID.
-*/
-static bool
-HashFeedMatch(HASHFEEDLIST *hf, char *MessageID)
-{
-  unsigned int qh = (unsigned int)-1;
-  unsigned int h;
-
-  while (hf) {
-    if (hf->type == HASHFEED_MD5)
-      h = HashFeedMD5(MessageID, hf->offset);
-    else if (hf->type == HASHFEED_QH)
-      h = HashFeedQH(MessageID, &qh);
-    else
-      continue;
-    if ((h % hf->mod + 1) >= hf->begin &&
-        (h % hf->mod + 1) <= hf->end)
-         return true;
-    hf = hf->next;
-  }
-
-  return false;
-}
-
-/*
-**  Propagate an article to the sites have "expressed an interest."
-*/
-static void
-ARTpropagate(ARTDATA *data, const char **hops, int hopcount, char **list,
-  bool ControlStore, bool OverviewCreated)
-{
-  HDRCONTENT   *hc = data->HdrContent;
-  SITE         *sp, *funnel;
-  int          i, j, Groupcount, Followcount, Crosscount;
-  char         *p, *q;
-  struct buffer        *bp;
-  bool         sendit;
-
-  /* Work out which sites should really get it. */
-  Groupcount = data->Groupcount;
-  Followcount = data->Followcount;
-  Crosscount = Groupcount + Followcount * Followcount;
-  for (sp = Sites, i = nSites; --i >= 0; sp++) {
-    if ((sp->IgnoreControl && ControlStore) ||
-      (sp->NeedOverviewCreation && !OverviewCreated))
-      sp->Sendit = false;
-    if (sp->Seenit || !sp->Sendit)
-      continue;
-    sp->Sendit = false;
-       
-    if (sp->Originator) {
-      if (!HDR_FOUND(HDR__XTRACE)) {
-       if (!sp->FeedwithoutOriginator)
-         continue;
-      } else {
-       if ((p = strchr(HDR(HDR__XTRACE), ' ')) != NULL) {
-         *p = '\0';
-         for (j = 0, sendit = false; (q = sp->Originator[j]) != NULL; j++) {
-           if (*q == '@') {
-             if (uwildmat(HDR(HDR__XTRACE), &q[1])) {
-               *p = ' ';
-               sendit = false;
-               break;
-             }
-           } else {
-             if (uwildmat(HDR(HDR__XTRACE), q))
-               sendit = true;
-           }
-         }
-         *p = ' ';
-         if (!sendit)
-           continue;
-       } else
-         continue;
-      }
-    }
-
-    if (sp->Master != NOSITE && Sites[sp->Master].Seenit)
-      continue;
-
-    if (sp->MaxSize && data->BytesValue > sp->MaxSize)
-      /* Too big for the site. */
-      continue;
-
-    if (sp->MinSize && data->BytesValue < sp->MinSize)
-      /* Too small for the site. */
-      continue;
-
-    if ((sp->Hops && hopcount > sp->Hops)
-      || (!sp->IgnorePath && ListHas(hops, sp->Name))
-      || (sp->Groupcount && Groupcount > sp->Groupcount)
-      || (sp->Followcount && Followcount > sp->Followcount)
-      || (sp->Crosscount && Crosscount > sp->Crosscount))
-      /* Site already saw the article; path too long; or too much
-       * cross-posting. */
-      continue;
-
-    if (sp->HashFeedList &&
-      !HashFeedMatch(sp->HashFeedList, HDR(HDR__MESSAGE_ID)))
-      /* hashfeed doesn't match */
-      continue;
-
-    if (list && *list != NULL && sp->Distributions &&
-      !DISTwantany(sp->Distributions, list))
-      /* Not in the site's desired list of distributions. */
-      continue;
-    if (sp->DistRequired && (list == NULL || *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/innd/cc.c b/innd/cc.c
deleted file mode 100644 (file)
index be17183..0000000
--- a/innd/cc.c
+++ /dev/null
@@ -1,2107 +0,0 @@
-/*  $Id: cc.c 7748 2008-04-06 13:49:56Z iulius $
-**
-**  Routines for the control channel.
-**
-**  Create a Unix-domain datagram socket that processes on the local server
-**  send messages to.  The control channel is used only by ctlinnd to tell
-**  the server to perform special functions.  We use datagrams so that we
-**  don't need to do an accept() and tie up another descriptor.  recvfrom
-**  seems to be broken on several systems, so the client passes in the
-**  socket name.
-**
-**  This module completely rips away all pretense of software layering.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/qio.h"
-#include "innd.h"
-#include "inndcomm.h"
-#include "innperl.h"
-
-/*
-**  An entry in the dispatch table.  The name, and implementing function,
-**  of every command we support.
-*/
-typedef struct _CCDISPATCH {
-    char Name;
-    int        argc;
-    const char * (*Function)(char *av[]);
-} CCDISPATCH;
-
-
-static const char *    CCallow(char *av[]);
-static const char *    CCbegin(char *av[]);
-static const char *    CCchgroup(char *av[]);
-static const char *    CCdrop(char *av[]);
-static const char *    CCfeedinfo(char *av[]);
-static const char *    CCflush(char *av[]);
-static const char *    CCflushlogs(char *unused[]);
-static const char *    CCgo(char *av[]);
-static const char *    CChangup(char *av[]);
-static const char *    CCreserve(char *av[]);
-static const char *    CClogmode(char *unused[]);
-static const char *    CCmode(char *unused[]);
-static const char *    CCname(char *av[]);
-static const char *    CCnewgroup(char *av[]);
-static const char *    CCparam(char *av[]);
-static const char *    CCpause(char *av[]);
-static const char *    CCreaders(char *av[]);
-static const char *    CCreject(char *av[]);
-static const char *    CCreload(char *av[]);
-static const char *    CCrenumber(char *av[]);
-static const char *    CCrmgroup(char *av[]);
-static const char *    CCsend(char *av[]);
-static const char *    CCshutdown(char *av[]);
-static const char *    CCsignal(char *av[]);
-static const char *    CCstathist(char *av[]);
-static const char *    CCstatus(char *av[]);
-static const char *    CCthrottle(char *av[]);
-static const char *    CCtimer(char *av[]);
-static const char *    CCtrace(char *av[]);
-static const char *    CCxabort(char *av[]);
-static const char *    CCxexec(char *av[]);
-static const char *    CCfilter(char *av[]);
-static const char *    CCperl(char *av[]);
-static const char *    CCpython(char *av[]);
-static const char *    CClowmark(char *av[]);
-
-
-static char            *CCpath = NULL;
-static char            **CCargv;
-static char            CCnosite[] = "1 No such site";
-static char            CCwrongtype[] = "1 Wrong site type";
-static char            CCnogroup[] = "1 No such group";
-static char            CCnochannel[] = "1 No such channel";
-static char            CCnoreason[] = "1 Empty reason";
-static char            CCbigreason[] = "1 Reason too long";
-static char            CCnotrunning[] = "1 Must be running";
-static struct buffer   CCreply;
-static CHANNEL         *CCchan;
-static int             CCwriter;
-static CCDISPATCH      CCcommands[] = {
-    {  SC_ADDHIST,     5, CCaddhist    },
-    {  SC_ALLOW,       1, CCallow      },
-    {  SC_BEGIN,       1, CCbegin      },
-    {  SC_CANCEL,      1, CCcancel     },
-    {  SC_CHANGEGROUP, 2, CCchgroup    },
-    {  SC_CHECKFILE,   0, CCcheckfile  },
-    {  SC_DROP,        1, CCdrop       },
-    {  SC_FEEDINFO,    1, CCfeedinfo   },
-    {  SC_FILTER,      1, CCfilter     },
-    {  SC_PERL,        1, CCperl       },
-    {  SC_PYTHON,      1, CCpython     },
-    {  SC_FLUSH,       1, CCflush      },
-    {  SC_FLUSHLOGS,   0, CCflushlogs  },
-    {  SC_GO,          1, CCgo         },
-    {  SC_HANGUP,      1, CChangup     },
-    {  SC_LOGMODE,     0, CClogmode    },
-    {  SC_MODE,        0, CCmode       },
-    {  SC_NAME,        1, CCname       },
-    {  SC_NEWGROUP,    3, CCnewgroup   },
-    {  SC_PARAM,       2, CCparam      },
-    {  SC_PAUSE,       1, CCpause      },
-    {  SC_READERS,     2, CCreaders    },
-    {  SC_REJECT,      1, CCreject     },
-    {  SC_RENUMBER,    1, CCrenumber   },
-    {  SC_RELOAD,      2, CCreload     },
-    {  SC_RESERVE,     1, CCreserve    },
-    {  SC_RMGROUP,     1, CCrmgroup    },
-    {  SC_SEND,        2, CCsend       },
-    {  SC_SHUTDOWN,    1, CCshutdown   },
-    {  SC_SIGNAL,      2, CCsignal     },
-    {  SC_STATHIST,    1, CCstathist   },
-    {  SC_STATUS,      1, CCstatus     },
-    {  SC_THROTTLE,    1, CCthrottle   },
-    {   SC_TIMER,       1, CCtimer      },
-    {  SC_TRACE,       2, CCtrace      },
-    {  SC_XABORT,      1, CCxabort     },
-    {  SC_LOWMARK,     1, CClowmark    },
-    {  SC_XEXEC,       1, CCxexec      }
-};
-
-static RETSIGTYPE CCresetup(int unused);
-\f
-
-void
-CCcopyargv(char *av[])
-{
-    char       **v;
-    int                i;
-
-    /* Get the vector size. */
-    for (i = 0; av[i]; i++)
-       continue;
-
-    /* Get the vector, copy each element. */
-    for (v = CCargv = xmalloc((i + 1) * sizeof(char *)); *av; av++) {
-       /* not to renumber */
-       if (strncmp(*av, "-r", 2) == 0)
-           continue;
-       *v++ = xstrdup(*av);
-    }
-    *v = NULL;
-}
-
-
-/*
-**  Return a string representing our operating mode.
-*/
-static const char *
-CCcurrmode(void)
-{
-    static char                buff[32];
-
-    /* Server's mode. */
-    switch (Mode) {
-    default:
-       snprintf(buff, sizeof(buff), "Unknown %d", Mode);
-       return buff;
-    case OMrunning:
-       return "running";
-    case OMpaused:
-       return "paused";
-    case OMthrottled:
-       return "throttled";
-    }
-}
-
-
-/*
-**  Add <> around Message-ID if needed.
-*/
-static const char *
-CCgetid(char *p, const char **store)
-{
-    static char        NULLMESGID[] = "1 Empty Message-ID";
-    static struct buffer Save = { 0, 0, 0, NULL };
-    int i;
-
-    if (*p == '\0')
-       return NULLMESGID;
-    if (*p == '<') {
-       if (p[1] == '\0' || p[1] == '>')
-           return NULLMESGID;
-       *store = p;
-       return NULL;
-    }
-
-    /* Make sure the Message-ID buffer has room. */
-    i = 1 + strlen(p) + 1 + 1;
-    buffer_resize(&Save, i);
-    *store = Save.data;
-    snprintf(Save.data, Save.size, "<%s>", p);
-    return NULL;
-}
-
-
-/*
-**  Abort and dump core.
-*/
-static const char *
-CCxabort(char *av[])
-{
-    syslog(L_FATAL, "%s abort %s", LogName, av[0]);
-    abort();
-    syslog(L_FATAL, "%s cant abort %m", LogName);
-    CleanupAndExit(1, av[0]);
-    /* NOTREACHED */
-}
-
-
-/*
-**  Do the work needed to add a history entry.
-*/
-const char *
-CCaddhist(char *av[])
-{
-    static char                DIGITS[] = "0123456789";
-    ARTDATA            Data;
-    const char *       p, *msgid;
-    bool               ok;
-    TOKEN              token;
-
-    /* You must pass a <message-id> ID, the history API will hash it as it
-     * wants */
-    if ((p = CCgetid(av[0], &msgid)) != NULL)
-       return p;
-
-    /* If paused, don't try to use the history database since expire may be
-       running */
-    if (Mode == OMpaused)
-       return "1 Server paused";
-
-    /* If throttled by admin, briefly open the history database. */
-    if (Mode != OMrunning) {
-       if (ThrottledbyIOError)
-           return "1 Server throttled";
-       InndHisOpen();
-    }
-
-    if (HIScheck(History, msgid)) {
-       if (Mode != OMrunning) InndHisClose();
-       return "1 Duplicate";
-    }
-    if (Mode != OMrunning) InndHisClose();
-    if (strspn(av[1], DIGITS) != strlen(av[1]))
-       return "1 Bad arrival date";
-    Data.Arrived = atol(av[1]);
-    if (strspn(av[2], DIGITS) != strlen(av[2]))
-       return "1 Bad expiration date";
-    Data.Expires = atol(av[2]);
-    if (strspn(av[3], DIGITS) != strlen(av[3]))
-       return "1 Bad posted date";
-    Data.Posted = atol(av[3]);
-
-    token = TextToToken(av[4]);
-    if (Mode == OMrunning)
-       ok = InndHisWrite(msgid, Data.Arrived, Data.Posted,
-                         Data.Expires, &token);
-    else {
-       /* Possible race condition, but documented in ctlinnd manpage. */
-       InndHisOpen();
-       ok = InndHisWrite(msgid, Data.Arrived, Data.Posted,
-                         Data.Expires, &token);
-       InndHisClose();
-    }
-    return ok ? NULL : "1 Write failed";
-}
-
-
-/*
-**  Do the work to allow foreign connectiosn.
-*/
-static const char *
-CCallow(char *av[])
-{
-    char       *p;
-
-    if (RejectReason == NULL)
-       return "1 Already allowed";
-    p = av[0];
-    if (*p && strcmp(p, RejectReason) != 0)
-       return "1 Wrong reason";
-    free(RejectReason);
-    RejectReason = NULL;
-    return NULL;
-}
-
-
-/*
-**  Do the work needed to start feeding a (new) site.
-*/
-static const char *
-CCbegin(char *av[])
-{
-    SITE       *sp;
-    int                i;
-    int                length;
-    char       *p;
-    const char *p1;
-    char       **strings;
-    NEWSGROUP  *ngp;
-    const char *error;
-    char       *subbed;
-    char       *poison;
-
-    /* If site already exists, drop it. */
-    if (SITEfind(av[0]) != NULL && (p1 = CCdrop(av)) != NULL)
-       return p1;
-
-    /* Find the named site. */
-    length = strlen(av[0]);
-    for (strings = SITEreadfile(true), i = 0; (p = strings[i]) != NULL; i++)
-       if ((p[length] == NF_FIELD_SEP || p[length] == NF_SUBFIELD_SEP)
-        && strncasecmp(p, av[0], length) == 0) {
-           p = xstrdup(p);
-           break;
-       }
-    if (p == NULL)
-       return CCnosite;
-
-    if (p[0] == 'M' && p[1] == 'E' && p[2] == NF_FIELD_SEP)
-       sp = &ME;
-    else {
-       /* Get space for the new site entry, and space for it in all
-        * the groups. */
-       for (i = nSites, sp = Sites; --i >= 0; sp++)
-           if (sp->Name == NULL)
-               break;
-       if (i < 0) {
-           nSites++;
-            Sites = xrealloc(Sites, nSites * sizeof(SITE));
-           sp = &Sites[nSites - 1];
-           sp->Next = sp->Prev = NOSITE;
-           for (i = nGroups, ngp = Groups; --i >= 0; ngp++) {
-                ngp->Sites = xrealloc(ngp->Sites, nSites * sizeof(int));
-                ngp->Poison = xrealloc(ngp->Poison, nSites * sizeof(int));
-           }
-       }
-    }
-
-    /* Parse. */
-    subbed = xmalloc(nGroups);
-    poison = xmalloc(nGroups);
-    error = SITEparseone(p, sp, subbed, poison);
-    free(subbed);
-    free(poison);
-    if (error != NULL) {
-       free((void *)p);
-       syslog(L_ERROR, "%s bad_newsfeeds %s", av[0], error);
-       return "1 Parse error";
-    }
-
-    if (sp != &ME && (!SITEsetup(sp) || !SITEfunnelpatch()))
-       return "1 Startup error";
-    SITEforward(sp, "begin");
-    return NULL;
-}
-
-
-/*
-**  Common code to change a group's flags.
-*/
-static const char *
-CCdochange(NEWSGROUP *ngp, char *Rest)
-{
-    int                        length;
-    char               *p;
-
-    if (ngp->Rest[0] == Rest[0]) {
-       length = strlen(Rest);
-       if (ngp->Rest[length] == '\n' && strncmp(ngp->Rest, Rest, length) == 0)
-           return "0 Group status unchanged";
-    }
-    if (Mode != OMrunning)
-       return CCnotrunning;
-
-    p = xstrdup(ngp->Name);
-    if (!ICDchangegroup(ngp, Rest)) {
-       syslog(L_NOTICE, "%s cant change_group %s to %s", LogName, p, Rest);
-       free(p);
-       return "1 Change failed (probably can't write active?)";
-    }
-    syslog(L_NOTICE, "%s change_group %s to %s", LogName, p, Rest);
-    free(p);
-    return NULL;
-}
-
-
-/*
-**  Change the mode of a newsgroup.
-*/
-static const char *
-CCchgroup(char *av[])
-{
-    NEWSGROUP  *ngp;
-    char       *Rest;
-
-    if ((ngp = NGfind(av[0])) == NULL)
-       return CCnogroup;
-    Rest = av[1];
-    if (Rest[0] != NF_FLAG_ALIAS) {
-       Rest[1] = '\0';
-       if (CTYPE(isupper, Rest[0]))
-           Rest[0] = tolower(Rest[0]);
-    }
-    return CCdochange(ngp, Rest);
-}
-
-
-/*
-**  Cancel a message.
-*/
-const char *
-CCcancel(char *av[])
-{
-    ARTDATA    Data;
-    const char *       p, *msgid;
-
-    Data.Posted = Data.Arrived = Now.time;
-    Data.Expires = 0;
-    Data.Feedsite = "?";
-    if ((p = CCgetid(av[0], &msgid)) != NULL)
-       return p;
-
-    Data.HdrContent[HDR__MESSAGE_ID].Value = (char *)msgid;
-    Data.HdrContent[HDR__MESSAGE_ID].Length = strlen(msgid);
-    if (Mode == OMrunning)
-       ARTcancel(&Data, msgid, true);
-    else {
-       /* If paused, don't try to use the history database since expire may be
-          running */
-       if (Mode == OMpaused)
-           return "1 Server paused";
-       if (ThrottledbyIOError)
-           return "1 Server throttled";
-       /* Possible race condition, but documented in ctlinnd manpage. */
-       InndHisOpen();
-       ARTcancel(&Data, msgid, true);
-       InndHisClose();
-    }
-    if (innconf->logcancelcomm)
-       syslog(L_NOTICE, "%s cancelled %s", LogName, msgid);
-    return NULL;
-}
-
-
-/*
-**  Syntax-check the newsfeeds file.
-*/
-const char *
-CCcheckfile(char *unused[])
-{
-  char         **strings;
-  char         *p;
-  int          i;
-  int          errors;
-  const char * error;
-  SITE         fake;
-  bool         needheaders, needoverview, needpath, needstoredgroup;
-  bool         needreplicdata;
-
-  unused = unused;             /* ARGSUSED */
-  /* Parse all site entries. */
-  strings = SITEreadfile(false);
-  fake.Buffer.size = 0;
-  fake.Buffer.data = NULL;
-  /* save global variables not to be changed */
-  needheaders = NeedHeaders;
-  needoverview = NeedOverview;
-  needpath = NeedPath;
-  needstoredgroup = NeedStoredGroup;
-  needreplicdata = NeedReplicdata;
-  for (errors = 0, i = 0; (p = strings[i]) != NULL; i++) {
-    if ((error = SITEparseone(p, &fake, (char *)NULL, (char *)NULL)) != NULL) {
-      syslog(L_ERROR, "%s bad_newsfeeds %s", MaxLength(p, p), error);
-      errors++;
-    }
-    SITEfree(&fake);
-  }
-  free(strings);
-  /* restore global variables not to be changed */
-  NeedHeaders = needheaders;
-  NeedOverview = needoverview;
-  NeedPath = needpath;
-  NeedStoredGroup = needstoredgroup;
-  NeedReplicdata = needreplicdata;
-
-  if (errors == 0)
-    return NULL;
-
-  buffer_resize(&CCreply, SMBUF);
-  snprintf(CCreply.data, CCreply.size, "1 Found %d errors -- see syslog",
-           errors);
-  return CCreply.data;
-}
-
-
-/*
-**  Drop a site.
-*/
-static const char *
-CCdrop(char *av[])
-{
-    SITE       *sp;
-    NEWSGROUP  *ngp;
-    int                *ip;
-    int                idx;
-    int                i;
-    int                j;
-
-    if ((sp = SITEfind(av[0])) == NULL)
-       return CCnosite;
-
-    SITEdrop(sp);
-
-    /* Loop over all groups, and if the site is in a group, clobber it. */
-    for (idx = sp - Sites, i = nGroups, ngp = Groups; --i >= 0; ngp++) {
-       for (j = ngp->nSites, ip = ngp->Sites; --j >= 0; ip++)
-           if (*ip == idx)
-               *ip = NOSITE;
-       for (j = ngp->nPoison, ip = ngp->Poison; --j >= 0; ip++)
-           if (*ip == idx)
-               *ip = NOSITE;
-    }
-
-       return NULL;
-}
-
-/*
-**  Return info on the feeds for one, or all, sites
-*/
-static const char *
-CCfeedinfo(char *av[])
-{
-    SITE       *sp;
-    char       *p;
-    int                i;
-
-    buffer_set(&CCreply, "0 ", 2);
-    p = av[0];
-    if (*p != '\0') {
-       if ((sp = SITEfind(p)) == NULL)
-           return "1 No such site";
-
-       SITEinfo(&CCreply, sp, true);
-       while ((sp = SITEfindnext(p, sp)) != NULL)
-           SITEinfo(&CCreply, sp, true);
-    }
-    else
-       for (i = nSites, sp = Sites; --i >= 0; sp++)
-           if (sp->Name)
-               SITEinfo(&CCreply, sp, false);
-
-    buffer_append(&CCreply, "", 1);
-    return CCreply.data;
-}
-
-
-static const char *
-CCfilter(char *av[] UNUSED)
-{
-#if defined(DO_TCL)
-    char       *p;
-
-    switch (av[0][0]) {
-    default:
-       return "1 Bad flag";
-    case 'y':
-       if (TCLFilterActive)
-           return "1 tcl filter already enabled";
-       TCLfilter(true);
-       break;
-    case 'n':
-       if (!TCLFilterActive)
-           return "1 tcl filter already disabled";
-       TCLfilter(false);
-       break;
-    }
-    return NULL;
-#else /* defined(DO_TCL) */
-    return "1 TCL filtering support not compiled in";
-#endif /* defined(DO_TCL) */
-}
-
-
-static const char *
-CCperl(char *av[])
-{
-#if defined(DO_PERL)
-    switch (av[0][0]) {
-    default:
-       return "1 Bad flag";
-    case 'y':
-       if (PerlFilterActive)
-           return "1 Perl filter already enabled";
-        else if (!PerlFilter(true))
-            return "1 Perl filter not defined";
-       break;
-    case 'n':
-       if (!PerlFilterActive)
-           return "1 Perl filter already disabled";
-        PerlFilter(false);
-       break;
-    }
-    return NULL;
-#else /* defined(DO_PERL) */
-    return "1 Perl filtering support not compiled in";
-#endif /* defined(DO_PERL) */
-}
-
-
-static const char *
-CCpython(char *av[] UNUSED)
-{
-#if defined(DO_PYTHON)
-    return PYcontrol(av);
-#else /* defined(DO_PYTHON) */
-    return "1 Python filtering support not compiled in";
-#endif /* defined(DO_PYTHON) */
-}
-
-
-/*
-**  Flush all sites or one site.
-*/
-static const char *
-CCflush(char *av[])
-{
-    SITE       *sp;
-    int                i;
-    char       *p;
-
-    p = av[0];
-    if (*p == '\0') {
-       ICDwrite();
-       for (sp = Sites, i = nSites; --i >= 0; sp++)
-           SITEflush(sp, true);
-       syslog(L_NOTICE, "%s flush_all", LogName);
-    }
-    else  {
-       if ((sp = SITEfind(p)) == NULL)
-           return CCnosite;
-       syslog(L_NOTICE, "%s flush", sp->Name);
-       SITEflush(sp, true);
-    }
-    return NULL;
-}
-
-
-/*
-**  Flush the log files.
-*/
-static const char *
-CCflushlogs(char *unused[])
-{
-    unused = unused;           /* ARGSUSED */
-
-    if (Debug)
-       return "1 In debug mode";
-
-    ICDwrite();
-    syslog(L_NOTICE, "%s flushlogs %s", LogName, CCcurrmode());
-    ReopenLog(Log);
-    ReopenLog(Errlog);
-    return NULL;
-}
-
-
-/*
-**  Leave paused or throttled mode.
-*/
-static const char *
-CCgo(char *av[])
-{
-    static char        YES[] = "y";
-    char       *p;
-
-    p = av[0];
-    if (Reservation && strcmp(p, Reservation) == 0) {
-       free(Reservation);
-       Reservation = NULL;
-    }
-    if (RejectReason && strcmp(p, RejectReason) == 0) {
-       free(RejectReason);
-       RejectReason = NULL;
-    }
-
-    if (Mode == OMrunning)
-       return "1 Already running";
-    if (*p && strcmp(p, ModeReason) != 0)
-       return "1 Wrong reason";
-
-#if defined(DO_PERL)
-    PLmode(Mode, OMrunning, p);
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-    PYmode(Mode, OMrunning, p);
-#endif /* defined(DO_PYTHON) */
-    
-    free(ModeReason);
-    ModeReason = NULL;
-    Mode = OMrunning;
-    ThrottledbyIOError = false;
-
-    if (NNRPReason && !innconf->readerswhenstopped) {
-       av[0] = YES;
-       av[1] = p;
-       CCreaders(av);
-    }
-    if (ErrorCount < 0)
-       ErrorCount = IO_ERROR_COUNT;
-    InndHisOpen();
-    syslog(L_NOTICE, "%s running", LogName);
-    if (ICDneedsetup)
-       ICDsetup(true);
-    SCHANwakeup(&Mode);
-    return NULL;
-}
-
-
-/*
-**  Hangup a channel.
-*/
-static const char *
-CChangup(char *av[])
-{
-    CHANNEL    *cp;
-    int                fd;
-    char       *p;
-    int                i;
-
-    /* Parse the argument, a channel number. */
-    for (p = av[0], fd = 0; *p; p++) {
-       if (!CTYPE(isdigit, *p))
-           return "1 Bad channel number";
-       fd = fd * 10 + *p - '0';
-    }
-
-    /* Loop over all channels for the desired one. */
-    for (i = 0; (cp = CHANiter(&i, CTany)) != NULL; )
-       if (cp->fd == fd) {
-           p = CHANname(cp);
-           switch (cp->Type) {
-           default:
-               snprintf(CCreply.data, CCreply.size, "1 Can't close %s", p);
-               return CCreply.data;
-           case CTexploder:
-           case CTprocess:
-           case CTfile:
-           case CTnntp:
-           case CTreject:
-               syslog(L_NOTICE, "%s hangup", p);
-               CHANclose(cp, p);
-               return NULL;
-           }
-       }
-    return "1 Not active";
-}
-
-
-/*
-**  Return our operating mode.
-*/
-static const char *
-CCmode(char *unused[] UNUSED)
-{
-    char       *p;
-    int                i;
-    int                h;
-    char       buff[BUFSIZ];
-#if defined(DO_PERL)
-    char        *stats;
-#endif /* defined(DO_PERL) */
-
-    /* FIXME: We assume here that BUFSIZ is >= 512, and that none of
-     * ModeReason, RejectReason, Reservation, NNRPReason, or the Perl filter
-     * statistics are longer than MAX_REASON_LEN bytes (or actually, the
-     * average of their lengths is <= MAX_REASON_LEN).  If this is not true,
-     * the sprintf's/strcpy's below are likely to overflow buff with somewhat
-     * nasty consequences...
-     */
-
-    p = buff;
-    p += strlen(strcpy(buff, "0 Server "));
-
-    /* Server's mode. */
-    switch (Mode) {
-    default:
-       sprintf(p, "Unknown %d", Mode);
-       p += strlen(p);
-       break;
-    case OMrunning:
-       p += strlen(strcpy(p, "running"));
-       break;
-    case OMpaused:
-       p += strlen(strcpy(p, "paused "));
-       p += strlen(strcpy(p, ModeReason));
-       break;
-    case OMthrottled:
-       p += strlen(strcpy(p, "throttled "));
-       p += strlen(strcpy(p, ModeReason));
-       break;
-    }
-    *p++ = '\n';
-    if (RejectReason) {
-       p += strlen(strcpy(p, "Rejecting "));
-       p += strlen(strcpy(p, RejectReason));
-    }
-    else
-       p += strlen(strcpy(p, "Allowing remote connections"));
-
-    /* Server parameters. */
-    for (i = 0, h = 0; CHANiter(&h, CTnntp) != NULL; )
-       i++;
-    *p++ = '\n';
-    sprintf(p, "Parameters c %ld i %ld (%d) l %ld o %d t %ld H %d T %d X %d %s %s",
-                  innconf->artcutoff, innconf->maxconnections, i,
-                  innconf->maxartsize, MaxOutgoing, (long)TimeOut.tv_sec,
-                  RemoteLimit, RemoteTotal, (int) RemoteTimer,
-                  innconf->xrefslave ? "slave" : "normal",
-                  AnyIncoming ? "any" : "specified");
-    p += strlen(p);
-
-    /* Reservation. */
-    *p++ = '\n';
-    if (Reservation) {
-       sprintf(p, "Reserved %s", Reservation);
-       p += strlen(p);
-    }
-    else
-       p += strlen(strcpy(p, "Not reserved"));
-
-    /* Newsreaders. */
-    *p++ = '\n';
-    p += strlen(strcpy(p, "Readers "));
-    if (innconf->readerswhenstopped)
-       p += strlen(strcpy(p, "independent "));
-    else
-       p += strlen(strcpy(p, "follow "));
-    if (NNRPReason == NULL)
-       p += strlen(strcpy(p, "enabled"));
-    else {
-       sprintf(p, "disabled %s", NNRPReason);
-       p += strlen(p);
-    }
-
-#if defined(DO_TCL)
-    *p++ = '\n';
-    p += strlen(strcpy(p, "Tcl filtering "));
-    if (TCLFilterActive)
-       p += strlen(strcpy(p, "enabled"));
-    else
-       p += strlen(strcpy(p, "disabled"));
-#endif /* defined(DO_TCL) */
-
-#if defined(DO_PERL)
-    *p++ = '\n';
-    p += strlen(strcpy(p, "Perl filtering "));
-    if (PerlFilterActive)
-        p += strlen(strcpy(p, "enabled"));
-    else
-        p += strlen(strcpy(p, "disabled"));
-
-    /* Perl filter status. */
-    stats = PLstats();
-    if (stats != NULL) {
-        *p++ = '\n';
-        p += strlen(strcpy(p, "Perl filter stats: "));
-        p += strlen(strcpy(p, stats));
-        free(stats);
-    }    
-#endif /* defined(DO_PERL) */
-
-#if defined(DO_PYTHON)
-    *p++ = '\n';
-    p += strlen(strcpy(p, "Python filtering "));
-    if (PythonFilterActive)
-        p += strlen(strcpy(p, "enabled"));
-    else
-        p += strlen(strcpy(p, "disabled"));
-#endif /* defined(DO_PYTHON) */
-
-    buffer_set(&CCreply, buff, strlen(buff) + 1);
-    return CCreply.data;
-}
-
-
-/*
-**  Log our operating mode (via syslog).
-*/
-static const char *
-CClogmode(char *unused[])
-{
-    unused = unused;           /* ARGSUSED */
-    syslog(L_NOTICE, "%s servermode %s", LogName, CCcurrmode());
-    return NULL;
-}
-
-
-/*
-**  Name the channels.  ("Name the bats -- simple names.")
-*/
-static const char *
-CCname(char *av[])
-{
-    static char                NL[] = "\n";
-    static char                NIL[] = "\0";
-    char               buff[SMBUF];
-    CHANNEL            *cp;
-    char               *p;
-    int                        count;
-    int                        i;
-
-    p = av[0];
-    if (*p != '\0') {
-       if ((cp = CHANfromdescriptor(atoi(p))) == NULL)
-           return xstrdup(CCnochannel);
-       snprintf(CCreply.data, CCreply.size, "0 %s", CHANname(cp));
-       return CCreply.data;
-    }
-    buffer_set(&CCreply, "0 ", 2);
-    for (count = 0, i = 0; (cp = CHANiter(&i, CTany)) != NULL; ) {
-       if (cp->Type == CTfree)
-           continue;
-       if (++count > 1)
-           buffer_append(&CCreply, NL, 1);
-       p = CHANname(cp);
-       buffer_append(&CCreply, p, strlen(p));
-       switch (cp->Type) {
-       case CTremconn:
-           sprintf(buff, ":remconn::");
-           break;
-       case CTreject:
-           sprintf(buff, ":reject::");
-           break;
-       case CTnntp:
-           sprintf(buff, ":%s:%ld:%s",
-                    cp->State == CScancel ? "cancel" : "nntp",
-                    (long) Now.time - cp->LastActive,
-                    (cp->MaxCnx > 0 && cp->ActiveCnx == 0) ? "paused" : "");
-           break;
-       case CTlocalconn:
-           sprintf(buff, ":localconn::");
-           break;
-       case CTcontrol:
-           sprintf(buff, ":control::");
-           break;
-       case CTfile:
-           sprintf(buff, "::");
-           break;
-       case CTexploder:
-           sprintf(buff, ":exploder::");
-           break;
-       case CTprocess:
-           sprintf(buff, ":");
-           break;
-       default:
-           sprintf(buff, ":unknown::");
-           break;
-       }
-       p = buff;
-       buffer_append(&CCreply, p, strlen(p));
-    }
-    buffer_append(&CCreply, NIL, 1);
-    return CCreply.data;
-}
-
-
-/*
-**  Create a newsgroup.
-*/
-static const char *
-CCnewgroup(char *av[])
-{
-    static char                *TIMES = NULL;
-    static char                WHEN[] = "updating active.times";
-    int                        fd;
-    char               *p;
-    NEWSGROUP          *ngp;
-    char               *Name;
-    char               *Rest;
-    const char *               who;
-    char               *buff;
-    int                        oerrno;
-    size_t              length;
-
-    if (TIMES == NULL)
-       TIMES = concatpath(innconf->pathdb, _PATH_ACTIVETIMES);
-
-    Name = av[0];
-    if (Name[0] == '.' || strspn(Name, "0123456789") == strlen(Name))
-       return "1 Illegal newsgroup name";
-    for (p = Name; *p; p++)
-       if (*p == '.') {
-           if (p[1] == '.' || p[1] == '\0')
-               return "1 Double or trailing period in newsgroup name";
-       }
-       else if (ISWHITE(*p) || *p == ':' || *p == '!' || *p == '/')
-           return "1 Illegal character in newsgroup name";
-
-    Rest = av[1];
-    if (Rest[0] != NF_FLAG_ALIAS) {
-       Rest[1] = '\0';
-       if (CTYPE(isupper, Rest[0]))
-           Rest[0] = tolower(Rest[0]);
-    }
-    if (strlen(Name) + strlen(Rest) > SMBUF - 24)
-       return "1 Name too long";
-
-    if ((ngp = NGfind(Name)) != NULL)
-       return CCdochange(ngp, Rest);
-
-    if (Mode == OMthrottled && ThrottledbyIOError)
-       return "1 server throttled";
-
-    /* Update the log of groups created.  Don't use stdio because SunOS
-     * 4.1 has broken libc which can't handle fd's greater than 127. */
-    if ((fd = open(TIMES, O_WRONLY | O_APPEND | O_CREAT, 0664)) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant open %s %m", LogName, TIMES);
-       IOError(WHEN, oerrno);
-    }
-    else {
-       who = av[2];
-       if (*who == '\0')
-           who = NEWSMASTER;
-
-        length = snprintf(NULL, 0, "%s %ld %s\n", Name, (long) Now.time, who) + 1;
-        buff = xmalloc(length);
-        snprintf(buff, length, "%s %ld %s\n", Name, (long) Now.time, who);
-       if (xwrite(fd, buff, strlen(buff)) < 0) {
-           oerrno = errno;
-           syslog(L_ERROR, "%s cant write %s %m", LogName, TIMES);
-           IOError(WHEN, oerrno);
-       }
-
-       free(buff);
-       
-       if (close(fd) < 0) {
-           oerrno = errno;
-           syslog(L_ERROR, "%s cant close %s %m", LogName, TIMES);
-           IOError(WHEN, oerrno);
-       }
-    }
-
-    /* Update the in-core data. */
-    if (!ICDnewgroup(Name, Rest))
-       return "1 Failed";
-    syslog(L_NOTICE, "%s newgroup %s as %s", LogName, Name, Rest);
-
-    return NULL;
-}
-
-
-/*
-**  Parse and set a boolean flag.
-*/
-static bool
-CCparsebool(char name, bool *bp, char value)
-{
-    switch (value) {
-    default:
-       return false;
-    case 'y':
-       *bp = false;
-       break;
-    case 'n':
-       *bp = true;
-       break;
-    }
-    syslog(L_NOTICE, "%s changed -%c %c", LogName, name, value);
-    return true;
-}
-
-
-/*
-**  Change a running parameter.
-*/
-static const char *
-CCparam(char *av[])
-{
-    static char        BADVAL[] = "1 Bad value";
-    char       *p;
-    int                temp;
-
-    p = av[1];
-    switch (av[0][0]) {
-    default:
-       return "1 Unknown parameter";
-    case 'a':
-       if (!CCparsebool('a', (bool *)&AnyIncoming, *p))
-           return BADVAL;
-       break;
-    case 'c':
-       innconf->artcutoff = atoi(p);
-       syslog(L_NOTICE, "%s changed -c %ld", LogName, innconf->artcutoff);
-       break;
-    case 'i':
-       innconf->maxconnections = atoi(p);
-       syslog(L_NOTICE, "%s changed -i %ld", LogName, innconf->maxconnections);
-       break;
-    case 'l':
-       innconf->maxartsize = atol(p);
-       syslog(L_NOTICE, "%s changed -l %ld", LogName, innconf->maxartsize);
-       break;
-    case 'n':
-       if (!CCparsebool('n', (bool *)&innconf->readerswhenstopped, *p))
-           return BADVAL;
-       break;
-    case 'o':
-       MaxOutgoing = atoi(p);
-       syslog(L_NOTICE, "%s changed -o %d", LogName, MaxOutgoing);
-       break;
-    case 't':
-       TimeOut.tv_sec = atol(p);
-       syslog(L_NOTICE, "%s changed -t %ld", LogName, (long)TimeOut.tv_sec);
-       break;
-    case 'H':
-       RemoteLimit = atoi(p);
-       syslog(L_NOTICE, "%s changed -H %d", LogName, RemoteLimit);
-       break;
-    case 'T':
-        temp = atoi(p);
-       if (temp > REMOTETABLESIZE) {
-           syslog(L_NOTICE, "%s -T must be lower than %d",
-                  LogName, REMOTETABLESIZE+1);
-           temp = REMOTETABLESIZE;
-       }
-       syslog(L_NOTICE, "%s changed -T from %d to %d",
-              LogName, RemoteTotal, temp);
-       RemoteTotal = temp;
-       break;
-    case 'X':
-       RemoteTimer = (time_t) atoi(p);
-       syslog(L_NOTICE, "%s changed -X %d", LogName, (int) RemoteTimer);
-       break;
-    }
-    return NULL;
-}
-
-
-/*
-**  Common code to implement a pause or throttle.
-*/
-const char *
-CCblock(OPERATINGMODE NewMode, char *reason)
-{
-    static char                NO[] = "n";
-    char *             av[2];
-
-    if (*reason == '\0')
-       return CCnoreason;
-
-    if (strlen(reason) > MAX_REASON_LEN) /* MAX_REASON_LEN is as big as is safe */
-       return CCbigreason;
-
-    if (Reservation) {
-       if (strcmp(reason, Reservation) != 0) {
-           snprintf(CCreply.data, CCreply.size, "1 Reserved \"%s\"",
-                     Reservation);
-           return CCreply.data;
-       }
-       free(Reservation);
-       Reservation = NULL;
-    }
-
-#if defined(DO_PERL)
-    PLmode(Mode, NewMode, reason);
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-    PYmode(Mode, NewMode, reason);
-#endif /* defined(DO_PYTHON) */
-
-    ICDwrite();
-    InndHisClose();
-    Mode = NewMode;
-    if (ModeReason)
-       free(ModeReason);
-    ModeReason = xstrdup(reason);
-    if (NNRPReason == NULL && !innconf->readerswhenstopped) {
-       av[0] = NO;
-       av[1] = ModeReason;
-       CCreaders(av);
-    }
-    syslog(L_NOTICE, "%s %s %s",
-       LogName, NewMode == OMpaused ? "paused" : "throttled", reason);
-    return NULL;
-}
-
-
-/*
-**  Enter paused mode.
-*/
-static const char *
-CCpause(char *av[])
-{
-    switch (Mode) {
-    case OMrunning:
-       return CCblock(OMpaused, av[0]);
-    case OMpaused:
-       return "1 Already paused";
-    case OMthrottled:
-       return "1 Already throttled";
-    }
-    return "1 Unknown mode";
-}
-
-
-/*
-**  Allow or disallow newsreaders.
-*/
-static const char *
-CCreaders(char *av[])
-{
-    const char *p;
-
-    switch (av[0][0]) {
-    default:
-       return "1 Bad flag";
-    case 'y':
-       if (NNRPReason == NULL)
-           return "1 Already allowing readers";
-       p = av[1];
-       if (*p && strcmp(p, NNRPReason) != 0)
-           return "1 Wrong reason";
-       free(NNRPReason);
-       NNRPReason = NULL;
-       break;
-    case 'n':
-       if (NNRPReason)
-           return "1 Already not allowing readers";
-       p = av[1];
-       if (*p == '\0')
-           return CCnoreason;
-       if (strlen(p) > MAX_REASON_LEN) /* MAX_REASON_LEN is as big as is safe */
-           return CCbigreason;
-       NNRPReason = xstrdup(p);
-       break;
-    }
-    return NULL;
-}
-
-
-/*
-**  Re-exec ourselves.
-*/
-static const char *
-CCxexec(char *av[])
-{
-    char       *inndstart;
-    char       *p;
-    int                i;
-
-    if (CCargv == NULL)
-       return "1 no argv!";
-    
-    inndstart = concatpath(innconf->pathbin, "inndstart");
-    /* Get the pathname. */
-    p = av[0];
-    if (*p == '\0' || strcmp(p, "innd") == 0 || strcmp(p, "inndstart") == 0)
-       CCargv[0] = inndstart;
-    else
-       return "1 Bad value";
-
-    JustCleanup();
-    syslog(L_NOTICE, "%s execv %s", LogName, CCargv[0]);
-
-    /* Close all fds to protect possible fd leaking accross successive innds. */
-    for (i=3; i<30; i++)
-        close(i);
-
-    execv(CCargv[0], CCargv);
-    syslog(L_FATAL, "%s cant execv %s %m", LogName, CCargv[0]);
-    _exit(1);
-    /* NOTREACHED */
-    return "1 Exit failed";
-}
-
-/*
-**  Reject remote readers.
-*/
-static const char *
-CCreject(char *av[])
-{
-    if (RejectReason)
-       return "1 Already rejecting";
-    if (strlen(av[0]) > MAX_REASON_LEN)        /* MAX_REASON_LEN is as big as is safe */
-       return CCbigreason;
-    RejectReason = xstrdup(av[0]);
-    return NULL;
-}
-
-
-/*
-**  Re-read all in-core data.
-*/
-static const char *
-CCreload(char *av[])
-{
-    static char        BADSCHEMA[] = "1 Can't read schema";
-#if defined(DO_PERL)
-    static char BADPERLRELOAD[] = "1 Failed to define filter_art" ;
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-    static char BADPYRELOAD[] = "1 Failed to reload filter_innd.py" ;
-#endif /* defined(DO_PYTHON) */
-    const char *p;
-    char *path;
-
-    p = av[0];
-    if (*p == '\0' || strcmp(p, "all") == 0) {
-       SITEflushall(false);
-        if (Mode == OMrunning)
-           InndHisClose();
-       RCreadlist();
-       if (Mode == OMrunning)
-           InndHisOpen();
-       ICDwrite();
-       ICDsetup(true);
-       if (!ARTreadschema())
-           return BADSCHEMA;
-#if defined(DO_TCL)
-       TCLreadfilter();
-#endif /* defined(DO_TCL) */
-#if defined(DO_PERL)
-        path = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_INND);
-        PERLreadfilter(path, "filter_art") ;
-        free(path);
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-       syslog(L_NOTICE, "reloading pyfilter");
-        PYreadfilter();
-       syslog(L_NOTICE, "reloaded pyfilter OK");
-#endif /* DO_PYTHON */
-       p = "all";
-    }
-    else if (strcmp(p, "active") == 0 || strcmp(p, "newsfeeds") == 0) {
-       SITEflushall(false);
-       ICDwrite();
-       ICDsetup(true);
-    }
-    else if (strcmp(p, "history") == 0) {
-        if (Mode != OMrunning)
-            return CCnotrunning;
-       InndHisClose();
-       InndHisOpen();
-    }
-    else if (strcmp(p, "incoming.conf") == 0)
-       RCreadlist();
-    else if (strcmp(p, "overview.fmt") == 0) {
-       if (!ARTreadschema())
-           return BADSCHEMA;
-    }
-#if 0 /* we should check almost all innconf parameter, but the code
-         is still incomplete for innd, so just commented out */
-    else if (strcmp(p, "inn.conf") == 0) {
-        struct innconf *saved;
-
-        saved = innconf;
-        innconf = NULL;
-        if (innconf_read(NULL))
-            innconf_free(saved);
-        else {
-            innconf = saved;
-            return "1 Reload of inn.conf failed";
-        }
-       if (innconf->pathhost == NULL) {
-           syslog(L_FATAL, "%s No pathhost set", LogName);
-           exit(1);
-       }   
-       free(Path.Data);
-       Path.Used = strlen(innconf->pathhost) + 1;
-       Path.Data = xmalloc(Path.Used + 1);
-       sprintf(Path.Data, "%s!", innconf->pathhost);
-       if (Pathalias.Used > 0)
-           free(Pathalias.Data);
-       if (innconf->pathalias == NULL) {
-           Pathalias.Used = 0;
-           Pathalias.Data = NULL;
-       } else {
-           Pathalias.Used = strlen(innconf->pathalias) + 1;
-           Pathalias.Data = xmalloc(Pathalias.Used + 1);
-           sprintf(Pathalias.Data, "%s!", innconf->pathalias);
-        }
-        if (Pathcluster.Used > 0)
-            free(Pathcluster.Data);
-        if (innconf->pathcluster == NULL) {
-            Pathcluster.Used = 0;
-            Pathcluster.Data = NULL;
-        } else {
-            Pathcluster.Used = strlen(innconf->pathcluster) + 1;
-            Pathcluster.Data = xmalloc(Pathcluster.Used + 1);
-            sprintf(Pathcluster.Data, "%s!", innconf->pathcluster);
-       }
-    }
-#endif
-#if defined(DO_TCL)
-    else if (strcmp(p, "filter.tcl") == 0) {
-       TCLreadfilter();
-    }
-#endif /* defined(DO_TCL) */
-#if defined(DO_PERL)
-    else if (strcmp(p, "filter.perl") == 0) {
-        path = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_INND);
-        if (!PERLreadfilter(path, "filter_art"))
-            return BADPERLRELOAD;
-    }
-#endif /* defined(DO_PERL) */
-#if defined(DO_PYTHON)
-    else if (strcmp(p, "filter.python") == 0) {
-       if (!PYreadfilter())
-           return BADPYRELOAD;
-    }
-#endif /* defined(DO_PYTHON) */
-    else
-       return "1 Unknown reload type";
-
-    syslog(L_NOTICE, "%s reload %s %s", LogName, p, av[1]);
-    return NULL;
-}
-
-
-/*
-**  Renumber the active file.
-*/
-static const char *
-CCrenumber(char *av[])
-{
-    static char        CANTRENUMBER[] = "1 Failed (see syslog)";
-    char       *p;
-    NEWSGROUP  *ngp;
-
-    if (Mode != OMrunning)
-       return CCnotrunning;
-    if (ICDneedsetup)
-       return "1 Must first reload newsfeeds";
-    p = av[0];
-    if (*p) {
-       if ((ngp = NGfind(p)) == NULL)
-           return CCnogroup;
-       if (!NGrenumber(ngp))
-           return CANTRENUMBER;
-    }
-    else if (!ICDrenumberactive())
-       return CANTRENUMBER;
-    return NULL;
-}
-
-
-/*
-**  Reserve a lock.
-*/
-static const char *
-CCreserve(char *av[])
-{
-    char       *p;
-
-    if (Mode != OMrunning)
-       return CCnotrunning;
-    p = av[0];
-    if (*p) {
-       /* Trying to make a reservation. */
-       if (Reservation)
-           return "1 Already reserved";
-       if (strlen(p) > MAX_REASON_LEN) /* MAX_REASON_LEN is as big as is safe */
-           return CCbigreason;
-       Reservation = xstrdup(p);
-    }
-    else {
-       /* Trying to remove a reservation. */
-       if (Reservation == NULL)
-           return "1 Not reserved";
-       free(Reservation);
-       Reservation = NULL;
-    }
-    return NULL;
-}
-
-
-/*
-**  Remove a newsgroup.
-*/
-static const char *
-CCrmgroup(char *av[])
-{
-    NEWSGROUP  *ngp;
-
-    if ((ngp = NGfind(av[0])) == NULL)
-       return CCnogroup;
-
-    if (Mode == OMthrottled && ThrottledbyIOError)
-       return "1 server throttled";
-
-    /* Update the in-core data. */
-    if (!ICDrmgroup(ngp))
-       return "1 Failed";
-    syslog(L_NOTICE, "%s rmgroup %s", LogName, av[0]);
-    return NULL;
-}
-
-
-/*
-**  Send a command line to an exploder.
-*/
-static const char *
-CCsend(char *av[])
-{
-    SITE               *sp;
-
-    if ((sp = SITEfind(av[0])) == NULL)
-       return CCnosite;
-    if (sp->Type != FTexploder)
-       return CCwrongtype;
-    SITEwrite(sp, av[1]);
-    return NULL;
-}
-
-
-/*
-**  Shut down the system.
-*/
-static const char *
-CCshutdown(char *av[])
-{
-    syslog(L_NOTICE, "%s shutdown %s", LogName, av[0]);
-    CleanupAndExit(0, av[0]);
-    /* NOTREACHED */
-    return "1 Exit failed";
-}
-
-
-/*
-**  Send a signal to a site's feed.
-*/
-static const char *
-CCsignal(char *av[])
-{
-    SITE       *sp;
-    char       *p;
-    int                s;
-    int                oerrno;
-
-    /* Parse the signal. */
-    p = av[0];
-    if (*p == '-')
-       p++;
-    if (strcasecmp(p, "HUP") == 0)
-       s = SIGHUP;
-    else if (strcasecmp(p, "INT") == 0)
-       s = SIGINT;
-    else if (strcasecmp(p, "TERM") == 0)
-       s = SIGTERM;
-    else if ((s = atoi(p)) <= 0)
-       return "1 Invalid signal";
-
-    /* Parse the site. */
-    p = av[1];
-    if ((sp = SITEfind(p)) == NULL)
-       return CCnosite;
-    if (sp->Type != FTchannel && sp->Type != FTexploder)
-       return CCwrongtype;
-    if (sp->Process < 0)
-       return "1 Site has no process";
-
-    /* Do it. */
-    if (kill(sp->pid, s) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant kill %ld %d site %s, %m", LogName, 
-               (long) sp->pid, s, p);
-       snprintf(CCreply.data, CCreply.size, "1 Can't signal process %ld, %s",
-               (long) sp->pid, strerror(oerrno));
-       return CCreply.data;
-    }
-
-    return NULL;
-}
-
-
-/*
-**  Enter throttled mode.
-*/
-static const char *
-CCthrottle(char *av[])
-{
-    char       *p;
-
-    p = av[0];
-    switch (Mode) {
-    case OMpaused:
-       if (*p && strcmp(p, ModeReason) != 0)
-           return "1 Already paused";
-       /* FALLTHROUGH */
-    case OMrunning:
-       return CCblock(OMthrottled, p);
-    case OMthrottled:
-       return "1 Already throttled";
-    }
-    return "1 unknown mode";
-}
-
-/*
-**  Turn on or off performance monitoring
-*/
-static const char *
-CCtimer(char *av[])
-{
-    int                 value;
-    char                *p;
-    
-    if (strcmp(av[0], "off") == 0)
-       value = 0;
-    else {
-       for (p = av[0]; *p; p++) {
-           if (!CTYPE(isdigit, *p))
-               return "1 parameter should be a number or 'off'";
-       }
-       value = atoi(av[0]);
-    }
-    innconf->timer = value;
-    if (innconf->timer)
-        TMRinit(TMR_MAX);
-    else
-       TMRinit(0);
-    return NULL;
-}
-
-/*
-**  Log into filename some history stats
-*/
-static const char *
-CCstathist(char *av[])
-{
-    if (strcmp(av[0], "off") == 0)
-        HISlogclose();
-    else
-        HISlogto(av[0]);
-    return NULL;
-}
-
-/*
-**  Turn innd status creation on or off
-*/
-static const char *
-CCstatus(char *av[])
-{
-    int                 value;
-    char                *p;
-    
-    if (strcmp(av[0], "off") == 0)
-       value = 0;
-    else {
-       for (p = av[0]; *p; p++) {
-           if (!CTYPE(isdigit, *p))
-               return "1 parameter should be a number or 'off'";
-       }
-       value = atoi(av[0]);
-    }
-    innconf->status = value;
-    return NULL;
-}
-
-/*
-**  Add or remove tracing.
-*/
-static const char *
-CCtrace(char *av[])
-{
-    char       *p;
-    bool       Flag;
-    const char *       word;
-    CHANNEL    *cp;
-
-    /* Parse the flag. */
-    p = av[1];
-    switch (p[0]) {
-    default:                   return "1 Bad trace flag";
-    case 'y': case 'Y':                Flag = true;    word = "on";    break;
-    case 'n': case 'N':                Flag = false;   word = "off";   break;
-    }
-
-    /* Parse what's being traced. */
-    p = av[0];
-    switch (*p) {
-    default:
-       return "1 Bad trace item";
-    case 'i': case 'I':
-       Tracing = Flag;
-       syslog(L_NOTICE, "%s trace innd %s", LogName, word);
-       break;
-    case 'n': case 'N':
-       NNRPTracing = Flag;
-       syslog(L_NOTICE, "%s trace nnrpd %s", LogName, word);
-       break;
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-       if ((cp = CHANfromdescriptor(atoi(p))) == NULL)
-           return CCnochannel;
-       CHANtracing(cp, Flag);
-       break;
-    }
-    return NULL;
-}
-
-\f
-
-/*
-**  Split up the text into fields and stuff them in argv.  Return the
-**  number of elements or -1 on error.
-*/
-static int
-CCargsplit(char *p, char *end, char **argv, int size)
-{
-    char               **save;
-
-    for (save = argv, *argv++ = p, size--; p < end; p++)
-       if (*p == SC_SEP) {
-           if (--size <= 0)
-               return -1;
-           *p = '\0';
-           *argv++ = p + 1;
-       }
-    *argv = NULL;
-    return argv - save;
-}
-
-
-/*
-**  Read function.  Read and process the message.
-*/
-static void
-CCreader(CHANNEL *cp)
-{
-    static char                TOOLONG[] = "0 Reply too long for server to send";
-    CCDISPATCH         *dp;
-    const char *       p;
-    char               *q;
-    ICC_MSGLENTYPE     bufflen;
-    ICC_PROTOCOLTYPE   protocol ;
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    struct sockaddr_un client;
-#else
-    int                        written;
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-    int                        i;
-    char                buff[BIG_BUFFER + 2];
-    char                copy[BIG_BUFFER + 2];
-    char               *argv[SC_MAXFIELDS + 2];
-    int                        argc;
-    int                        len;
-    char               *tbuff ;
-
-    if (cp != CCchan) {
-       syslog(L_ERROR, "%s internal CCreader wrong channel 0x%p not 0x%p",
-           LogName, (void *)cp, (void *)CCchan);
-       return;
-    }
-
-#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
-    
-    i = RECVorREAD(CCchan->fd, buff, BIG_BUFFER) ;
-    if (i < 0) {
-       syslog(L_ERROR, "%s cant recv CCreader %m", LogName);
-       return;
-    } else if (i == 0) {
-       syslog(L_ERROR, "%s cant recv CCreader empty", LogName);
-       return;
-    } else if (i < (int)HEADER_SIZE) {
-       syslog(L_ERROR, "%s cant recv CCreader header-length %m", LogName);
-       return;
-    }
-
-    memcpy (&protocol,buff,sizeof (protocol)) ;
-    memcpy (&bufflen,buff + sizeof (protocol),sizeof (bufflen)) ;
-    bufflen = ntohs (bufflen) ;
-    
-    if (i != bufflen) {
-       syslog(L_ERROR, "%s cant recv CCreader short-read %m", LogName);
-       return;
-    }
-
-    i -= HEADER_SIZE ;
-    memmove (buff,buff + HEADER_SIZE,i) ;
-    buff[i] = '\0';
-
-    if (protocol != ICC_PROTOCOL_1) {
-        syslog(L_ERROR, "%s CCreader protocol mismatch", LogName) ;
-        return ;
-    }
-
-#else  /* defined (HAVE_UNIX_DOMAIN_SOCKETS) */
-
-    i = RECVorREAD(CCchan->fd, buff, HEADER_SIZE) ;
-    if (i < 0) {
-       syslog(L_ERROR, "%s cant read CCreader header %m", LogName);
-       return;
-    } else if (i == 0) {
-       syslog(L_ERROR, "%s cant read CCreader header empty", LogName);
-       return;
-    } else if (i != HEADER_SIZE) {
-       syslog(L_ERROR, "%s cant read CCreader header-length %m", LogName);
-       return;
-    }
-
-    memcpy (&protocol,buff,sizeof (protocol)) ;
-    memcpy (&bufflen,buff + sizeof (protocol),sizeof (bufflen)) ;
-    bufflen = ntohs (bufflen);
-    if (bufflen < HEADER_SIZE || bufflen > BIG_BUFFER) {
-       syslog(L_ERROR, "%s cant read CCreader bad length", LogName);
-       return;
-    }
-    bufflen -= HEADER_SIZE ;
-    
-    i = RECVorREAD(CCchan->fd, buff, bufflen) ;
-
-    if (i < 0) {
-       syslog(L_ERROR, "%s cant read CCreader buffer %m", LogName);
-       return;
-    } else if (i == 0) {
-       syslog(L_ERROR, "%s cant read CCreader buffer empty", LogName);
-       return;
-    } else if (i != bufflen) {
-       syslog(L_ERROR, "%s cant read CCreader buffer-length %m", LogName);
-       return;
-    }
-
-    buff[i] = '\0';
-
-    if (protocol != ICC_PROTOCOL_1) {
-        syslog(L_ERROR, "%s CCreader protocol mismatch", LogName) ;
-        return ;
-    }
-
-#endif /* defined (HAVE_UNIX_DOMAIN_SOCKETS) */
-    
-    /* Copy to a printable buffer, and log. */
-    strcpy(copy, buff);
-    for (p = NULL, q = copy; *q; q++)
-       if (*q == SC_SEP) {
-           *q = ':';
-           if (p == NULL)
-               p = q + 1;
-       }
-    syslog(L_CC_CMD, "%s", p ? p : copy);
-
-    /* Split up the fields, get the command letter. */
-    if ((argc = CCargsplit(buff, &buff[i], argv, ARRAY_SIZE(argv))) < 2
-     || argc == ARRAY_SIZE(argv)) {
-       syslog(L_ERROR, "%s bad_fields CCreader", LogName);
-       return;
-    }
-    p = argv[1];
-    i = *p;
-
-    /* Dispatch to the command function. */
-    for (argc -= 2, dp = CCcommands; dp < ARRAY_END(CCcommands); dp++)
-       if (i == dp->Name) {
-           if (argc != dp->argc)
-               p = "1 Wrong number of parameters";
-           else
-               p = (*dp->Function)(&argv[2]);
-           break;
-       }
-    if (dp == ARRAY_END(CCcommands)) {
-       syslog(L_NOTICE, "%s bad_message %c", LogName, i);
-       p = "1 Bad command";
-    }
-    else if (p == NULL)
-       p = "0 Ok";
-
-    /* Build the reply address and send the reply. */
-    len = strlen(p) + HEADER_SIZE ;
-    tbuff = xmalloc(len + 1);
-    
-    protocol = ICC_PROTOCOL_1 ;
-    memcpy (tbuff,&protocol,sizeof (protocol)) ;
-    tbuff += sizeof (protocol) ;
-    
-    bufflen = htons (len) ;
-    memcpy (tbuff,&bufflen,sizeof (bufflen)) ;
-    tbuff += sizeof (bufflen) ;
-
-    strcpy (tbuff,p) ;
-    tbuff -= HEADER_SIZE ;
-
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    memset(&client, 0, sizeof client);
-    client.sun_family = AF_UNIX;
-    strcpy(client.sun_path, argv[0]);
-    if (sendto(CCwriter, tbuff, len, 0,
-           (struct sockaddr *) &client, SUN_LEN(&client)) < 0) {
-       i = errno;
-       syslog(i == ENOENT ? L_NOTICE : L_ERROR,
-           "%s cant sendto CCreader bytes %d %m", LogName, len);
-       if (i == EMSGSIZE)
-           sendto(CCwriter, TOOLONG, strlen(TOOLONG), 0,
-               (struct sockaddr *) &client, SUN_LEN(&client));
-    }
-#else
-    if ((i = open(argv[0], O_WRONLY | O_NDELAY)) < 0)
-       syslog(L_ERROR, "%s cant open %s %m", LogName, argv[0]);
-    else {
-       if ((written = write(i, tbuff, len)) != len)
-           if (written < 0)
-               syslog(L_ERROR, "%s cant write %s %m", LogName, argv[0]);
-           else
-               syslog(L_ERROR, "%s cant write %s", LogName, argv[0]);
-       if (close(i) < 0)
-           syslog(L_ERROR, "%s cant close %s %m", LogName, argv[0]);
-    }
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-    free (tbuff) ;
-}
-
-
-/*
-**  Called when a write-in-progress is done on the channel.  Shouldn't happen.
-*/
-static void
-CCwritedone(CHANNEL *unused)
-{
-    unused = unused;           /* ARGSUSED */
-    syslog(L_ERROR, "%s internal CCwritedone", LogName);
-}
-
-
-/*
-**  Create the channel.
-*/
-void
-CCsetup(void)
-{
-    int                        i;
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    struct sockaddr_un server;
-    int size = 65535;
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-
-    if (CCpath == NULL)
-       CCpath = concatpath(innconf->pathrun, _PATH_NEWSCONTROL);
-    /* Remove old detritus. */
-    if (unlink(CCpath) < 0 && errno != ENOENT) {
-       syslog(L_FATAL, "%s cant unlink %s %m", LogName, CCpath);
-       exit(1);
-    }
-
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    /* Create a socket and name it. */
-    if ((i = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
-       syslog(L_FATAL, "%s cant socket %s %m", LogName, CCpath);
-       exit(1);
-    }
-    memset(&server, 0, sizeof server);
-    server.sun_family = AF_UNIX;
-    strcpy(server.sun_path, CCpath);
-    if (bind(i, (struct sockaddr *) &server, SUN_LEN(&server)) < 0) {
-       syslog(L_FATAL, "%s cant bind %s %m", LogName, CCpath);
-       exit(1);
-    }
-
-    /* Create an unbound socket to reply on. */
-    if ((CCwriter = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
-       syslog(L_FATAL, "%s cant socket unbound %m", LogName);
-       exit(1);
-    }
-
-    /* Increase the buffer size for the Unix domain socket */
-    if (setsockopt(CCwriter, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0)
-       syslog(L_ERROR, "%s cant setsockopt %m", LogName);
-#else
-    /* Create a named pipe and open it. */
-    if (mkfifo(CCpath, 0666) < 0) {
-       syslog(L_FATAL, "%s cant mkfifo %s %m", LogName, CCpath);
-       exit(1);
-    }
-    if ((i = open(CCpath, O_RDWR)) < 0) {
-       syslog(L_FATAL, "%s cant open %s %m", LogName, CCpath);
-       exit(1);
-    }
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-
-    CCchan = CHANcreate(i, CTcontrol, CSwaiting, CCreader, CCwritedone);
-    syslog(L_NOTICE, "%s ccsetup %s", LogName, CHANname(CCchan));
-    RCHANadd(CCchan);
-
-    buffer_resize(&CCreply, SMBUF);
-
-    /*
-     *  Catch SIGUSR1 so that we can recreate the control channel when
-     *  needed (i.e. something has deleted our named socket.
-     */
-#if     defined(SIGUSR1)
-    xsignal(SIGUSR1, CCresetup);
-#endif  /* defined(SIGUSR1) */
-}
-
-
-/*
-**  Cleanly shut down the channel.
-*/
-void
-CCclose(void)
-{
-    CHANclose(CCchan, CHANname(CCchan));
-    CCchan = NULL;
-    if (unlink(CCpath) < 0)
-       syslog(L_ERROR, "%s cant unlink %s %m", LogName, CCpath);
-    free(CCpath);
-    CCpath = NULL;
-    free(CCreply.data);
-    CCreply.data = NULL;
-    CCreply.size = 0;
-    CCreply.used = 0;
-    CCreply.left = 0;
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    if (close(CCwriter) < 0)
-       syslog(L_ERROR, "%s cant close unbound %m", LogName);
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-}
-
-
-/*
-**  Restablish the control channel.
-*/
-static RETSIGTYPE
-CCresetup(int unused)
-{
-#ifndef HAVE_SIGACTION
-    xsignal(s, CCresetup);
-#else
-    unused = unused;           /* ARGSUSED */
-#endif
-    CCclose();
-    CCsetup();
-}
-
-
-/*
- * Read a file containing lines of the form "newsgroup lowmark",
- * and reset the low article number for the specified groups.
- */
-static const char *
-CClowmark(char *av[])
-{
-    long lo;
-    char *line, *cp;
-    const char  *ret = NULL;
-    QIOSTATE *qp;
-    NEWSGROUP *ngp;
-
-    if (Mode != OMrunning)
-       return CCnotrunning;
-    if (ICDneedsetup)
-       return "1 Must first reload newsfeeds";
-    if ((qp = QIOopen(av[0])) == NULL) {
-       syslog(L_ERROR, "%s cant open %s %m", LogName, av[0]);
-       return "1 Cannot read input file";
-    }
-    while ((line = QIOread(qp)) != NULL) {
-       if (QIOerror(qp))
-               break;
-       if (QIOtoolong(qp)) {
-           ret = "1 Malformed input line (too long)";
-           break;
-       }
-       while (ISWHITE(*line))
-           line++;
-       for (cp = line; *cp && !ISWHITE(*cp); cp++)
-           ;
-       if (*cp == '\0') {
-           ret = "1 Malformed input line (only one field)";
-           break;
-       }
-       *cp++ = '\0';
-       while (ISWHITE(*cp))
-           cp++;
-       if (strspn(cp, "0123456789") != strlen(cp)) {
-           ret = "1 Malformed input line (non-digit in low mark)";
-           break;
-       }
-       if ((lo = atol(cp)) == 0 && (cp[0] != '0' || cp[1] != '\0')) {
-           ret = "1 Malformed input line (bad low mark)";
-           break;
-       }
-        if ((ngp = NGfind(line)) == NULL) {
-           /* ret = CCnogroup; break; */
-           continue;
-       }
-        if (!NGlowmark(ngp, lo)) {
-           ret = "1 Cannot set low mark - see syslog";
-           break;
-       }
-    }
-    if (ret == NULL && QIOerror(qp)) {
-       syslog(L_ERROR, "%s cant read %s %m", LogName, av[0]);
-       ret = "1 Error reading input file";
-    }
-    QIOclose(qp);
-    ICDwrite();
-    return ret;
-}
diff --git a/innd/chan.c b/innd/chan.c
deleted file mode 100644 (file)
index 664c943..0000000
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*  $Id: chan.c 6720 2004-05-16 20:54:25Z rra $
-**
-**  I/O channel (and buffer) processing.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-/* These errno values don't exist on all systems, but may be returned as an
-   (ignorable) error to setting the accept socket nonblocking.  Define them
-   to 0 if they don't exist so that we can unconditionally compare errno to
-   them in the code. */
-#ifndef ENOTSOCK
-# define ENOTSOCK 0
-#endif
-#ifndef ENOTTY
-# define ENOTTY 0
-#endif
-
-static const char * const timer_name[] = {
-    "idle", "artclean", "artwrite", "artcncl", "sitesend", "overv",
-    "perl", "python", "nntpread", "artparse", "artlog", "datamove"
-};
-
-/* Minutes - basically, keep the connection open but idle */
-#define PAUSE_BEFORE_DROP               5
-
-/* Divisor of the BUFFER size. If the amount free at the beginning of the
-   buffer is bigger than the quotient, then it is compacted in the
-   readloop */
-#define COMP_THRESHOLD 10
-
-static fd_set  RCHANmask;
-static fd_set  SCHANmask;
-static fd_set  WCHANmask;
-static int     SCHANcount;
-static int     CHANlastfd;
-static int     CHANlastsleepfd;
-static int     CHANccfd;
-static int     CHANtablesize;
-static CHANNEL *CHANtable;
-static CHANNEL *CHANcc;
-static CHANNEL CHANnull = { CTfree, CSerror, -1 };
-
-#define PRIORITISE_REMCONN
-#ifdef PRIORITISE_REMCONN
-static int     *CHANrcfd;
-static CHANNEL **CHANrc;
-static int     chanlimit;
-#endif /* PRIORITISE_REMCONN */
-
-/*
-** Tear down our world
-*/
-void
-CHANshutdown(void)
-{
-  CHANNEL              *cp;
-  int                  i;
-
-  if (CHANtable) {
-    for (i = CHANtablesize, cp = &CHANtable[0]; --i >= 0; cp++) {
-      if (cp->In.data) {
-       free(cp->In.data);
-      }
-      if (cp->Out.data) {
-       free(cp->Out.data);
-      }
-    }
-    free(CHANtable);
-    CHANtable = NULL;
-  }
-}
-
-/*
-**  Initialize all the I/O channels.
-*/
-void
-CHANsetup(int i)
-{
-    CHANNEL            *cp;
-
-    FD_ZERO(&RCHANmask);
-    FD_ZERO(&SCHANmask);
-    FD_ZERO(&WCHANmask);
-    CHANshutdown();
-    CHANtablesize = i;
-    CHANtable = xcalloc(CHANtablesize, sizeof(CHANNEL));
-    CHANnull.NextLog = innconf->chaninacttime;
-    memset(&CHANnull.Address, 0, sizeof(CHANnull.Address));
-    for (cp = CHANtable; --i >= 0; cp++)
-       *cp = CHANnull;
-}
-
-
-/*
-**  Create a channel from a descriptor.
-*/
-CHANNEL *
-CHANcreate(int fd, CHANNELTYPE Type, CHANNELSTATE State,
-           innd_callback_t Reader, innd_callback_t WriteDone)
-{
-    CHANNEL            *cp;
-    struct buffer      in  = { 0, 0, 0, NULL };
-    struct buffer      out = { 0, 0, 0, NULL };
-
-    cp = &CHANtable[fd];
-
-    /* Don't overwrite the buffers with CHANnull. */
-    in = cp->In;
-    buffer_resize(&in, START_BUFF_SIZE);
-    in.used = 0;
-    in.left = in.size;
-    out = cp->Out;
-    buffer_resize(&out, SMBUF);
-    buffer_set(&out, "", 0);
-
-    /* Set up the channel's info. */
-    *cp = CHANnull;
-    cp->fd = fd;
-    cp->Type = Type;
-    cp->State = State;
-    cp->Streaming = false;
-    cp->Skip = false;
-    cp->NoResendId = false;
-    cp->privileged = false;
-    cp->Ihave = cp->Ihave_Duplicate = cp->Ihave_Deferred = cp->Ihave_SendIt = cp->Ihave_Cybercan = 0;
-    cp->Check = cp->Check_send = cp->Check_deferred = cp->Check_got = cp->Check_cybercan = 0;
-    cp->Takethis = cp->Takethis_Ok = cp->Takethis_Err = 0;
-    cp->Size = cp->Duplicate = 0;
-    cp->Unwanted_s = cp->Unwanted_f = cp->Unwanted_d = 0;
-    cp->Unwanted_g = cp->Unwanted_u = cp->Unwanted_o = 0;
-    cp->Reader = Reader;
-    cp->WriteDone = WriteDone;
-    cp->Started = cp->LastActive = Now.time;
-    cp->In = in;
-    cp->Out = out;
-    cp->Tracing = Tracing;
-    cp->Sendid.size = 0;
-    cp->Next=0;
-    cp->MaxCnx=0;
-    cp->ActiveCnx=0;
-    cp->ArtBeg = 0;
-    cp->ArtMax = 0;
-    cp->Start = 0;
-    HashClear(&cp->CurrentMessageIDHash);
-    memset(cp->PrecommitWIP, '\0', sizeof(cp->PrecommitWIP));
-    cp->PrecommitiCachenext=0;
-    ARTprepare(cp);
-
-    close_on_exec(fd, true);
-
-#ifndef _HPUX_SOURCE
-    /* Stupid HPUX 11.00 has a broken listen/accept where setting the listen
-       socket to nonblocking prevents you from successfully setting the
-       socket returned by accept(2) back to blocking mode, no matter what,
-       resulting in all kinds of funny behaviour, data loss, etc. etc.  */
-    if (nonblocking(fd, true) < 0 && errno != ENOTSOCK && errno != ENOTTY)
-       syslog(L_ERROR, "%s cant nonblock %d %m", LogName, fd);
-#endif
-
-    /* Note control channel, for efficiency. */
-    if (Type == CTcontrol) {
-       CHANcc = cp;
-       CHANccfd = fd;
-    }
-#ifdef PRIORITISE_REMCONN
-    /* Note remconn channel, for efficiency */
-    if (Type == CTremconn) {
-       int j;
-       for (j = 0 ; j < chanlimit ; j++ ) {
-           if (CHANrcfd[j] == -1) {
-               break;
-           }
-       }
-       if (j < chanlimit) {
-           CHANrc[j] = cp;
-           CHANrcfd[j] = fd;
-       } else if (chanlimit == 0) {
-           /* assuming two file descriptors(AF_INET and AF_INET6) */
-           chanlimit = 2;
-           CHANrc = xmalloc(chanlimit * sizeof(CHANNEL **));
-           CHANrcfd = xmalloc(chanlimit * sizeof(int *));
-           for (j = 0 ; j < chanlimit ; j++ ) {
-               CHANrc[j] = NULL;
-               CHANrcfd[j] = -1;
-           }
-           CHANrc[0] = cp;
-           CHANrcfd[0] = fd;
-       } else {
-           /* extend to double size */
-            CHANrc = xrealloc(CHANrc, chanlimit * 2 * sizeof(CHANNEL **));
-            CHANrcfd = xrealloc(CHANrcfd, chanlimit * 2 * sizeof(int *));
-           for (j = chanlimit ; j < chanlimit * 2 ; j++ ) {
-               CHANrc[j] = NULL;
-               CHANrcfd[j] = -1;
-           }
-           CHANrc[chanlimit] = cp;
-           CHANrcfd[chanlimit] = fd;
-           chanlimit *= 2;
-       }
-    }
-#endif /* PRIORITISE_REMCONN */
-    return cp;
-}
-
-
-/*
-**  Start tracing a channel.
-*/
-void
-CHANtracing(CHANNEL *cp, bool Flag)
-{
-    char               *p;
-
-    p = CHANname(cp);
-    syslog(L_NOTICE, "%s trace %s", p, Flag ? "on" : "off");
-    cp->Tracing = Flag;
-    if (Flag) {
-       syslog(L_NOTICE, "%s trace badwrites %d blockwrites %d badreads %d",
-           p, cp->BadWrites, cp->BlockedWrites, cp->BadReads);
-       syslog(L_NOTICE, "%s trace address %s lastactive %ld nextlog %ld",
-           p, sprint_sockaddr((struct sockaddr *)&cp->Address),
-           (long) cp->LastActive, (long) cp->NextLog);
-       if (FD_ISSET(cp->fd, &SCHANmask))
-           syslog(L_NOTICE, "%s trace sleeping %ld 0x%p",
-               p, (long)cp->Waketime, (void *)cp->Waker);
-       if (FD_ISSET(cp->fd, &RCHANmask))
-           syslog(L_NOTICE, "%s trace reading %lu %s",
-               p, (unsigned long) cp->In.used,
-               MaxLength(cp->In.data, cp->In.data));
-       if (FD_ISSET(cp->fd, &WCHANmask))
-           syslog(L_NOTICE, "%s trace writing %lu %s",
-               p, (unsigned long) cp->Out.left,
-               MaxLength(cp->Out.data, cp->Out.data));
-    }
-}
-
-
-/*
-**  Close a channel.
-*/
-void
-CHANclose(CHANNEL *cp, const char *name)
-{
-    char       *label, *tmplabel, buff[SMBUF];
-
-    if (cp->Type == CTfree)
-       syslog(L_ERROR, "%s internal closing free channel %d", name, cp->fd);
-    else {
-       if (cp->Type == CTnntp) {
-           WIPprecomfree(cp);
-           NCclearwip(cp);
-            if (cp->State == CScancel)
-                syslog(L_NOTICE,
-               "%s closed seconds %ld cancels %ld",
-               name, (long)(Now.time - cp->Started),
-               cp->Received);
-            else {
-           snprintf(buff, sizeof(buff),
-                     "accepted size %.0f duplicate size %.0f", cp->Size,
-                     cp->DuplicateSize);
-           syslog(L_NOTICE,
-               "%s closed seconds %ld accepted %ld refused %ld rejected %ld duplicate %ld %s",
-               name, (long)(Now.time - cp->Started),
-               cp->Received, cp->Refused, cp->Rejected,
-               cp->Duplicate, buff);
-           }
-           if (cp->Data.Newsgroups.Data != NULL) {
-               free(cp->Data.Newsgroups.Data);
-               cp->Data.Newsgroups.Data = NULL;
-           }
-           if (cp->Data.Newsgroups.List != NULL) {
-               free(cp->Data.Newsgroups.List);
-               cp->Data.Newsgroups.List = NULL;
-           }
-           if (cp->Data.Distribution.Data != NULL) {
-               free(cp->Data.Distribution.Data);
-               cp->Data.Distribution.Data = NULL;
-           }
-           if (cp->Data.Distribution.List != NULL) {
-               free(cp->Data.Distribution.List);
-               cp->Data.Distribution.List = NULL;
-           }
-           if (cp->Data.Path.Data != NULL) {
-               free(cp->Data.Path.Data);
-               cp->Data.Path.Data = NULL;
-           }
-           if (cp->Data.Path.List != NULL) {
-               free(cp->Data.Path.List);
-               cp->Data.Path.List = NULL;
-           }
-           if (cp->Data.Overview.size != 0) {
-               free(cp->Data.Overview.data);
-               cp->Data.Overview.data = NULL;
-               cp->Data.Overview.size = 0;
-                cp->Data.Overview.left = 0;
-                cp->Data.Overview.used = 0;
-           }
-           if (cp->Data.XrefBufLength != 0) {
-               free(cp->Data.Xref);
-               cp->Data.Xref = NULL;
-               cp->Data.XrefBufLength = 0;
-           }
-       } else if (cp->Type == CTreject)
-           syslog(L_NOTICE, "%s %ld", name, cp->Rejected);
-       else if (cp->Out.left)
-           syslog(L_NOTICE, "%s closed lost %lu", name,
-                   (unsigned long) cp->Out.left);
-       else
-           syslog(L_NOTICE, "%s closed", name);
-       WCHANremove(cp);
-       RCHANremove(cp);
-       SCHANremove(cp);
-       if (cp->Argument != NULL)
-           /* Set to NULL below. */
-           free(cp->Argument);
-       if (cp->fd >= 0 && close(cp->fd) < 0)
-           syslog(L_ERROR, "%s cant close %s %m", LogName, name);
-       if (cp->MaxCnx > 0 && cp->Type == CTnntp) {
-           int tfd;
-           CHANNEL *tempchan;
-
-           cp->fd = -1;
-           if ((label = RClabelname(cp)) != NULL) {
-               for(tfd = 0; tfd <= CHANlastfd; tfd++) {
-                   tempchan = &CHANtable[tfd];
-                   if(tempchan->fd > 0 && tempchan->Type == CTnntp &&
-                       ((tmplabel = RClabelname(tempchan)) != NULL) &&
-                       strcmp(label, tmplabel) == 0 &&
-                       tempchan->ActiveCnx == 0) {
-                           tempchan->ActiveCnx = cp->ActiveCnx;
-                           RCHANadd(tempchan);
-                           break;
-                   }
-               }
-           }
-       }
-    }
-
-    /* Mark it unused. */
-    cp->Type = CTfree;
-    cp->State = CSerror;
-    cp->fd = -1;
-    cp->Argument = NULL;
-    cp->ActiveCnx = 0;
-
-    /* Free the buffers if they got big. */
-    if (cp->In.size > BIG_BUFFER) {
-       cp->In.size = 0;
-        cp->In.used = 0;
-        cp->In.left = 0;
-       free(cp->In.data);
-       cp->In.data = NULL;
-    }
-    if (cp->Out.size > BIG_BUFFER) {
-       cp->Out.size = 0;
-        cp->Out.used = 0;
-        cp->Out.left = 0;
-       free(cp->Out.data);
-       cp->Out.data = NULL;
-    }
-    if (cp->Sendid.size > 0) {
-       cp->Sendid.size = 0;
-       cp->Sendid.used = 0;
-       cp->Sendid.left = 0;
-       free(cp->Sendid.data);
-        cp->Sendid.data = NULL;
-    }
-}
-
-
-/*
-**  Return a printable name for the channel.
-*/
-char *
-CHANname(const CHANNEL *cp)
-{
-    static char                buff[SMBUF];
-    int                        i;
-    SITE *             sp;
-    const char *       p;
-    pid_t              pid;
-
-    switch (cp->Type) {
-    default:
-       snprintf(buff, sizeof(buff), "?%d(#%d@%ld)?", cp->Type, cp->fd,
-                 (long) (cp - CHANtable));
-       break;
-    case CTany:
-       snprintf(buff, sizeof(buff), "any:%d", cp->fd);
-       break;
-    case CTfree:
-       snprintf(buff, sizeof(buff), "free:%d", cp->fd);
-       break;
-    case CTremconn:
-       snprintf(buff, sizeof(buff), "remconn:%d", cp->fd);
-       break;
-    case CTreject:
-       snprintf(buff, sizeof(buff), "%s rejected", RChostname(cp));
-       break;
-    case CTnntp:
-       snprintf(buff, sizeof(buff), "%s:%d",
-                 cp->Address.ss_family == 0 ? "localhost" : RChostname(cp),
-                 cp->fd);
-       break;
-    case CTlocalconn:
-       snprintf(buff, sizeof(buff), "localconn:%d", cp->fd);
-       break;
-    case CTcontrol:
-       snprintf(buff, sizeof(buff), "control:%d", cp->fd);
-       break;
-    case CTexploder:
-    case CTfile:
-    case CTprocess:
-       /* Find the site that has this channel. */
-       for (p = "?", i = nSites, sp = Sites, pid = 0; --i >= 0; sp++)
-           if (sp->Channel == cp) {
-               p = sp->Name;
-               if (cp->Type != CTfile)
-                   pid = sp->pid;
-               break;
-           }
-       if (pid == 0)
-           snprintf(buff, sizeof(buff), "%s:%d:%s",
-                     MaxLength(p, p), cp->fd,
-                     cp->Type == CTfile ? "file" : "proc");
-       else
-           snprintf(buff, sizeof(buff), "%s:%d:%s:%ld",
-                     MaxLength(p, p), cp->fd,
-                     cp->Type == CTfile ? "file" : "proc", (long)pid);
-       break;
-    }
-    return buff;
-}
-
-
-/*
-**  Return the channel for a specified descriptor.
-*/
-CHANNEL *
-CHANfromdescriptor(int fd)
-{
-    if (fd <0 || fd > CHANtablesize)
-       return NULL;
-    return &CHANtable[fd];
-}
-
-
-/*
-**  Iterate over all channels of a specified type.
-*/
-CHANNEL *
-CHANiter(int *ip, CHANNELTYPE Type)
-{
-    CHANNEL            *cp;
-    int                        i;
-
-    if ((i = *ip) >= 0 && i < CHANtablesize) {
-       do {
-           cp = &CHANtable[i];
-           if (cp->Type == CTfree && cp->fd == -1)
-               continue;
-           if (Type == CTany || cp->Type == Type) {
-               *ip = ++i;
-               return cp;
-           }
-       } while (++i < CHANtablesize);
-    }
-    return NULL;
-}
-
-
-/*
-**  Mark a channel as an active reader.
-*/
-void
-RCHANadd(CHANNEL *cp)
-{
-    FD_SET(cp->fd, &RCHANmask);
-    if (cp->fd > CHANlastfd)
-       CHANlastfd = cp->fd;
-
-    if (cp->Type != CTnntp)
-       /* Start reading at the beginning of the buffer. */
-       cp->In.used = 0;
-}
-
-
-/*
-**  Remove a channel from the set of readers.
-*/
-void
-RCHANremove(CHANNEL *cp)
-{
-    if (FD_ISSET(cp->fd, &RCHANmask)) {
-       FD_CLR(cp->fd, &RCHANmask);
-       if (cp->fd == CHANlastfd) {
-           /* This was the highest descriptor, get a new highest. */
-           while (!FD_ISSET(CHANlastfd, &RCHANmask)
-             && !FD_ISSET(CHANlastfd, &WCHANmask)
-             && CHANlastfd > 1)
-               CHANlastfd--;
-       }
-    }
-}
-
-
-/*
-**  Put a channel to sleep, call a function when it wakes.
-**  Note that the Argument must be NULL or allocated memory!
-*/
-void
-SCHANadd(CHANNEL *cp, time_t Waketime, void *Event, innd_callback_t Waker,
-         void *Argument)
-{
-    if (!FD_ISSET(cp->fd, &SCHANmask)) {
-       SCHANcount++;
-       FD_SET(cp->fd, &SCHANmask);
-    }
-    if (cp->fd > CHANlastsleepfd)
-       CHANlastsleepfd = cp->fd;
-    cp->Waketime = Waketime;
-    cp->Waker = Waker;
-    if (cp->Argument != Argument) {
-       free(cp->Argument);
-       cp->Argument = Argument;
-    }
-    cp->Event = Event;
-}
-
-
-/*
-**  Take a channel off the sleep list.
-*/
-void
-SCHANremove(CHANNEL *cp)
-{
-    if (FD_ISSET(cp->fd, &SCHANmask)) {
-       FD_CLR(cp->fd, &SCHANmask);
-       SCHANcount--;
-       cp->Waketime = 0;
-       if (cp->fd == CHANlastsleepfd) {
-           /* This was the highest descriptor, get a new highest. */
-           while (!FD_ISSET(CHANlastsleepfd, &SCHANmask)
-             && CHANlastsleepfd > 1)
-               CHANlastsleepfd--;
-       }
-    }
-}
-
-
-/*
-**  Is a channel on the sleep list?
-*/
-bool
-CHANsleeping(CHANNEL *cp)
-{
-    return FD_ISSET(cp->fd, &SCHANmask);
-}
-
-
-/*
-**  Wake up channels waiting for a specific event.
-*/
-void
-SCHANwakeup(void *Event)
-{
-    CHANNEL            *cp;
-    int                        i;
-
-    for (cp = CHANtable, i = CHANtablesize; --i >= 0; cp++)
-       if (cp->Type != CTfree && cp->Event == Event && CHANsleeping(cp))
-           cp->Waketime = 0;
-}
-
-
-/*
-**  Mark a channel as an active writer.  Don't reset the Out->left field
-**  since we could have buffered I/O already in there.
-*/
-void
-WCHANadd(CHANNEL *cp)
-{
-    if (cp->Out.left > 0) {
-       FD_SET(cp->fd, &WCHANmask);
-       if (cp->fd > CHANlastfd)
-           CHANlastfd = cp->fd;
-    }
-}
-
-
-/*
-**  Remove a channel from the set of writers.
-*/
-void
-WCHANremove(CHANNEL *cp)
-{
-    if (FD_ISSET(cp->fd, &WCHANmask)) {
-       FD_CLR(cp->fd, &WCHANmask);
-       if (cp->Out.left <= 0) {
-           /* No data left -- reset used so we don't grow the buffer. */
-           cp->Out.used = 0;
-           cp->Out.left = 0;
-       }
-       if (cp->fd == CHANlastfd) {
-           /* This was the highest descriptor, get a new highest. */
-           while (!FD_ISSET(CHANlastfd, &RCHANmask)
-             && !FD_ISSET(CHANlastfd, &WCHANmask)
-             && CHANlastfd > 1)
-               CHANlastfd--;
-       }
-    }
-}
-
-
-/*
-**  Set a channel to start off with the contents of an existing channel.
-*/
-void
-WCHANsetfrombuffer(CHANNEL *cp, struct buffer *bp)
-{
-    WCHANset(cp, &bp->data[bp->used], bp->left);
-}
-
-\f
-
-/*
-**  Read in text data, return the amount we read.
-*/
-int
-CHANreadtext(CHANNEL *cp)
-{
-    ptrdiff_t           i, j;
-    struct buffer       *bp;
-    char               *p;
-    int                        oerrno;
-    int                        maxbyte;
-    HDRCONTENT         *hc = cp->Data.HdrContent;
-
-    /* Grow buffer if we're getting close to current limit.  FIXME: The In
-       buffer doesn't use the normal meanings of .used and .left.  */
-    bp = &cp->In;
-    bp->left = bp->size - bp->used;
-    if (bp->left <= LOW_WATER) {
-       i = GROW_AMOUNT(bp->size);
-       bp->size += i;
-       bp->left += i;
-       p = bp->data;
-       TMRstart(TMR_DATAMOVE);
-        bp->data = xrealloc(bp->data, bp->size);
-
-       /* Adjust offets of realloc moved the location of the memory region.
-           FIXME: This is invalid C, although it will work on most (all?)
-           common systems.  The pointers need to be reduced to offets and then
-           turned back into relative pointers rather than adjusting the
-           pointers directly, since as soon as realloc is called, pointers
-           into the old space become invalid and may not be used further. */
-       if ((i = p - bp->data) != 0) {
-           if (cp->State == CSgetheader || cp->State == CSgetbody ||
-               cp->State == CSeatarticle) {
-               /* adjust offset only in CSgetheader, CSgetbody or
-                  CSeatarticle */
-               if (cp->Data.BytesHeader != NULL)
-                 cp->Data.BytesHeader -= i;
-               for (j = 0 ; j < MAX_ARTHEADER ; j++, hc++) {
-                   if (hc->Value != NULL)
-                       hc->Value -= i;
-               }
-           }
-       }
-       TMRstop(TMR_DATAMOVE);
-    }
-
-    /* Read in whatever is there, up to some reasonable limit.
-
-       We want to limit the amount of time devoted to processing the incoming
-       data for any given channel.  There's no easy way of doing that, though,
-       so we restrict the data size instead.
-
-       If the data is part of a single large article, then reading and
-       processing many kilobytes at a time costs very little.  If the data is
-       a long list of CHECK commands from a streaming feed, then every line of
-       data will require a history lookup, and we probably don't want to do
-       more than about 10 of those per channel on each cycle of the main
-       select() loop (otherwise we might take too long before giving other
-       channels a turn).  10 lines of CHECK commands suggests a limit of about
-       1KB of data, or less.  innconf->maxcmdreadsize (BUFSIZ by default) is
-       often about 1KB, and is attractive for other reasons, so let's use that
-       as our size limit.  If innconf->maxcmdreadsize is 0, there is no limit.
-
-       Reduce the read size only if we're reading commands.
-
-       FIXME: A better approach would be to limit the number of commands we
-       process for each channel. */
-    if (innconf->maxcmdreadsize <= 0 || cp->State != CSgetcmd
-        || bp->left < innconf->maxcmdreadsize)
-        maxbyte = bp->left;
-    else
-        maxbyte = innconf->maxcmdreadsize;
-    TMRstart(TMR_NNTPREAD);
-    i = read(cp->fd, &bp->data[bp->used], maxbyte);
-    TMRstop(TMR_NNTPREAD);
-    if (i < 0) {
-        /* Solaris (at least 2.4 through 2.6) will occasionally return
-           EAGAIN in response to a read even if the file descriptor already
-           selected true for reading, apparently due to some internal
-           resource exhaustion.  In that case, return -2, which will drop
-           back out to the main loop and go on to the next file descriptor,
-           as if the descriptor never selected true.  This check will
-           probably never trigger on platforms other than Solaris. */
-        if (errno == EAGAIN)
-            return -2;
-       oerrno = errno;
-       p = CHANname(cp);
-       errno = oerrno;
-       sysnotice("%s cant read", p);
-       return -1;
-    }
-    if (i == 0) {
-       p = CHANname(cp);
-       notice("%s readclose", p);
-       return 0;
-    }
-
-    bp->used += i;
-    bp->left -= i;
-    return i;
-}
-
-
-/*
-**  If I/O backs up a lot, we can get EMSGSIZE on some systems.  If that
-**  happens we want to do the I/O in chunks.  We assume stdio's BUFSIZ is
-**  a good chunk value.
-*/
-static int
-CHANwrite(int fd, char *p, long length)
-{
-    int        i;
-    char       *save;
-
-    do {
-       /* Try the standard case -- write it all. */
-       i = write(fd, p, length);
-       if (i > 0 || (i < 0 && errno != EMSGSIZE && errno != EINTR))
-           return i;
-    } while (i < 0 && errno == EINTR);
-
-    /* Write it in pieces. */
-    for (save = p, i = 0; length; p += i, length -= i) {
-       i = write(fd, p, (length > BUFSIZ ? BUFSIZ : length));
-       if (i <= 0)
-           break;
-    }
-
-    /* Return error, or partial results if we got something. */
-    return p == save ? i : p - save;
-}
-
-
-/*
-**  Try to flush out the buffer.  Use this only on file channels!
-*/
-bool
-WCHANflush(CHANNEL *cp)
-{
-    struct buffer       *bp;
-    int                        i;
-
-    /* Write it. */
-    for (bp = &cp->Out; bp->left > 0; bp->left -= i, bp->used += i) {
-       i = CHANwrite(cp->fd, &bp->data[bp->used], bp->left);
-       if (i < 0) {
-           syslog(L_ERROR, "%s cant flush count %lu %m",
-               CHANname(cp), (unsigned long) bp->left);
-           return false;
-       }
-       if (i == 0) {
-           syslog(L_ERROR, "%s cant flush count %lu",
-               CHANname(cp), (unsigned long) bp->left);
-           return false;
-       }
-    }
-    WCHANremove(cp);
-    return true;
-}
-
-\f
-
-/*
-**  Wakeup routine called after a write channel was put to sleep.
-*/
-static void
-CHANwakeup(CHANNEL *cp)
-{
-    syslog(L_NOTICE, "%s wakeup", CHANname(cp));
-    WCHANadd(cp);
-}
-
-
-/*
-**  Attempting to write would block; stop output or give up.
-*/
-static void
-CHANwritesleep(CHANNEL *cp, char *p)
-{
-    int                        i;
-
-    if ((i = ++(cp->BlockedWrites)) > innconf->badiocount)
-       switch (cp->Type) {
-       default:
-           break;
-       case CTreject:
-       case CTnntp:
-       case CTfile:
-       case CTexploder:
-       case CTprocess:
-           syslog(L_ERROR, "%s blocked closing", p);
-           SITEchanclose(cp);
-           CHANclose(cp, p);
-           return;
-       }
-    i *= innconf->blockbackoff;
-    syslog(L_ERROR, "%s blocked sleeping %d", p, i);
-    SCHANadd(cp, Now.time + i, NULL, CHANwakeup, NULL);
-}
-
-
-#if    defined(INND_FIND_BAD_FDS)
-/*
-**  We got an unknown error in select.  Find out the culprit.
-**  Not really ready for production use yet, and it's expensive, too.
-*/
-static void
-CHANdiagnose(void)
-{
-    fd_set             Test;
-    int                        i;
-    struct timeval     t;
-
-    FD_ZERO(&Test);
-    for (i = CHANlastfd; i >= 0; i--) {
-       if (FD_ISSET(i, &RCHANmask)) {
-           FD_SET(i, &Test);
-           t.tv_sec = 0;
-           t.tv_usec = 0;
-           if (select(i + 1, &Test, NULL, NULL, &t) < 0
-             && errno != EINTR) {
-               syslog(L_ERROR, "%s Bad Read File %d", LogName, i);
-               FD_CLR(i, &RCHANmask);
-               /* Probably do something about the file descriptor here; call
-                * CHANclose on it? */
-           }
-           FD_CLR(i, &Test);
-       }
-       if (FD_ISSET(i, &WCHANmask)) {
-           FD_SET(i, &Test);
-           t.tv_sec = 0;
-           t.tv_usec = 0;
-           if (select(i + 1, NULL, &Test, NULL, &t) < 0
-            && errno != EINTR) {
-               syslog(L_ERROR, "%s Bad Write File %d", LogName, i);
-               FD_CLR(i, &WCHANmask);
-               /* Probably do something about the file descriptor here; call
-                * CHANclose on it? */
-           }
-           FD_CLR(i, &Test);
-       }
-    }
-}
-#endif /* defined(INND_FIND_BAD_FDS) */
-
-void
-CHANsetActiveCnx(CHANNEL *cp) {
-    int                found;  
-    CHANNEL    *tempchan;
-    char       *label, *tmplabel;
-    int                tfd;
-    
-    if((cp->fd > 0) && (cp->Type == CTnntp) && (cp->ActiveCnx == 0)) {
-       found = 1;      
-       if ((label = RClabelname(cp)) != NULL) {
-           for(tfd = 0; tfd <= CHANlastfd; tfd++) {
-               tempchan = &CHANtable[tfd];
-               if ((tmplabel = RClabelname(tempchan)) == NULL) {
-                   continue;
-               }
-               if(strcmp(label, tmplabel) == 0) {
-                   if(tempchan->ActiveCnx != 0)
-                       found++;
-               }
-           }
-       } 
-       cp->ActiveCnx = found;
-    }   
-}
-
-/*
-**  Main I/O loop.  Wait for data, call the channel's handler when there is
-**  something to read or when the queued write is finished.  In order to
-**  be fair (i.e., don't always give descriptor n priority over n+1), we
-**  remember where we last had something and pick up from there.
-**
-**  Yes, the main code has really wandered over to the side a lot.
-*/
-void
-CHANreadloop(void)
-{
-    static char                EXITING[] = "INND exiting because of signal\n";
-    static int         fd;
-    ptrdiff_t          i, j;
-    int                        startpoint;
-    int                        count;
-    int                        lastfd;
-    int                        oerrno;
-    CHANNEL            *cp;
-    struct buffer      *bp;
-    fd_set             MyRead;
-    fd_set             MyWrite;
-    struct timeval     MyTime;
-    long               silence;
-    char               *p;
-    time_t             LastUpdate;
-    HDRCONTENT         *hc;
-
-    STATUSinit();
-    
-    LastUpdate = GetTimeInfo(&Now) < 0 ? 0 : Now.time;
-    for ( ; ; ) {
-       /* See if any processes died. */
-       PROCscan();
-
-       /* Wait for data, note the time. */
-       MyRead = RCHANmask;
-       MyWrite = WCHANmask;
-       MyTime = TimeOut;
-       if (innconf->timer) {
-           unsigned long now = TMRnow();
-
-           if (now >= 1000 * (unsigned long)(innconf->timer)) {
-               TMRsummary("ME", timer_name);
-               InndHisLogStats();
-               MyTime.tv_sec = innconf->timer;
-           }
-           else {
-               MyTime.tv_sec = innconf->timer - now / 1000;
-           }
-       }
-       TMRstart(TMR_IDLE);
-       count = select(CHANlastfd + 1, &MyRead, &MyWrite, NULL, &MyTime);
-       TMRstop(TMR_IDLE);
-
-       STATUSmainloophook();
-       if (GotTerminate) {
-           write(2, EXITING, strlen(EXITING));
-           CleanupAndExit(0, (char *)NULL);
-       }
-       if (count < 0) {
-           if (errno != EINTR) {
-               syslog(L_ERROR, "%s cant select %m", LogName);
-#if    defined(INND_FIND_BAD_FDS)
-               CHANdiagnose();
-#endif /* defined(INND_FIND_BAD_FDS) */
-           }
-           continue;
-       }
-
-       /* Update the "reasonably accurate" time. */
-       if (GetTimeInfo(&Now) < 0)
-           syslog(L_ERROR, "%s cant gettimeinfo %m", LogName);
-       if (Now.time > LastUpdate + TimeOut.tv_sec) {
-           HISsync(History);
-           if (ICDactivedirty) {
-               ICDwriteactive();
-               ICDactivedirty = 0;
-           }
-            LastUpdate = Now.time;
-       }
-
-       if (count == 0) {
-           /* No channels active, so flush and skip if nobody's
-            * sleeping. */
-           if (Mode == OMrunning)
-               ICDwrite();
-           if (SCHANcount == 0)
-               continue;
-       }
-
-       /* Try the control channel first. */
-       if (FD_ISSET(CHANccfd, &RCHANmask) && FD_ISSET(CHANccfd, &MyRead)) {
-           count--;
-           if (count > 3)
-               count = 3; /* might be more requests */
-           (*CHANcc->Reader)(CHANcc);
-           FD_CLR(CHANccfd, &MyRead);
-       }
-
-#ifdef PRIORITISE_REMCONN
-       /* Try the remconn channel next. */
-       for (j = 0 ; (j < chanlimit) && (CHANrcfd[j] >= 0) ; j++) {
-           if (FD_ISSET(CHANrcfd[j], &RCHANmask) && FD_ISSET(CHANrcfd[j], &MyRead)) {
-               count--;
-               if (count > 3)
-                   count = 3; /* might be more requests */
-               (*CHANrc[j]->Reader)(CHANrc[j]);
-               FD_CLR(CHANrcfd[j], &MyRead);
-           }
-       }
-#endif /* PRIORITISE_REMCONN */
-
-       /* Loop through all active channels.  Somebody could have closed
-        * closed a channel so we double-check the global mask before
-        * looking at what select returned.  The code here is written so
-        * that a channel could be reading and writing and sleeping at the
-        * same time, even though that's not possible.  (Just as well,
-        * since in SysVr4 the count would be wrong.) */
-       lastfd = CHANlastfd;
-       if (lastfd < CHANlastsleepfd)
-           lastfd = CHANlastsleepfd;
-       if (fd > lastfd)
-           fd = 0;
-       startpoint = fd;
-       do {
-           cp = &CHANtable[fd];
-
-            if (cp->MaxCnx > 0 && cp->HoldTime > 0) {
-               CHANsetActiveCnx(cp);
-                if((cp->ActiveCnx > cp->MaxCnx) && (cp->fd > 0)) {
-                   if(cp->Started + cp->HoldTime < Now.time) {
-                        CHANclose(cp, CHANname(cp));
-                    } else {
-                        if (fd >= lastfd)
-                            fd = 0;
-                        else
-                            fd++;
-                       cp->ActiveCnx = 0;
-                       RCHANremove(cp);
-                    }
-                    continue;
-                }
-            }
-           
-           /* Anything to read? */
-           if (FD_ISSET(fd, &RCHANmask) && FD_ISSET(fd, &MyRead)) {
-               count--;
-               if (cp->Type == CTfree) {
-                   syslog(L_ERROR, "%s %d free but was in RMASK",
-                       CHANname(cp), fd);
-                   /* Don't call RCHANremove since cp->fd will be -1. */
-                   FD_CLR(fd, &RCHANmask);
-                   close(fd);
-               }
-               else {
-                   cp->LastActive = Now.time;
-                   (*cp->Reader)(cp);
-               }
-           }
-
-           /* Check and see if the buffer is grossly overallocated and shrink
-              if needed */
-           if (cp->In.size > (BIG_BUFFER)) {
-               if (cp->In.used != 0) {
-                   if ((cp->In.size / cp->In.used) > 10) {
-                       cp->In.size = (cp->In.used * 2) > START_BUFF_SIZE ? (cp->In.used * 2) : START_BUFF_SIZE;
-                       p = cp->In.data;
-                       TMRstart(TMR_DATAMOVE);
-                        cp->In.data = xrealloc(cp->In.data, cp->In.size);
-                       cp->In.left = cp->In.size - cp->In.used;
-                       /* do not move data, since xrealloc did it already */
-                       if ((i = p - cp->In.data) != 0) {
-                           if (cp->State == CSgetheader ||
-                               cp->State == CSgetbody ||
-                               cp->State == CSeatarticle) {
-                               /* adjust offset only in CSgetheader, CSgetbody
-                                  or CSeatarticle */
-                               if (cp->Data.BytesHeader != NULL)
-                                 cp->Data.BytesHeader -= i;
-                               hc = cp->Data.HdrContent;
-                               for (j = 0 ; j < MAX_ARTHEADER ; j++, hc++) {
-                                   if (hc->Value != NULL)
-                                       hc->Value -= i;
-                               }
-                           }
-                       }
-                       TMRstop(TMR_DATAMOVE);
-                   }
-               } else {
-                   p = cp->In.data;
-                   TMRstart(TMR_DATAMOVE);
-                    cp->In.data = xrealloc(cp->In.data, START_BUFF_SIZE);
-                   cp->In.size = cp->In.left = START_BUFF_SIZE;
-                   if ((i = p - cp->In.data) != 0) {
-                       if (cp->State == CSgetheader ||
-                           cp->State == CSgetbody ||
-                           cp->State == CSeatarticle) {
-                           /* adjust offset only in CSgetheader, CSgetbody
-                              or CSeatarticle */
-                           if (cp->Data.BytesHeader != NULL)
-                             cp->Data.BytesHeader -= i;
-                           hc = cp->Data.HdrContent;
-                           for (j = 0 ; j < MAX_ARTHEADER ; j++, hc++) {
-                               if (hc->Value != NULL)
-                                   hc->Value -= i;
-                           }
-                       }
-                   }
-                   TMRstop(TMR_DATAMOVE);
-               }
-           }
-           /* Possibly recheck for dead children so we don't get SIGPIPE
-            * on readerless channels. */
-           if (PROCneedscan)
-               PROCscan();
-
-           /* Ready to write? */
-           if (FD_ISSET(fd, &WCHANmask) && FD_ISSET(fd, &MyWrite)) {
-               count--;
-               if (cp->Type == CTfree) {
-                   syslog(L_ERROR, "%s %d free but was in WMASK",
-                       CHANname(cp), fd);
-                   /* Don't call WCHANremove since cp->fd will be -1. */
-                   FD_CLR(fd, &WCHANmask);
-                   close(fd);
-               }
-               else {
-                   bp = &cp->Out;
-                   if (bp->left) {
-                       cp->LastActive = Now.time;
-                       i = CHANwrite(fd, &bp->data[bp->used], bp->left);
-                       if (i <= 0) {
-                           oerrno = errno;
-                           p = CHANname(cp);
-                           errno = oerrno;
-                           if (i < 0)
-                               sysnotice("%s cant write", p);
-                           else
-                               notice("%s cant write", p);
-                           cp->BadWrites++;
-                           if (i < 0 && oerrno == EPIPE) {
-                               SITEchanclose(cp);
-                               CHANclose(cp, p);
-                           }
-                           else if (i < 0 &&
-                                     (oerrno == EWOULDBLOCK
-                                      || oerrno == EAGAIN)) {
-                               WCHANremove(cp);
-                               CHANwritesleep(cp, p);
-                           }
-                           else if (cp->BadWrites >= innconf->badiocount) {
-                               syslog(L_ERROR, "%s sleeping", p);
-                               WCHANremove(cp);
-                               SCHANadd(cp,
-                                         Now.time + innconf->pauseretrytime,
-                                         NULL, CHANwakeup, NULL);
-                           }
-                       }
-                       else {
-                           cp->BadWrites = 0;
-                           cp->BlockedWrites = 0;
-                           bp->left -= i;
-                           bp->used += i;
-                           if (bp->left <= 0) {
-                               WCHANremove(cp);
-                               (*cp->WriteDone)(cp);
-                           } else if (bp->used > (bp->size/COMP_THRESHOLD)) {
-                                /* compact the buffer, shoving the
-                                   data back to the beginning.
-                                   <rmtodd@mailhost.ecn.ou.edu> */
-                                buffer_set(bp, &bp->data[bp->used], bp->left);
-                           }
-                       }
-                   }
-                   else
-                       /* Should not be possible. */
-                       WCHANremove(cp);
-               }
-           }
-
-           /* Coming off a sleep? */
-           if (FD_ISSET(fd, &SCHANmask) && cp->Waketime <= Now.time) {
-               if (cp->Type == CTfree) {
-                   syslog(L_ERROR,"%s ERROR s-select free %d",CHANname(cp),fd);
-                   FD_CLR(fd, &SCHANmask);
-                    close(fd);
-               } else {
-                   cp->LastActive = Now.time;
-                   SCHANremove(cp);
-                   (*cp->Waker)(cp);
-               }
-           }
-
-           /* Toss CTreject channel early if it's inactive. */
-           if (cp->Type == CTreject
-            && cp->LastActive + REJECT_TIMEOUT < Now.time) {
-               p = CHANname(cp);
-               syslog(L_NOTICE, "%s timeout reject", p);
-               CHANclose(cp, p);
-           }
-
-           /* Has this channel been inactive very long? */
-           if (cp->Type == CTnntp
-            && cp->LastActive + cp->NextLog < Now.time) {
-               p = CHANname(cp);
-               silence = Now.time - cp->LastActive;
-               cp->NextLog += innconf->chaninacttime;
-               syslog(L_NOTICE, "%s inactive %ld", p, silence / 60L);
-               if (silence > innconf->peertimeout) {
-                   syslog(L_NOTICE, "%s timeout", p);
-                   CHANclose(cp, p);
-               }
-           }
-
-           /* Bump pointer, modulo the table size. */
-           if (fd >= lastfd)
-               fd = 0;
-           else
-               fd++;
-
-           /* If there is nothing to do, break out. */
-           if (count == 0 && SCHANcount == 0)
-               break;
-
-       } while (fd != startpoint);
-    }
-}
diff --git a/innd/icd.c b/innd/icd.c
deleted file mode 100644 (file)
index 4066197..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/*  $Id: icd.c 6156 2003-01-19 20:58:05Z rra $
-**
-**  Routines to read and write the active file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <sys/uio.h>
-
-#include "inn/innconf.h"
-#include "innd.h"
-#include "ov.h"
-
-/* If we fork and exec under Cygwin, children hold onto the mmap */
-/* of active, and Windows won't let us resize or replace it.     */
-#ifdef __CYGWIN__
-# undef HAVE_MMAP
-#endif
-
-static char            *ICDactpath = NULL;
-static char            *ICDactpointer;
-static int             ICDactfd;
-static int             ICDactsize;
-
-
-/*
-**  Set and unset (or copy) IOVEC elements.  We make copies to
-**  avoid problems with mmap.
-*/
-#ifdef HAVE_MMAP
-static void
-ICDiovset(struct iovec *iovp, char *base, int len)
-{
-    iovp->iov_len = len; 
-    iovp->iov_base = xmalloc(iovp->iov_len); 
-    memcpy(iovp->iov_base, base, iovp->iov_len);
-}
-#define ICDiovrelease(iovp)            free((iovp)->iov_base)
-
-#else /* !HAVE_MMAP */
-
-#define ICDiovset(iovp, base, len)     \
-       (iovp)->iov_base = base, (iovp)->iov_len = len
-#define ICDiovrelease(iovp)            /* NULL */
-
-#endif /* HAVE_MMAP */
-
-
-/*
-**  Close the active file, releasing its resources.
-*/
-static void
-ICDcloseactive(void)
-{
-    if (ICDactpointer) {
-#ifdef HAVE_MMAP
-       if (munmap(ICDactpointer, ICDactsize) < 0)
-           syslog(L_ERROR, "%s cant munmap %s %m", LogName, ICDactpath);
-#else
-       free(ICDactpointer);
-#endif
-       ICDactpointer = NULL;
-       if (close(ICDactfd) < 0) {
-           syslog(L_FATAL, "%s cant close %s %m", LogName, ICDactpath);
-           exit(1);
-       }
-    }
-}
-
-
-/*
-**  Set up the hash and in-core tables.
-*/
-void
-ICDsetup(StartSites)
-    bool       StartSites;
-{
-    if (ICDneedsetup == true) {
-       ICDneedsetup = false;
-    }
-    else {
-       ICDcloseactive();
-       NGparsefile();
-    }
-    if (NGfind("control") == NULL || NGfind("junk") == NULL) {
-       syslog(L_FATAL, "%s internal no control and/or junk group", LogName);
-       exit(1);
-    }
-    if (NGfind("control.cancel") == NULL) {
-       syslog(L_FATAL, "%s internal no control.cancel group", LogName);
-       exit(1);
-    }
-    if (innconf->mergetogroups && NGfind("to") == NULL) {
-       syslog(L_FATAL, "%s internal no to group", LogName);
-       exit(1);
-    }
-    SITEparsefile(StartSites);
-}
-
-
-/*
-**  Write out all in-core data.
-*/
-void
-ICDwrite(void)
-{
-    HISsync(History);
-    SMflushcacheddata(SM_ALL);
-
-    if (ICDactivedirty) {
-       ICDwriteactive();
-       ICDactivedirty = 0;
-    }
-
-    /* Flush log and error log. */
-    if (fflush(Log) == EOF)
-       syslog(L_ERROR, "%s cant fflush log %m", LogName);
-    if (fflush(Errlog) == EOF)
-       syslog(L_ERROR, "%s cant fflush errlog %m", LogName);
-}
-
-
-/*
-**  Close things down.
-*/
-void
-ICDclose(void)
-{
-    ICDwrite();
-    ICDcloseactive();
-}
-
-
-/*
-**  Scan the active file, and renumber the min/max counts.
-*/
-bool
-ICDrenumberactive(void)
-{
-    int        i;
-    NEWSGROUP  *ngp;
-
-    for (i = nGroups, ngp = Groups; --i >= 0; ngp++)
-       if (!NGrenumber(ngp))
-           return false;
-    if (i < 0)
-       ICDwrite();
-    return true;
-}
-
-
-/*
-**  Use writev() to replace the active file.
-*/
-static bool
-ICDwritevactive(struct iovec *vp, int vpcount)
-{
-    static char                *BACKUP = NULL;
-    static char         *NEWACT = NULL;
-    static char                WHEN[] = "backup active";
-    int                        fd;
-    int                        oerrno;
-#ifdef __CYGWIN__
-    size_t             newactsize, padactsize, wrote;
-    struct iovec       *newvp;
-    char               *filler;
-    int                        i;
-#endif
-
-    if (BACKUP == NULL)
-       BACKUP = concatpath(innconf->pathdb, _PATH_OLDACTIVE);
-    if (NEWACT == NULL)
-       NEWACT = concatpath(innconf->pathdb, _PATH_NEWACTIVE);
-    /* Write the current file to a backup. */
-    if (unlink(BACKUP) < 0 && errno != ENOENT) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant unlink %s %m", LogName, BACKUP);
-       IOError(WHEN, oerrno);
-    }
-    if ((fd = open(BACKUP, O_WRONLY | O_TRUNC | O_CREAT, 0664)) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant open %s %m", LogName, BACKUP);
-       IOError(WHEN, oerrno);
-    }
-    else if (xwrite(fd, ICDactpointer, ICDactsize) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant write %s %m", LogName, BACKUP);
-       IOError(WHEN, oerrno);
-       close(fd);
-    }
-    else if (close(fd) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant close %s %m", LogName, BACKUP);
-       IOError(WHEN, oerrno);
-    }
-
-#ifdef __CYGWIN__
-    /* If we are shrinking active, junk will be at the end between the */
-    /* writev and ftruncate.  Clobber it with values that overview and */
-    /* nnrpd can ignore. */
-    for (newactsize = 0, i = 0; i < vpcount; i++)
-        newactsize += vp[i].iov_len;
-    if (newactsize < ICDactsize) {
-        padactsize = ICDactsize - newactsize;
-        newvp = xmalloc((vpcount + 1) * sizeof(struct iovec));
-        for (i = 0; i < vpcount; i++)
-             newvp[i] = vp[i];
-        filler = xcalloc(padactsize, 1);
-        *filler = '.';
-        filler[padactsize - 1] = '\n';
-        newvp[vpcount].iov_base = filler;
-        newvp[vpcount].iov_len = padactsize;
-        vpcount++;
-    }
-    else {
-        padactsize = 0;
-        newvp = vp;
-    }
-    oerrno = 0;
-    if (lseek(ICDactfd, 0, SEEK_SET) == -1) {
-        oerrno = errno;
-       syslog(L_ERROR, "%s cant rewind %s %m", LogName, ICDactpath);
-       IOError(WHEN, oerrno);
-       goto bailout;
-    }
-    if (xwritev(ICDactfd, newvp, vpcount) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant write %s %m", LogName, ICDactpath);
-       IOError(WHEN, oerrno);
-       goto bailout;
-    }
-    if (newactsize < ICDactsize && ftruncate(ICDactfd, newactsize) != 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant truncate %s", LogName, ICDactpath);
-    }
-
-bailout:
-    if (padactsize != 0) {
-        free(filler);
-        free(newvp);
-    }
-    if (oerrno != 0)
-        return false;
-
-#else /* !__CYGWIN__, do it the Unix way. */
-
-    /* Open the active file. */
-    fd = open(NEWACT, O_WRONLY | O_TRUNC | O_CREAT, ARTFILE_MODE);
-    if (fd < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant open %s %m", LogName, NEWACT);
-       IOError(WHEN, oerrno);
-       return false;
-    }
-
-    /* Write it. */
-    if (xwritev(fd, vp, vpcount) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant write %s %m", LogName, NEWACT);
-       IOError(WHEN, oerrno);
-       close(fd);
-       return false;
-    }
-
-    /* Close it. */
-    close(fd);
-
-    /* Rename it to be the canonical active file */
-    if (rename(NEWACT, ICDactpath) < 0) {
-       oerrno = errno;
-       syslog(L_ERROR, "%s cant rename %s to %s %m",
-              LogName, NEWACT, ICDactpath);
-       IOError(WHEN, oerrno);
-       return false;
-    }
-
-#endif /* __CYGWIN__ */
-
-    /* Invalidate in-core pointers. */
-    ICDcloseactive();
-
-    /* Restore in-core pointers. */
-    if (Mode != OMrunning) {
-       ICDneedsetup = true;
-       /* Force the active file into memory. */
-       NGparsefile();
-    }
-    else
-       ICDsetup(true);
-    return true;
-}
-
-
-/*
-**  Change the flag on a newsgroup.  Fairly easy.
-*/
-bool
-ICDchangegroup(NEWSGROUP *ngp, char *Rest)
-{
-    static char                NEWLINE[] = "\n";
-    int                 i;
-    struct iovec       iov[3];
-    bool               ret;
-    char               *Name;
-    long               Last;
-
-    /* Set up the scatter/gather vectors. */
-    ICDiovset(&iov[0], ICDactpointer, ngp->Rest - ICDactpointer);
-    ICDiovset(&iov[1], Rest, strlen(Rest));
-    Name = xstrdup(ngp->Name);
-    Last = ngp->Last;
-    if (++ngp < &Groups[nGroups]) {
-       /* Not the last group, keep the \n from the next line. */
-       i = ngp->Start;
-       ICDiovset(&iov[2], &ICDactpointer[i - 1], ICDactsize - i + 1);
-    }
-    else {
-       /* Last group -- append a newline. */
-       ICDiovset(&iov[2], NEWLINE, strlen(NEWLINE));
-    }
-    ret = ICDwritevactive(iov, 3);
-    ICDiovrelease(&iov[0]);
-    ICDiovrelease(&iov[1]);
-    ICDiovrelease(&iov[2]);
-
-    if (ret) {
-       if (innconf->enableoverview && !OVgroupadd(Name, 0, Last, Rest)) {
-           free(Name);
-           return false;
-       }
-    }
-    free(Name);
-    return ret;
-}
-
-
-/*
-**  Add a newsgroup.  Append a line to the end of the active file and reload.
-*/
-bool
-ICDnewgroup(char *Name, char *Rest)
-{
-    char               buff[SMBUF];
-    struct iovec       iov[2];
-    bool               ret;
-
-    /* Set up the scatter/gather vectors. */
-    if (strlen(Name) + strlen(Rest) > SMBUF - 24) {
-       syslog(L_ERROR, "%s too_long %s", LogName, MaxLength(Name, Name));
-       return false;
-    }
-    snprintf(buff, sizeof(buff), "%s 0000000000 0000000001 %s\n", Name, Rest);
-    ICDiovset(&iov[0], ICDactpointer, ICDactsize);
-    ICDiovset(&iov[1], buff, strlen(buff));
-
-    ret = ICDwritevactive(iov, 2);
-    ICDiovrelease(&iov[0]);
-    ICDiovrelease(&iov[1]);
-    if (ret) {
-       if (innconf->enableoverview && !OVgroupadd(Name, 1, 0, Rest))
-           return false;
-    }
-    return ret;
-}
-
-
-/*
-**  Remove a newsgroup.  Splice the line out of the active file and reload.
-*/
-bool
-ICDrmgroup(NEWSGROUP *ngp)
-{
-    struct iovec iov[2];
-    int i;
-    bool ret;
-    char *Name;
-
-    /* Don't let anyone remove newsgroups that INN requires exist. */
-    if (strcmp(ngp->Name, "junk") == 0 || strcmp(ngp->Name, "control") == 0)
-        return false;
-    if (innconf->mergetogroups && strcmp(ngp->Name, "to") == 0)
-        return false;
-
-    Name = xstrdup(ngp->Name);
-    /* If this is the first group in the file, write everything after. */
-    if (ngp == &Groups[0]) {
-       i = ngp[1].Start;
-       ICDiovset(&iov[0], &ICDactpointer[i], ICDactsize - i);
-       ret = ICDwritevactive(iov, 1);
-       ICDiovrelease(&iov[0]);
-       if (ret) {
-           if (innconf->enableoverview && !OVgroupdel(Name)) {
-               free(Name);
-               return false;
-           }
-       }
-       free(Name);
-       return ret;
-    }
-
-    /* Write everything up to this group. */
-    ICDiovset(&iov[0], ICDactpointer, ngp->Start);
-
-    /* If this is the last group, that's all we have to write. */
-    if (ngp == &Groups[nGroups - 1]) {
-       ret = ICDwritevactive(iov, 1);
-       ICDiovrelease(&iov[0]);
-       if (ret) {
-           if (innconf->enableoverview && !OVgroupdel(Name)) {
-               free(Name);
-               return false;
-           }
-       }
-       free(Name);
-       return ret;
-    }
-
-    /* Write everything after this group. */
-    i = ngp[1].Start;
-    ICDiovset(&iov[1], &ICDactpointer[i], ICDactsize - i);
-    ret = ICDwritevactive(iov, 2);
-    ICDiovrelease(&iov[0]);
-    ICDiovrelease(&iov[1]);
-    if (ret) {
-       if (innconf->enableoverview && !OVgroupdel(Name)) {
-           free(Name);
-           return false;
-       }
-    }
-    free(Name);
-    return ret;
-}
-
-\f
-
-/*
-**  Open the active file and "map" it into memory.
-*/
-char *
-ICDreadactive(endp)
-    char               **endp;
-{
-    struct stat                Sb;
-
-    if (ICDactpointer) {
-       *endp = ICDactpointer + ICDactsize;
-       return ICDactpointer;
-    }
-    if (ICDactpath == NULL) 
-       ICDactpath = concatpath(innconf->pathdb, _PATH_ACTIVE);
-    if ((ICDactfd = open(ICDactpath, O_RDWR)) < 0) {
-       syslog(L_FATAL, "%s cant open %s %m", LogName, ICDactpath);
-       exit(1);
-    }
-    close_on_exec(ICDactfd, true);
-
-#ifdef HAVE_MMAP
-
-    if (fstat(ICDactfd, &Sb) < 0) {
-       syslog(L_FATAL, "%s cant fstat %d %s %m",
-           LogName, ICDactfd, ICDactpath);
-       exit(1);
-    }
-    ICDactsize = Sb.st_size;
-    ICDactpointer = mmap(NULL, ICDactsize, PROT_READ|PROT_WRITE,
-                         MAP_SHARED, ICDactfd, 0);
-    if (ICDactpointer == (char *)-1) {
-       syslog(L_FATAL, "%s cant mmap %d %s %m",
-           LogName, ICDactfd, ICDactpath);
-       exit(1);
-    }
-
-#else /* !HAVE_MMAP */
-
-    if ((ICDactpointer = ReadInDescriptor(ICDactfd, &Sb)) == NULL) {
-       syslog(L_FATAL, "%s cant read %s %m", LogName, ICDactpath);
-       exit(1);
-    }
-    ICDactsize = Sb.st_size;
-
-#endif /* HAVE_MMAP */
-
-    *endp = ICDactpointer + ICDactsize;
-    return ICDactpointer;
-}
-
-
-/*
-**  Write the active file out.
-*/
-void
-ICDwriteactive(void)
-{
-#ifdef HAVE_MMAP
-    if (msync(ICDactpointer, ICDactsize, MS_ASYNC) < 0) {
-        syslog(L_FATAL, "%s msync failed %s %m", LogName, ICDactpath);
-        exit(1);
-    }
-#else /* !HAVE_MMAP */
-    if (lseek(ICDactfd, 0, SEEK_SET) == -1) {
-       syslog(L_FATAL, "%s cant rewind %s %m", LogName, ICDactpath);
-       exit(1);
-    }
-    if (xwrite(ICDactfd, ICDactpointer, ICDactsize) < 0) {
-       syslog(L_FATAL, "%s cant write %s %m", LogName, ICDactpath);
-       exit(1);
-    }
-#endif /* HAVE_MMAP */
-}
diff --git a/innd/innd.c b/innd/innd.c
deleted file mode 100644 (file)
index 8b1589f..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-/*  $Id: innd.c 7858 2008-06-05 18:51:20Z iulius $
-**
-**  Variable definitions, miscellany, and main().
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "innperl.h"
-
-#define DEFINE_DATA
-#include "innd.h"
-#include "ov.h"
-
-
-bool           Debug = false;
-bool           NNRPTracing = false;
-bool           StreamingOff = false ; /* default is we can stream */
-bool           Tracing = false;
-bool           DoCancels = true;
-char           LogName[] = "SERVER";
-int            ErrorCount = IO_ERROR_COUNT;
-OPERATINGMODE  Mode = OMrunning;
-int            RemoteLimit = REMOTELIMIT;
-time_t         RemoteTimer = REMOTETIMER;
-int            RemoteTotal = REMOTETOTAL;
-bool           ThrottledbyIOError = false;
-
-static char    *PID = NULL;
-
-/* Signal handling.  If we receive a signal that should kill the server,
-   killer_signal is set to the signal number that we received.  This isn't
-   what indicates that we should terminate; that's the separate global
-   variable GotTerminate, used in CHANreadloop. */
-static volatile sig_atomic_t killer_signal = 0;
-
-/* Whether our self-maintained logs (stdout and stderr) are buffered, used
-   to determine whether fflush is needed.  Should be static. */
-bool BufferedLogs = true;
-
-/* FILEs for logs and error logs.  Everything should just use stdout and
-   stderr. */
-FILE *Log = NULL;
-FILE *Errlog = NULL;
-
-/* Some very old systems have a completely inadequate BUFSIZ buffer size, at
-   least for our logging purposes. */
-#if BUFSIZ < 4096
-# define LOG_BUFSIZ 4096
-#else
-# define LOG_BUFSIZ BUFSIZ
-#endif
-
-/* Internal prototypes. */
-static RETSIGTYPE       catch_terminate(int sig);
-static void             xmalloc_abort(const char *what, size_t size,
-                                      const char *file, int line);
-
-/* header table initialization */
-#define ARTHEADERINIT(name, type) {name, type, sizeof(name) - 1}
-const ARTHEADER ARTheaders[] = {
-  /*            Name                   Type */
-  ARTHEADERINIT("Approved",            HTstd),
-/* #define HDR__APPROVED                       0 */
-  ARTHEADERINIT("Control",             HTstd),
-/* #define HDR__CONTROL                                1 */
-  ARTHEADERINIT("Date",                        HTreq),
-/* #define HDR__DATE                           2 */
-  ARTHEADERINIT("Distribution",                HTstd),
-/* #define HDR__DISTRIBUTION                   3 */
-  ARTHEADERINIT("Expires",             HTstd),
-/* #define HDR__EXPIRES                                4 */
-  ARTHEADERINIT("From",                        HTreq),
-/* #define HDR__FROM                           5 */
-  ARTHEADERINIT("Lines",               HTstd),
-/* #define HDR__LINES                          6 */
-  ARTHEADERINIT("Message-ID",          HTreq),
-/* #define HDR__MESSAGE_ID                     7 */
-  ARTHEADERINIT("Newsgroups",          HTreq),
-/* #define HDR__NEWSGROUPS                     8 */
-  ARTHEADERINIT("Path",                        HTreq),
-/* #define HDR__PATH                           9 */
-  ARTHEADERINIT("Reply-To",            HTstd),
-/* #define HDR__REPLY_TO                       10 */
-  ARTHEADERINIT("Sender",              HTstd),
-/* #define HDR__SENDER                         11 */
-  ARTHEADERINIT("Subject",             HTreq),
-/* #define HDR__SUBJECT                                12 */
-  ARTHEADERINIT("Supersedes",          HTstd),
-/* #define HDR__SUPERSEDES                     13 */
-  ARTHEADERINIT("Bytes",               HTstd),
-/* #define HDR__BYTES                          14 */
-  ARTHEADERINIT("Also-Control",                HTobs),
-/* #define HDR__ALSOCONTROL                    15 */
-  ARTHEADERINIT("References",          HTstd),
-/* #define HDR__REFERENCES                     16 */
-  ARTHEADERINIT("Xref",                        HTsav),
-/* #define HDR__XREF                           17 */
-  ARTHEADERINIT("Keywords",            HTstd),
-/* #define HDR__KEYWORDS                       18 */
-  ARTHEADERINIT("X-Trace",             HTstd),
-/* #define HDR__XTRACE                         19 */
-  ARTHEADERINIT("Date-Received",       HTobs),
-/* #define HDR__DATERECEIVED                   20 */
-  ARTHEADERINIT("Posted",              HTobs),
-/* #define HDR__POSTED                         21 */
-  ARTHEADERINIT("Posting-Version",     HTobs),
-/* #define HDR__POSTINGVERSION                 22 */
-  ARTHEADERINIT("Received",            HTobs),
-/* #define HDR__RECEIVED                       23 */
-  ARTHEADERINIT("Relay-Version",       HTobs),
-/* #define HDR__RELAYVERSION                   24 */
-  ARTHEADERINIT("NNTP-Posting-Host",   HTstd),
-/* #define HDR__NNTPPOSTINGHOST                        25 */
-  ARTHEADERINIT("Followup-To",         HTstd),
-/* #define HDR__FOLLOWUPTO                     26 */
-  ARTHEADERINIT("Organization",                HTstd),
-/* #define HDR__ORGANIZATION                   27 */
-  ARTHEADERINIT("Content-Type",                HTstd),
-/* #define HDR__CONTENTTYPE                    28 */
-  ARTHEADERINIT("Content-Base",                HTstd),
-/* #define HDR__CONTENTBASE                    29 */
-  ARTHEADERINIT("Content-Disposition", HTstd),
-/* #define HDR__CONTENTDISPOSITION             30 */
-  ARTHEADERINIT("X-Newsreader",                HTstd),
-/* #define HDR__XNEWSREADER                    31 */
-  ARTHEADERINIT("X-Mailer",            HTstd),
-/* #define HDR__XMAILER                                32 */
-  ARTHEADERINIT("X-Newsposter",                HTstd),
-/* #define HDR__XNEWSPOSTER                    33 */
-  ARTHEADERINIT("X-Cancelled-By",      HTstd),
-/* #define HDR__XCANCELLEDBY                   34 */
-  ARTHEADERINIT("X-Canceled-By",       HTstd),
-/* #define HDR__XCANCELEDBY                    35 */
-  ARTHEADERINIT("Cancel-Key",          HTstd),
-/* #define HDR__CANCELKEY                      36 */
-  ARTHEADERINIT("User-Agent",          HTstd),
-/* #define HDR__USER_AGENT                     37 */
-  ARTHEADERINIT("X-Original-Message-ID",       HTstd),
-/* #define HDR__X_ORIGINAL_MESSAGE_ID          38 */
-  ARTHEADERINIT("Cancel-Lock",         HTstd),
-/* #define HDR__CANCEL_LOCK                    39 */
-  ARTHEADERINIT("Content-Transfer-Encoding",   HTstd),
-/* #define HDR__CONTENT_TRANSFER_ENCODING      40 */
-  ARTHEADERINIT("Face",                        HTstd),
-/* #define HDR__FACE                           41 */
-  ARTHEADERINIT("Injection-Info",      HTstd),
-/* #define HDR__INJECTION_INFO                 42 */
-  ARTHEADERINIT("List-ID",             HTstd),
-/* #define HDR__LIST_ID                                43 */
-  ARTHEADERINIT("MIME-Version",                HTstd),
-/* #define HDR__MIME_VERSION                   44 */
-  ARTHEADERINIT("Originator",          HTstd),
-/* #define HDR__ORIGINATOR                     45 */
-  ARTHEADERINIT("X-Auth",              HTstd),
-/* #define HDR__X_AUTH                         46 */
-  ARTHEADERINIT("X-Complaints-To",     HTstd),
-/* #define HDR__X_COMPLAINTS_TO                        47 */
-  ARTHEADERINIT("X-Face",              HTstd),
-/* #define HDR__X_FACE                         48 */
-  ARTHEADERINIT("X-HTTP-UserAgent",    HTstd),
-/* #define HDR__X_HTTP_USERAGENT               49 */
-  ARTHEADERINIT("X-HTTP-Via",          HTstd),
-/* #define HDR__X_HTTP_VIA                     50 */
-  ARTHEADERINIT("X-Modbot",            HTstd),
-/* #define HDR__X_MODBOT                       51 */
-  ARTHEADERINIT("X-Modtrace",          HTstd),
-/* #define HDR__X_MODTRACE                     52 */
-  ARTHEADERINIT("X-No-Archive",                HTstd),
-/* #define HDR__X_NO_ARCHIVE                   53 */
-  ARTHEADERINIT("X-Original-Trace",    HTstd),
-/* #define HDR__X_ORIGINAL_TRACE               54 */
-  ARTHEADERINIT("X-Originating-IP",    HTstd),
-/* #define HDR__X_ORIGINATING_IP               55 */
-  ARTHEADERINIT("X-PGP-Key",           HTstd),
-/* #define HDR__X_PGP_KEY                      56 */
-  ARTHEADERINIT("X-PGP-Sig",           HTstd),
-/* #define HDR__X_PGP_SIG                      57 */
-  ARTHEADERINIT("X-Poster-Trace",      HTstd),
-/* #define HDR__X_POSTER_TRACE                 58 */
-  ARTHEADERINIT("X-Postfilter",                HTstd),
-/* #define HDR__X_POSTFILTER                   59 */
-  ARTHEADERINIT("X-Proxy-User",                HTstd),
-/* #define HDR__X_PROXY_USER                   60 */
-  ARTHEADERINIT("X-Submissions-To",    HTstd),
-/* #define HDR__X_SUBMISSIONS_TO               61 */
-  ARTHEADERINIT("X-Usenet-Provider",   HTstd),
-/* #define HDR__X_USENET_PROVIDER              62 */
-  ARTHEADERINIT("In-Reply-To",         HTstd),
-/* #define HDR__IN_REPLY_TO                    63 */
-  ARTHEADERINIT("Injection-Date",      HTstd),
-/* #define HDR__INJECTION_DATE                 64 */
-  ARTHEADERINIT("NNTP-Posting-Date",   HTstd)
-/* #define HDR__NNTP_POSTING_DATE              65 */
-};
-/* #define MAX_ARTHEADER                       66 */
-\f
-
-/*
-**  Signal handler to catch SIGTERM and similar signals and queue a clean
-**  shutdown.
-*/
-static RETSIGTYPE
-catch_terminate(int sig)
-{
-    GotTerminate = true;
-    killer_signal = sig;
-
-#ifndef HAVE_SIGACTION
-    xsignal(sig, catch_terminate);
-#endif
-}
-
-
-/*
-**  Memory allocation failure handler.  Instead of the default behavior of
-**  just exiting, call abort to generate a core dump.
-*/
-static void
-xmalloc_abort(const char *what, size_t size, const char *file, int line)
-{
-    fprintf(stderr, "SERVER cant %s %lu bytes at %s line %d: %s", what,
-            (unsigned long) size, file, line, strerror(errno));
-    syslog(LOG_CRIT, "SERVER cant %s %lu bytes at %s line %d: %m", what,
-           (unsigned long) size, file, line);
-    abort();
-}
-
-
-/*
-**  The name is self-explanatory.
-*/
-void
-CleanupAndExit(int status, const char *why)
-{
-    JustCleanup();
-    if (why)
-        syslog(LOG_WARNING, "SERVER shutdown %s", why);
-    else
-        syslog(LOG_WARNING, "SERVER shutdown received signal %d",
-               killer_signal);
-    exit(status);
-}
-
-
-/*
-**  Close down all parts of the system (e.g., before calling exit or exec).
-*/
-void
-JustCleanup(void)
-{
-    SITEflushall(false);
-    CCclose();
-    LCclose();
-    NCclose();
-    RCclose();
-    ICDclose();
-    InndHisClose();
-    ARTclose();
-    if (innconf->enableoverview) 
-        OVclose();
-    NGclose();
-    SMshutdown();
-
-#if DO_TCL
-    TCLclose();
-#endif
-
-#if DO_PERL
-    PerlFilter(false);
-    PerlClose();
-#endif
-
-#if DO_PYTHON
-    PYclose();
-#endif
-
-    CHANshutdown();
-    innconf_free(innconf);
-    innconf = NULL;
-
-    sleep(1);
-
-    if (unlink(PID) < 0 && errno != ENOENT)
-        syslog(LOG_ERR, "SERVER cant unlink %s: %m", PID);
-}
-
-
-/*
-**  Flush one log file, re-establishing buffering if necessary.  stdout is
-**  block-buffered, stderr is line-buffered.
-*/
-void
-ReopenLog(FILE *F)
-{
-    char *path, *oldpath;
-    int mask;
-
-    if (Debug)
-       return;
-
-    path = concatpath(innconf->pathlog,
-                      (F == stdout) ? _PATH_LOGFILE : _PATH_ERRLOG);
-    oldpath = concat(path, ".old", (char *) 0);
-    if (rename(path, oldpath) < 0)
-        syswarn("SERVER cant rename %s to %s", path, oldpath);
-    free(oldpath);
-    mask = umask(033);
-    if (freopen(path, "a", F) != F)
-        sysdie("SERVER cant freopen %s", path);
-    free(path);
-    umask(mask);
-    if (BufferedLogs)
-        setvbuf(F, NULL, (F == stdout) ? _IOFBF : _IOLBF, LOG_BUFSIZ);
-}
-
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage error.\n");
-    exit(1);
-}
-
-
-int
-main(int ac, char *av[])
-{
-    const char *name, *p;
-    char *path;
-    char *t;
-    bool flag;
-    static char                WHEN[] = "PID file";
-    int                        i, j, fd[MAX_SOCKETS + 1];
-    char               buff[SMBUF], *path1, *path2;
-    FILE               *F;
-    bool               ShouldFork;
-    bool               ShouldRenumber;
-    bool               ShouldSyntaxCheck;
-    bool               filter = true;
-    pid_t              pid;
-#if    defined(_DEBUG_MALLOC_INC)
-    union malloptarg   m;
-#endif /* defined(_DEBUG_MALLOC_INC) */
-
-    /* Set up the pathname, first thing, and teach our error handlers about
-       the name of the program. */
-    name = av[0];
-    if (name == NULL || *name == '\0')
-       name = "innd";
-    else {
-        p = strrchr(name, '/');
-        if (p != NULL)
-            name = p + 1;
-    }
-    message_program_name = name;
-    openlog(name, LOG_CONS | LOG_NDELAY, LOG_INN_SERVER);
-    message_handlers_die(2, message_log_stderr, message_log_syslog_crit);
-    message_handlers_warn(2, message_log_stderr, message_log_syslog_err);
-    message_handlers_notice(1, message_log_syslog_notice);
-
-    /* Make sure innd is not running as root.  innd must be either started
-       via inndstart or use a non-privileged port. */
-    if (getuid() == 0 || geteuid() == 0)
-        die("SERVER must be run as user news, not root (use inndstart)");
-
-    /* Handle malloc debugging. */
-#if    defined(_DEBUG_MALLOC_INC)
-    m.i = M_HANDLE_ABORT;
-    dbmallopt(MALLOC_WARN, &m);
-    dbmallopt(MALLOC_FATAL, &m);
-    m.i = 3;
-    dbmallopt(MALLOC_FILLAREA, &m);
-    m.i = 0;
-    dbmallopt(MALLOC_CKCHAIN, &m);
-    dbmallopt(MALLOC_CKDATA, &m);
-#endif /* defined(_DEBUG_MALLOC_INC) */
-
-    /* Set defaults. */
-    TimeOut.tv_sec = DEFAULT_TIMEOUT;
-    TimeOut.tv_usec = 0;
-    ShouldFork = true;
-    ShouldRenumber = false;
-    ShouldSyntaxCheck = false;
-    fd[0] = fd[1] = -1;
-
-    /* Set some options from inn.conf that can be overridden with
-       command-line options if they exist, so read inn.conf first. */
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Parse JCL. */
-    CCcopyargv(av);
-    while ((i = getopt(ac, av, "ac:Cdfi:l:m:o:Nn:p:P:rst:uH:T:X:")) != EOF)
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'a':
-           AnyIncoming = true;
-           break;
-       case 'c':
-           innconf->artcutoff = atoi(optarg);
-           break;
-       case 'C':
-           DoCancels = false;
-           break;
-       case 'd':
-           Debug = true;
-           break;
-       case 'f':
-           ShouldFork = false;
-           break;
-       case 'H':
-           RemoteLimit = atoi(optarg);
-           break;
-       case 'i':
-           innconf->maxconnections = atoi(optarg);
-           break;
-       case 'I':
-           if (innconf->bindaddress) free(innconf->bindaddress);
-           innconf->bindaddress = xstrdup(optarg);
-           break;
-       case 'l':
-           innconf->maxartsize = atol(optarg);
-           break;
-       case 'm':
-           if (ModeReason)
-               free(ModeReason);
-           switch (*optarg) {
-           default:
-               Usage();
-               /* NOTREACHED */
-           case 'g':   Mode = OMrunning;       break;
-           case 'p':   Mode = OMpaused;        break;
-           case 't':   Mode = OMthrottled;     break;
-           }
-           if (Mode != OMrunning)
-                ModeReason = concat(OMpaused ? "Paus" : "Throttl",
-                                    "ed from the command line", (char *) 0);
-           break;
-       case 'N':
-           filter = false;
-           break;
-       case 'n':
-           switch (*optarg) {
-           default:
-               Usage();
-               /* NOTREACHED */
-           case 'n':   innconf->readerswhenstopped = false;    break;
-           case 'y':   innconf->readerswhenstopped = true;     break;
-           }
-           break;
-       case 'o':
-           MaxOutgoing = atoi(optarg);
-           break;
-       case 'p':
-           /* Silently ignore multiple -p flags, in case ctlinnd xexec
-              called inndstart. */
-           if (fd[0] != -1)
-               break;
-           t = xstrdup(optarg);
-           p = strtok(t, ",");
-           j = 0;
-           do {
-               fd[j++] = atoi(p);
-               if (j == MAX_SOCKETS)
-                   break;
-           } while ((p = strtok(NULL, ",")) != NULL);
-           fd[j] = -1;
-           free(t);
-           break;
-       case 'P':
-           innconf->port = atoi(optarg);
-           break;
-       case 'r':
-           ShouldRenumber = true;
-           break;
-       case 's':
-           ShouldSyntaxCheck = true;
-           break;
-       case 't':
-           TimeOut.tv_sec = atol(optarg);
-           break;
-       case 'T':
-           RemoteTotal = atoi(optarg);
-           break;
-       case 'u':
-           BufferedLogs = false;
-           break;
-       case 'X':
-           RemoteTimer = atoi(optarg);
-           break;
-        case 'Z':
-            StreamingOff = true;
-            break;
-       }
-    ac -= optind;
-    if (ac != 0)
-       Usage();
-    if (ModeReason && !innconf->readerswhenstopped)
-       NNRPReason = xstrdup(ModeReason);
-
-    if (ShouldSyntaxCheck) {
-       if ((p = CCcheckfile((char **)NULL)) == NULL)
-           exit(0);
-       fprintf(stderr, "%s\n", p + 2);
-       exit(1);
-    }
-
-    /* Get the Path entry. */
-    if (innconf->pathhost == NULL) {
-       syslog(L_FATAL, "%s No pathhost set", LogName);
-       exit(1);
-    }
-    Path.used = strlen(innconf->pathhost) + 1;
-    Path.size = Path.used + 1;
-    Path.data = xmalloc(Path.size);
-    snprintf(Path.data, Path.size, "%s!", innconf->pathhost);
-    if (innconf->pathalias == NULL) {
-       Pathalias.used = 0;
-       Pathalias.data = NULL;
-    } else {
-       Pathalias.used = strlen(innconf->pathalias) + 1;
-       Pathalias.size = Pathalias.used + 1;
-       Pathalias.data = xmalloc(Pathalias.size);
-       snprintf(Pathalias.data, Pathalias.size, "%s!", innconf->pathalias);
-    }
-    if (innconf->pathcluster == NULL) {
-        Pathcluster.used = 0;
-        Pathcluster.data = NULL;
-    } else {
-        Pathcluster.used = strlen(innconf->pathcluster) + 1;
-        Pathcluster.size = Pathcluster.used + 1;
-        Pathcluster.data = xmalloc(Pathcluster.size);
-        snprintf(Pathcluster.data, Pathcluster.size, "%s!", innconf->pathcluster);
-    }
-    /* Trace history ? */
-    if (innconf->stathist != NULL) {
-        syslog(L_NOTICE, "logging hist stats to %s", innconf->stathist);
-        HISlogto(innconf->stathist);
-    }
-
-    i = dbzneedfilecount();
-    if (!fdreserve(3 + i)) { /* TEMPORARYOPEN, history stats, INND_HISTORY and i */
-       syslog(L_FATAL, "%s cant reserve file descriptors %m", LogName);
-       exit(1);
-    }
-
-    /* Set up our permissions. */
-    umask(NEWSUMASK);
-
-    /* Become a daemon and initialize our log files. */
-    if (Debug) {
-       xsignal(SIGINT, catch_terminate);
-        if (chdir(innconf->patharticles) < 0)
-            sysdie("SERVER cant chdir to %s", innconf->patharticles);
-    } else {
-       if (ShouldFork)
-            daemonize(innconf->patharticles);
-
-       /* Open the logs.  stdout is used to log information about incoming
-           articles and stderr is used to log serious error conditions (as
-           well as to capture stderr from embedded filters).  Both are
-           normally fully buffered. */
-        path = concatpath(innconf->pathlog, _PATH_LOGFILE);
-        if (freopen(path, "a", stdout) == NULL)
-            sysdie("SERVER cant freopen stdout to %s", path);
-        setvbuf(stdout, NULL, _IOFBF, LOG_BUFSIZ);
-        free(path);
-        path = concatpath(innconf->pathlog, _PATH_ERRLOG);
-        if (freopen(path, "a", stderr) == NULL)
-            sysdie("SERVER cant freopen stderr to %s", path);
-        setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
-        free(path);
-    }
-    Log = stdout;
-    Errlog = stderr;
-
-    /* Initialize overview if necessary. */
-    if (innconf->enableoverview && !OVopen(OV_WRITE))
-        die("SERVER cant open overview method");
-
-    /* Always attempt to increase the number of open file descriptors.  If
-       we're not root, this may just fail quietly. */
-    if (innconf->rlimitnofile > 0)
-        setfdlimit(innconf->rlimitnofile);
-
-    /* Get number of open channels. */
-    i = getfdlimit();
-    if (i < 0) {
-       syslog(L_FATAL, "%s cant get file descriptor limit: %m", LogName);
-       exit(1);
-    }
-
-    /* There is no file descriptor limit on some hosts; for those, cap at
-       MaxOutgoing plus maxconnections plus 20, or 5000, whichever is larger. 
-       Otherwise, we use insane amounts of memory for the channel table.
-       FIXME: Get rid of this hard-coded constant. */
-    if (i > 5000) {
-        int max;
-
-        max = innconf->maxconnections + MaxOutgoing + 20;
-        if (max < 5000)
-            max = 5000;
-        i = max;
-    }
-    syslog(L_NOTICE, "%s descriptors %d", LogName, i);
-    if (MaxOutgoing == 0) {
-       /* getfdlimit() - (stdio + dbz + cc + lc + rc + art + fudge) */
-       MaxOutgoing = i - (  3   +  3  +  2 +  1 +  1 +  1  +  2  );
-       syslog(L_NOTICE, "%s outgoing %d", LogName, MaxOutgoing);
-    }
-
-    /* See if another instance is alive. */
-    if (PID == NULL)
-       PID = concatpath(innconf->pathrun, _PATH_SERVERPID);
-    if ((F = fopen(PID, "r")) != NULL) {
-       if (fgets(buff, sizeof buff, F) != NULL
-        && ((pid = (pid_t) atol(buff)) > 0)
-        && (kill(pid, 0) > 0 || errno != ESRCH)) {
-           syslog(L_FATAL, "%s already_running pid %ld", LogName,
-           (long) pid);
-           exit(1);
-       }
-       fclose(F);
-    }
-
-    if (GetTimeInfo(&Now) < 0)
-       syslog(L_ERROR, "%s cant gettimeinfo %m", LogName);
-
-    /* Set up signal and error handlers. */
-    xmalloc_error_handler = xmalloc_abort;
-    xsignal(SIGHUP, catch_terminate);
-    xsignal(SIGTERM, catch_terminate);
-
-    /* Set up the various parts of the system.  Channel feeds start
-       processes so call PROCsetup before ICDsetup.  NNTP needs to know if
-       it's a slave, so call RCsetup before NCsetup. */
-    CHANsetup(i);
-    PROCsetup(10);
-    if (Mode == OMrunning)
-        InndHisOpen();
-    CCsetup();
-    LCsetup();
-    RCsetup(fd[0]);
-    for (i = 1; fd[i] != -1; i++)
-       RCsetup(fd[i]);
-    WIPsetup();
-    NCsetup();
-    ARTsetup();
-    ICDsetup(true);
-    if (innconf->timer)
-        TMRinit(TMR_MAX);
-
-    /* Initialize the storage subsystem. */
-    flag = true;
-    if (!SMsetup(SM_RDWR, &flag) || !SMsetup(SM_PREOPEN, &flag))
-        die("SERVER cant set up storage manager");
-    if (!SMinit())
-        die("SERVER cant initalize storage manager: %s", SMerrorstr);
-
-#if    defined(_DEBUG_MALLOC_INC)
-    m.i = 1;
-    dbmallopt(MALLOC_CKCHAIN, &m);
-    dbmallopt(MALLOC_CKDATA, &m);
-#endif /* defined(_DEBUG_MALLOC_INC) */
-
-    /* Record our PID. */
-    pid = getpid();
-    if ((F = fopen(PID, "w")) == NULL) {
-       i = errno;
-       syslog(L_ERROR, "%s cant fopen %s %m", LogName, PID);
-       IOError(WHEN, i);
-    }
-    else {
-       if (fprintf(F, "%ld\n", (long)pid) == EOF || ferror(F)) {
-           i = errno;
-           syslog(L_ERROR, "%s cant fprintf %s %m", LogName, PID);
-           IOError(WHEN, i);
-       }
-       if (fclose(F) == EOF) {
-           i = errno;
-           syslog(L_ERROR, "%s cant fclose %s %m", LogName, PID);
-           IOError(WHEN, i);
-       }
-       if (chmod(PID, 0664) < 0) {
-           i = errno;
-           syslog(L_ERROR, "%s cant chmod %s %m", LogName, PID);
-           IOError(WHEN, i);
-       }
-    }
-
-#if DO_TCL
-    TCLsetup();
-    if (!filter)
-       TCLfilter(false);
-#endif /* DO_TCL */
-
-#if DO_PERL
-    /* Load the Perl code */
-    path1 = concatpath(innconf->pathfilter, _PATH_PERL_STARTUP_INND);
-    path2 = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_INND);
-    PERLsetup(path1, path2, "filter_art");
-    free(path1);
-    free(path2);
-    PLxsinit();
-    if (filter)
-       PerlFilter(true);
-#endif /* DO_PERL */
-
-#if DO_PYTHON
-    PYsetup();
-    if (!filter)
-       PYfilter(false);
-#endif /* DO_PYTHON */
-    /* And away we go... */
-    if (ShouldRenumber) {
-        syslog(LOG_NOTICE, "SERVER renumbering");
-        if (!ICDrenumberactive())
-            die("SERVER cant renumber");
-    }
-    syslog(LOG_NOTICE, "SERVER starting");
-    CHANreadloop();
-
-    /* CHANreadloop should never return. */
-    CleanupAndExit(1, "CHANreadloop returned");
-    return 1;
-}
diff --git a/innd/innd.h b/innd/innd.h
deleted file mode 100644 (file)
index d8b60f0..0000000
+++ /dev/null
@@ -1,858 +0,0 @@
-/*  $Id: innd.h 7858 2008-06-05 18:51:20Z iulius $
-**
-**  Many of the data types used here have abbreviations, such as CT
-**  for CHANNELTYPE.  Here are a list of the conventions and meanings:
-**
-**    ART   A news article
-**    CHAN  An I/O channel
-**    CS    Channel state
-**    CT    Channel type
-**    FNL   Funnel, into which other feeds pour
-**    FT    Feed type -- how a site gets told about new articles
-**    ICD   In-core data (primarily the active and sys files)
-**    LC    Local NNTP connection-receiving channel
-**    CC    Control channel (used by ctlinnd)
-**    NC    NNTP client channel
-**    NG    Newsgroup
-**    NGH   Newgroup hashtable
-**    PROC  A process (used to feed a site)
-**    PS    Process state
-**    RC    Remote NNTP connection-receiving channel
-**    RCHAN A channel in "read" state
-**    SITE  Something that gets told when we get an article
-**    WCHAN A channel in "write" state
-**    WIP   Work-In-Progress, keeps track of articles before committed.
-*/
-
-#ifndef INND_H
-#define INND_H 1
-
-#include "config.h"
-#include "portable/time.h"
-#include "portable/socket.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <syslog.h> 
-#include <sys/stat.h>
-
-#include "inn/buffer.h"
-#include "inn/history.h"
-#include "inn/messages.h"
-#include "inn/timer.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-#include "storage.h"
-
-/* TCL defines EXTERN, so undef it after inclusion since we use it. */
-#if DO_TCL
-# include <tcl.h>
-# undef EXTERN
-#endif
-
-BEGIN_DECLS
-
-typedef short  SITEIDX;
-#define NOSITE ((SITEIDX) -1)
-
-/*
-**  Various constants.
-*/
-
-/* Used for storing group subscriptions for feeds. */
-#define SUB_DEFAULT            false
-#define SUB_NEGATE             '!'
-#define SUB_POISON             '@'
-
-/* Special characters for newsfeeds entries. */
-#define NF_FIELD_SEP            ':'
-#define NF_SUBFIELD_SEP         '/'
-
-
-/*
-**  Server's operating mode.
-*/
-typedef enum _OPERATINGMODE {
-  OMrunning,
-  OMpaused,
-  OMthrottled
-} OPERATINGMODE;
-
-
-typedef struct _LISTBUFFER {
-  char *   Data;
-  int      DataLength;
-  char  **  List;
-  int      ListLength;
-} LISTBUFFER;
-
-/*
-**  What program to handoff a connection to.
-*/
-typedef enum _HANDOFF {
-  HOnnrpd,
-  HOnntpd
-} HANDOFF;
-
-
-/*
-**  Header types.
-*/
-typedef enum _ARTHEADERTYPE {
-  HTreq,  /* Drop article if this is missing             */
-  HTobs,  /* obsolete header but keep untouched                  */
-  HTstd,  /* Standard optional header                    */
-  HTsav          /* Save header, but may be deleted from article */
-} ARTHEADERTYPE;
-
-
-/*
-**  Entry in the header table.
-*/
-typedef struct _ARTHEADER {
-  const char     *  Name;
-  ARTHEADERTYPE            Type;
-  int              Size;  /* Length of Name. */
-} ARTHEADER;
-
-
-/*
-**  Header content
-*/
-typedef struct _HDRCONTENT {
-  char  *  Value;   /* don't copy, shows where it begins */
-  int     Length;  /* Length of Value(tailing CRLF is not
-                          included.  -1 if duplicated */
-} HDRCONTENT;
-
-
-/*
-**  A way to index into the header table.
-*/
-#define HDR_FOUND(_x)          (hc[(_x)].Length > 0)
-#define HDR_PARSE_START(_x)    hc[(_x)].Value[hc[_x].Length] = '\0'
-#define HDR(_x)                        (hc[(_x)].Value)
-/* HDR_LEN does not includes trailing "\r\n" */
-#define HDR_LEN(_x)            (hc[(_x)].Length)
-#define HDR_PARSE_END(_x)      hc[(_x)].Value[hc[_x].Length] = '\r'
-
-
-#define HDR__APPROVED          0
-#define HDR__CONTROL           1
-#define HDR__DATE              2
-#define HDR__DISTRIBUTION      3
-#define HDR__EXPIRES           4
-#define HDR__FROM              5
-#define HDR__LINES             6
-#define HDR__MESSAGE_ID                7
-#define HDR__NEWSGROUPS                8
-#define HDR__PATH              9
-#define HDR__REPLY_TO          10
-#define HDR__SENDER            11
-#define HDR__SUBJECT           12
-#define HDR__SUPERSEDES                13
-#define HDR__BYTES             14
-#define HDR__ALSOCONTROL       15
-#define HDR__REFERENCES                16
-#define HDR__XREF              17
-#define HDR__KEYWORDS          18
-#define HDR__XTRACE            19
-#define HDR__DATERECEIVED      20
-#define HDR__POSTED            21
-#define HDR__POSTINGVERSION    22
-#define HDR__RECEIVED          23
-#define HDR__RELAYVERSION      24
-#define HDR__NNTPPOSTINGHOST   25
-#define HDR__FOLLOWUPTO                26
-#define HDR__ORGANIZATION      27
-#define HDR__CONTENTTYPE       28
-#define HDR__CONTENTBASE       29
-#define HDR__CONTENTDISPOSITION        30
-#define HDR__XNEWSREADER       31
-#define HDR__XMAILER           32
-#define HDR__XNEWSPOSTER       33
-#define HDR__XCANCELLEDBY      34
-#define HDR__XCANCELEDBY       35
-#define HDR__CANCELKEY         36
-#define HDR__USER_AGENT                37
-#define HDR__X_ORIGINAL_MESSAGE_ID     38
-#define HDR__CANCEL_LOCK       39
-#define HDR__CONTENT_TRANSFER_ENCODING 40
-#define HDR__FACE              41
-#define HDR__INJECTION_INFO    42
-#define HDR__LIST_ID           43
-#define HDR__MIME_VERSION      44
-#define HDR__ORIGINATOR                45
-#define HDR__X_AUTH            46
-#define HDR__X_COMPLAINTS_TO   47
-#define HDR__X_FACE            48
-#define HDR__X_HTTP_USERAGENT  49
-#define HDR__X_HTTP_VIA                50
-#define HDR__X_MODBOT          51
-#define HDR__X_MODTRACE                52
-#define HDR__X_NO_ARCHIVE      53
-#define HDR__X_ORIGINAL_TRACE  54
-#define HDR__X_ORIGINATING_IP  55
-#define HDR__X_PGP_KEY         56
-#define HDR__X_PGP_SIG         57
-#define HDR__X_POSTER_TRACE    58
-#define HDR__X_POSTFILTER      59
-#define HDR__X_PROXY_USER      60
-#define HDR__X_SUBMISSIONS_TO  61
-#define HDR__X_USENET_PROVIDER 62
-#define HDR__IN_REPLY_TO       63
-#define HDR__INJECTION_DATE    64
-#define HDR__NNTP_POSTING_DATE 65
-
-#define MAX_ARTHEADER           66
-
-/*
-**  Miscellaneous data we want to keep on an article.  All the fields
-**  are not always valid.
-*/
-typedef struct _ARTDATA {
-  int            Body;                 /* where body begins in article
-                                          it indicates offset from bp->Data */
-  char       *   Poster;               /* Sender otherwise From in article */
-  char       *   Replyto;              /* Reply-To otherwise From in article */
-  time_t         Posted;               /* when article posted */
-  time_t         Arrived;              /* when article arrived */
-  time_t         Expires;              /* when article should be expired */
-  int            Lines;                /* number of body lines */
-  int            HeaderLines;          /* number of header lines */
-  long           BytesValue;           /* size of stored article, "\r\n" is
-                                          counted as 1 byte */
-  char           Bytes[16];            /* generated Bytes header */
-  int            BytesLength;          /* generated Bytes header length */
-  char       *   BytesHeader;          /* where Bytes header begins in
-                                          received article */
-  char           TokenText[(sizeof(TOKEN) * 2) + 3];
-                                       /* token of stored article */
-  LISTBUFFER     Newsgroups;           /* newsgroup list */
-  int            Groupcount;           /* number of newsgroups */
-  int            Followcount;          /* number of folloup to newsgroups */
-  char       *   Xref;                 /* generated Xref header */
-  int            XrefLength;           /* generated Xref header length */
-  int            XrefBufLength;        /* buffer length of generated Xref
-                                          header */
-  LISTBUFFER     Distribution;         /* distribution list */
-  const char  *   Feedsite;            /* who gives me this article */
-  int            FeedsiteLength;       /* length of Feedsite */
-  LISTBUFFER     Path;                 /* path name list */
-  int            StoredGroupLength;    /* 1st newsgroup name in Xref */
-  char       *   Replic;               /* replication data */
-  int            ReplicLength;         /* length of Replic */
-  HASH       *   Hash;                 /* Message-ID hash */
-  struct buffer          Headers;              /* buffer for headers which will be sent
-                                          to site */
-  struct buffer          Overview;             /* buffer for overview data */
-  int            CRwithoutLF;          /* counter for '\r' without '\n' */
-  int            LFwithoutCR;          /* counter for '\n' without '\r' */
-  long           CurHeader;            /* where current header starts.
-                                          this is used for folded header
-                                          it indicates offset from bp->Data */
-  bool           NullHeader;           /* contains NULL in current header    */
-  long           LastTerminator;       /* where last '.' exists.  only set if
-                                          it exists at the begining of line
-                                          it indicates offset from bp->Data */
-  long           LastCR;               /* where last CR exists
-                                          it indicates offset from bp->Data */
-  long           LastCRLF;             /* where last CRLF exists.
-                                          indicates where last LF exists
-                                          it indicates offset from bp->Data */
-  HDRCONTENT     HdrContent[MAX_ARTHEADER];
-                                       /* includes system headers info */
-  bool            AddAlias;             /* Whether Pathalias should be added
-                                           to this article */
-  bool            Hassamepath;          /* Whether this article matches Path */
-  bool            Hassamecluster;       /* Whether this article matches 
-                                           Pathcluster */
-} ARTDATA;
-
-/*
-**  Set of channel types.
-*/
-typedef enum _CHANNELTYPE {
-  CTany,
-  CTfree,
-  CTremconn,
-  CTreject,
-  CTnntp,
-  CTlocalconn,
-  CTcontrol,
-  CTfile,
-  CTexploder,
-  CTprocess
-} CHANNELTYPE;
-
-
-/*
-**  The state a channel is in.  Interpretation of this depends on the
-**  channel's type.  Used mostly by CTnntp channels.
-*/
-typedef enum _CHANNELSTATE {
-  CSerror,
-  CSwaiting,
-  CSgetcmd,
-  CSgetauth,
-  CSwritegoodbye,
-  CSwriting,
-  CSpaused,
-  CSgetheader,
-  CSgetbody,
-  CSgotarticle,
-  CSgotlargearticle,
-  CSnoarticle,
-  CSeatarticle,
-  CSeatcommand,
-  CSgetxbatch,
-  CScancel
-} CHANNELSTATE;
-
-#define SAVE_AMT       10      /* used for eating article/command */
-
-/*
-**  I/O channel, the heart of the program.  A channel has input and output
-**  buffers, and functions to call when there is input to be read, or when
-**  all the output was been written.  Many callback functions take a
-**  pointer to a channel, so set up a typedef for that.
-*/
-#define PRECOMMITCACHESIZE 128
-struct _CHANNEL;
-typedef void (*innd_callback_t)(struct _CHANNEL *);
-
-typedef struct _CHANNEL {
-  CHANNELTYPE         Type;
-  CHANNELSTATE        State;
-  int                 fd;
-  bool                Skip;
-  bool                Streaming;
-  bool                NoResendId;
-  bool                privileged;
-  bool                Nolist;
-  unsigned long               Duplicate;
-  unsigned long               Unwanted_s;
-  unsigned long               Unwanted_f;
-  unsigned long               Unwanted_d;
-  unsigned long               Unwanted_g;
-  unsigned long               Unwanted_u;
-  unsigned long               Unwanted_o;
-  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;
-  int                 Reported;
-  long                Received;
-  long                Refused;
-  long                Rejected;
-  int                 BadWrites;
-  int                 BadReads;
-  int                 BlockedWrites;
-  int                 BadCommands;
-  time_t              LastActive;
-  time_t              NextLog;
-  struct sockaddr_storage Address;
-  innd_callback_t      Reader;
-  innd_callback_t      WriteDone;
-  time_t              Waketime;
-  time_t              Started;
-  innd_callback_t      Waker;
-  void             *  Argument;
-  void             *  Event;
-  struct buffer               In;
-  struct buffer               Out;
-  bool                Tracing;
-  struct buffer               Sendid;
-  HASH                CurrentMessageIDHash;
-  struct _WIP      *  PrecommitWIP[PRECOMMITCACHESIZE];
-  int                 PrecommitiCachenext;
-  int                 XBatchSize;
-  int                 LargeArtSize;
-  int                 LargeCmdSize;
-  int                 ActiveCnx;
-  int                 MaxCnx;
-  int                 HoldTime;
-  time_t              ArtBeg;
-  int                 ArtMax;
-  long                Start;           /* where current cmd/article starts
-                                          it indicates offset from bp->Data */
-  long                Next;            /* next pointer to read
-                                          it indicates offset from bp->Data */
-  char                Error[SMBUF];    /* error buffer */
-  ARTDATA             Data;            /* used for processing article */
-  struct _CHANNEL      *nextcp;                /* linked list for each incoming site */
-} CHANNEL;
-
-#define        DEFAULTNGBOXSIZE        64
-
-/*
-**  A newsgroup has a name in different formats, and a high-water count,
-**  also kept in different formats.  It also has a list of sites that
-**  get this group.
-*/
-typedef struct _NEWSGROUP {
-  long                 Start;       /* Offset into the active file  */
-  char              *  Name;
-  int                  NameLength;
-  ARTNUM               Last;
-  ARTNUM               Filenum;     /* File name to use             */
-  int                  Lastwidth;
-  int                  PostCount;   /* Have we already put it here? */
-  char              *  LastString;
-  char              *  Rest;        /* Flags, NOT NULL TERMINATED   */
-  SITEIDX              nSites;
-  int               *  Sites;
-  SITEIDX              nPoison;
-  int               *  Poison;
-  struct _NEWSGROUP  *  Alias;
-} NEWSGROUP;
-
-
-/*
-**  How a site is fed.
-*/
-typedef enum _FEEDTYPE {
-  FTerror,
-  FTfile,
-  FTchannel,
-  FTexploder,
-  FTfunnel,
-  FTlogonly,
-  FTprogram
-} FEEDTYPE;
-
-
-/*
-**  Diablo-style hashed feeds or hashfeeds.
-*/
-#define HASHFEED_QH    1
-#define HASHFEED_MD5   2
-
-typedef struct _HASHFEEDLIST {
-  int                  type;
-  unsigned int         begin;
-  unsigned int         end;
-  unsigned int         mod;
-  unsigned int         offset;
-  struct _HASHFEEDLIST *next;
-} HASHFEEDLIST;
-
-
-/*
-**  A site may reject something in its subscription list if it has
-**  too many hops, or a bad distribution.
-*/
-typedef struct _SITE {
-  const char  *   Name;
-  char       *   Entry;
-  int            NameLength;
-  char       **  Exclusions;
-  char       **  Distributions;
-  char       **  Patterns;
-  bool           Poison;
-  bool           PoisonEntry;
-  bool           Sendit;
-  bool           Seenit;
-  bool           IgnoreControl;
-  bool           DistRequired;
-  bool           IgnorePath;
-  bool           ControlOnly;
-  bool           DontWantNonExist;
-  bool           NeedOverviewCreation;
-  bool           FeedwithoutOriginator;
-  bool           DropFiltered;
-  int            Hops;
-  int            Groupcount;
-  int            Followcount;
-  int            Crosscount;
-  FEEDTYPE       Type;
-  NEWSGROUP   *   ng;
-  bool           Spooling;
-  char       *   SpoolName;
-  bool           Working;
-  long           StartWriting;
-  long           StopWriting;
-  long           StartSpooling;
-  char       *   Param;
-  char           FileFlags[FEED_MAXFLAGS + 1];
-  long           MaxSize;
-  long           MinSize;
-  int            Nice;
-  CHANNEL     *   Channel;
-  bool           IsMaster;
-  int            Master;
-  int            Funnel;
-  bool           FNLwantsnames;
-  struct buffer          FNLnames;
-  int            Process;
-  pid_t                  pid;
-  long           Flushpoint;
-  struct buffer          Buffer;
-  bool           Buffered;
-  char       **  Originator;
-  HASHFEEDLIST *  HashFeedList;
-  int            Next;
-  int            Prev;
-} SITE;
-
-
-/*
-**  A process is something we start up to send articles.
-*/
-typedef enum _PROCSTATE {
-  PSfree,
-  PSrunning,
-  PSdead
-} PROCSTATE;
-
-
-/*
-**  We track our children and collect them synchronously.
-*/
-typedef struct _PROCESS {
-  PROCSTATE    State;
-  pid_t                Pid;
-  int          Status;
-  time_t       Started;
-  time_t       Collected;
-  int          Site;
-} PROCESS;
-
-/*
-**  A work in progress entry, an article that we've been offered but haven't
-**  received yet.
-*/
-typedef struct _WIP {
-  HASH         MessageID;      /* Hash of the messageid.  Doing it like
-                                  this saves us from haveing to allocate
-                                  and deallocate memory a lot, and also
-                                  means lookups are faster. */ 
-  time_t       Timestamp;      /* Time we last looked at this MessageID */
-  CHANNEL      *Chan;          /* Channel that this message is associated
-                                  with */
-  struct _WIP  *Next;          /* Next item in this bucket */
-} WIP;
-
-/*
-**  Supported timers.  If you add new timers to this list, also add them to
-**  the list of tags in chan.c.
-*/
-enum timer {
-    TMR_IDLE = TMR_APPLICATION, /* Server is completely idle. */
-    TMR_ARTCLEAN,               /* Analyzing an incoming article. */
-    TMR_ARTWRITE,               /* Writing an article. */
-    TMR_ARTCNCL,                /* Processing a cancel message. */
-    TMR_SITESEND,               /* Sending an article to feeds. */
-    TMR_OVERV,                  /* Generating overview information. */
-    TMR_PERL,                   /* Perl filter. */
-    TMR_PYTHON,                 /* Python filter. */
-    TMR_NNTPREAD,               /* Reading NNTP data from the network. */
-    TMR_ARTPARSE,               /* Parsing an article. */
-    TMR_ARTLOG,                 /* Logging article disposition. */
-    TMR_DATAMOVE,               /* Moving data. */
-    TMR_MAX
-};
-
-\f
-
-/*
-**  In-line macros for efficiency.
-**
-**  Set or append data to a channel's output buffer.
-*/
-#define WCHANset(cp, p, l)      buffer_set(&(cp)->Out, (p), (l))
-#define WCHANappend(cp, p, l)   buffer_append(&(cp)->Out, (p), (l))
-
-/*
-**  Mark that an I/O error occurred, and block if we got too many.
-*/
-#define IOError(WHEN, e)                    \
-  do {                                      \
-    if (--ErrorCount <= 0 || (e) == ENOSPC) \
-      ThrottleIOError(WHEN);                \
-  } while (0)
-\f
-
-/*
-**  Global data.
-**
-** Do not change "extern" to "EXTERN" in the Global data.  The ones
-** marked with "extern" are initialized in innd.c.  The ones marked
-** with "EXTERN" are not explicitly initialized in innd.c.
-*/
-#if defined(DEFINE_DATA)
-# define EXTERN                /* NULL */
-#else
-# define EXTERN                extern
-#endif
-extern const ARTHEADER ARTheaders[MAX_ARTHEADER];
-extern bool            BufferedLogs;
-EXTERN bool            AnyIncoming;
-extern bool            Debug;
-EXTERN bool            ICDneedsetup;
-EXTERN bool            NeedHeaders;
-EXTERN bool            NeedOverview;
-EXTERN bool            NeedPath;
-EXTERN bool            NeedStoredGroup;
-EXTERN bool            NeedReplicdata;
-extern bool            NNRPTracing;
-extern bool            StreamingOff;
-extern bool            Tracing;
-EXTERN struct buffer   Path;
-EXTERN struct buffer   Pathalias;
-EXTERN struct buffer    Pathcluster;
-EXTERN char         *  ModeReason;     /* NNTP reject message   */
-EXTERN char         *  NNRPReason;     /* NNRP reject message   */
-EXTERN char         *  Reservation;    /* Reserved lock message */
-EXTERN char         *  RejectReason;   /* NNTP reject message   */
-EXTERN FILE         *  Errlog;
-EXTERN FILE         *  Log;
-extern char            LogName[];
-extern int             ErrorCount;
-EXTERN int             ICDactivedirty;
-EXTERN int             MaxOutgoing;
-EXTERN int             nGroups;
-EXTERN SITEIDX         nSites;
-EXTERN int             PROCneedscan;
-EXTERN NEWSGROUP    ** GroupPointers;
-EXTERN NEWSGROUP    *  Groups;
-extern OPERATINGMODE   Mode;
-EXTERN sig_atomic_t    GotTerminate;
-EXTERN SITE        *   Sites;
-EXTERN SITE            ME;
-EXTERN struct timeval  TimeOut;
-EXTERN TIMEINFO                Now;            /* Reasonably accurate time     */
-EXTERN bool            ThrottledbyIOError;
-EXTERN char        *   NCgreeting;
-EXTERN struct history   *History;
-
-/*
-** Table size for limiting incoming connects.  Do not change the table
-** size unless you look at the code manipulating it in rc.c.
-*/
-#define REMOTETABLESIZE        128
-
-/*
-** Setup the default values.  The REMOTETIMER being zero turns off the
-** code to limit incoming connects.
-*/
-#define REMOTELIMIT    2
-#define REMOTETIMER    0
-#define REMOTETOTAL    60
-#define REJECT_TIMEOUT 10
-extern int             RemoteLimit;    /* Per host limit. */
-extern time_t          RemoteTimer;    /* How long to remember connects. */
-extern int             RemoteTotal;    /* Total limit. */
-
-
-/*
-**  Function declarations.
-*/
-extern void            InndHisOpen(void);
-extern void             InndHisClose(void);
-extern bool             InndHisWrite(const char *key, time_t arrived,
-                                    time_t posted, time_t expires,
-                                    TOKEN *token);
-extern bool             InndHisRemember(const char *key);
-extern void             InndHisLogStats(void);
-extern bool            FormatLong(char *p, unsigned long value, int width);
-extern bool            NeedShell(char *p, const char **av, const char **end);
-extern char        **  CommaSplit(char *text);
-extern void            SetupListBuffer(int size, LISTBUFFER *list);
-extern char         *  MaxLength(const char *p, const char *q);
-extern pid_t           Spawn(int niceval, int fd0, int fd1, int fd2,
-                             char * const av[]);
-extern void            CleanupAndExit(int x, const char *why);
-extern void            FileGlue(char *p, const char *n1, char c, const char *n2);
-extern void            JustCleanup(void);
-extern void            ThrottleIOError(const char *when);
-extern void            ThrottleNoMatchError(void);
-extern void            ReopenLog(FILE *F);
-extern void            xchown(char *p);
-
-extern bool            ARTidok(const char *MessageID);
-extern bool            ARTreadschema(void);
-extern const char   *  ARTreadarticle(char *files);
-extern char        *   ARTreadheader(char *files);
-extern bool            ARTpost(CHANNEL *cp);
-extern void            ARTcancel(const ARTDATA *Data,
-                                 const char *MessageID, bool Trusted);
-extern void            ARTclose(void);
-extern void            ARTsetup(void);
-extern void            ARTprepare(CHANNEL *cp);
-extern void            ARTparse(CHANNEL *cp);
-
-extern bool            CHANsleeping(CHANNEL *cp);
-extern CHANNEL      *  CHANcreate(int fd, CHANNELTYPE Type,
-                                  CHANNELSTATE State,
-                                  innd_callback_t Reader,
-                                  innd_callback_t WriteDone);
-extern CHANNEL      *  CHANiter(int *cp, CHANNELTYPE Type);
-extern CHANNEL      *  CHANfromdescriptor(int fd);
-extern char        *   CHANname(const CHANNEL *cp);
-extern int             CHANreadtext(CHANNEL *cp);
-extern void            CHANclose(CHANNEL *cp, const char *name);
-extern void            CHANreadloop(void);
-extern void            CHANsetup(int i);
-extern void            CHANshutdown(void);
-extern void            CHANtracing(CHANNEL *cp, bool Flag);
-extern void            CHANsetActiveCnx(CHANNEL *cp);
-
-extern void            RCHANadd(CHANNEL *cp);
-extern void            RCHANremove(CHANNEL *cp);
-
-extern void            SCHANadd(CHANNEL *cp, time_t Waketime, void *Event,
-                                innd_callback_t Waker, void *Argument);
-extern void            SCHANremove(CHANNEL *cp);
-extern void            SCHANwakeup(void *Event);
-
-extern bool            WCHANflush(CHANNEL *cp);
-extern void            WCHANadd(CHANNEL *cp);
-extern void            WCHANremove(CHANNEL *cp);
-extern void            WCHANsetfrombuffer(CHANNEL *cp, struct buffer *bp);
-
-extern void            CCcopyargv(char *av[]);
-extern const char   *  CCaddhist(char *av[]);
-extern const char   *  CCblock(OPERATINGMODE NewMode, char *reason);
-extern const char   *  CCcancel(char *av[]);
-extern const char   *  CCcheckfile(char *av[]);
-
-extern bool            ICDnewgroup(char *Name, char *Rest);
-extern char        *   ICDreadactive(char **endp);
-extern bool            ICDchangegroup(NEWSGROUP *ngp, char *Rest);
-extern void            ICDclose(void);
-extern bool            ICDrenumberactive(void);
-extern bool            ICDrmgroup(NEWSGROUP *ngp);
-extern void            ICDsetup(bool StartSites);
-extern void            ICDwrite(void);
-extern void            ICDwriteactive(void);
-
-extern void            CCclose(void);
-extern void            CCsetup(void);
-
-extern void             KEYgenerate(HDRCONTENT *, const char *body,
-                                    const char *orig, size_t length);
-
-extern void            LCclose(void);
-extern void            LCsetup(void);
-
-extern int             NGsplit(char *p, int size, LISTBUFFER *List);
-extern NEWSGROUP    *  NGfind(const char *Name);
-extern void            NGclose(void);
-extern CHANNEL     *   NCcreate(int fd, bool MustAuthorize, bool IsLocal);
-extern void            NGparsefile(void);
-extern bool            NGrenumber(NEWSGROUP *ngp);
-extern bool            NGlowmark(NEWSGROUP *ngp, long lomark);
-
-extern void            NCclearwip(CHANNEL *cp);
-extern void            NCclose(void);
-extern void            NCsetup(void);
-extern void            NCwritereply(CHANNEL *cp, const char *text);
-extern void            NCwriteshutdown(CHANNEL *cp, const char *text);
-
-/* perl.c */
-extern char        *   PLartfilter(const ARTDATA *Data, char *artBody, long artLen, int lines);
-extern char        *   PLmidfilter(char *messageID);
-extern void            PLmode(OPERATINGMODE mode, OPERATINGMODE NewMode,
-                              char *reason);
-extern char         *   PLstats(void);
-extern void            PLxsinit(void);
-
-extern int             PROCwatch(pid_t pid, int site);
-extern void            PROCunwatch(int process);
-/* extern void         PROCclose(bool Quickly); */
-extern void            PROCscan(void);
-extern void            PROCsetup(int i);
-
-extern int             RClimit(CHANNEL *cp);
-extern bool            RCnolimit(CHANNEL *cp);
-extern bool            RCauthorized(CHANNEL *cp, char *pass);
-extern int             RCcanpost(CHANNEL *cp, char *group);
-extern char        *   RChostname(const CHANNEL *cp);
-extern char        *   RClabelname(CHANNEL *cp);
-extern void            RCclose(void);
-extern void            RChandoff(int fd, HANDOFF h);
-extern void            RCreadlist(void);
-extern void            RCsetup(int i);
-
-extern bool            SITEfunnelpatch(void);
-extern bool            SITEsetup(SITE *sp);
-extern bool            SITEwantsgroup(SITE *sp, char *name);
-extern bool            SITEpoisongroup(SITE *sp, char *name);
-extern char        **  SITEreadfile(const bool ReadOnly);
-extern SITE        *   SITEfind(const char *p);
-extern SITE        *   SITEfindnext(const char *p, SITE *sp);
-extern const char   *  SITEparseone(char *Entry, SITE *sp,
-                                    char *subbed, char *poison);
-extern void            SITEchanclose(CHANNEL *cp);
-extern void            SITEdrop(SITE *sp);
-extern void            SITEflush(SITE *sp, const bool Restart);
-extern void            SITEflushall(const bool Restart);
-extern void            SITEforward(SITE *sp, const char *text);
-extern void            SITEfree(SITE *sp);
-extern void            SITEinfo(struct buffer *bp, SITE *sp, bool Verbose);
-extern void            SITEparsefile(bool StartSite);
-extern void            SITEprocdied(SITE *sp, int process, PROCESS *pp);
-extern void            SITEsend(SITE *sp, ARTDATA *Data);
-extern void            SITEwrite(SITE *sp, const char *text);
-
-extern void            STATUSinit(void);
-extern void            STATUSmainloophook(void);
-
-extern void            WIPsetup(void);
-extern WIP         *   WIPnew(const char *messageid, CHANNEL *cp);
-extern void            WIPprecomfree(CHANNEL *cp);
-extern void            WIPfree(WIP *wp);
-extern bool            WIPinprogress(const char *msgid, CHANNEL *cp,
-                                     bool Add);
-extern WIP         *   WIPbyid(const char *mesageid);
-extern WIP         *   WIPbyhash(const HASH hash);
-
-/*
-**  TCL globals and functions
-*/
-#if DO_TCL
-extern Tcl_Interp   *  TCLInterpreter;
-extern bool            TCLFilterActive;
-extern struct buffer * TCLCurrArticle;
-extern ARTDATA     *   TCLCurrData;
-
-extern void            TCLfilter(bool value);
-extern void            TCLreadfilter(void);
-extern void            TCLsetup(void);
-extern void            TCLclose(void);
-#endif /* DO_TCL */
-
-/*
-**  Python globals and functions
-*/
-#if DO_PYTHON
-extern bool            PythonFilterActive;
-
-void                   PYfilter(bool value);
-extern const char   *  PYcontrol(char **av);
-extern int             PYreadfilter(void);
-extern char        *   PYartfilter(const ARTDATA *Data, char *artBody, long artLen, int lines);
-extern char        *   PYmidfilter(char *messageID, int msglen);
-extern void            PYmode(OPERATINGMODE mode, OPERATINGMODE newmode,
-                              char *reason);
-extern void            PYsetup(void);
-extern void            PYclose(void);
-#endif /* DO_PYTHON */
-
-END_DECLS
-
-#endif /* INND_H */
diff --git a/innd/inndstart.c b/innd/inndstart.c
deleted file mode 100644 (file)
index 56ac6e6..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*  $Id: inndstart.c 7749 2008-04-06 14:15:04Z iulius $
-**
-**  Open the privileged port, then exec innd.
-**
-**  inndstart, in a normal INN installation, is installed setuid root and
-**  executable only by users in the news group.  Because it is setuid root,
-**  it's very important to ensure that it be as simple and secure as
-**  possible so that news access can't be leveraged into root access.
-**
-**  Fighting against this desire, as much of INN's operation as possible
-**  should be configurable at run-time using inn.conf, and the news system
-**  should be able to an alternate inn.conf by setting INNCONF to the path
-**  to that file before starting any programs.  The configuration data
-**  therefore can't be trusted.
-**
-**  Our security model is therefore:
-**
-**   - The only three operations performed while privileged are determining
-**     the UID and GID of NEWSUSER and NEWSGRP, setting system limits, and
-**     opening the privileged port we're binding to.
-**
-**   - We can only be executed by the NEWSUSER and NEWSGRP, both compile-
-**     time constants; otherwise, we exit.  Similarly, we will only setuid()
-**     to the NEWSUSER.  This is to prevent someone other than the NEWSUSER
-**     but still able to execute inndstart for whatever reason from using it
-**     to run innd as the news user with bogus configuration information,
-**     thereby possibly compromising the news account.
-**
-**   - The only ports < 1024 that we'll bind to are 119 and 433, or a port
-**     given at configure time with --with-innd-port.  This is to prevent
-**     the news user from taking over a service such as telnet or POP and
-**     potentially gaining access to user passwords.
-**
-**  This program therefore gives the news user the ability to revoke system
-**  file descriptor limits and bind to the news port, and nothing else.
-**
-**  Note that we do use getpwnam() to determine the UID of NEWSUSER, which
-**  potentially opens an exploitable hole on those systems that don't
-**  correctly prevent a user running a setuid program from interfering with
-**  the running process (replacing system calls, for example, or using
-**  things like LD_PRELOAD).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <syslog.h>
-
-#ifdef HAVE_INET6
-# include <netdb.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-
-/* Fake up a do-nothing setgroups for Cygwin. */
-#if !HAVE_SETGROUPS
-# define setgroups(n, list)     0
-#endif
-
-/* To run innd under the debugger, uncomment this and fix the path. */
-/* #define DEBUGGER "/usr/ucb/dbx" */
-
-
-int
-main(int argc, char *argv[])
-{
-    struct passwd *pwd;
-    struct group *grp;
-    uid_t news_uid, real_uid;
-    gid_t news_gid;
-    int snum = 0;
-    int port, s[MAX_SOCKETS + 1], i, j;
-#ifdef HAVE_INET6
-    struct in6_addr address6;
-    bool addr6_specified = false;
-#endif
-    struct in_addr address;
-    bool addr_specified = false;
-    char *p;
-    char **innd_argv;
-    char pflag[SMBUF];
-#ifdef PURIFY
-    char *innd_env[11];
-#else
-    char *innd_env[9];
-#endif
-
-    /* Set up the error handlers.  Always print to stderr, and for warnings
-       also syslog with a priority of LOG_ERR.  For fatal errors, also
-       syslog with a priority of LOG_CRIT.  These priority levels are a
-       little high, but they're chosen to match innd. */
-    openlog("inndstart", LOG_CONS, LOG_INN_PROG);
-    message_handlers_warn(2, message_log_stderr, message_log_syslog_err);
-    message_handlers_die(2, message_log_stderr, message_log_syslog_crit);
-    message_program_name = "inndstart";
-
-    /* Convert NEWSUSER and NEWSGRP to a UID and GID.  getpwnam() and
-       getgrnam() don't set errno normally, so don't print strerror() on
-       failure; it probably contains garbage.*/
-    pwd = getpwnam(NEWSUSER);
-    if (!pwd)
-        die("can't getpwnam(%s)", NEWSUSER);
-    news_uid = pwd->pw_uid;
-    grp = getgrnam(NEWSGRP);
-    if (!grp)
-        die("can't getgrnam(%s)", NEWSGRP);
-    news_gid = grp->gr_gid;
-
-    /* Exit if run by any other user or group. */
-    real_uid = getuid();
-    if (real_uid != news_uid)
-        die("must be run by user %s (%lu), not %lu", NEWSUSER,
-                (unsigned long)news_uid, (unsigned long)real_uid);
-
-    /* Drop all supplemental groups and drop privileges to read inn.conf.
-       setgroups() can only be invoked by root, so if inndstart isn't setuid
-       root this is where we fail. */
-    if (setgroups(1, &news_gid) < 0)
-        syswarn("can't setgroups (is inndstart setuid root?)");
-    if (seteuid(news_uid) < 0)
-        sysdie("can't seteuid to %lu", (unsigned long)news_uid);
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Check for a bind address specified in inn.conf.  "any" or "all" will
-       cause inndstart to bind to INADDR_ANY. */
-    address.s_addr = htonl(INADDR_ANY);
-    p = innconf->bindaddress;
-    if (p && strcmp(p, "all") != 0 && strcmp(p, "any") != 0) {
-        if (!inet_aton(p, &address))
-            die("invalid bindaddress in inn.conf (%s)", p);
-        addr_specified = true;
-    }
-#ifdef HAVE_INET6
-    address6 = in6addr_any;
-    p = innconf->bindaddress6;
-    if (p && strcmp(p, "all") != 0 && strcmp(p, "any") != 0) {
-       if (inet_pton(AF_INET6, p, &address6) < 1)
-           die("invalid bindaddress6 in inn.conf (%s)", p);
-        addr6_specified = true;
-    }
-#endif
-
-    /* Parse our command-line options.  The only options we take are -P,
-       which specifies what port number to bind to, and -I, which specifies
-       what IP address to bind to.  Both override inn.conf.  Support both
-       "-P <port>" and "-P<port>".  All other options are passed through to
-       innd. */
-    port = innconf->port;
-    for (i = 1; i < argc; i++) {
-        if (strncmp("-P", argv[i], 2) == 0) {
-            if (strlen(argv[i]) > 2) {
-                port = atoi(&argv[i][2]);
-            } else {
-                i++;
-                if (argv[i] == NULL)
-                    die("missing port after -P");
-                port = atoi(argv[i]);
-            }
-            if (port == 0)
-                die("invalid port %s (must be a number)", argv[i]);
-#ifdef HAVE_INET6
-        } else if (strncmp("-6", argv[i], 2) == 0) {
-            if (strlen(argv[i]) > 2) {
-                p = &argv[i][2];
-            } else {
-                i++;
-                if (argv[i] == NULL)
-                    die("missing address after -6");
-                p = argv[i];
-            }
-            if (inet_pton(AF_INET6, p, &address6) < 1)
-                die("invalid address %s", p);
-           addr6_specified = true;
-#endif
-        } else if (strncmp("-I", argv[i], 2) == 0) {
-            if (strlen(argv[i]) > 2) {
-                p = &argv[i][2];
-            } else {
-                i++;
-                if (argv[i] == NULL)
-                    die("missing address after -I");
-                p = argv[i];
-            }
-            if (!inet_aton(p, &address))
-                die("invalid address %s", p);
-           addr_specified = true;
-        }
-    }
-            
-    /* Make sure that the requested port is legitimate. */
-    if (port < 1024 && port != 119
-#ifdef INND_PORT
-        && port != INND_PORT
-#endif
-        && port != 433)
-        die("can't bind to restricted port %d", port);
-
-    /* Now, regain privileges so that we can change system limits and bind
-       to our desired port. */
-    if (seteuid(0) < 0)
-        sysdie("can't seteuid to 0");
-
-    /* innconf->rlimitnofile <= 0 says to leave it alone. */
-    if (innconf->rlimitnofile > 0 && setfdlimit(innconf->rlimitnofile) < 0)
-        syswarn("can't set file descriptor limit to %ld",
-                innconf->rlimitnofile);
-
-#if defined(HAVE_INET6) && defined(IPV6_V6ONLY)
-    /* If we have the IPV6_V6ONLY socket option, and it works,
-       always open separate IPv4 and IPv6 sockets. */
-    if (addr_specified == 0 && addr6_specified == 0) {
-       j = socket(PF_INET6, SOCK_STREAM, 0);
-       if (j >= 0) {
-           i = 1;
-            if (setsockopt (j, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&i,
-                            sizeof i) == 0) {
-               addr_specified = 1;
-               addr6_specified = 1;
-           }
-           close (j);
-       }
-    }
-#endif
-
-    /* Create a socket and name it. */
-#ifdef HAVE_INET6
-    if( ! (addr_specified || addr6_specified) ) {
-       struct addrinfo hints, *addr, *ressave;
-       char service[16];
-       int error;
-
-       memset(&hints, 0, sizeof hints);
-       hints.ai_family = PF_UNSPEC;
-       hints.ai_flags = AI_PASSIVE;
-       hints.ai_socktype = SOCK_STREAM;
-       snprintf(service, sizeof(service), "%d", port);
-       error = getaddrinfo(NULL, service, &hints, &addr);
-       if (error < 0)
-           die("getaddrinfo: %s", gai_strerror(error));
-
-       for (ressave = addr; addr; addr = addr->ai_next) {
-           if ((i = socket(addr->ai_family, addr->ai_socktype,
-                           addr->ai_protocol)) < 0)
-               continue; /* ignore */
-#ifdef SO_REUSEADDR
-           j = 1;
-           if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, (char *)&j,
-                       sizeof j) < 0)
-               syswarn("can't set SO_REUSEADDR");
-#endif
-           if (bind(i, addr->ai_addr, addr->ai_addrlen) < 0) {
-               j = errno;
-               close(i);
-               errno = j;
-               continue; /* ignore */
-           }
-           s[snum++] = i;
-           if (snum == MAX_SOCKETS)
-               break;
-       }
-       freeaddrinfo(ressave);
-
-       if (snum == 0)
-           sysdie("can't bind socket");
-    } else {
-       if ( addr6_specified ) {
-           struct sockaddr_in6 server6;
-
-           s[snum] = socket(PF_INET6, SOCK_STREAM, 0);
-           if (s[snum] < 0)
-               sysdie("can't open inet6 socket");
-#ifdef SO_REUSEADDR
-           i = 1;
-           if (setsockopt(s[snum], SOL_SOCKET, SO_REUSEADDR, (char *)&i,
-                       sizeof i) < 0)
-               syswarn("can't set SO_REUSEADDR");
-#endif
-#ifdef IPV6_V6ONLY
-           i = 1;
-            if (setsockopt(s[snum], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&i,
-                       sizeof i) < 0)
-               syswarn("can't set IPV6_V6ONLY");
-#endif
-           memset(&server6, 0, sizeof server6);
-           server6.sin6_port = htons(port);
-           server6.sin6_family = AF_INET6;
-           server6.sin6_addr = address6;
-#ifdef HAVE_SOCKADDR_LEN
-           server6.sin6_len = sizeof server6;
-#endif
-           if (bind(s[snum], (struct sockaddr *)&server6, sizeof server6) < 0)
-               sysdie("can't bind inet6 socket");
-           snum++;
-       }
-       if ( addr_specified )
-#endif /* HAVE_INET6 */
-       {
-           struct sockaddr_in server;
-
-           s[snum] = socket(PF_INET, SOCK_STREAM, 0);
-           if (s[snum] < 0)
-               sysdie("can't open inet socket");
-#ifdef SO_REUSEADDR
-           i = 1;
-           if (setsockopt(s[snum], SOL_SOCKET, SO_REUSEADDR, (char *) &i,
-                       sizeof i) < 0)
-               syswarn("can't set SO_REUSEADDR");
-#endif
-           memset(&server, 0, sizeof server);
-           server.sin_port = htons(port);
-           server.sin_family = AF_INET;
-#ifdef HAVE_SOCKADDR_LEN
-           server.sin_len = sizeof server;
-#endif
-           server.sin_addr = address;
-           if (bind(s[snum], (struct sockaddr *)&server, sizeof server) < 0)
-               sysdie("can't bind inet socket");
-           snum++;
-       }
-#ifdef HAVE_INET6
-    }
-#endif
-    s[snum] = -1;
-
-    /* Now, permanently drop privileges. */
-    if (setgid(news_gid) < 0 || getgid() != news_gid)
-        sysdie("can't setgid to %lu", (unsigned long)news_gid);
-    if (setuid(news_uid) < 0 || getuid() != news_uid)
-        sysdie("can't setuid to %lu", (unsigned long)news_uid);
-
-    /* Build the argument vector for innd.  Pass -p<port> to innd to tell it
-       what port we just created and bound to for it. */
-    innd_argv = xmalloc((1 + argc + 1) * sizeof(char *));
-    i = 0;
-    strlcpy(pflag, "-p ", sizeof(pflag));
-    for (j = 0; s[j] > 0; j++) {
-       char temp[16];
-
-       snprintf(temp, sizeof(temp), "%d,", s[j]);
-       strlcat(pflag, temp, sizeof(pflag));
-    }
-    /* chop off the trailing , */
-    j = strlen(pflag) - 1;
-    pflag[j] = '\0';
-#ifdef DEBUGGER
-    innd_argv[i++] = DEBUGGER;
-    innd_argv[i++] = concatpath(innconf->pathbin, "innd");
-    innd_argv[i] = 0;
-    printf("When starting innd, use -d %s\n", s, pflag);
-#else /* DEBUGGER */
-    innd_argv[i++] = concatpath(innconf->pathbin, "innd");
-    innd_argv[i++] = pflag;
-
-    /* Don't pass along -p, -P, or -I.  Check the length of the argument
-       string, and if it == 2 (meaning there's nothing after the -p or -P or
-       -I), skip the next argument too, to support leaving a space between
-       the argument and the value. */
-    for (j = 1; j < argc; j++) {
-        if (argv[j][0] == '-' && strchr("pP6I", argv[j][1])) {
-            if (strlen(argv[j]) == 2)
-                j++;
-            continue;
-        } else {
-            innd_argv[i++] = argv[j];
-        }
-    }
-    innd_argv[i] = 0;
-#endif /* !DEBUGGER */
-
-    /* Set up the environment.  Note that we're trusting BIND_INADDR and TZ;
-       everything else is either from inn.conf or from configure.  These
-       should be sanity-checked before being propagated, but that requires
-       knowledge of the range of possible values.  Just limiting their
-       length doesn't necessarily do anything to prevent exploits and may
-       stop things from working that should.  We have to pass BIND_INADDR so
-       that it's set for programs, such as innfeed, that innd may spawn. */
-    innd_env[0] = concat("PATH=", innconf->pathbin, ":", innconf->pathetc,
-                         ":/bin:/usr/bin:/usr/ucb", (char *) 0);
-    innd_env[1] = concat( "TMPDIR=", innconf->pathtmp,  (char *) 0);
-    innd_env[2] = concat(  "SHELL=", _PATH_SH,          (char *) 0);
-    innd_env[3] = concat("LOGNAME=", NEWSMASTER,        (char *) 0);
-    innd_env[4] = concat(   "USER=", NEWSMASTER,        (char *) 0);
-    innd_env[5] = concat(   "HOME=", innconf->pathnews, (char *) 0);
-    i = 6;
-    p = getenv("BIND_INADDR");
-    if (p != NULL)
-        innd_env[i++] = concat("BIND_INADDR=", p, (char *) 0);
-    p = getenv("TZ");
-    if (p != NULL)
-        innd_env[i++] = concat("TZ=", p, (char *) 0);
-#ifdef PURIFY
-    /* you have to compile with `purify cc -DPURIFY' to get this */
-    p = getenv("DISPLAY");
-    if (p != NULL)
-        innd_env[i++] = concat("DISPLAY=", p, (char *) 0);
-    p = getenv("PURIFYOPTIONS");
-    if (p != NULL)
-        innd_env[i++] = concat("PURIFYOPTIONS=", p, (char *) 0);
-#endif
-    innd_env[i] = 0;
-
-    /* Go exec innd. */
-    execve(innd_argv[0], innd_argv, innd_env);
-    sysdie("can't exec %s", innd_argv[0]);
-
-    /* Not reached. */
-    return 1;
-}
diff --git a/innd/keywords.c b/innd/keywords.c
deleted file mode 100644 (file)
index c4340e8..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/*  $Id: keywords.c 6269 2003-03-28 01:52:36Z rra $
-**
-**  Optional keyword generation code.
-**
-**  Additional code for sake of manufacturing Keywords: headers out of air in
-**  order to provide better (scorable) XOVER data, containing bits of article
-**  body content which have a reasonable expectation of utility.
-**
-**  Basic idea: Simple word-counting.  We find words in the article body,
-**  separated by whitespace.  Remove punctuation.  Sort words, count unique
-**  words, sort those counts.  Write the resulting Keywords: header containing
-**  the poster's original Keywords: (if any) followed by a magic cookie
-**  separator and then the sorted list of words.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "libinn.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-/* If keyword support wasn't requested, stub out the main function provided by
-   this file. */
-#if !DO_KEYWORDS
-void
-KEYgenerate(HDRCONTENT *header UNUSED, const char *body UNUSED,
-            const char *orig UNUSED, size_t length UNUSED)
-{
-}
-
-#else
-
-/* For regex-based common word elimination. */
-#include <regex.h>
-
-#define        MIN_WORD_LENGTH 3       /* 1- and 2-char words don't count. */
-#define        MAX_WORD_LENGTH 28      /* fits "antidisestablishmentarianism". */
-
-/*
-** A trivial structure for keeping track of words via both
-** index to the overall word list and their counts.
-*/
-struct word_entry {
-    int        index;
-    int        length;
-    int        count;
-};
-
-/*
-** Wrapper for qsort(3) comparison of word_entry (frequency).
-*/
-
-static int
-wvec_freq_cmp(const void *p1, const void *p2)
-{
-    return ((const struct word_entry *)p2)->count -    /* decreasing sort */
-           ((const struct word_entry *)p1)->count;
-}
-
-/*
-** Wrapper for qsort(3) comparison of word_entry (word length).
-*/
-
-static int
-wvec_length_cmp(const void *p1, const void *p2)
-{
-    return ((const struct word_entry *)p2)->length -   /* decreasing sort */
-           ((const struct word_entry *)p1)->length;
-}
-
-/*
-** Wrapper for qsort(3), for pointer-to-pointer strings.
-*/
-
-static int
-ptr_strcmp(const void *p1, const void *p2)
-{
-    int cdiff;
-
-    cdiff = (**(const char **)p1) - (**(const char **)p2);
-    if (cdiff)
-       return cdiff;
-    return strcmp((*(const char **)p1)+1, (*(const char **)p2)+1);
-}
-
-/*
-**  Build new Keywords.
-*/
-
-void
-KEYgenerate(
-    HDRCONTENT *hc,    /* header data */
-    const char *body,  /* article body */
-    const char *v,     /* old kw value */
-    size_t     l)      /* old kw length */
-{
-
-    int                word_count, word_length, bodylen, word_index, distinct_words;
-    int                last;
-    char       *text, *orig_text, *text_end, *this_word, *chase, *punc;
-    static struct word_entry   *word_vec;
-    static char                **word;
-    static const char  *whitespace  = " \t\r\n";
-
-    /* ---------------------------------------------------------------- */
-    /* Prototype setup: Regex match preparation. */
-    static     int     regex_lib_init = 0;
-    static     regex_t preg;
-    static const char  *elim_regexp = "^\\([-+/0-9][-+/0-9]*\\|.*1st\\|.*2nd\\|.*3rd\\|.*[04-9]th\\|about\\|after\\|ago\\|all\\|already\\|also\\|among\\|and\\|any\\|anybody\\|anyhow\\|anyone\\|anywhere\\|are\\|bad\\|because\\|been\\|before\\|being\\|between\\|but\\|can\\|could\\|did\\|does\\|doing\\|done\\|dont\\|during\\|eight\\|eighth\\|eleven\\|else\\|elsewhere\\|every\\|everywhere\\|few\\|five\\|fifth\\|first\\|for\\|four\\|fourth\\|from\\|get\\|going\\|gone\\|good\\|got\\|had\\|has\\|have\\|having\\|he\\|her\\|here\\|hers\\|herself\\|him\\|himself\\|his\\|how\\|ill\\|into\\|its\\|ive\\|just\\|kn[eo]w\\|least\\|less\\|let\\|like\\|look\\|many\\|may\\|more\\|m[ou]st\\|myself\\|next\\|nine\\|ninth\\|not\\|now\\|off\\|one\\|only\\|onto\\|our\\|out\\|over\\|really\\|said\\|saw\\|says\\|second\\|see\\|set\\|seven\\|seventh\\|several\\|shall\\|she\\|should\\|since\\|six\\|sixth\\|some\\|somehow\\|someone\\|something\\|somewhere\\|such\\|take\\|ten\\|tenth\\|than\\|that\\|the\\|their\\!|them\\|then\\|there\\|therell\\|theres\\|these\\|they\\|thing\\|things\\|third\\|this\\|those\\|three\\|thus\\|together\\|told\\|too\\|twelve\\|two\\|under\\|upon\\|very\\|via\\|want\\|wants\\|was\\|wasnt\\|way\\|were\\|weve\\|what\\|whatever\\|when\\|where\\|wherell\\|wheres\\|whether\\|which\\|while\\|who\\|why\\|will\\|will\\|with\\|would\\|write\\|writes\\|wrote\\|yes\\|yet\\|you\\|your\\|youre\\|yourself\\)$";
-
-    if (word_vec == 0) {
-       word_vec = xmalloc(innconf->keymaxwords * sizeof(struct word_entry));
-       if (word_vec == 0)
-           return;
-       word = xmalloc(innconf->keymaxwords * sizeof(char *));
-       if (word == NULL) {
-           free(word_vec);
-           return;
-       }
-    }
-
-    if (regex_lib_init == 0) {
-       regex_lib_init++;
-
-       if (regcomp(&preg, elim_regexp, REG_ICASE|REG_NOSUB) != 0) {
-           syslog(L_FATAL, "%s regcomp failure", LogName);
-           abort();
-       }
-    }
-    /* ---------------------------------------------------------------- */
-
-    /* first re-init kw from original value. */
-    if (l > innconf->keylimit - (MAX_WORD_LENGTH+5))   /* mostly arbitrary cutoff: */
-        l = innconf->keylimit - (MAX_WORD_LENGTH+5);   /* room for minimal word vec */
-    hc->Value = xmalloc(innconf->keylimit+1);
-    if ((v != NULL) && (*v != '\0')) {
-        memcpy(hc->Value, v, l);
-        hc->Value[l] = '\0';
-    } else
-        *hc->Value = '\0';
-    l = hc->Length = strlen(hc->Value);
-
-    /*
-     * now figure acceptable extents, and copy body to working string.
-     * (Memory-intensive for hefty articles: limit to non-ABSURD articles.)
-     */
-    bodylen = strlen(body);
-    if ((bodylen < 100) || (bodylen > innconf->keyartlimit)) /* too small/big to bother */
-       return;
-
-    orig_text = text = xstrdup(body);  /* orig_text is for free() later on */
-
-    text_end = text + bodylen;
-
-    /* abusive punctuation stripping: turn it all into SPCs. */
-    for (punc = text; *punc; punc++)
-       if (!CTYPE(isalpha, *punc))
-           *punc = ' ';
-
-    /* move to first word. */
-    text += strspn(text, whitespace);
-    word_count = 0;
-
-    /* hunt down words */
-    while ((text < text_end) &&                /* while there might be words... */
-          (*text != '\0') &&
-          (word_count < innconf->keymaxwords)) {
-
-       /* find a word. */
-       word_length = strcspn(text, whitespace);
-       if (word_length == 0)
-           break;                      /* no words left */
-
-       /* bookkeep to save word location, then move through text. */
-       word[word_count++] = this_word = text;
-       text += word_length;
-       *(text++) = '\0';
-       text += strspn(text, whitespace);       /* move to next word. */
-
-       /* 1- and 2-char words don't count, nor do excessively long ones. */
-       if ((word_length < MIN_WORD_LENGTH) ||
-           (word_length > MAX_WORD_LENGTH)) {
-           word_count--;
-           continue;
-       }
-
-       /* squash to lowercase. */
-       for (chase = this_word; *chase; chase++)
-           if (CTYPE(isupper, *chase))
-               *chase = tolower(*chase);
-    }
-
-    /* If there were no words, we're done. */
-    if (word_count < 1)
-       goto out;
-
-    /* Sort the words. */
-    qsort(word, word_count, sizeof(word[0]), ptr_strcmp);
-
-    /* Count unique words. */
-    distinct_words = 0;                        /* the 1st word is "pre-figured". */
-    word_vec[0].index = 0;
-    word_vec[0].length = strlen(word[0]);
-    word_vec[0].count = 1;
-
-    for (word_index = 1;               /* we compare (N-1)th and Nth words. */
-        word_index < word_count;
-        word_index++) {
-       if (strcmp(word[word_index-1], word[word_index]) == 0)
-           word_vec[distinct_words].count++;
-       else {
-           distinct_words++;
-           word_vec[distinct_words].index = word_index;
-           word_vec[distinct_words].length = strlen(word[word_index]);
-           word_vec[distinct_words].count = 1;
-       }
-    }
-
-    /* Sort the counts. */
-    distinct_words++;                  /* we were off-by-1 until this. */
-    qsort(word_vec, distinct_words, sizeof(struct word_entry), wvec_freq_cmp);
-
-    /* Sub-sort same-frequency words on word length. */
-    for (last = 0, word_index = 1;     /* again, (N-1)th and Nth entries. */
-        word_index < distinct_words;
-        word_index++) {
-       if (word_vec[last].count != word_vec[word_index].count) {
-           if ((word_index - last) != 1)       /* 2+ entries to sub-sort. */
-               qsort(&word_vec[last], word_index - last,
-                     sizeof(struct word_entry), wvec_length_cmp);
-           last = word_index;
-       }
-    }
-    /* do it one last time for the only-one-appearance words. */
-    if ((word_index - last) != 1)
-       qsort(&word_vec[last], word_index - last,
-             sizeof(struct word_entry), wvec_length_cmp);
-
-    /* Scribble onto end of Keywords:. */
-    strcpy(hc->Value + l, ",\377");            /* magic separator, 'ÿ' */
-    for (chase = hc->Value + l + 2, word_index = 0;
-        word_index < distinct_words;
-        word_index++) {
-       /* ---------------------------------------------------------------- */
-       /* "noise" words don't count */
-       if (regexec(&preg, word[word_vec[word_index].index], 0, NULL, 0) == 0)
-           continue;
-       /* ---------------------------------------------------------------- */
-
-       /* add to list. */
-       *chase++ = ',';
-       strcpy(chase, word[word_vec[word_index].index]);
-       chase += word_vec[word_index].length;
-
-       if (chase - hc->Value > (innconf->keylimit - (MAX_WORD_LENGTH + 4)))
-           break;
-    }
-    /* note #words we didn't get to add. */
-    /* This code can potentially lead to a buffer overflow if the number of
-       ignored words is greater than 100, under some circumstances.  It's
-       temporarily disabled until fixed. */
-    hc->Length = strlen(hc->Value);
-
-out:
-    /* We must dispose of the original strdup'd text area. */
-    free(orig_text);
-}
-
-#endif /* DO_KEYWORDS */
diff --git a/innd/lc.c b/innd/lc.c
deleted file mode 100644 (file)
index 4e16daf..0000000
--- a/innd/lc.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*  $Id: lc.c 6155 2003-01-19 19:58:25Z rra $
-**
-**  Routines for the local connect channel.  Create a Unix-domain stream
-**  socket that processes on the local server connect to.  Once the
-**  connection is set up, we speak NNTP.  The connect channel is used only
-**  by rnews to feed in articles from the UUCP sites.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-
-#if HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-
-static char    *LCpath = NULL;
-static CHANNEL *LCchan;
-
-
-/*
-**  Read function.  Accept the connection and create an NNTP channel.
-*/
-static void
-LCreader(CHANNEL *cp)
-{
-    int                fd;
-    CHANNEL    *new;
-
-    if (cp != LCchan) {
-       syslog(L_ERROR, "%s internal LCreader wrong channel 0x%p not 0x%p",
-           LogName, (void *)cp, (void *)LCchan);
-       return;
-    }
-
-    if ((fd = accept(cp->fd, NULL, NULL)) < 0) {
-       syslog(L_ERROR, "%s cant accept CCreader %m", LogName);
-       return;
-    }
-    if ((new = NCcreate(fd, false, true)) != NULL) {
-       memset( &new->Address, 0, sizeof( new->Address ) );
-       syslog(L_NOTICE, "%s connected %d", "localhost", new->fd);
-       NCwritereply(new, (char *)NCgreeting);
-    }
-}
-
-
-/*
-**  Write-done function.  Shouldn't happen.
-*/
-static void
-LCwritedone(CHANNEL *unused)
-{
-    unused = unused;           /* ARGSUSED */
-    syslog(L_ERROR, "%s internal LCwritedone", LogName);
-}
-
-#endif /* HAVE_UNIX_DOMAIN_SOCKETS */
-
-
-/*
-**  Create the channel.
-*/
-void
-LCsetup(void)
-{
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    int                        i;
-    struct sockaddr_un server;
-
-    if (LCpath == NULL)
-       LCpath = concatpath(innconf->pathrun, _PATH_NNTPCONNECT);
-    /* Remove old detritus. */
-    if (unlink(LCpath) < 0 && errno != ENOENT) {
-       syslog(L_FATAL, "%s cant unlink %s %m", LogName, LCpath);
-       exit(1);
-    }
-
-    /* Create a socket and name it. */
-    if ((i = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-       syslog(L_FATAL, "%s cant socket %s %m", LogName, LCpath);
-       exit(1);
-    }
-    memset(&server, 0, sizeof server);
-    server.sun_family = AF_UNIX;
-    strlcpy(server.sun_path, LCpath, sizeof(server.sun_path));
-    if (bind(i, (struct sockaddr *) &server, SUN_LEN(&server)) < 0) {
-       syslog(L_FATAL, "%s cant bind %s %m", LogName, LCpath);
-       exit(1);
-    }
-
-    /* Set it up to wait for connections. */
-    if (listen(i, MAXLISTEN) < 0) {
-       syslog(L_FATAL, "%s cant listen %s %m", LogName, LCpath);
-       exit(1);
-    }
-    LCchan = CHANcreate(i, CTlocalconn, CSwaiting, LCreader, LCwritedone);
-    syslog(L_NOTICE, "%s lcsetup %s", LogName, CHANname(LCchan));
-    RCHANadd(LCchan);
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-}
-
-
-/*
-**  Cleanly shut down the channel.
-*/
-void
-LCclose(void)
-{
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    CHANclose(LCchan, CHANname(LCchan));
-    LCchan = NULL;
-    if (unlink(LCpath) < 0)
-       syslog(L_ERROR, "%s cant unlink %s %m", LogName, LCpath);
-    free(LCpath);
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-}
diff --git a/innd/nc.c b/innd/nc.c
deleted file mode 100644 (file)
index c27f45f..0000000
--- a/innd/nc.c
+++ /dev/null
@@ -1,1462 +0,0 @@
-/*  $Id: nc.c 7418 2005-10-09 04:37:05Z eagle $
-**
-**  Routines for the NNTP channel.  Other channels get the descriptors which
-**  we turn into NNTP channels, and over which we speak NNTP.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-#define BAD_COMMAND_COUNT      10
-
-
-/*
-**  An entry in the dispatch table.  The name, and implementing function,
-**  of every command we support.
-*/
-typedef struct _NCDISPATCH {
-    const char *        Name;
-    innd_callback_t     Function;
-    int                 Size;
-} NCDISPATCH;
-
-/* The functions that implement the various commands. */
-static void NCauthinfo(CHANNEL *cp);
-static void NCcancel(CHANNEL *cp);
-static void NCcheck(CHANNEL *cp);
-static void NChead(CHANNEL *cp);
-static void NChelp(CHANNEL *cp);
-static void NCihave(CHANNEL *cp);
-static void NClist(CHANNEL *cp);
-static void NCmode(CHANNEL *cp);
-static void NCquit(CHANNEL *cp);
-static void NCstat(CHANNEL *cp);
-static void NCtakethis(CHANNEL *cp);
-static void NCxbatch(CHANNEL *cp);
-
-/* Handlers for unimplemented commands.  We need two handlers so that we can
-   return the right status code; reader commands that are required by the
-   standard must return a 502 error rather than a 500 error. */
-static void NC_reader(CHANNEL *cp);
-static void NC_unimp(CHANNEL *cp);
-
-/* Supporting functions. */
-static void NCwritedone(CHANNEL *cp);
-
-/* Set up the dispatch table for all of the commands. */
-#define COMMAND(name, func) { name, func, sizeof(name) - 1 }
-static NCDISPATCH NCcommands[] = {
-    COMMAND("authinfo",  NCauthinfo),
-    COMMAND("check",     NCcheck),
-    COMMAND("head",      NChead),
-    COMMAND("help",      NChelp),
-    COMMAND("ihave",     NCihave),
-    COMMAND("list",      NClist),
-    COMMAND("mode",      NCmode),
-    COMMAND("quit",      NCquit),
-    COMMAND("stat",      NCstat),
-    COMMAND("takethis",  NCtakethis),
-    COMMAND("xbatch",    NCxbatch),
-
-    /* Unimplemented reader commands which may become available after a MODE
-       READER command. */
-    COMMAND("article",   NC_reader),
-    COMMAND("body",      NC_reader),
-    COMMAND("group",     NC_reader),
-    COMMAND("last",      NC_reader),
-    COMMAND("newgroups", NC_reader),
-    COMMAND("newnews",   NC_reader),
-    COMMAND("next",      NC_reader),
-    COMMAND("post",      NC_reader),
-
-    /* Other unimplemented standard commands. */
-    COMMAND("date",      NC_unimp),
-    COMMAND("slave",     NC_unimp)
-};
-#undef COMMAND
-
-/* Number of open connections. */
-static int NCcount;
-
-static char            *NCquietlist[] = { INND_QUIET_BADLIST };
-static const char      NCterm[] = "\r\n";
-static const char      NCdot[] = "." ;
-static const char      NCbadcommand[] = NNTP_BAD_COMMAND;
-static const char       NCbadsubcommand[] = NNTP_BAD_SUBCMD;
-
-/*
-** Clear the WIP entry for the given channel
-*/
-void
-NCclearwip(CHANNEL *cp)
-{
-    WIPfree(WIPbyhash(cp->CurrentMessageIDHash));
-    HashClear(&cp->CurrentMessageIDHash);
-    cp->ArtBeg = 0;
-}
-
-/*
-**  Write an NNTP reply message.
-**
-**  Tries to do the actual write immediately if it will not block and if there
-**  is not already other buffered output.  Then, if the write is successful,
-**  calls NCwritedone (which does whatever is necessary to accommodate state
-**  changes).  Else, NCwritedone will be called from the main select loop
-**  later.
-**
-**  If the reply that we are writing now is associated with a state change,
-**  then cp->State must be set to its new value *before* NCwritereply is
-**  called.
-*/
-void
-NCwritereply(CHANNEL *cp, const char *text)
-{
-    struct buffer *bp;
-    int i;
-
-    /* XXX could do RCHANremove(cp) here, as the old NCwritetext() used to
-     * do, but that would be wrong if the channel is sreaming (because it
-     * would zap the channell's input buffer).  There's no harm in
-     * never calling RCHANremove here.  */
-
-    bp = &cp->Out;
-    i = bp->left;
-    WCHANappend(cp, text, strlen(text));       /* text in buffer */
-    WCHANappend(cp, NCterm, strlen(NCterm));   /* add CR NL to text */
-
-    if (i == 0) {      /* if only data then try to write directly */
-       i = write(cp->fd, &bp->data[bp->used], bp->left);
-       if (Tracing || cp->Tracing)
-           syslog(L_TRACE, "%s NCwritereply %d=write(%d, \"%.15s\", %lu)",
-               CHANname(cp), i, cp->fd, &bp->data[bp->used],
-               (unsigned long) bp->left);
-       if (i > 0)
-            bp->used += i;
-       if (bp->used == bp->left) {
-           /* all the data was written */
-           bp->used = bp->left = 0;
-           NCwritedone(cp);
-       } else {
-            bp->left -= i;
-            i = 0;
-        }
-    } else i = 0;
-    if (i <= 0) {      /* write failed, queue it for later */
-       WCHANadd(cp);
-    }
-    if (Tracing || cp->Tracing)
-       syslog(L_TRACE, "%s > %s", CHANname(cp), text);
-}
-
-/*
-**  Tell the NNTP channel to go away.
-*/
-void
-NCwriteshutdown(CHANNEL *cp, const char *text)
-{
-    cp->State = CSwritegoodbye;
-    RCHANremove(cp); /* we're not going to read anything more */
-    WCHANappend(cp, NNTP_GOODBYE, strlen(NNTP_GOODBYE));
-    WCHANappend(cp, " ", 1);
-    WCHANappend(cp, text, (int)strlen(text));
-    WCHANappend(cp, NCterm, strlen(NCterm));
-    WCHANadd(cp);
-}
-
-
-/*
-**  If a Message-ID is bad, write a reject message and return true.
-*/
-static bool
-NCbadid(CHANNEL *cp, char *p)
-{
-    if (ARTidok(p))
-       return false;
-
-    NCwritereply(cp, NNTP_HAVEIT_BADID);
-    syslog(L_NOTICE, "%s bad_messageid %s", CHANname(cp), MaxLength(p, p));
-    return true;
-}
-
-
-/*
-**  We have an entire article collected; try to post it.  If we're
-**  not running, drop the article or just pause and reschedule.
-*/
-static void
-NCpostit(CHANNEL *cp)
-{
-  bool postok;
-  const char   *response;
-  char buff[SMBUF];
-
-  /* Note that some use break, some use return here. */
-  if ((postok = ARTpost(cp)) != 0) {
-    cp->Received++;
-    if (cp->Sendid.size > 3) { /* We be streaming */
-      cp->Takethis_Ok++;
-      snprintf(buff, sizeof(buff), "%d", NNTP_OK_RECID_VAL);
-      cp->Sendid.data[0] = buff[0];
-      cp->Sendid.data[1] = buff[1];
-      cp->Sendid.data[2] = buff[2];
-      response = cp->Sendid.data;
-    } else
-      response = NNTP_TOOKIT;
-  } else {
-    cp->Rejected++;
-    if (cp->Sendid.size)
-      response = cp->Sendid.data;
-    else
-      response = cp->Error;
-  }
-  cp->Reported++;
-  if (cp->Reported >= innconf->nntpactsync) {
-    snprintf(buff, sizeof(buff), "accepted size %.0f duplicate size %.0f",
-             cp->Size, cp->DuplicateSize);
-    syslog(L_NOTICE,
-      "%s checkpoint seconds %ld accepted %ld refused %ld rejected %ld duplicate %ld %s",
-      CHANname(cp), (long)(Now.time - cp->Started),
-    cp->Received, cp->Refused, cp->Rejected,
-    cp->Duplicate, buff);
-    cp->Reported = 0;
-  }
-  if (Mode == OMthrottled) {
-    NCwriteshutdown(cp, ModeReason);
-    return;
-  }
-  cp->State = CSgetcmd;
-  NCwritereply(cp, response);
-}
-
-
-/*
-**  Write-done function.  Close down or set state for what we expect to
-**  read next.
-*/
-static void
-NCwritedone(CHANNEL *cp)
-{
-    switch (cp->State) {
-    default:
-       syslog(L_ERROR, "%s internal NCwritedone state %d",
-           CHANname(cp), cp->State);
-       break;
-
-    case CSwritegoodbye:
-       if (NCcount > 0)
-           NCcount--;
-       CHANclose(cp, CHANname(cp));
-       break;
-
-    case CSgetcmd:
-    case CSgetauth:
-    case CSgetheader:
-    case CSgetbody:
-    case CSgetxbatch:
-    case CSgotlargearticle:
-    case CScancel:
-       RCHANadd(cp);
-       break;
-    }
-}
-
-\f
-
-/*
-**  The "head" command.
-*/
-static void
-NChead(CHANNEL *cp)
-{
-    char               *p;
-    TOKEN              token;
-    ARTHANDLE          *art;
-
-    /* Snip off the Message-ID. */
-    for (p = cp->In.data + cp->Start + strlen("head"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    if (NCbadid(cp, p))
-       return;
-
-    /* Get the article token and retrieve it. */
-    if (!HISlookup(History, p, NULL, NULL, NULL, &token)) {
-       NCwritereply(cp, NNTP_DONTHAVEIT);
-       return;
-    }
-    if ((art = SMretrieve(token, RETR_HEAD)) == NULL) {
-       NCwritereply(cp, NNTP_DONTHAVEIT);
-       return;
-    }
-
-    /* Write it. */
-    WCHANappend(cp, NNTP_HEAD_FOLLOWS, strlen(NNTP_HEAD_FOLLOWS));
-    WCHANappend(cp, " 0 ", 3);
-    WCHANappend(cp, p, strlen(p));
-    WCHANappend(cp, NCterm, strlen(NCterm));
-    WCHANappend(cp, art->data, art->len);
-
-    /* Write the terminator. */
-    NCwritereply(cp, NCdot);
-    SMfreearticle(art);
-}
-
-
-/*
-**  The "stat" command.
-*/
-static void
-NCstat(CHANNEL *cp)
-{
-    char               *p;
-    TOKEN              token;
-    ARTHANDLE          *art;
-    char               *buff;
-    size_t              length;
-
-    /* Snip off the Message-ID. */
-    for (p = cp->In.data + cp->Start + strlen("stat"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    if (NCbadid(cp, p))
-       return;
-
-    /* Get the article filenames; open the first file (to make sure
-     * the article is still here). */
-    if (!HISlookup(History, p, NULL, NULL, NULL, &token)) {
-       NCwritereply(cp, NNTP_DONTHAVEIT);
-       return;
-    }
-    if ((art = SMretrieve(token, RETR_STAT)) == NULL) {
-       NCwritereply(cp, NNTP_DONTHAVEIT);
-       return;
-    }
-    SMfreearticle(art);
-
-    /* Write the message. */
-    length = snprintf(NULL, 0, "%d 0 %s", NNTP_NOTHING_FOLLOWS_VAL, p) + 1;
-    buff = xmalloc(length);
-    snprintf(buff, length, "%d 0 %s", NNTP_NOTHING_FOLLOWS_VAL, p);
-    NCwritereply(cp, buff);
-    free(buff);
-}
-
-
-/*
-**  The "authinfo" command.  Actually, we come in here whenever the
-**  channel is in CSgetauth state and we just got a command.
-*/
-static void
-NCauthinfo(CHANNEL *cp)
-{
-    static char                AUTHINFO[] = "authinfo ";
-    static char                PASS[] = "pass ";
-    static char                USER[] = "user ";
-    char               *p;
-
-    p = cp->In.data + cp->Start;
-    cp->Start = cp->Next;
-
-    /* Allow the poor sucker to quit. */
-    if (strcasecmp(p, "quit") == 0) {
-       NCquit(cp);
-       return;
-    }
-
-    /* Otherwise, make sure we're only getting "authinfo" commands. */
-    if (strncasecmp(p, AUTHINFO, strlen(AUTHINFO)) != 0) {
-       NCwritereply(cp, NNTP_AUTH_NEEDED);
-       return;
-    }
-    for (p += strlen(AUTHINFO); ISWHITE(*p); p++)
-       continue;
-
-    /* Ignore "authinfo user" commands, since we only care about the
-     * password. */
-    if (strncasecmp(p, USER, strlen(USER)) == 0) {
-       NCwritereply(cp, NNTP_AUTH_NEXT);
-       return;
-    }
-
-    /* Now make sure we're getting only "authinfo pass" commands. */
-    if (strncasecmp(p, PASS, strlen(PASS)) != 0) {
-       NCwritereply(cp, NNTP_AUTH_NEEDED);
-       return;
-    }
-    for (p += strlen(PASS); ISWHITE(*p); p++)
-       continue;
-
-    /* Got the password -- is it okay? */
-    if (!RCauthorized(cp, p)) {
-       cp->State = CSwritegoodbye;
-       NCwritereply(cp, NNTP_AUTH_BAD);
-    } else {
-       cp->State = CSgetcmd;
-       NCwritereply(cp, NNTP_AUTH_OK);
-    }
-}
-
-/*
-**  The "help" command.
-*/
-static void
-NChelp(CHANNEL *cp)
-{
-    static char                LINE1[] = "For more information, contact \"";
-    static char                LINE2[] = "\" at this machine.";
-    NCDISPATCH         *dp;
-
-    WCHANappend(cp, NNTP_HELP_FOLLOWS,strlen(NNTP_HELP_FOLLOWS));
-    WCHANappend(cp, NCterm,strlen(NCterm));
-    for (dp = NCcommands; dp < ARRAY_END(NCcommands); dp++)
-       if (dp->Function != NC_unimp) {
-            if ((!StreamingOff && cp->Streaming) ||
-                (dp->Function != NCcheck && dp->Function != NCtakethis)) {
-                WCHANappend(cp, "\t", 1);
-                WCHANappend(cp, dp->Name, dp->Size);
-                WCHANappend(cp, NCterm, strlen(NCterm));
-            }
-       }
-    WCHANappend(cp, LINE1, strlen(LINE1));
-    WCHANappend(cp, NEWSMASTER, strlen(NEWSMASTER));
-    WCHANappend(cp, LINE2, strlen(LINE2));
-    WCHANappend(cp, NCterm, strlen(NCterm));
-    NCwritereply(cp, NCdot) ;
-    cp->Start = cp->Next;
-}
-
-/*
-**  The "ihave" command.  Check the Message-ID, and see if we want the
-**  article or not.  Set the state appropriately.
-*/
-static void
-NCihave(CHANNEL *cp)
-{
-    char       *p;
-#if defined(DO_PERL) || defined(DO_PYTHON)
-    char       *filterrc;
-    int                msglen;
-#endif /*defined(DO_PERL) || defined(DO_PYTHON) */
-
-    cp->Ihave++;
-    /* Snip off the Message-ID. */
-    for (p = cp->In.data + cp->Start + strlen("ihave"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    if (NCbadid(cp, p))
-       return;
-
-    if ((innconf->refusecybercancels) && (strncmp(p, "<cancel.", 8) == 0)) {
-       cp->Refused++;
-       cp->Ihave_Cybercan++;
-       NCwritereply(cp, NNTP_HAVEIT);
-       return;
-    }
-
-#if defined(DO_PERL)
-    /*  Invoke a perl message filter on the message ID. */
-    filterrc = PLmidfilter(p);
-    if (filterrc) {
-        cp->Refused++;
-        msglen = strlen(p) + 5; /* 3 digits + space + id + null */
-        if (cp->Sendid.size < msglen) {
-            if (cp->Sendid.size > 0) free(cp->Sendid.data);
-            if (msglen > MAXHEADERSIZE)
-                cp->Sendid.size = msglen;
-            else
-                cp->Sendid.size = MAXHEADERSIZE;
-            cp->Sendid.data = xmalloc(cp->Sendid.size);
-        }
-        snprintf(cp->Sendid.data, cp->Sendid.size, "%d %.200s",
-                 NNTP_HAVEIT_VAL, filterrc);
-        NCwritereply(cp, cp->Sendid.data);
-        free(cp->Sendid.data);
-        cp->Sendid.size = 0;
-        return;
-    }
-#endif
-
-#if defined(DO_PYTHON)
-    /*  invoke a Python message filter on the message id */
-    msglen = strlen(p);
-    TMRstart(TMR_PYTHON);
-    filterrc = PYmidfilter(p, msglen);
-    TMRstop(TMR_PYTHON);
-    if (filterrc) {
-       cp->Refused++;
-       msglen += 5; /* 3 digits + space + id + null */
-       if (cp->Sendid.size < msglen) {
-           if (cp->Sendid.size > 0)
-               free(cp->Sendid.data);
-           if (msglen > MAXHEADERSIZE)
-               cp->Sendid.size = msglen;
-           else
-               cp->Sendid.size = MAXHEADERSIZE;
-           cp->Sendid.data = xmalloc(cp->Sendid.size);
-       }
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %.200s",
-                 NNTP_HAVEIT_VAL, filterrc);
-       NCwritereply(cp, cp->Sendid.data);
-       free(cp->Sendid.data);
-       cp->Sendid.size = 0;
-       return;
-    }
-#endif
-
-    if (HIScheck(History, p)) {
-       cp->Refused++;
-       cp->Ihave_Duplicate++;
-       NCwritereply(cp, NNTP_HAVEIT);
-    }
-    else if (WIPinprogress(p, cp, false)) {
-       cp->Ihave_Deferred++;
-       if (cp->NoResendId) {
-           cp->Refused++;
-           NCwritereply(cp, NNTP_HAVEIT);
-       } else {
-           NCwritereply(cp, NNTP_RESENDIT_LATER);
-       }
-    }
-    else {
-       if (cp->Sendid.size > 0) {
-            free(cp->Sendid.data);
-           cp->Sendid.size = 0;
-       }
-       cp->Ihave_SendIt++;
-       NCwritereply(cp, NNTP_SENDIT);
-       cp->ArtBeg = Now.time;
-       cp->State = CSgetheader;
-       ARTprepare(cp);
-    }
-}
-
-/* 
-** The "xbatch" command. Set the state appropriately.
-*/
-
-static void
-NCxbatch(CHANNEL *cp)
-{
-    char       *p;
-
-    /* Snip off the batch size */
-    for (p = cp->In.data + cp->Start + strlen("xbatch"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-
-    if (cp->XBatchSize) {
-        syslog(L_FATAL, "NCxbatch(): oops, cp->XBatchSize already set to %d",
-              cp->XBatchSize);
-    }
-
-    cp->XBatchSize = atoi(p);
-    if (Tracing || cp->Tracing)
-        syslog(L_TRACE, "%s will read batch of size %d",
-              CHANname(cp), cp->XBatchSize);
-
-    if (cp->XBatchSize <= 0 || ((innconf->maxartsize != 0) && (innconf->maxartsize < cp->XBatchSize))) {
-        syslog(L_NOTICE, "%s got bad xbatch size %d",
-              CHANname(cp), cp->XBatchSize);
-       NCwritereply(cp, NNTP_XBATCH_BADSIZE);
-       return;
-    }
-
-    /* we prefer not to touch the buffer, NCreader() does enough magic
-     * with it
-     */
-    cp->State = CSgetxbatch;
-    NCwritereply(cp, NNTP_CONT_XBATCH);
-}
-
-/*
-**  The "list" command.  Send the active file.
-*/
-static void
-NClist(CHANNEL *cp)
-{
-    char *p, *q, *trash, *end, *path;
-
-    for (p = cp->In.data + cp->Start + strlen("list"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    if (cp->Nolist) {
-       NCwritereply(cp, NCbadcommand);
-       return;
-    }
-    if (strcasecmp(p, "newsgroups") == 0) {
-        path = concatpath(innconf->pathdb, _PATH_NEWSGROUPS);
-       trash = p = ReadInFile(path, NULL);
-        free(path);
-       if (p == NULL) {
-           NCwritereply(cp, NCdot);
-           return;
-       }
-       end = p + strlen(p);
-    }
-    else if (strcasecmp(p, "active.times") == 0) {
-        path = concatpath(innconf->pathdb, _PATH_ACTIVETIMES);
-       trash = p = ReadInFile(path, NULL);
-        free(path);
-       if (p == NULL) {
-           NCwritereply(cp, NCdot);
-           return;
-       }
-       end = p + strlen(p);
-    }
-    else if (*p == '\0' || (strcasecmp(p, "active") == 0)) {
-       p = ICDreadactive(&end);
-       trash = NULL;
-    }
-    else {
-       NCwritereply(cp, NCbadsubcommand);
-       return;
-    }
-
-    /* Loop over all lines, sending the text and \r\n. */
-    WCHANappend(cp, NNTP_LIST_FOLLOWS,strlen(NNTP_LIST_FOLLOWS));
-    WCHANappend(cp, NCterm, strlen(NCterm)) ;
-    for (; p < end && (q = strchr(p, '\n')) != NULL; p = q + 1) {
-       WCHANappend(cp, p, q - p);
-       WCHANappend(cp, NCterm, strlen(NCterm));
-    }
-    NCwritereply(cp, NCdot);
-    if (trash)
-       free(trash);
-}
-
-
-/*
-**  The "mode" command.  Hand off the channel.
-*/
-static void
-NCmode(CHANNEL *cp)
-{
-    char               *p;
-    HANDOFF            h;
-
-    /* Skip the first word, get the argument. */
-    for (p = cp->In.data + cp->Start + strlen("mode"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-
-    if (strcasecmp(p, "reader") == 0 && !innconf->noreader)
-       h = HOnnrpd;
-    else if (strcasecmp(p, "stream") == 0 &&
-             (!StreamingOff && cp->Streaming)) {
-       char buff[16];
-
-       snprintf(buff, sizeof(buff), "%d StreamOK.", NNTP_OK_STREAM_VAL);
-       NCwritereply(cp, buff);
-       syslog(L_NOTICE, "%s NCmode \"mode stream\" received",
-               CHANname(cp));
-       return;
-    } else if (strcasecmp(p, "cancel") == 0 && cp->privileged) {
-       char buff[16];
-
-       cp->State = CScancel;
-       snprintf(buff, sizeof(buff), "%d CancelOK.", NNTP_OK_CANCEL_VAL);
-       NCwritereply(cp, buff);
-       syslog(L_NOTICE, "%s NCmode \"mode cancel\" received",
-               CHANname(cp));
-       return;
-    } else {
-       NCwritereply(cp, NCbadsubcommand);
-       return;
-    }
-    RChandoff(cp->fd, h);
-    if (NCcount > 0)
-       NCcount--;
-    CHANclose(cp, CHANname(cp));
-}
-
-
-/*
-**  The "quit" command.  Acknowledge, and set the state to closing down.
-*/
-static void
-NCquit(CHANNEL *cp)
-{
-    cp->State = CSwritegoodbye;
-    NCwritereply(cp, NNTP_GOODBYE_ACK);
-}
-
-
-/*
-**  The catch-all for reader commands, which should return a different status
-**  than just "unrecognized command" since a change of state may make them
-**  available.
-*/
-static void
-NC_reader(CHANNEL *cp)
-{
-    cp->Start = cp->Next;
-    NCwritereply(cp, NNTP_ACCESS);
-}
-
-
-/*
-**  The catch-all for inimplemented commands.
-*/
-static void
-NC_unimp(CHANNEL *cp)
-{
-    char               *p, *q;
-    char               buff[SMBUF];
-
-    /* Nip off the first word. */
-    for (p = q = cp->In.data + cp->Start; *p && !ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    *p = '\0';
-    snprintf(buff, sizeof(buff), "%d \"%s\" not implemented; try \"help\".",
-             NNTP_BAD_COMMAND_VAL, MaxLength(q, q));
-    NCwritereply(cp, buff);
-}
-
-\f
-
-/*
-**  Check whatever data is available on the channel.  If we got the
-**  full amount (i.e., the command or the whole article) process it.
-*/
-static void
-NCproc(CHANNEL *cp)
-{
-  char         *p, *q;
-  NCDISPATCH           *dp;
-  struct buffer        *bp;
-  char         buff[SMBUF];
-  int          i, j;
-  bool         readmore, movedata;
-  ARTDATA      *data = &cp->Data;
-  HDRCONTENT    *hc = data->HdrContent;
-
-  readmore = movedata = false;
-  if (Tracing || cp->Tracing)
-    syslog(L_TRACE, "%s NCproc Used=%lu", CHANname(cp),
-           (unsigned long) cp->In.used);
-
-  bp = &cp->In;
-  if (bp->used == 0)
-    return;
-
-  for ( ; ; ) {
-    if (Tracing || cp->Tracing) {
-      syslog(L_TRACE, "%s cp->Start=%lu cp->Next=%lu bp->Used=%lu",
-        CHANname(cp), (unsigned long) cp->Start, (unsigned long) cp->Next,
-        (unsigned long) bp->used);
-      if (bp->used > 15)
-       syslog(L_TRACE, "%s NCproc state=%d next \"%.15s\"", CHANname(cp),
-         cp->State, &bp->data[cp->Next]);
-    }
-    switch (cp->State) {
-    default:
-      syslog(L_ERROR, "%s internal NCproc state %d", CHANname(cp), cp->State);
-      movedata = false;
-      readmore = true;
-      break;
-
-    case CSwritegoodbye:
-      movedata = false;
-      readmore = true;
-      break;
-
-    case CSgetcmd:
-    case CSgetauth:
-    case CScancel:
-      /* Did we get the whole command, terminated with "\r\n"? */
-      for (i = cp->Next; (i < bp->used) && (bp->data[i] != '\n'); i++) ;
-      if (i == bp->used) {
-       /* Check for too long command. */
-       if ((j = bp->used - cp->Start) > NNTP_STRLEN) {
-         /* Make some room, saving only the last few bytes. */
-         for (p = bp->data, i = 0; i < SAVE_AMT; i++)
-           p[i] = p[bp->used - SAVE_AMT + i];
-         cp->LargeCmdSize += j - SAVE_AMT;
-         bp->used = cp->Next = SAVE_AMT;
-         bp->left = bp->size - SAVE_AMT;
-         cp->Start = 0;
-         cp->State = CSeatcommand;
-         /* above means moving data already */
-         movedata = false;
-       } else {
-         cp->Next = bp->used;
-         /* move data to the begining anyway */
-         movedata = true;
-       }
-       readmore = true;
-       break;
-      }
-      /* i points where '\n" and go forward */
-      cp->Next = ++i;
-      /* never move data so long as "\r\n" is found, since subsequent
-        data may also include command line */
-      movedata = false;
-      readmore = false;
-      if (i - cp->Start < 3) {
-       break;
-      }
-      p = &bp->data[i];
-      if (p[-2] != '\r') { /* probably in an article */
-       char *tmpstr;
-
-       tmpstr = xmalloc(i - cp->Start + 1);
-       memcpy(tmpstr, bp->data + cp->Start, i - cp->Start);
-       tmpstr[i - cp->Start] = '\0';
-       
-       syslog(L_NOTICE, "%s bad_command %s", CHANname(cp),
-         MaxLength(tmpstr, tmpstr));
-       free(tmpstr);
-
-       if (++(cp->BadCommands) >= BAD_COMMAND_COUNT) {
-         cp->State = CSwritegoodbye;
-         NCwritereply(cp, NCbadcommand);
-         break;
-       }
-       NCwritereply(cp, NCbadcommand);
-       /* still some data left, go for it */
-       cp->Start = cp->Next;
-       break;
-      }
-
-      q = &bp->data[cp->Start];
-      /* Ignore blank lines. */
-      if (*q == '\0' || i - cp->Start == 2) {
-       cp->Start = cp->Next;
-       break;
-      }
-      p[-2] = '\0';
-      if (Tracing || cp->Tracing)
-       syslog(L_TRACE, "%s < %s", CHANname(cp), q);
-
-      /* We got something -- stop sleeping (in case we were). */
-      SCHANremove(cp);
-      if (cp->Argument != NULL) {
-       free(cp->Argument);
-       cp->Argument = NULL;
-      }
-
-      if (cp->State == CSgetauth) {
-       if (strncasecmp(q, "mode", 4) == 0)
-         NCmode(cp);
-       else
-         NCauthinfo(cp);
-       break;
-      } else if (cp->State == CScancel) {
-       NCcancel(cp);
-       break;
-      }
-
-      /* Loop through the command table. */
-      for (p = q, dp = NCcommands; dp < ARRAY_END(NCcommands); dp++) {
-       if (strncasecmp(p, dp->Name, dp->Size) == 0) {
-         /* ignore the streaming commands if necessary. */
-         if (!StreamingOff || cp->Streaming ||
-           (dp->Function != NCcheck && dp->Function != NCtakethis)) {
-           (*dp->Function)(cp);
-           cp->BadCommands = 0;
-           break;
-         }
-       }
-      }
-      if (dp == ARRAY_END(NCcommands)) {
-       if (++(cp->BadCommands) >= BAD_COMMAND_COUNT)
-           cp->State = CSwritegoodbye;
-       NCwritereply(cp, NCbadcommand);
-       cp->Start = cp->Next;
-
-       /* Channel could have been freed by above NCwritereply if 
-          we're writing-goodbye */
-       if (cp->Type == CTfree)
-         return;
-       for (i = 0; (p = NCquietlist[i]) != NULL; i++)
-         if (strcasecmp(p, q) == 0)
-           break;
-       if (p == NULL)
-         syslog(L_NOTICE, "%s bad_command %s", CHANname(cp),
-           MaxLength(q, q));
-      }
-      break;
-
-    case CSgetheader:
-    case CSgetbody:
-    case CSeatarticle:
-      TMRstart(TMR_ARTPARSE);
-      ARTparse(cp);
-      TMRstop(TMR_ARTPARSE);
-      if (cp->State == CSgetbody || cp->State == CSgetheader ||
-             cp->State == CSeatarticle) {
-       if (cp->Next - cp->Start > innconf->datamovethreshold ||
-         (innconf->maxartsize > 0 && cp->Size > innconf->maxartsize)) {
-         /* avoid buffer extention for ever */
-         movedata = true;
-       } else {
-         movedata = false;
-       }
-       readmore = true;
-       break;
-      }
-
-      if (cp->State == CSgotlargearticle) {
-       syslog(L_NOTICE, "%s internal rejecting huge article (%d > %ld)",
-         CHANname(cp), cp->Next - cp->Start, innconf->maxartsize);
-       if (cp->Sendid.size)
-         NCwritereply(cp, cp->Sendid.data);
-       else {
-         snprintf(buff, sizeof(buff),
-                   "%d Article exceeds local limit of %ld bytes",
-                   NNTP_REJECTIT_VAL, innconf->maxartsize);
-         NCwritereply(cp, buff);
-        }
-       cp->State = CSgetcmd;
-       cp->Rejected++;
-       cp->Start = cp->Next;
-
-       /* Write a local cancel entry so nobody else gives it to us. */
-       if (HDR_FOUND(HDR__MESSAGE_ID)) {
-         HDR_PARSE_START(HDR__MESSAGE_ID);
-         if (!HIScheck(History, HDR(HDR__MESSAGE_ID)) &&
-             !InndHisRemember(HDR(HDR__MESSAGE_ID)))
-           syslog(L_ERROR, "%s cant write %s", LogName, HDR(HDR__MESSAGE_ID)); 
-       }
-       /* Clear the work-in-progress entry. */
-       NCclearwip(cp);
-       readmore = false;
-       movedata = false;
-       break;
-      }
-
-      if (*cp->Error != '\0') {
-       cp->Rejected++;
-       cp->State = CSgetcmd;
-       cp->Start = cp->Next;
-       NCclearwip(cp);
-       if (cp->Sendid.size > 3)
-         NCwritereply(cp, cp->Sendid.data);
-       else
-         NCwritereply(cp, cp->Error);
-       readmore = false;
-       movedata = false;
-       break;
-      }
-
-      if (cp->State == CSnoarticle) {
-       /* this should happen when parsing header */
-       cp->Rejected++;
-       cp->State = CSgetcmd;
-       cp->Start = cp->Next;
-       /* Clear the work-in-progress entry. */
-       NCclearwip(cp);
-       if (cp->Sendid.size > 3) { /* We be streaming */
-         cp->Takethis_Err++;
-         snprintf(buff, sizeof(buff), "%d", NNTP_ERR_FAILID_VAL);
-         cp->Sendid.data[0] = buff[0];
-         cp->Sendid.data[1] = buff[1];
-         cp->Sendid.data[2] = buff[2];
-         NCwritereply(cp, cp->Sendid.data);
-       } else
-         NCwritereply(cp, NNTP_REJECTIT_EMPTY);
-       readmore = false;
-       movedata = false;
-       break;
-      }
-    case CSgotarticle: /* in case caming back from pause */
-      /* never move data so long as "\r\n.\r\n" is found, since subsequent data
-        may also include command line */
-      readmore = false;
-      movedata = false;
-      if (Mode == OMpaused) { /* defer processing while paused */
-       RCHANremove(cp); /* don't bother trying to read more for now */
-       SCHANadd(cp, Now.time + innconf->pauseretrytime, &Mode, NCproc, NULL);
-       return;
-      } else if (Mode == OMthrottled) {
-       /* Clear the work-in-progress entry. */
-       NCclearwip(cp);
-       NCwriteshutdown(cp, ModeReason);
-       cp->Rejected++;
-       return;
-      }
-
-      SCHANremove(cp);
-      if (cp->Argument != NULL) {
-       free(cp->Argument);
-       cp->Argument = NULL;
-      }
-      NCpostit(cp);
-      /* Clear the work-in-progress entry. */
-      NCclearwip(cp);
-      if (cp->State == CSwritegoodbye)
-       break;
-      cp->State = CSgetcmd;
-      cp->Start = cp->Next;
-      break;
-
-    case CSeatcommand:
-      /* Eat the command line and then complain that it was too large */
-      /* Reading a line; look for "\r\n" terminator. */
-      /* cp->Next should be SAVE_AMT(10) */
-      for (i = cp->Next ; i < bp->used; i++) {
-       if ((bp->data[i - 1] == '\r') && (bp->data[i] == '\n')) {
-         cp->Next = i + 1;
-         break;
-       }
-      }
-      if (i < bp->used) {      /* did find terminator */
-       /* Reached the end of the command line. */
-       SCHANremove(cp);
-       if (cp->Argument != NULL) {
-         free(cp->Argument);
-         cp->Argument = NULL;
-       }
-       i += cp->LargeCmdSize;
-       syslog(L_NOTICE, "%s internal rejecting too long command line (%d > %d)",
-         CHANname(cp), i, NNTP_STRLEN);
-       cp->LargeCmdSize = 0;
-       snprintf(buff, sizeof(buff), "%d command exceeds limit of %d bytes",
-                 NNTP_BAD_COMMAND_VAL, NNTP_STRLEN);
-       cp->State = CSgetcmd;
-       cp->Start = cp->Next;
-       NCwritereply(cp, buff);
-        readmore = false;
-        movedata = false;
-      } else {
-       cp->LargeCmdSize += bp->used - cp->Next;
-       bp->used = cp->Next = SAVE_AMT;
-       bp->left = bp->size - SAVE_AMT;
-       cp->Start = 0;
-        readmore = true;
-        movedata = false;
-      }
-      break;
-
-    case CSgetxbatch:
-      /* if the batch is complete, write it out into the in.coming
-       * directory with an unique timestamp, and start rnews on it.
-       */
-      if (Tracing || cp->Tracing)
-       syslog(L_TRACE, "%s CSgetxbatch: now %lu of %d bytes", CHANname(cp),
-         (unsigned long) bp->used, cp->XBatchSize);
-
-      if (cp->Next != 0) {
-       /* data must start from the begining of the buffer */
-        movedata = true;
-       readmore = false;
-       break;
-      }
-      if (bp->used < cp->XBatchSize) {
-       movedata = false;
-       readmore = true;
-       break;  /* give us more data */
-      }
-      movedata = false;
-      readmore = false;
-
-      /* now do something with the batch */
-      {
-       char buff2[SMBUF];
-       int fd, oerrno, failed;
-       long now;
-
-       now = time(NULL);
-       failed = 0;
-       /* time+channel file descriptor should make an unique file name */
-       snprintf(buff, sizeof(buff), "%s/%ld%d.tmp", innconf->pathincoming,
-                 now, cp->fd);
-       fd = open(buff, O_WRONLY|O_CREAT|O_EXCL, ARTFILE_MODE);
-       if (fd < 0) {
-         oerrno = errno;
-         failed = 1;
-         syslog(L_ERROR, "%s cannot open outfile %s for xbatch: %m",
-           CHANname(cp), buff);
-         snprintf(buff, sizeof(buff), "%s cant create file: %s",
-                   NNTP_RESENDIT_XBATCHERR, strerror(oerrno));
-         NCwritereply(cp, buff);
-       } else {
-         if (write(fd, cp->In.data, cp->XBatchSize) != cp->XBatchSize) {
-           oerrno = errno;
-           syslog(L_ERROR, "%s cant write batch to file %s: %m", CHANname(cp),
-             buff);
-           snprintf(buff, sizeof(buff), "%s cant write batch to file: %s",
-                     NNTP_RESENDIT_XBATCHERR, strerror(oerrno));
-           NCwritereply(cp, buff);
-           failed = 1;
-         }
-       }
-       if (fd >= 0 && close(fd) != 0) {
-         oerrno = errno;
-         syslog(L_ERROR, "%s error closing batch file %s: %m", CHANname(cp),
-           failed ? "" : buff);
-         snprintf(buff, sizeof(buff), "%s error closing batch file: %s",
-                   NNTP_RESENDIT_XBATCHERR, strerror(oerrno));
-         NCwritereply(cp, buff);
-         failed = 1;
-       }
-       snprintf(buff2, sizeof(buff2), "%s/%ld%d.x", innconf->pathincoming,
-                 now, cp->fd);
-       if (rename(buff, buff2)) {
-         oerrno = errno;
-         syslog(L_ERROR, "%s cant rename %s to %s: %m", CHANname(cp),
-           failed ? "" : buff, buff2);
-         snprintf(buff, sizeof(buff), "%s cant rename batch to %s: %s",
-                   NNTP_RESENDIT_XBATCHERR, buff2, strerror(oerrno));
-         NCwritereply(cp, buff);
-         failed = 1;
-       }
-       cp->Reported++;
-       if (!failed) {
-         NCwritereply(cp, NNTP_OK_XBATCHED);
-         cp->Received++;
-       } else
-         cp->Rejected++;
-      }
-      syslog(L_NOTICE, "%s accepted batch size %d", CHANname(cp),
-       cp->XBatchSize);
-      cp->State = CSgetcmd;
-      cp->Start = cp->Next = cp->XBatchSize;
-      break;
-    }
-    if (cp->State == CSwritegoodbye || cp->Type == CTfree)
-      break;
-    if (Tracing || cp->Tracing)
-      syslog(L_TRACE, "%s NCproc state=%d Start=%lu Next=%lu Used=%lu",
-       CHANname(cp), cp->State, (unsigned long) cp->Start,
-        (unsigned long) cp->Next, (unsigned long) bp->used);
-
-    if (movedata) { /* move data rather than extend buffer */
-      TMRstart(TMR_DATAMOVE);
-      movedata = false;
-      if (cp->Start > 0)
-       memmove(bp->data, &bp->data[cp->Start], bp->used - cp->Start);
-      bp->used -= cp->Start;
-      bp->left += cp->Start;
-      cp->Next -= cp->Start;
-      if (cp->State == CSgetheader || cp->State == CSgetbody ||
-       cp->State == CSeatarticle) {
-       /* adjust offset only in CSgetheader, CSgetbody or CSeatarticle */
-       data->CurHeader -= cp->Start;
-       data->LastTerminator -= cp->Start;
-       data->LastCR -= cp->Start;
-       data->LastCRLF -= cp->Start;
-       data->Body -= cp->Start;
-       if (data->BytesHeader != NULL)
-         data->BytesHeader -= cp->Start;
-       for (i = 0 ; i < MAX_ARTHEADER ; i++, hc++) {
-         if (hc->Value != NULL)
-           hc->Value -= cp->Start;
-       }
-      }
-      cp->Start = 0;
-      TMRstop(TMR_DATAMOVE);
-    }
-    if (readmore)
-      /* need to read more */
-      break;
-  }
-}
-
-
-/*
-**  Read whatever data is available on the channel.  If we got the
-**  full amount (i.e., the command or the whole article) process it.
-*/
-static void
-NCreader(CHANNEL *cp)
-{
-    int                        i;
-
-    if (Tracing || cp->Tracing)
-       syslog(L_TRACE, "%s NCreader Used=%lu",
-           CHANname(cp), (unsigned long) cp->In.used);
-
-    /* Read any data that's there; ignore errors (retry next time it's our
-     * turn) and if we got nothing, then it's EOF so mark it closed. */
-    if ((i = CHANreadtext(cp)) <= 0) {
-        /* Return of -2 indicates we got EAGAIN even though the descriptor
-           selected true for reading, probably due to the Solaris select
-           bug.  Drop back out to the main loop as if the descriptor never
-           selected true. */
-        if (i == -2) {
-            return;
-        }
-       if (i == 0 || cp->BadReads++ >= innconf->badiocount) {
-           if (NCcount > 0)
-               NCcount--;
-           CHANclose(cp, CHANname(cp));
-       }
-       return;
-    }
-
-    NCproc(cp);            /* check and process data */
-}
-
-
-
-/*
-**  Set up the NNTP channel state.
-*/
-void
-NCsetup(void)
-{
-    char               *p;
-    char               buff[SMBUF];
-
-    /* Set the greeting message. */
-    p = innconf->pathhost;
-    if (p == NULL)
-       /* Worked in main, now it fails?  Curious. */
-       p = Path.data;
-    snprintf(buff, sizeof(buff), "%d %s InterNetNews server %s ready",
-           NNTP_POSTOK_VAL, p, inn_version_string);
-    NCgreeting = xstrdup(buff);
-}
-
-
-/*
-**  Tear down our state.
-*/
-void
-NCclose(void)
-{
-    CHANNEL            *cp;
-    int                        j;
-
-    /* Close all incoming channels. */
-    for (j = 0; (cp = CHANiter(&j, CTnntp)) != NULL; ) {
-       if (NCcount > 0)
-           NCcount--;
-       CHANclose(cp, CHANname(cp));
-    }
-}
-
-
-/*
-**  Create an NNTP channel and print the greeting message.
-*/
-CHANNEL *
-NCcreate(int fd, bool MustAuthorize, bool IsLocal)
-{
-    CHANNEL            *cp;
-    int                        i;
-
-    /* Create the channel. */
-    cp = CHANcreate(fd, CTnntp, MustAuthorize ? CSgetauth : CSgetcmd,
-           NCreader, NCwritedone);
-
-    NCclearwip(cp);
-    cp->privileged = IsLocal;
-#if defined(SOL_SOCKET) && defined(SO_SNDBUF) && defined(SO_RCVBUF) 
-    if (!IsLocal) {
-       i = 24 * 1024;
-       if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&i, sizeof i) < 0)
-           syslog(L_ERROR, "%s cant setsockopt(SNDBUF) %m", CHANname(cp));
-       if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof i) < 0)
-           syslog(L_ERROR, "%s cant setsockopt(RCVBUF) %m", CHANname(cp));
-    }
-#endif /* defined(SOL_SOCKET) && defined(SO_SNDBUF) && defined(SO_RCVBUF) */
-
-#if    defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
-    if (!IsLocal) {
-       /* Set KEEPALIVE to catch broken socket connections. */
-       i = 1;
-       if (setsockopt(fd, SOL_SOCKET,  SO_KEEPALIVE, (char *)&i, sizeof i) < 0)
-           syslog(L_ERROR, "%s cant setsockopt(KEEPALIVE) %m", CHANname(cp));
-    }
-#endif /* defined(SOL_SOCKET) && defined(SO_KEEPALIVE) */
-
-    /* Now check our operating mode. */
-    NCcount++;
-    if (Mode == OMthrottled) {
-       NCwriteshutdown(cp, ModeReason);
-       return NULL;
-    }
-    if (RejectReason) {
-       NCwriteshutdown(cp, RejectReason);
-       return NULL;
-    }
-
-    /* See if we have too many channels. */
-    if (!IsLocal && innconf->maxconnections && 
-                       NCcount >= innconf->maxconnections && !RCnolimit(cp)) {
-       /* Recount, just in case we got out of sync. */
-       for (NCcount = 0, i = 0; CHANiter(&i, CTnntp) != NULL; )
-           NCcount++;
-       if (NCcount >= innconf->maxconnections) {
-           NCwriteshutdown(cp, "Too many connections");
-           return NULL;
-       }
-    }
-    cp->BadReads = 0;
-    cp->BadCommands = 0;
-    return cp;
-}
-
-
-
-/* These modules support the streaming option to tranfer articles
-** faster.
-*/
-
-/*
-**  The "check" command.  Check the Message-ID, and see if we want the
-**  article or not.  Stay in command state.
-*/
-static void
-NCcheck(CHANNEL *cp)
-{
-    char               *p;
-    int                        idlen, msglen;
-#if defined(DO_PERL) || defined(DO_PYTHON)
-    char               *filterrc;
-#endif /* DO_PERL || DO_PYTHON */
-
-    cp->Check++;
-    /* Snip off the Message-ID. */
-    for (p = cp->In.data + cp->Start; *p && !ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    for ( ; ISWHITE(*p); p++)
-       continue;
-    idlen = strlen(p);
-    msglen = idlen + 5; /* 3 digits + space + id + null */
-    if (cp->Sendid.size < msglen) {
-       if (cp->Sendid.size > 0) free(cp->Sendid.data);
-       if (msglen > MAXHEADERSIZE) cp->Sendid.size = msglen;
-       else cp->Sendid.size = MAXHEADERSIZE;
-       cp->Sendid.data = xmalloc(cp->Sendid.size);
-    }
-    if (!ARTidok(p)) {
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_ERR_GOTID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-       syslog(L_NOTICE, "%s bad_messageid %s", CHANname(cp), MaxLength(p, p));
-       return;
-    }
-
-    if ((innconf->refusecybercancels) && (strncmp(p, "<cancel.", 8) == 0)) {
-       cp->Refused++;
-       cp->Check_cybercan++;
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_ERR_GOTID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-       return;
-    }
-
-#if defined(DO_PERL)
-    /*  Invoke a perl message filter on the message ID. */
-    filterrc = PLmidfilter(p);
-    if (filterrc) {
-       cp->Refused++;
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_ERR_GOTID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-       return;
-    }
-#endif /* defined(DO_PERL) */
-
-#if defined(DO_PYTHON)
-    /*  invoke a python message filter on the message id */
-    filterrc = PYmidfilter(p, idlen);
-    if (filterrc) {
-       cp->Refused++;
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_ERR_GOTID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-       return;
-    }
-#endif /* defined(DO_PYTHON) */
-
-    if (HIScheck(History, p)) {
-       cp->Refused++;
-       cp->Check_got++;
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_ERR_GOTID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-    } else if (WIPinprogress(p, cp, true)) {
-       cp->Check_deferred++;
-       if (cp->NoResendId) {
-           cp->Refused++;
-           snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                     NNTP_ERR_GOTID_VAL, p);
-       } else {
-           snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                     NNTP_RESENDID_VAL, p);
-       }
-       NCwritereply(cp, cp->Sendid.data);
-    } else {
-       cp->Check_send++;
-       snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
-                 NNTP_OK_SENDID_VAL, p);
-       NCwritereply(cp, cp->Sendid.data);
-    }
-    /* stay in command mode */
-}
-
-/*
-**  The "takethis" command.  Article follows.
-**  Remember <id> for later ack.
-*/
-static void
-NCtakethis(CHANNEL *cp)
-{
-    char               *p;
-    int                        msglen;
-    WIP                 *wp;
-
-    cp->Takethis++;
-    /* Snip off the Message-ID. */
-    for (p = cp->In.data + cp->Start + strlen("takethis"); ISWHITE(*p); p++)
-       continue;
-    cp->Start = cp->Next;
-    for ( ; ISWHITE(*p); p++)
-       continue;
-    if (!ARTidok(p)) {
-       syslog(L_NOTICE, "%s bad_messageid %s", CHANname(cp), MaxLength(p, p));
-    }
-    msglen = strlen(p) + 5; /* 3 digits + space + id + null */
-    if (cp->Sendid.size < msglen) {
-       if (cp->Sendid.size > 0) free(cp->Sendid.data);
-       if (msglen > MAXHEADERSIZE) cp->Sendid.size = msglen;
-       else cp->Sendid.size = MAXHEADERSIZE;
-       cp->Sendid.data = xmalloc(cp->Sendid.size);
-    }
-    /* save ID for later NACK or ACK */
-    snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s", NNTP_ERR_FAILID_VAL,
-             p);
-
-    cp->ArtBeg = Now.time;
-    cp->State = CSgetheader;
-    ARTprepare(cp);
-    /* set WIP for benefit of later code in NCreader */
-    if ((wp = WIPbyid(p)) == (WIP *)NULL)
-       wp = WIPnew(p, cp);
-    cp->CurrentMessageIDHash = wp->MessageID;
-}
-
-/*
-**  Process a cancel ID from a "mode cancel" channel.
-*/
-static void
-NCcancel(CHANNEL *cp)
-{
-    char *av[2] = { NULL, NULL };
-    const char *res;
-
-    ++cp->Received;
-    av[0] = cp->In.data + cp->Start;
-    cp->Start = cp->Next;
-    res = CCcancel(av);
-    if (res) {
-        char buff[SMBUF];
-
-        snprintf(buff, sizeof(buff), "%d %s", NNTP_ERR_CANCEL_VAL,
-                 MaxLength(res, res));
-        syslog(L_NOTICE, "%s cant_cancel %s", CHANname(cp),
-               MaxLength(res, res));
-        NCwritereply(cp, buff);
-    } else {
-        NCwritereply(cp, NNTP_OK_CANCELLED);
-    }
-}
diff --git a/innd/newsfeeds.c b/innd/newsfeeds.c
deleted file mode 100644 (file)
index a5ac9da..0000000
+++ /dev/null
@@ -1,957 +0,0 @@
-/*  $Id: newsfeeds.c 7730 2008-04-06 08:27:16Z iulius $
-**
-**  Routines for the in-core data structures for the newsfeeds file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-/*
-** List of variables assigned in the configuration file.
-*/
-typedef struct _SITEVARIABLES {
-    char      *Name;
-    char      *Value;
-    int               Elements;
-    struct _SITEVARIABLES     *Next;
-} SITEVARIABLES;
-
-/* The character which introduces a variable assignment or reference. */
-#define VARIABLE_CHAR '$'
-
-static SITE    SITEnull;
-static char    *SITEfeedspath = NULL;
-static SITEVARIABLES  *SITEvariables = NULL;
-
-
-/*
-**  Return a copy of an array of strings.
-*/
-static char **
-SITEcopystrings(char **av)
-{
-    char       **new;
-    char       **pp;
-    char       **save;
-
-    for (pp = av; *pp; pp++)
-       continue;
-    for (new = save = xmalloc((pp - av + 1) * sizeof(char *)), pp = av; *pp; pp++)
-       *new++ = xstrdup(*pp);
-    *new = NULL;
-    return save;
-}
-
-/*
-** Adds a variable from a line.
-*/
-static bool
-SITEaddvariable(char *line)
-{
-    char *p, *q;
-    SITEVARIABLES *v, *w;
-    
-    if (*line != VARIABLE_CHAR)
-       return false;
-       
-    for (p = line + 1; *p != '\0' && CTYPE(isalnum, *p); p++)
-        ;
-    if (*p != '=')
-       return false;
-    if (p - line > 32) {
-       syslog(L_FATAL, "%s bad_newsfeed variable name '%s' too long", 
-               LogName, line+1);
-       return false;
-    }
-
-    /* Chop off trailing spaces. */
-    q = p + strlen(p) - 1;
-    while (q > p && (*q == ' ' || *q == '\t'))
-       *q-- = '\0';
-
-    /* Seperate variable name from contents. */
-    *p++ = '\0';       
-    if (*p == '\0')
-       return false;
-
-    /* Is variable already defined?  Free and reassign. */
-    w = NULL;
-    v = SITEvariables;
-    while (v && strcmp(line + 1, v->Name)) {
-        w = v;
-       v = v->Next;
-    }
-    if (v)
-       free(v->Value);
-    else {
-       v = xmalloc(sizeof(SITEVARIABLES));
-       if (!SITEvariables)
-           SITEvariables = v;
-       if (w)
-            w->Next = v;
-       v->Name = xstrdup(line + 1);
-       v->Next = NULL;
-    }
-
-    /* Add variable's contents. */
-    v->Elements = 1;
-    for (q = v->Value = xmalloc(strlen(p) + 1); *p != '\0'; p++) {
-        if (*p != ' ' && *p != '\t')
-            *q++ = *p;
-        if (*p == ',')
-            v->Elements++;
-    }
-    *q = '\0';
-    return true;        
-}
-
-static void
-SITEclearvariables(void)
-{
-    SITEVARIABLES *v, *w;
-    
-    v = SITEvariables;
-    while (v) {
-       free(v->Name);
-       free(v->Value);
-       w = v;
-       v = v->Next;
-       free(w);
-    }
-    SITEvariables = NULL;
-}
-
-static SITEVARIABLES *
-SITEfindvariable(char *name)
-{
-    SITEVARIABLES *v;
-
-    v = SITEvariables;
-    while (v && strcmp(v->Name, name) != 0)
-       v = v->Next;
-    return v;
-}
-
-static char *
-SITEexpandvariables(char *site)
-{
-    char *p, *r, *s;
-    char *q = NULL;
-    int c = 0;
-    char modifier;
-    char varname[64];
-    SITEVARIABLES *v;
-
-    /* Count characters. */
-    *varname = '\0';
-    modifier = '\0';
-    for (p = site; p <= site + strlen(site); p++) {
-        /* In variable name. */
-        if (*varname) {
-            if (CTYPE(isalnum, *p)) {
-                if (q - varname > 32) {
-                    /* Add ignored modifier. */
-                    if (modifier)
-                        c++;
-                    /* Add ignored $ and characters. */
-                    c += strlen(varname);
-                    /* Add this character. */
-                    c++;
-                    *varname = '\0';
-                    modifier = '\0';
-                    continue;
-                }
-                /* Append to variable name. */
-                *q++ = *p;
-                continue;
-            } else {
-                v = SITEfindvariable(varname + 1);
-                if (v != NULL) {
-                    /* Add length of contents. */
-                    c += strlen(v->Value);
-                    /* If modified add number of mods. */
-                    if (modifier)
-                        c += v->Elements;
-                } else {
-                    /* Add ignored modifier. */
-                    if (modifier)
-                        c++;
-                    c += strlen(varname); /* add ignored $ and characters */
-                }
-                *varname = '\0';
-                modifier = '\0';
-            }
-        }
-        /* New variable starts */
-        if (*p == VARIABLE_CHAR) {
-            q = varname;
-            memset(varname, 0, sizeof(varname));
-            *q++ = VARIABLE_CHAR;
-            continue;
-        }
-        if (modifier) {
-            /* Add last modifier */
-            c++;
-            modifier = '\0';
-        }
-        if (*p == SUB_NEGATE || *p == SUB_POISON) {
-            modifier = *p;
-        } else {
-            /* Add this character. */
-            c++;
-        }
-    }
-
-    /* Copy contents. */
-    s = r = xmalloc(c + 1);
-    *varname = '\0';
-    modifier = '\0';
-    for (p = site; p <= site + strlen(site); p++) {
-        /* In variable name. */
-        if (*varname) {
-            if (CTYPE(isalnum, *p)) {
-                if (q - varname > 32) {
-                    if (modifier)
-                        *s++ = modifier;
-                    for (q = varname; *q; q++)
-                        *s++ = *q;
-                    *s++ = *p;
-                    *varname = '\0';
-                    modifier = '\0';
-                    continue;
-                }
-                *q++ = *p;
-                continue;
-            } else {
-                v = SITEfindvariable(varname + 1);
-                if (v != NULL) {
-                    if (modifier)
-                        *s++ = modifier;
-                    for (q = v->Value; *q; q++) {
-                        *s++ = *q;
-                        if (*q == ',' && modifier)
-                            *s++ = modifier;
-                    }
-                } else {
-                    if (modifier)
-                        *s++ = modifier;
-                    for (q = varname; *q; q++)
-                        *s++ = *q;
-                }
-                *varname = '\0';
-                modifier = '\0';
-            }
-        }
-        /* New variable starts. */
-        if (*p == VARIABLE_CHAR) {
-            q = varname;
-            memset(varname, 0, sizeof(varname));
-            *q++ = VARIABLE_CHAR;
-            continue;
-        }
-        if (modifier) {
-            *s++ = modifier;
-            modifier = '\0';
-        }
-        if (*p == SUB_NEGATE || *p == SUB_POISON)
-            modifier = *p;
-        else
-            *s++ = *p;
-    }
-    *s++ = '\0';
-
-    return r;
-}
-
-/*
-**  Read the newsfeeds file, return a string array of entries.
-*/
-char **
-SITEreadfile(const bool ReadOnly)
-{
-    static char                **old_strings;
-    static time_t      old_mtime;
-    static ino_t       old_ino;
-    static off_t       old_size;
-    char               *p;
-    char               *to;
-    char               *site;
-    int                        i;
-    struct stat                Sb;
-    char               *data;
-
-    if (SITEfeedspath == NULL)
-       SITEfeedspath = concatpath(innconf->pathetc, _PATH_NEWSFEEDS);
-    if (old_strings != NULL) {
-       /* If the file hasn't changed, return a copy of the old data. */
-       if (stat(SITEfeedspath, &Sb) >= 0
-        && Sb.st_ino == old_ino
-        && Sb.st_size == old_size
-        && Sb.st_mtime == old_mtime)
-           return ReadOnly ? old_strings : SITEcopystrings(old_strings);
-
-       /* Data's bad, toss it. */
-       for (i = 0; old_strings[i] != NULL; i++)
-           free(old_strings[i]);
-       free(old_strings);
-    }
-
-    /* Read in the file, note its statistics. */
-    if ((data = ReadInFile(SITEfeedspath, &Sb)) == NULL) {
-       syslog(L_FATAL, "%s cant read %s %m", LogName, SITEfeedspath);
-       exit(1);
-    }
-    old_mtime = Sb.st_mtime;
-    old_ino = Sb.st_ino;
-    old_size = Sb.st_size;
-
-    /* Get a gross count of the number of sites. */
-    for (p = data, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
-       continue;
-
-    /* Scan the file, parse all multi-line entries. */
-    for (old_strings = xmalloc((i + 1) * sizeof(char *)), i = 0, to = p = data; *p; ) {
-       for (site = to; *p; ) {
-           if (*p == '\n') {
-               p++;
-               *to = '\0';
-               break;
-           }
-           if (*p == '\\' && p[1] == '\n')
-               while (*++p && CTYPE(isspace, *p))
-                   continue;
-           else
-               *to++ = *p++;
-       }
-       *to++ = '\0';
-       if (*site == '#' || *site == '\0')
-            continue ;
-        if (*site == VARIABLE_CHAR && SITEaddvariable(site))
-           continue ;        
-        if (strspn(site," \t") == strlen (site))
-           continue;
-       if (SITEvariables)
-           old_strings[i++] = SITEexpandvariables(site);
-       else
-           old_strings[i++] = xstrdup(site);
-    }
-    old_strings[i] = NULL;
-    
-    SITEclearvariables();
-    free(data);
-    return ReadOnly ? old_strings : SITEcopystrings(old_strings);
-}
-
-
-/*
-**  Modify "subbed" according to the patterns in "patlist."
-*/
-static void
-SITEsetlist(char **patlist, char *subbed, char *poison, bool *poisonEntry)
-{
-    char       *pat;
-    char       *p;
-    char       *u;
-    char       subvalue;
-    char       poisonvalue;
-    NEWSGROUP  *ngp;
-    int                i;
-
-    while ((pat = *patlist++) != NULL) {
-       subvalue = *pat != SUB_NEGATE && *pat != SUB_POISON;
-       poisonvalue = *pat == SUB_POISON;
-       if (!subvalue)
-           pat++;
-       if (!*pat)
-           continue;
-       if (!*poisonEntry && poisonvalue)
-           *poisonEntry = true;
-
-       /* See if pattern is a simple newsgroup name.  If so, set the
-        * right subbed element for that one group (if found); if not,
-        * pattern-match against all the groups. */
-       for (p = pat; *p; p++)
-           if (*p == '?' || *p == '*' || *p == '[')
-               break;
-       if (*p == '\0') {
-           /* Simple string; look it up, set it. */
-           if ((ngp = NGfind(pat)) != NULL) {
-               subbed[ngp - Groups] = subvalue;
-               poison[ngp - Groups] = poisonvalue;
-           }
-       }
-       else
-           for (p = subbed, u = poison, ngp = Groups, i = nGroups;
-                       --i >= 0; ngp++, p++, u++)
-               if (uwildmat(ngp->Name, pat)) {
-                   *p = subvalue;
-                   *u = poisonvalue;
-               }
-    }
-}
-
-/*
-**  Split text into slash-separated fields.  Return an allocated
-**  NULL-terminated array of the fields within the modified argument that
-**  the caller is expected to save or free.  We don't use strchr() since
-**  the text is expected to be either relatively short or "slash-dense."
-*/
-static char **
-SlashSplit(char *text)
-{
-    int                i;
-    char       *p;
-    char       **av;
-    char       **save;
-
-    /* How much space do we need? */
-    for (i = 2, p = text; *p; p++)
-       if (*p == '/')
-           i++;
-
-    for (av = save = xmalloc(i * sizeof(char *)), *av++ = p = text; *p; )
-       if (*p == '/') {
-           *p++ = '\0';
-           *av++ = p;
-       }
-       else
-           p++;
-    *av = NULL;
-    return save;
-}
-
-/*
-**  Parse an individual site entry.  Subbed is used to build the subscription
-**  list.  Since this routine is called once for each site, the caller
-**  allocates subbed once, and frees it after the last site has been parsed.
-**  If subbed is NULL, we don't update the SITE array, since we're just
-**  doing syntax checking.
-*/
-const char *
-SITEparseone(char *Entry, SITE *sp, char *subbed, char *poison)
-{
-    int                        i;
-    int                        j;
-    NEWSGROUP          *ngp;
-    char               *p;
-    char               *u;
-    char               *f2;
-    char               *f3;
-    char               *f4;
-    char               **save;
-    char               **argv;
-    bool               JustModerated;
-    bool               JustUnmoderated;
-    int                        isp;
-    SITE               *nsp;
-    struct buffer      b;
-    HASHFEEDLIST       *hf;
-
-    b = sp->Buffer;
-    *sp = SITEnull;
-    sp->Buffer = b;
-    sp->Master = NOSITE;
-    sp->Funnel = NOSITE;
-    sp->PoisonEntry = false;
-    sp->Process = -1;
-    sp->Next = sp->Prev = NOSITE;
-    sp->Entry = Entry;
-    sp->Originator = NULL;
-    sp->FileFlags[0] = FEED_NAME;
-    sp->FileFlags[1] = '\0';
-    sp->Nice = innconf->nicekids;
-    sp->ControlOnly = false;
-    sp->DontWantNonExist = false;
-    sp->NeedOverviewCreation = false;
-    sp->FeedwithoutOriginator = false;
-    sp->DropFiltered = false;
-    sp->HashFeedList = NULL;
-
-    /* Nip off the first field, the site name. */
-    if ((f2 = strchr(Entry, NF_FIELD_SEP)) == NULL)
-       return "missing field 2";
-    *f2++ = '\0';
-    sp->Name = Entry;
-    if ((p = strchr(sp->Name, NF_SUBFIELD_SEP)) != NULL) {
-       /* Exclusions within the site field. */
-       *p++ = '\0';
-       if (*p)
-       sp->Exclusions = CommaSplit(p);
-    }
-    sp->NameLength = strlen(sp->Name);
-
-    /* Parse the second field, the subscriptions. */
-    if ((f3 = strchr(f2, NF_FIELD_SEP)) == NULL)
-       return "missing field 3";
-    *f3++ = '\0';
-    if ((p = strchr(f2, NF_SUBFIELD_SEP)) != NULL) {
-       /* Distributions within the subscription field. */
-       *p++ = '\0';
-       if (*p)
-       sp->Distributions = CommaSplit(p);
-    }
-    if (f2)
-    sp->Patterns = CommaSplit(f2);
-
-    if (subbed) {
-       /* Read the subscription patterns and set the bits. */
-       memset(subbed, SUB_DEFAULT, nGroups);
-       memset(poison, SUB_DEFAULT, nGroups);
-       if (ME.Patterns)
-           SITEsetlist(ME.Patterns, subbed, poison, &ME.PoisonEntry);
-       SITEsetlist(sp->Patterns, subbed, poison, &sp->PoisonEntry);
-    }
-
-    /* Get the third field, the flags. */
-    if ((f4 = strchr(f3, NF_FIELD_SEP)) == NULL)
-       return "missing field 4";
-    *f4++ = '\0';
-    JustModerated = false;
-    JustUnmoderated = false;
-    sp->Type = FTfile;
-    for (save = argv = CommaSplit(f3); (p = *argv++) != NULL; )
-       switch (*p) {
-       default:
-           return "unknown field 3 flag";
-       case '\0':
-           break;
-       case '<':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->MaxSize = atol(p);
-           break;
-       case '>':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->MinSize = atol(p);
-           break;
-       case 'A':
-           while (*++p)
-               switch (*p) {
-               default:
-                   return "unknown A param in field 3";
-               case 'c': sp->IgnoreControl = true;
-                         sp->ControlOnly = false;
-                         break;
-               case 'C': sp->ControlOnly = true;
-                         sp->IgnoreControl = false;
-                         break;
-               case 'd': sp->DistRequired = true;      break;
-               case 'e': sp->DontWantNonExist = true;  break;
-               case 'f': sp->DropFiltered = true;      break;
-               case 'o': sp->NeedOverviewCreation = true;      break;
-               case 'O': sp->FeedwithoutOriginator = true;     break;
-               case 'p': sp->IgnorePath = true;        break;
-               }
-           break;
-       case 'B':
-           if (*++p && CTYPE(isdigit, *p)) {
-               sp->StartWriting = atoi(p);
-               if ((p = strchr(p, NF_SUBFIELD_SEP)) != NULL
-                && *++p
-                && CTYPE(isdigit, *p))
-                   sp->StopWriting = atoi(p);
-           }
-           break;
-       case 'C':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->Crosscount = atoi(p);
-           else
-               sp->Crosscount = 1;
-           break;
-       case 'F':
-           if (*++p == '\0')
-               return "missing file name for F param in field 3";
-           else if (*p == '/')
-               sp->SpoolName = xstrdup(p);
-           else {
-               sp->SpoolName = xmalloc(strlen(innconf->pathoutgoing) + 1 +
-                                               strlen(p) + 1);
-               FileGlue(sp->SpoolName, innconf->pathoutgoing, '/', p);
-           }
-           break;
-       case 'G':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->Groupcount = atoi(p);
-           else
-               sp->Groupcount = 1;
-           break;
-       case 'H':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->Hops = atoi(p);
-           else
-               sp->Hops = 1;
-           break;
-       case 'I':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->Flushpoint = atol(p);
-           break;
-       case 'N':
-           while (*++p)
-               switch (*p) {
-               default:
-                   return "unknown N param in field 3";
-               case 'm': JustModerated = true;         break;
-               case 'u': JustUnmoderated = true;       break;
-               }
-           break;
-       case 'O':
-           if (*++p == '\0')
-               return "missing originator name for O param in field 3";
-           sp->Originator = SlashSplit(p);
-           break;
-        case 'P':
-            if (*++p && CTYPE(isdigit, *p))
-                sp->Nice = atoi(p);
-            break;
-       case 'Q':
-           hf = xmalloc(sizeof(HASHFEEDLIST));
-           p++;
-            /* Check whether it is a quickhash or a MD5 hashfeed. */
-           if (*p == '@') {
-               p++;
-               hf->type = HASHFEED_QH;
-           } else
-               hf->type = HASHFEED_MD5;
-            /* Check the presence of a starting byte-offset for hashfeed. */
-           if ((u = strchr(p, '_')) != NULL) {
-               if (sscanf(u + 1, "%u", &hf->offset) != 1 || hf->offset > 12) {
-                   free(hf);
-                   return "invalid hash offset for Q param in field 3";
-               }
-           } else
-               hf->offset = 0;
-            if (sscanf(p, "%u/%u", &hf->begin, &hf->mod) == 2) {
-                hf->end = hf->begin;
-            } else if (sscanf(p, "%u-%u/%u", &hf->begin, &hf->end,
-                              &hf->mod) != 3) {
-                free(hf);
-                return "hash not in x/z or x-y/z format for Q param in field 3";
-            }
-            if (hf->begin > hf->end || hf->end > hf->mod) {
-                free(hf);
-                return "incorrect hash values for Q param in field 3";
-            }
-           hf->next = sp->HashFeedList;
-           sp->HashFeedList = hf;
-           break;
-       case 'S':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->StartSpooling = atol(p);
-           break;
-       case 'T':
-           switch (*++p) {
-           default:
-               return "unknown T param in field 3";
-           case 'c': sp->Type = FTchannel;     break;
-           case 'l': sp->Type = FTlogonly;     break;
-           case 'f': sp->Type = FTfile;        break;
-           case 'm': sp->Type = FTfunnel;      break;
-           case 'p': sp->Type = FTprogram;     break;
-           case 'x': sp->Type = FTexploder;    break;
-           }
-           break;
-       case 'U':
-           if (*++p && CTYPE(isdigit, *p))
-               sp->Followcount = atoi(p);
-           else
-               sp->Followcount = 1;
-           break;
-       case 'W':
-           for (i = 0; *++p && i < FEED_MAXFLAGS; ) {
-               switch (*p) {
-               default:
-                   return "unknown W param in field 3";
-               case FEED_FNLNAMES:             /* Funnel feed names    */
-                   sp->FNLwantsnames = true;
-                   break;
-               case FEED_HEADERS:              /* Article headers      */
-                   NeedHeaders = true;
-                   break;
-               case FEED_OVERVIEW:
-                   NeedOverview = true;        /* Overview data        */
-                   break;
-               case FEED_PATH:                 /* Path                 */
-                   NeedPath = true;
-                   break;
-               case FEED_BYTESIZE:             /* Size in bytes        */
-               case FEED_FULLNAME:             /* Full filename        */
-               case FEED_HASH:                 /* Hash                 */
-               case FEED_HDR_DISTRIB:          /* Distribution header  */
-               case FEED_STOREDGROUP:          /* stored newsgroup     */
-                   NeedStoredGroup = true;
-                   break;
-               case FEED_HDR_NEWSGROUP:        /* Newsgroup header     */
-               case FEED_MESSAGEID:            /* Message-ID           */
-               case FEED_NAME:                 /* Filename             */
-               case FEED_NEWSGROUP:            /* Newsgroup            */
-               case FEED_REPLIC:               /* Replication data     */
-                   NeedReplicdata = true;
-                   break;
-               case FEED_SITE:                 /* Site that gave it    */
-               case FEED_TIMERECEIVED:         /* When received        */
-               case FEED_TIMEPOSTED:           /* When posted          */
-               case FEED_TIMEEXPIRED:          /* When will be expired */
-                   break;
-               }
-               sp->FileFlags[i++] = *p;
-           }
-           if (*p)
-               return "too many W param values";
-           sp->FileFlags[i] = '\0';
-           break;
-       }
-    free(save);
-    if (sp->Flushpoint && sp->Type != FTfile)
-       return "I param with non-file feed";
-    if (sp->Flushpoint == 0 && sp->Type == FTfile)
-       sp->Flushpoint = SITE_BUFFER_SIZE;
-
-    if (subbed) {
-       /* Modify the subscription list based on the flags. */
-       if (JustModerated)
-           for (p = subbed, ngp = Groups, i = nGroups; --i >= 0; ngp++, p++)
-               if (ngp->Rest[0] != NF_FLAG_MODERATED)
-                   *p = false;
-       if (JustUnmoderated)
-           for (p = subbed, ngp = Groups, i = nGroups; --i >= 0; ngp++, p++)
-               if (ngp->Rest[0] == NF_FLAG_MODERATED)
-                   *p = false;
-    }
-
-    /* Get the fourth field, the param. */
-    if (*f4 == '\0' && sp != &ME) {
-       if (sp->Type != FTfile && sp->Type != FTlogonly)
-           return "empty field 4";
-       sp->Param = xmalloc(strlen(innconf->pathoutgoing) + 1 +
-                                               sp->NameLength + 1);
-       FileGlue(sp->Param, innconf->pathoutgoing, '/', sp->Name);
-    }
-    else if (sp->Type == FTfile && *f4 != '/') {
-       sp->Param = xmalloc(strlen(innconf->pathoutgoing) + 1 +
-                                               strlen(f4) + 1);
-       FileGlue(sp->Param, innconf->pathoutgoing, '/', f4);
-    }
-    else
-       sp->Param = xstrdup(f4);
-
-    if (sp->SpoolName == NULL) {
-       sp->SpoolName = xmalloc(strlen(innconf->pathoutgoing) + 1 +
-                                               strlen(sp->Name) + 1);
-       FileGlue(sp->SpoolName, innconf->pathoutgoing, '/', sp->Name);
-    }
-
-    /* Make sure there is only one %s, and only one *. */
-    if (sp->Type == FTprogram) {
-       f3 = NULL;
-       for (f2 = sp->Param; *f2; f2 = p + 1) {
-           p = strchr(f2, '%');
-           if (p == NULL)
-               break;
-           if (p[1] == '%') {
-               p++;
-               continue;
-           }
-           if (f3 != NULL)
-               return "bad (extra) sprintf format for field 4";
-           f3 = p;
-           while (*++p && *p != '*' && !CTYPE(isalpha, *p))
-               continue;
-           if (*p != 's')
-               return "bad sprintf format for field 4";
-       }
-       if (sp->FNLwantsnames
-        && ((p = strchr(sp->Param, '*')) == NULL
-         || strchr(++p, '*') != NULL))
-           return "multiple or no *'s in field 4";
-    }
-
-    /* Now tell the groups this site gets that they should feed this site. */
-    if (sp != &ME && subbed) {
-       isp = sp - Sites;
-       for (p = subbed, u = poison, ngp = Groups, i = nGroups;
-               --i >= 0; ngp++) {
-           if (*p++) {
-               for (j = 0; j < ngp->nSites; j++)
-                   if (ngp->Sites[j] == NOSITE) {
-                       ngp->Sites[j] = isp;
-                       break;
-                   }
-               if (j == ngp->nSites)
-                   ngp->Sites[ngp->nSites++] = isp;
-           }
-           if (*u++) {
-               for (j = 0; j < ngp->nPoison; j++)
-                   if (ngp->Poison[j] == NOSITE) {
-                       ngp->Poison[j] = isp;
-                       break;
-                   }
-               if (j == ngp->nPoison)
-                   ngp->Poison[ngp->nPoison++] = isp;
-           }
-        }
-    }
-
-    /* If this is a duplicate name, find the master. */
-    nsp = SITEfind(sp->Name);
-    if (nsp == sp)
-       nsp = SITEfindnext(sp->Name, nsp);
-    if (nsp != NULL) {
-       if (nsp->Master != NOSITE)
-           nsp = &Sites[nsp->Master];
-       if (nsp != sp) {
-           sp->Master = nsp - Sites;
-           nsp->IsMaster = true;
-       }
-    }
-
-    return NULL;
-}
-
-
-/*
-**  Patch up the funnel references.
-*/
-bool
-SITEfunnelpatch(void)
-{
-    int                i;
-    int                length;
-    SITE       *sp;
-    SITE       *funnel;
-    bool       result;
-
-    /* Get worst-case length of all sitenames. */
-    for (length = 0, i = nSites, sp = Sites; --i >= 0; sp++)
-       if (sp->Name != NULL)
-           length += 1 + strlen(sp->Name);
-
-    /* Loop over all funnel feeds. */
-    for (result = true, i = nSites, sp = Sites; --i >= 0; sp++) {
-       if (sp->Name == NULL || sp->Type != FTfunnel)
-           continue;
-
-       /* Find the entry they feed in to, give that entry a buffer. */
-       if (sp->Param == NULL) {
-           syslog(L_FATAL, "%s funnel NULL", sp->Name);
-           SITEfree(sp);
-           result = false;
-           continue;
-       }
-       if ((funnel = SITEfind(sp->Param)) == NULL) {
-           syslog(L_FATAL, "%s funnel_bad", sp->Name);
-           SITEfree(sp);
-           result = false;
-           continue;
-       }
-       if (funnel->Type == FTfunnel) {
-           syslog(L_FATAL, "%s funnels to funnel %s", sp->Name, funnel->Name);
-           SITEfree(sp);
-           result = false;
-           continue;
-       }
-       if (funnel->FNLnames.data == NULL) {
-           funnel->FNLnames.size = length;
-           funnel->FNLnames.data = xmalloc(length);
-       }
-       else if (funnel->FNLnames.size != length) {
-           funnel->FNLnames.size = length;
-            funnel->FNLnames.data = xrealloc(funnel->FNLnames.data, length);
-       }
-       sp->Funnel = funnel - Sites;
-    }
-
-    return result;
-}
-
-
-/*
-**  Read the entries in the newsfeeds file, and parse them one at a time.
-*/
-void
-SITEparsefile(bool StartSite)
-{
-  int          i;
-  char *       p;
-  char **      strings;
-  SITE *       sp;
-  char *       subbed;
-  char *       poison;
-  const char * error;
-  int          errors;
-  int          setuperrors;
-
-  /* Free old sites info. */
-  if (Sites) {
-    for (i = nSites, sp = Sites; --i >= 0; sp++) {
-      SITEflush(sp, false);
-      SITEfree(sp);
-    }
-    free(Sites);
-    SITEfree(&ME);
-  }
-
-  /* Count the number of sites. */
-  for (strings = SITEreadfile(false), nSites = 0; strings[nSites]; nSites++)
-    continue;
-  Sites = xcalloc(nSites, sizeof(SITE));
-
-  /* Set up scratch subscription list. */
-  subbed = xmalloc(nGroups);
-  poison = xmalloc(nGroups);
-  /* reset global variables */
-  NeedHeaders = NeedOverview = NeedPath = NeedStoredGroup = NeedReplicdata
-    = false;
-
-  ME.Prev = 0; /* Used as a flag to ensure exactly one ME entry */
-  for (sp = Sites, errors = 0, setuperrors = 0, i = 0; i < nSites; i++) {
-    p = strings[i];
-    if (p[0] == 'M' && p[1] == 'E' &&
-      ((p[2] == NF_FIELD_SEP) || (p[2] == NF_SUBFIELD_SEP))) {
-      if (ME.Prev == NOSITE) {
-       syslog(L_FATAL, "bad_newsfeeds. Must have exactly one ME entry");
-       errors++;
-      } else if ((error = SITEparseone(p, &ME, subbed, poison)) != NULL) {
-       syslog(L_FATAL, "%s bad_newsfeeds %s", MaxLength(p, p), error);
-       errors++;
-      }
-      continue;
-    }
-    if ((error = SITEparseone(p, sp, subbed, poison)) != NULL) {
-      syslog(L_FATAL, "%s bad_newsfeeds %s", MaxLength(p, p), error);
-      errors++;
-      continue;
-    }
-    if (StartSite && !SITEsetup(sp)) {
-      syslog(L_FATAL, "%s cant setup %m", sp->Name);
-      setuperrors++;
-      continue;
-    }
-    sp->Working = true;
-    sp++;
-  }
-  if (ME.Prev != NOSITE) {
-    syslog(L_FATAL, "bad_newsfeeds. Must have exactly one ME entry");
-    errors++;
-  }
-
-  if (errors || setuperrors) {
-    if (errors)
-      syslog(L_FATAL, "%s syntax_error %s", LogName, SITEfeedspath);
-    if (setuperrors)
-      syslog(L_FATAL, "%s setup_error %s", LogName, SITEfeedspath);
-    JustCleanup();
-    exit(1);
-  }
-
-  /* Free our scratch array, set up the funnel links. */
-  nSites = sp - Sites;
-  free(subbed);
-  free(poison);
-  free(strings);
-  if (!SITEfunnelpatch()) {
-    JustCleanup();
-    exit(1);
-  }
-}
diff --git a/innd/ng.c b/innd/ng.c
deleted file mode 100644 (file)
index 5f83f3b..0000000
--- a/innd/ng.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*  $Id: ng.c 6494 2003-10-20 01:12:50Z rra $
-**
-**  Routine for the in-core data structures for the active and newsfeeds
-**  files.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <dirent.h>
-
-#include "inn/innconf.h"
-#include "innd.h"
-#include "ov.h"
-
-
-/*
-**  Hash function taken from Chris Torek's hash package posted to
-**  comp.lang.c on 18-Oct-90 in <27038@mimsy.umd.edu>.  Thanks, Chris.
-*/
-#define NGH_HASH(Name, p, j)   \
-       for (p = Name, j = 0; *p; ) j = (j << 5) + j + *p++
-
-
-/*
-**  Size of hash table.   Change NGH_BUCKET if not a power of two.
-*/
-#define NGH_SIZE       2048
-#define NGH_BUCKET(j)  &NGHtable[j & (NGH_SIZE - 1)]
-
-
-/*
-**  Newsgroup hash entry, which is really a hash bucket -- pointers
-**  to all the groups with this hash code.
-*/
-typedef struct _NGHASH {
-    int                        Size;
-    int                        Used;
-    NEWSGROUP          **Groups;
-} NGHASH;
-
-
-static struct buffer   NGnames;
-static NGHASH          NGHtable[NGH_SIZE];
-static int             NGHbuckets;
-static int             NGHcount;
-
-\f
-
-/*
-**  Sorting predicate for qsort call in NGparsefile.  Put newsgroups in
-**  rough order of their activity.  Will be better if we write a "counts"
-**  file sometime.
-*/
-static int
-NGcompare(const void *p1, const void *p2)
-{
-    return ((const NEWSGROUP **)p1)[0]->Last - 
-          ((const NEWSGROUP **)p2)[0]->Last;
-}
-
-
-/*
-**  Parse a single line from the active file, filling in ngp.  Be careful
-**  not to write NUL's into the in-core copy, since we're either mmap(2)'d,
-**  or we want to just blat it out to disk later.
-*/
-static bool
-NGparseentry(NEWSGROUP *ngp, const char *p, char *end)
-{
-    char               *q;
-    unsigned int       j;
-    NGHASH             *htp;
-    NEWSGROUP          **ngpp;
-    int                        i;
-    ARTNUM             lo;
-
-    if ((q = strchr(p, ' ')) == NULL)
-       return false;
-    i = q - p;
-
-    ngp->NameLength = i;
-    ngp->Name = &NGnames.data[NGnames.used];
-    strncpy(ngp->Name, p, i);
-    ngp->Name[i] = '\0';
-    NGnames.used += i + 1;
-
-    ngp->LastString = ++q;
-    if ((q = strchr(q, ' ')) == NULL || q > end)
-       return false;
-    ngp->Lastwidth = q - ngp->LastString;
-    if ((q = strchr(q, ' ')) == NULL || q > end)
-       return false;
-    lo = (ARTNUM)atol(q + 1);
-    if ((q = strchr(q + 1, ' ')) == NULL || q > end)
-       return false;
-    ngp->Rest = ++q;
-    /* We count on atoi() to stop at the space after the digits! */
-    ngp->Last = atol(ngp->LastString);
-    ngp->nSites = 0;
-    ngp->Sites = xmalloc(NGHcount * sizeof(int));
-    ngp->nPoison = 0;
-    ngp->Poison = xmalloc(NGHcount * sizeof(int));
-    ngp->Alias = NULL;
-
-    /* Find the right bucket for the group, make sure there is room. */
-    NGH_HASH(ngp->Name, p, j);
-    htp = NGH_BUCKET(j);
-    for (p = ngp->Name, ngpp = htp->Groups, i = htp->Used; --i >= 0; ngpp++)
-       if (*p == ngpp[0]->Name[0] && strcmp(p, ngpp[0]->Name) == 0) {
-           syslog(L_ERROR, "%s duplicate_group %s", LogName, p);
-           return false;
-       }
-    if (htp->Used >= htp->Size) {
-       htp->Size += NGHbuckets;
-        htp->Groups = xrealloc(htp->Groups, htp->Size * sizeof(NEWSGROUP *));
-    }
-    htp->Groups[htp->Used++] = ngp;
-
-    if (innconf->enableoverview && !OVgroupadd(ngp->Name, lo, ngp->Last, ngp->Rest))
-       return false;
-
-    return true;
-}
-
-
-/*
-**  Parse the active file, building the initial Groups global.
-*/
-void
-NGparsefile(void)
-{
-    char       *p;
-    char       *q;
-    int                i;
-    bool       SawMe;
-    NEWSGROUP  *ngp;
-    NGHASH     *htp;
-    char       **strings;
-    char       *active;
-    char       *end;
-
-    /* If re-reading, remove anything we might have had. */
-    NGclose();
-
-    /* Get active file and space for group entries. */
-    active = ICDreadactive(&end);
-    for (p = active, i = 0; p < end; p++)
-       if (*p == '\n') i++;
-    if ((nGroups = i) == 0) {
-       syslog(L_FATAL, "%s empty active file", LogName);
-       exit(1);
-    }
-    Groups = xmalloc(nGroups * sizeof(NEWSGROUP));
-    GroupPointers = xmalloc(nGroups * sizeof(NEWSGROUP *));
-
-    /* Get space to hold copies of the names.  This might take more space
-     * than individually allocating each element, but it is definitely easier
-     * on the system. */
-    i = end - active;
-    NGnames.size = i;
-    NGnames.data = xmalloc(NGnames.size + 1);
-    NGnames.used = 0;
-
-    /* Set up the default hash buckets. */
-    NGHbuckets = nGroups / NGH_SIZE;
-    if (NGHbuckets == 0)
-       NGHbuckets = 1;
-    if (NGHtable[0].Groups)
-       for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++)
-           htp->Used = 0;
-    else
-       for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++) {
-           htp->Size = NGHbuckets;
-           htp->Groups = xmalloc(htp->Size * sizeof(NEWSGROUP *));
-           htp->Used = 0;
-       }
-
-    /* Count the number of sites. */
-    SawMe = false;
-    for (strings = SITEreadfile(true), i = 0; (p = strings[i]) != NULL; i++)
-       if (*p == 'M' && *++p == 'E' && *++p == ':')
-           SawMe = true;
-    if (i == 0 || (i == 1 && SawMe)) {
-       syslog(L_ERROR, "%s bad_newsfeeds no feeding sites", LogName);
-       NGHcount = 1;
-    }
-    else
-       NGHcount = i;
-
-    /* Loop over all lines in the active file, filling in the fields of
-     * the Groups array. */
-    for (p = active, ngp = Groups, i = nGroups; --i >= 0; ngp++, p = q + 1) {
-       ngp->Start = p - active;
-       if ((q = strchr(p, '\n')) == NULL || !NGparseentry(ngp, p, q)) {
-           syslog(L_FATAL, "%s bad_active %s...", LogName, MaxLength(p, q));
-           exit(1);
-       }
-    }
-
-    /* Sort each bucket. */
-    for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++)
-       if (htp->Used > 1)
-           qsort(htp->Groups, htp->Used, sizeof htp->Groups[0], NGcompare);
-
-    /* Chase down any alias flags. */
-    for (ngp = Groups, i = nGroups; --i >= 0; ngp++)
-       if (ngp->Rest[0] == NF_FLAG_ALIAS) {
-           ngp->Alias = ngp;
-           if ((p = strchr(ngp->Alias->Rest, '\n')) != NULL)
-               *p = '\0';
-           ngp->Alias = NGfind(&ngp->Alias->Rest[1]);
-           if (p)
-               *p = '\n';
-           if (ngp->Alias != NULL && ngp->Alias->Rest[0] == NF_FLAG_ALIAS)
-               syslog(L_NOTICE, "%s alias_error %s too many levels",
-                   LogName, ngp->Name);
-       }
-}
-
-/*
-** Free allocated memory
-*/
-void
-NGclose(void)
-{
-    int                i;
-    NEWSGROUP  *ngp;
-    NGHASH     *htp;
-
-    if (Groups) {
-       for (i = nGroups, ngp = Groups; --i >= 0; ngp++) {
-           free(ngp->Sites);
-           free(ngp->Poison);
-       }
-       free(Groups);
-       Groups = NULL;
-       free(GroupPointers);
-       free(NGnames.data);
-    }
-
-    for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++) {
-      htp->Size = NGHbuckets;
-      if (htp->Groups) {
-       free(htp->Groups);
-       htp->Used = 0;
-       htp->Groups = NULL;
-      }
-    }
-}
-
-/*
-**  Hash a newsgroup and see if we get it.
-*/
-NEWSGROUP *
-NGfind(const char *Name)
-{
-    const char         *p;
-    int                        i;
-    unsigned int       j;
-    NEWSGROUP          **ngp;
-    char               c;
-    NGHASH             *htp;
-
-    NGH_HASH(Name, p, j);
-    htp = NGH_BUCKET(j);
-    for (c = *Name, ngp = htp->Groups, i = htp->Used; --i >= 0; ngp++)
-       if (c == ngp[0]->Name[0] && strcmp(Name, ngp[0]->Name) == 0)
-           return ngp[0];
-    return NULL;
-}
-
-
-/*
-**  Split a newsgroups header line into the groups we get.  Return the
-**  number of newsgroups.  ' ' and '\t' are dropped when copying.
-*/
-int
-NGsplit(char *p, int size, LISTBUFFER *list)
-{
-  char         **gp, *q;
-  int          i;
-
-  /* setup buffer */
-  SetupListBuffer(size, list);
-
-  /* loop over and copy */
-  for (i = 0, q = list->Data, gp = list->List ; *p ; p++, *q++ = '\0') {
-    /* skip leading separators and white spaces. */
-    for (; *p && (NG_ISSEP(*p) || ISWHITE(*p)) ; p++)
-      continue;
-    if (*p == '\0')
-      break;
-
-    if (i == list->ListLength) {
-      list->ListLength += DEFAULTNGBOXSIZE;
-      list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-      gp = &list->List[i];
-    }
-    /* mark the start of the newsgroup, move to the end of it while copying */
-    for (*gp++ = q, i++ ; *p && !NG_ISSEP(*p) && !ISWHITE(*p) ;) {
-      if (*p == ':')
-       /* reject if ':' is included */
-       return 0;
-      *q++ = *p++;
-      continue;
-    }
-    if (*p == '\0')
-      break;
-  }
-  *q = '\0';
-  if (i == list->ListLength) {
-    list->ListLength += DEFAULTNGBOXSIZE;
-    list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
-    gp = &list->List[i];
-  }
-  *gp = NULL;
-  return i;
-}
-
-
-/*
-**  Renumber a group.
-*/
-static char            NORENUMBER[] = "%s cant renumber %s %s too wide";
-static char            RENUMBER[] = "%s renumber %s %s from %ld to %ld";
-
-bool
-NGrenumber(NEWSGROUP *ngp)
-{
-    int                        low, high, count,flag;
-    char               *f2;
-    char               *f3;
-    char               *f4;
-    char               *start;
-    long               lomark, himark;
-    long               l;
-    char               *dummy;
-
-    if (!innconf->enableoverview) return true; /* can't do anything w/o overview */
-
-    /* Get a valid offset into the active file. */
-    if (ICDneedsetup) {
-       syslog(L_ERROR, "%s unsynched must reload before renumber", LogName);
-       return false;
-    }
-    start = ICDreadactive(&dummy) + ngp->Start;
-
-    /* Check the file format. */
-    if ((f2 = strchr(start, ' ')) == NULL
-     || (f3 = strchr(++f2, ' ')) == NULL
-     || (f4 = strchr(++f3, ' ')) == NULL) {
-       syslog(L_ERROR, "%s bad_format active %s",
-           LogName, MaxLength(start, start));
-       return false;
-    }
-    himark = atol(f2);
-    lomark = himark + 1;
-    /* note these will be the low and himarks if the group turns out to be empty. */
-
-    /* Check overview data for the group. */
-    if (!OVgroupstats(ngp->Name, &low, &high, &count, &flag)) return false;
-    if (count != 0) {
-       /* non-empty group, so set low/himarks from overview. */
-       lomark = low;
-       himark = high;
-    }
-    l = atol(f2);
-    if (himark > l) {
-       syslog(L_NOTICE, RENUMBER, LogName, ngp->Name, "hi", l, himark);
-       if (!FormatLong(f2, himark, f3 - f2 - 1)) {
-           syslog(L_ERROR, NORENUMBER, LogName, ngp->Name, "hi");
-           return false;
-       }
-       ngp->Last = himark;
-       ICDactivedirty++;
-    } else if (himark < l) {
-        syslog(L_NOTICE, "%s renumber %s hi not decreasing %ld to %ld",
-               LogName, ngp->Name, l, himark);
-    }
-    l = atol(f3);
-    if (lomark != l) {
-       if (lomark < l)
-           syslog(L_NOTICE, RENUMBER, LogName, ngp->Name, "lo", l, lomark);
-       if (!FormatLong(f3, lomark, f4 - f3)) {
-           syslog(L_ERROR, NORENUMBER, LogName, ngp->Name, "lo");
-           return false;
-       }
-       ICDactivedirty++;
-    }
-    return true;
-}
-
-/*
- * Set the low article count for the given group.
- * Like NGrenumber(), but we don't scan the spool,
- * and the himark is ignored.
- */
-bool
-NGlowmark(NEWSGROUP *ngp, long lomark)
-{
-    long l;
-    char *f2, *f3, *f4;
-    char *start;
-
-    start = ICDreadactive(&f2) + ngp->Start;
-    /* Check the file format. */
-    if ((f2 = strchr(start, ' ')) == NULL
-     || (f3 = strchr(++f2, ' ')) == NULL
-     || (f4 = strchr(++f3, ' ')) == NULL) {
-        syslog(L_ERROR, "%s bad_format active %s",
-            LogName, MaxLength(start, start));
-        return false;
-    }
-    l = atol(f3);
-    if (lomark != l) {
-        if (lomark < l)
-            syslog(L_NOTICE, RENUMBER, LogName, ngp->Name, "lo", l, lomark);
-        if (!FormatLong(f3, lomark, f4 - f3)) {
-            syslog(L_ERROR, NORENUMBER, LogName, ngp->Name, "lo");
-            return false;
-        }
-        ICDactivedirty++;
-    }
-    return true;
-}
diff --git a/innd/perl.c b/innd/perl.c
deleted file mode 100644 (file)
index c0e286e..0000000
+++ /dev/null
@@ -1,497 +0,0 @@
-/*  $Id: perl.c 7815 2008-05-05 08:43:58Z iulius $
-**
-**  Perl filtering support for innd.
-**
-**  Originally written by Christophe Wolfhugel <wolf@pasteur.fr> (although
-**  he wouldn't recognise it anymore so don't blame him) and modified,
-**  expanded and tweaked since by James Brister, Jeremy Nixon, Ed Mooring,
-**  Russell Vincent, and Russ Allbery.
-**
-**  This file should contain all innd-specific Perl linkage.  Linkage
-**  applicable to both innd and nnrpd should go into lib/perl.c instead.
-**
-**  We are assuming Perl 5.004 or later.
-**
-**  Future work:
-**
-**   - What we're doing with Path headers right now doesn't work for folded
-**     headers.  It's also kind of gross.  There has to be a better way of
-**     handling this.
-**
-**   - The breakdown between this file, lib/perl.c, and nnrpd/perl.c should
-**     be rethought, ideally in the light of supporting multiple filters in
-**     different languages.
-**
-**   - We're still calling strlen() on artBody, which should be avoidable
-**     since we've already walked it several times.  We should just cache
-**     the length somewhere for speed.
-**
-**   - Variable and key names should be standardized between this and nnrpd.
-**
-**   - The XS code is still calling CC* functions.  The common code between
-**     the two control interfaces should be factored out into the rest of
-**     innd instead.
-**
-**   - There's a needless perl_get_cv() call for *every message ID* offered
-**     to the server right now.  We need to stash whether that filter is
-**     active.
-*/
-
-#include "config.h"
-
-/* Skip this entire file if DO_PERL (./configure --with-perl) isn't set. */
-#if DO_PERL
-
-#include "clibrary.h"
-#include "innd.h"
-
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-#include "ppport.h"
-
-#include "innperl.h"
-
-/* From art.c.  Ew.  Need header parsing that doesn't use globals. */
-extern char             *filterPath;
-
-/*
-**  Run an incoming article through the Perl article filter.  Returns NULL
-**  accept the article or a rejection message to reject it.
-*/
-char *
-PLartfilter(const ARTDATA *data, char *artBody, long artLen, int lines)
-{
-    dSP;
-    const ARTHEADER * hp;
-    const HDRCONTENT *hc = data->HdrContent;
-    HV *        hdr;
-    CV *        filter;
-    int         i, rc;
-    char *      p;
-    static 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.  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 (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);
-
-    ENTER;
-    SAVETMPS;
-    PUSHMARK(SP);
-    rc = perl_call_sv((SV *) filter, G_EVAL|G_SCALAR|G_NOARGS);
-    SPAGAIN;
-
-    hv_undef(hdr);
-
-    /* Check $@, which will be set if the sub died. */
-    buf[0] = '\0';
-    if (SvTRUE(ERRSV)) {
-        syslog(L_ERROR, "Perl function filter_art died on article %s: %s",
-               HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "?",
-               SvPV(ERRSV, PL_na));
-        (void) POPs;
-        PerlFilter(false);
-    } else if (rc == 1) {
-        p = POPp;
-        if (p && *p)
-            strlcpy(buf, p, sizeof(buf));
-    }
-
-    PUTBACK;
-    FREETMPS;
-    LEAVE;
-    return (buf[0] != '\0') ? buf : NULL;
-}
-
-
-/*
-**  Run an incoming message ID from CHECK or IHAVE through the Perl filter.
-**  Returns NULL to accept the article or a rejection message to reject it.
-*/
-char *
-PLmidfilter(char *messageID)
-{
-    dSP;
-    CV          *filter;
-    int         rc;
-    char        *p;
-    static char buf[256];
-
-    if (!PerlFilterActive) return NULL;
-    filter = perl_get_cv("filter_messageid", 0);
-    if (!filter) return NULL;
-
-    /* Pass filter_messageid() the message ID on the Perl stack. */
-    ENTER;
-    SAVETMPS;
-    PUSHMARK(SP);
-    XPUSHs(sv_2mortal(newSVpv(messageID, 0)));
-    PUTBACK;
-    rc = perl_call_sv((SV *) filter, G_EVAL|G_SCALAR);
-    SPAGAIN;
-
-    /* Check $@, which will be set if the sub died. */
-    buf[0] = '\0';
-    if (SvTRUE(ERRSV)) {
-        syslog(L_ERROR, "Perl function filter_messageid died on id %s: %s",
-               messageID, SvPV(ERRSV, PL_na));
-        (void) POPs;
-        PerlFilter(false);
-    } else if (rc == 1) {
-        p = POPp;
-        if (p && *p)
-            strlcpy(buf, p, sizeof(buf));
-    }
-    
-    PUTBACK;
-    FREETMPS;
-    LEAVE;
-    return (buf[0] != '\0') ? buf : NULL;
-}
-
-
-/*
-**  Call a Perl sub on any change in INN's mode, passing in the old and new
-**  mode and the reason.
-*/
-void
-PLmode(OPERATINGMODE Mode, OPERATINGMODE NewMode, char *reason)
-{
-    dSP;
-    HV          *mode;
-    CV          *filter;
-
-    filter = perl_get_cv("filter_mode", 0);
-    if (!filter) return;
-
-    /* Current mode goes into $mode{Mode}, new mode in $mode{NewMode}, and
-       the reason in $mode{reason}. */
-    mode = perl_get_hv("mode", 1);
-
-    if (Mode == OMrunning)
-        hv_store(mode, "Mode", 4, newSVpv("running", 0), 0);
-    if (Mode == OMpaused)
-        hv_store(mode, "Mode", 4, newSVpv("paused", 0), 0);
-    if (Mode == OMthrottled)
-        hv_store(mode, "Mode", 4, newSVpv("throttled", 0), 0);
-
-    if (NewMode == OMrunning)
-        hv_store(mode, "NewMode", 7, newSVpv("running", 0), 0);
-    if (NewMode == OMpaused)
-        hv_store(mode, "NewMode", 7, newSVpv("paused", 0), 0);
-    if (NewMode == OMthrottled)
-        hv_store(mode, "NewMode", 7, newSVpv("throttled", 0), 0);
-
-    hv_store(mode, "reason", 6, newSVpv(reason, 0), 0);
-
-    PUSHMARK(SP);
-    perl_call_sv((SV *) filter, G_EVAL|G_DISCARD|G_NOARGS);
-
-    /* Check $@, which will be set if the sub died. */
-    if (SvTRUE(ERRSV)) {
-        syslog(L_ERROR, "Perl function filter_mode died: %s",
-                SvPV(ERRSV, PL_na));
-        (void) POPs;
-        PerlFilter(false);
-    }
-}
-
-
-/*
-**  Called by CCmode, this returns the Perl filter statistics if a Perl
-**  function to generate such statistics has been defined, or NULL otherwise.
-**  If a string is returned, it's in newly allocated memory that must be freed
-**  by the caller.
-*/
-char *
-PLstats(void)
-{
-    dSP;
-    char *argv[] = { NULL };
-    
-    if (perl_get_cv("filter_stats", false) == NULL)
-        return NULL;
-    else {
-        char *stats = NULL;
-        char *result;
-
-       ENTER;
-       SAVETMPS;
-       perl_call_argv("filter_stats", G_EVAL | G_NOARGS, argv);
-       SPAGAIN;
-        result = POPp;
-        if (result != NULL && *result)
-            stats = xstrdup(result);
-       PUTBACK;
-       FREETMPS;
-       LEAVE;
-
-        return stats;
-    }
-}
-
-
-/*
-**  The remainder of this file are XS callbacks visible to embedded Perl
-**  code to perform various innd functions.  They were originally written by
-**  Ed Mooring (mooring@acm.org) on May 14, 1998, and have since been split
-**  between this file and lib/perl.c (which has the ones that can also be
-**  used in nnrpd).  The function that registers them at startup is at the
-**  end.
-*/
-
-/*
-**  Add an entry to history.  Takes message ID and optionally arrival,
-**  article, and expire times and storage API token.  If the times aren't
-**  given, they default to now.  If the token isn't given, that field will
-**  be left empty.  Returns boolean success.
-*/
-XS(XS_INN_addhist)
-{
-    dXSARGS;
-    int         i;
-    char        tbuff[32];
-    char*       parambuf[6];
-
-    if (items < 1 || items > 5)
-        croak("Usage INN::addhist(msgid,[arrival,articletime,expire,token])");
-
-    for (i = 0; i < items; i++)
-        parambuf[i] = (char *) SvPV(ST(0), PL_na);
-
-    /* If any of the times are missing, they should default to now. */
-    if (i < 4) {
-        snprintf(tbuff, sizeof(tbuff), "%ld", (long) time(NULL));
-        for (; i < 4; i++)
-            parambuf[i] = tbuff;
-    }
-
-    /* The token defaults to an empty string. */
-    if (i == 4)
-        parambuf[4] = "";
-
-    parambuf[5] = NULL;
-
-    /* CCaddhist returns NULL on success. */
-    if (CCaddhist(parambuf))
-        XSRETURN_NO;
-    else
-        XSRETURN_YES;
-}
-
-
-/*
-**  Takes the message ID of an article and returns the full article as a
-**  string or undef if the article wasn't found.  It will be converted from
-**  wire format to native format.  Note that this call isn't particularly
-**  optimized or cheap.
-*/
-XS(XS_INN_article)
-{
-    dXSARGS;
-    char *      msgid;
-    TOKEN       token;
-    ARTHANDLE * art;
-    char *      p;
-    size_t      len;
-
-    if (items != 1)
-       croak("Usage: INN::article(msgid)");
-
-    /* Get the article token from the message ID and the history file. */
-    msgid = (char *) SvPV(ST(0), PL_na);
-    if (!HISlookup(History, msgid, NULL, NULL, NULL, &token)) XSRETURN_UNDEF;
-
-    /* Retrieve the article and convert it from wire format. */
-    art = SMretrieve(token, RETR_ALL);
-    if (art == NULL) XSRETURN_UNDEF;
-    p = FromWireFmt(art->data, art->len, &len);
-    SMfreearticle(art);
-
-    /* Push a copy of the article onto the Perl stack, free our temporary
-       memory allocation, and return the article to Perl. */
-    ST(0) = sv_2mortal(newSVpv(p, len));
-    free(p);
-    XSRETURN(1);
-}
-
-
-/*
-**  Cancel a message by message ID; returns boolean success.  Equivalent to
-**  ctlinnd cancel <message>.
-*/
-XS(XS_INN_cancel)
-{
-    dXSARGS;
-    char        *msgid;
-    char        *parambuf[2];
-
-    if (items != 1)
-        croak("Usage: INN::cancel(msgid)");
-
-    msgid = (char *) SvPV(ST(0), PL_na);
-    parambuf[0] = msgid;
-    parambuf[1] = NULL;
-
-    /* CCcancel returns NULL on success. */
-    if (CCcancel(parambuf))
-        XSRETURN_NO;
-    else
-        XSRETURN_YES;
-}
-
-
-/*
-**  Return the files for a given message ID, taken from the history file.
-**  This function should really be named INN::token() and probably will be
-**  some day.
-*/
-XS(XS_INN_filesfor)
-{
-    dXSARGS;
-    char        *msgid;
-    TOKEN       token;
-
-    if (items != 1)
-        croak("Usage: INN::filesfor(msgid)");
-
-    msgid = (char *) SvPV(ST(0), PL_na);
-    if (HISlookup(History, msgid, NULL, NULL, NULL, &token)) {
-        XSRETURN_PV(TokenToText(token));
-    } else {
-        XSRETURN_UNDEF;
-    }
-}
-
-
-/*
-**  Whether message ID is in the history file; returns boolean.
-*/
-XS(XS_INN_havehist)
-{
-    dXSARGS;
-    char        *msgid;
-
-    if (items != 1)
-        croak("Usage: INN::havehist(msgid)");
-
-    msgid = (char *) SvPV(ST(0), PL_na);
-    if (HIScheck(History, msgid))
-        XSRETURN_YES;
-    else
-        XSRETURN_NO;
-}
-
-
-/*
-**  Takes the message ID of an article and returns the article headers as
-**  a string or undef if the article wasn't found.  Each line of the header
-**  will end with \n.
-*/
-XS(XS_INN_head)
-{
-    dXSARGS;
-    char *      msgid;
-    TOKEN       token;
-    ARTHANDLE * art;
-    char *      p;
-    size_t      len;
-
-    if (items != 1)
-        croak("Usage: INN::head(msgid)");
-
-    /* Get the article token from the message ID and the history file. */
-    msgid = (char *) SvPV(ST(0), PL_na);
-    if (!HISlookup(History, msgid, NULL, NULL, NULL, &token)) XSRETURN_UNDEF;
-
-    /* Retrieve the article header and convert it from wire format. */
-    art = SMretrieve(token, RETR_HEAD);
-    if (art == NULL) XSRETURN_UNDEF;
-    p = FromWireFmt(art->data, art->len, &len);
-    SMfreearticle(art);
-
-    /* Push a copy of the article header onto the Perl stack, free our
-       temporary memory allocation, and return the header to Perl. */
-    ST(0) = sv_2mortal(newSVpv(p, len));
-    free(p);
-    XSRETURN(1);
-}
-
-
-/*
-**  Returns the active file flag for a newsgroup or undef if it isn't in the
-**  active file.
-*/
-XS(XS_INN_newsgroup)
-{
-    dXSARGS;
-    char *      newsgroup;
-    NEWSGROUP * ngp;
-    char *      end;
-    int         size;
-
-    if (items != 1)
-        croak("Usage: INN::newsgroup(group)");
-    newsgroup = (char *) SvPV(ST(0), PL_na);
-
-    ngp = NGfind(newsgroup);
-    if (!ngp) {
-        XSRETURN_UNDEF;
-    } else {
-        /* ngp->Rest is newline-terminated; find the end. */
-        end = strchr(ngp->Rest, '\n');
-        if (end == NULL) {
-            size = strlen(ngp->Rest);
-        } else {
-            size = end - ngp->Rest;
-        }
-        ST(0) = sv_2mortal(newSVpv(ngp->Rest, size));
-        XSRETURN(1);
-    }
-}
-
-
-/*
-**  Initialize the XS callbacks defined in this file.
-*/
-void
-PLxsinit(void)
-{
-    newXS("INN::addhist", XS_INN_addhist, "perl.c");
-    newXS("INN::article", XS_INN_article, "perl.c");
-    newXS("INN::cancel", XS_INN_cancel, "perl.c");
-    newXS("INN::havehist", XS_INN_havehist, "perl.c");
-    newXS("INN::head", XS_INN_head, "perl.c");
-    newXS("INN::newsgroup", XS_INN_newsgroup, "perl.c");
-    newXS("INN::filesfor", XS_INN_filesfor, "perl.c");
-}
-
-#endif /* defined(DO_PERL) */
diff --git a/innd/proc.c b/innd/proc.c
deleted file mode 100644 (file)
index c3b55dc..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*  $Id: proc.c 6124 2003-01-14 06:03:29Z rra $
-**
-**  Process control routines.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-
-#include "innd.h"
-
-
-static PROCESS *PROCtable;
-static int     PROCtablesize;
-static PROCESS PROCnull = { PSfree, 0, 0, 0, 0, 0 };
-
-
-/*
-**  Collect dead processes.
-*/
-static void
-PROCreap(void)
-{
-    int                status;
-    PROCESS    *pp;
-    int         i;
-    pid_t      pid;
-
-    for ( ; ; ) {
-       pid = waitpid(-1, &status, WNOHANG);
-       if (pid == 0)
-           break;
-       if (pid < 0) {
-           if (errno != ECHILD)
-               syslog(L_ERROR, "%s cant wait %m", LogName);
-           break;
-       }
-       for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++)
-           if (pp->Pid == pid) {
-               PROCneedscan = true;
-               pp->Status = WEXITSTATUS(status);
-               pp->State = PSdead;
-               pp->Collected = Now.time;
-               break;
-           }
-    }
-}
-
-
-/*
-**  Signal handler that collects the processes, then resets the signal.
-*/
-static RETSIGTYPE
-PROCcatchsignal(int s)
-{
-    PROCreap();
-
-#ifndef HAVE_SIGACTION
-    xsignal(s, PROCcatchsignal);
-#else
-    s = s;                     /* ARGSUSED */
-#endif
-}
-
-
-/*
-**  Synchronous version that notifies a site when its process went away.
-*/
-void
-PROCscan(void)
-{
-    PROCESS    *pp;
-    int        i;
-
-    for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++)
-       if (pp->State == PSdead) {
-           if (pp->Site >= 0)
-               SITEprocdied(&Sites[pp->Site], pp - PROCtable, pp);
-           pp->State = PSfree;
-       }
-    PROCneedscan = false;
-}
-
-
-#if    0
-/*
-**  Close down all processes.
-*/
-void
-PROCclose(Quickly)
-    bool               Quickly;
-{
-    int        sig;
-    PROCESS    *pp;
-    int        i;
-
-    /* What signal are we sending? */
-    sig = Quickly ? SIGKILL : SIGTERM;
-
-    /* Send the signal to all living processes. */
-    for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++) {
-       if (pp->State != PSrunning)
-           continue;
-       if (kill(pp->Pid, sig) < 0 && errno != ESRCH)
-           syslog(L_ERROR, "%s cant kill %s %ld %m",
-               LogName, Quickly ? "KILL" : "TERM", (long) pp->Pid);
-    }
-
-    /* Collect any who might have died. */
-    PROCreap();
-    for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++)
-       if (pp->State == PSdead)
-           *pp = PROCnull;
-}
-#endif /* 0 */
-
-
-/*
-**  Stop watching a process -- we don't care about it any more.
-*/
-void
-PROCunwatch(int process)
-{
-    if (process < 0 || process >= PROCtablesize) {
-       syslog(L_ERROR, "%s internal PROCunwatch %d", LogName, process);
-       return;
-    }
-    PROCtable[process].Site = -1;
-}
-
-
-/*
-**  Add a pid to the list of processes we watch.
-*/
-int
-PROCwatch(pid_t pid, int site)
-{
-    PROCESS     *pp;
-    int         i;
-
-    /* Find a free slot for this process. */
-    for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++)
-       if (pp->State == PSfree)
-           break;
-    if (i < 0) {
-       /* Ran out of room -- grow the table. */
-        PROCtable = xrealloc(PROCtable, (PROCtablesize + 20) * sizeof(PROCESS));
-        for (pp = &PROCtable[PROCtablesize], i=20; --i >= 0; pp++)
-          *pp = PROCnull;
-       pp = &PROCtable[PROCtablesize];
-       PROCtablesize += 20;
-    }
-
-    pp->State = PSrunning;
-    pp->Pid = pid;
-    pp->Started = Now.time;
-    pp->Site = site;
-    return pp - PROCtable;
-}
-
-
-/*
-**  Setup.
-*/
-void
-PROCsetup(int i)
-{
-    PROCESS    *pp;
-
-    if (PROCtable)
-       free(PROCtable);
-    PROCtablesize = i;
-    PROCtable = xmalloc(PROCtablesize * sizeof(PROCESS));
-    for (pp = PROCtable, i = PROCtablesize; --i >= 0; pp++)
-       *pp = PROCnull;
-
-#if    defined(SIGCHLD)
-    xsignal(SIGCHLD, PROCcatchsignal);
-#endif /* defined(SIGCHLD) */
-    xsignal(SIGPIPE, PROCcatchsignal);
-}
diff --git a/innd/python.c b/innd/python.c
deleted file mode 100644 (file)
index f14a312..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-/*  $Id: python.c 7891 2008-06-22 09:59:11Z iulius $
-**
-**  python.c: Embed Python in the style of innd's TCL and Perl stuff.
-** 
-**  Written by G.J. Andruk <meowing@banet.net> patterned after
-**  TCL/Perl work by Bob Heiney and Christophe Wolfhugel and a whole
-**  bunch of other people mentioned in the docs and sources for the
-**  other filters.
-**
-**  The astute reader may notice the commission of blatant atrocities
-**  against Python's OO model here.  Don't tell Guido.
-**
-**  A quick note regarding Python exceptions:  functions like
-**      PyObject_GetAttrString(PyObject *o, const char *attr_name)
-**  raise an exception when they fail, even though they return NULL.
-**  And as exceptions accumulate from caller to caller and so on,
-**  it generates weird issues with Python scripts afterwards.  So such
-**  uses should be checked before.  For instance with:
-**      PyObject_HasAttrString(PyObject *o, const char *attr_name).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-
-#if defined(DO_PYTHON)
-
-#include "Python.h"
-
-
-bool           PythonFilterActive;
-char           *filterPath;    /* this gets set in art.c */
-PyObject       *PYFilterObject = NULL;
-PyObject       *PYFilterModule = NULL;
-
-/* article filter bits and pieces */
-PyObject       *PYheaders = NULL;
-PyObject       **PYheaditem;
-PyObject       **PYheadkey;
-PyObject       *PYpathkey, *PYlineskey, *PYbodykey;
-
-/* external functions */
-PyObject       *msgid_method = NULL;
-PyObject       *art_method = NULL;
-PyObject       *mode_method = NULL;
-PyObject       *pre_reload_method = NULL;
-PyObject       *close_method = NULL;
-
-
-
-/*
-**  Turn filtering on or off.
-*/
-void
-PYfilter(value)
-    bool value;
-{
-    PythonFilterActive = value;
-    syslog(L_NOTICE, "%s Python filtering %s", LogName,
-          PythonFilterActive ? "enabled" : "disabled");
-}
-
-
-
-/*
-**  Front end for PYfilter()
-*/
-const char *
-PYcontrol(char **av)
-{
-    char        *p;
-    extern bool PythonFilterActive;
-
-    switch (av[0][0]) {
-    default:
-        return "1 Bad flag";
-    case 'y':
-        if (PythonFilterActive)
-            return "1 Python filter already enabled";
-        else if (PYFilterObject == NULL)
-            return "1 Python filter not defined" ;
-        PYfilter(true);
-        break;
-    case 'n':
-        if (!PythonFilterActive)
-            return "1 Python filter already disabled";
-        PYfilter(false);
-        break;
-    }
-    return NULL;
-}
-
-
-
-
-/*
-**  Reject articles we don't like.
-*/
-char *
-PYartfilter(const ARTDATA *data, char *artBody, long artLen, int lines)
-{
-    const ARTHEADER *hp;
-    const HDRCONTENT *hc = data->HdrContent;
-    int                hdrnum;
-    int                i;
-    char       *p, save;
-    static char buf[256];
-    PyObject   *result;
-
-    if (!PythonFilterActive || PYFilterObject == NULL || art_method == NULL)
-       return NULL;
-
-    /* Add headers to the dictionary... */
-    hdrnum = 0;
-    for (i = 0 ; i < MAX_ARTHEADER ; i++) {
-       if (HDR_FOUND(i)) {
-           hp = &ARTheaders[i];
-           PYheaditem[hdrnum] = PyBuffer_FromMemory(HDR(i), HDR_LEN(i));
-       } else
-           PYheaditem[hdrnum] = Py_None;
-       PyDict_SetItem(PYheaders, PYheadkey[hdrnum], PYheaditem[hdrnum]);
-       hdrnum++;
-    }
-
-    /* ...then the body... */
-    if (artLen && artBody != NULL)
-        PYheaditem[hdrnum] = PyBuffer_FromMemory(artBody, --artLen);
-    else
-        PYheaditem[hdrnum] = Py_None;
-    PyDict_SetItem(PYheaders, PYbodykey, PYheaditem[hdrnum++]);
-
-    /* ...and finally, the line count. */
-    PYheaditem[hdrnum] = PyInt_FromLong((long) lines);
-    PyDict_SetItem(PYheaders, PYlineskey, PYheaditem[hdrnum++]);
-
-    /* Now see if the filter likes it. */
-    result = PyObject_CallFunction(art_method, "O", PYheaders);
-    if ((result != NULL) && PyObject_IsTrue(result))
-       strlcpy(buf, PyString_AS_STRING(result), sizeof(buf));
-    else
-       *buf = '\0';
-    Py_XDECREF(result);
-
-    /* Clean up after ourselves */
-    PyDict_Clear(PYheaders);
-    for (i = 0; i < hdrnum; i++)
-       if (PYheaditem[i] != Py_None)
-           Py_DECREF(PYheaditem[i]);
-
-    if (*buf != '\0') 
-       return buf;
-    return NULL;
-}
-
-
-
-/*
-**  Refuse message IDs offered thru CHECK or IHAVE that we don't like.
-*/
-char *
-PYmidfilter(messageID, msglen)
-    char *messageID;
-    int msglen;
-{
-    static char                buf[256];
-    PyObject           *result;
-
-    if (!PythonFilterActive || PYFilterObject == NULL || msgid_method == NULL)
-       return NULL;
-
-    result = PyObject_CallFunction(msgid_method, "s#", messageID, msglen);
-    if ((result != NULL) && PyObject_IsTrue(result))
-       strlcpy(buf, PyString_AS_STRING(result), sizeof(buf));
-    else
-       *buf = '\0';
-    Py_XDECREF(result);
-
-    if (*buf != '\0') 
-       return buf;
-    return NULL;
-}
-
-
-
-/*
-**  Tell the external module about innd's state.
-*/
-void
-PYmode(Mode, NewMode, reason)
-    OPERATINGMODE Mode, NewMode;
-    char *reason;
-{
-    PyObject   *result;
-    char       oldmode[10], newmode[10];
-
-    if (!PythonFilterActive || PYFilterObject == NULL || mode_method == NULL)
-       return;
-
-    switch (Mode) {
-    default:           strlcpy(oldmode, "unknown", 10);        break;
-    case OMrunning:    strlcpy(oldmode, "running", 10);        break;
-    case OMpaused:     strlcpy(oldmode, "paused", 10);         break;
-    case OMthrottled:  strlcpy(oldmode, "throttled", 10);      break;
-    }
-
-    switch (NewMode) {
-    default:           strlcpy(newmode, "unknown", 10);        break;
-    case OMrunning:    strlcpy(newmode, "running", 10);        break;
-    case OMpaused:     strlcpy(newmode, "paused", 10);         break;
-    case OMthrottled:  strlcpy(newmode, "throttled", 10);      break;
-    }
-
-    result = PyObject_CallFunction(mode_method, "sss",
-                                  oldmode, newmode, reason);
-    Py_XDECREF(result);
-}
-
-
-
-/*
-**  Called by the external module so it can register itself with innd.
-*/
-static PyObject *
-PY_set_filter_hook(dummy, args)
-    PyObject *dummy, *args;
-{
-    PyObject   *result = NULL;
-    PyObject   *temp;
-
-    if (PyArg_ParseTuple(args, "O:set_filter_hook", &temp)) {
-       Py_XINCREF(temp);
-       Py_XDECREF(PYFilterObject);
-       PYFilterObject = temp;
-       Py_INCREF(Py_None);
-       result = Py_None;
-    }
-    return result;
-}
-
-
-
-/*
-**  Allow external module to ask innd if an ID is in history.
-*/
-static PyObject *
-PY_havehist(self, args)
-    PyObject *self, *args;
-{
-    char       *msgid;
-    int                msgidlen;
-
-    if (!PyArg_ParseTuple(args, "s#", &msgid, &msgidlen))
-       return NULL;
-
-    if (HIScheck(History, msgid))
-       return PyInt_FromLong(1);
-    return PyInt_FromLong(0);
-}
-
-
-
-/*
-**  Allow external module to locally delete an article.
-*/
-static PyObject *
-PY_cancel(self, args)
-    PyObject *self, *args;
-{
-    char       *msgid;
-    int                msgidlen;
-    char       *parambuf[2];
-
-    if (!PyArg_ParseTuple(args, "s#", &msgid, &msgidlen))
-       return NULL;
-
-    parambuf[0]= msgid;
-    parambuf[1]= 0;
-
-    if (!CCcancel(parambuf))
-       return PyInt_FromLong(1);
-    return PyInt_FromLong(0);
-}
-
-
-
-/*
-**  Stuff an ID into history so that it will be refused later.
-*/
-static PyObject *
-PY_addhist(self, args)
-    PyObject *self, *args;
-{
-    char       *msgid;
-    int                msgidlen;
-    char       *articlepaths = "";
-    char       tbuff[12];
-    char       *parambuf[6];
-
-    if (!PyArg_ParseTuple(args, "s#", &msgid, &msgidlen))
-       return NULL;
-
-    snprintf(tbuff, sizeof(tbuff), "%d", time(NULL));
-
-    parambuf[0] = msgid;
-    parambuf[1] = parambuf[2] = parambuf[3] = tbuff;
-    parambuf[4] = articlepaths;
-    parambuf[5] = 0;
-
-    if (!CCaddhist(parambuf))
-       return PyInt_FromLong(1);
-    return PyInt_FromLong(0);
-}
-
-
-
-/*
-**  Get a newsgroup's status flag (j, m, n, x, y, =other.group)
-*/
-static PyObject *
-PY_newsgroup(self, args)
-    PyObject *self, *args;
-{
-    char       *newsgroup;
-    int                nglen;
-    NEWSGROUP  *ngp;
-    char       *end;
-    char       *rest;
-    int                size;
-
-    if (!PyArg_ParseTuple(args, "s#", &newsgroup, &nglen))
-       return NULL;
-
-    ngp = NGfind(newsgroup);
-    if (ngp == NULL)
-       return PyString_FromStringAndSize(NULL, 0);
-
-    /* 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;
-
-    /* If an alias is longer than this, active is probably broken. */
-    if (size > MAXHEADERSIZE) {
-       syslog(L_ERROR, "too-long flag field in active for %s", newsgroup);
-       size = MAXHEADERSIZE;
-    }
-
-    return PyString_FromStringAndSize(ngp->Rest, size);
-}
-
-
-
-/*
-**  Return an article header to the external module as a string.  We
-**  don't use a buffer object here because that would make it harder,
-**  for example, to compare two on-spool articles.
-*/
-static PyObject *
-PY_head(self, args)
-    PyObject *self, *args;
-{
-    char       *msgid;
-    int                msgidlen;
-    char       *p;
-    TOKEN      token;
-    ARTHANDLE  *art;
-    PyObject   *header;
-    int                headerlen;
-
-    if (!PyArg_ParseTuple(args, "s#", &msgid, &msgidlen))
-       return NULL;
-
-    if (! HISlookup(History, msgid, NULL, NULL, NULL, &token))
-       return Py_BuildValue("s", "");  
-    if ((art = SMretrieve(token, RETR_HEAD)) == NULL)
-       return Py_BuildValue("s", "");  
-    p = FromWireFmt(art->data, art->len, &headerlen);
-    SMfreearticle(art);
-    header = PyString_FromStringAndSize(p, headerlen);
-    free(p);
-
-    return header;
-}
-
-
-
-/*
-**  Return a whole article to the external module as a string.
-*/
-static PyObject *
-PY_article(self, args)
-    PyObject *self, *args;
-{
-    char       *msgid;
-    int                msgidlen;
-    char       *p;
-    TOKEN      token;
-    ARTHANDLE  *arth;
-    PyObject   *art;
-    int                artlen;
-
-    if (!PyArg_ParseTuple(args, "s#", &msgid, &msgidlen))
-       return NULL;
-
-    if (! HISlookup(History, msgid, NULL, NULL, NULL, &token))
-       return Py_BuildValue("s", "");
-    if ((arth = SMretrieve(token, RETR_ALL)) == NULL)
-       return Py_BuildValue("s", "");  
-    p = FromWireFmt(arth->data, arth->len, &artlen);
-    SMfreearticle(arth);
-    art = PyString_FromStringAndSize(p, artlen);
-    free(p);
-
-    return art;
-}
-
-
-
-/*
-**  Python's syslog module isn't compiled in by default.  It's easier
-**  to do it this way, and the switch block looks pretty in a color
-**  editor).
-*/
-static PyObject *
-PY_syslog(self, args)
-    PyObject *self, *args;
-{
-    char       *loglevel;
-    int                levellen;
-    char       *logmsg;
-    int                msglen;
-    int                priority;
-
-    if (!PyArg_ParseTuple(args, "s#s#",
-                         &loglevel, &levellen, &logmsg, &msglen))
-       return NULL;
-
-    switch (*loglevel) {
-    default:           priority = LOG_NOTICE ;
-    case 'd': case 'D': priority = LOG_DEBUG ;         break;
-    case 'i': case 'I': priority = LOG_INFO ;          break;
-    case 'n': case 'N': priority = LOG_NOTICE ;                break;
-    case 'w': case 'W': priority = LOG_WARNING ;       break;
-    case 'e': case 'E': priority = LOG_ERR ;           break;
-    case 'c': case 'C': priority = LOG_CRIT ;          break;
-    case 'a': case 'A': priority = LOG_ALERT ;         break;
-    }
-
-    syslog(priority, "python: %s", logmsg);
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-
-
-/*
-**  Compute a hash digest for a string.
-*/
-static PyObject *
-PY_hashstring(self, args)
-    PyObject *self, *args;
-{
-    char       *instring, *wpos, *p, *q;
-    char       *workstring = NULL;
-    int                insize, worksize, newsize, i, wasspace;
-    int                lines = 0;
-    HASH       myhash;
-
-    if (!PyArg_ParseTuple(args, "s#|i", &instring, &insize, &lines))
-       return NULL;
-
-    /* If a linecount is provided, munge before hashing. */
-    if (lines > 0) {
-       worksize = insize;
-
-       /* chop leading whitespace */
-       for (p=instring ; worksize>0 && isspace(*p) ; p++) {
-           if (*p == '\n')
-               lines--;
-           worksize--;
-       }
-       wpos = p;
-
-       /* and trailing */
-       for (p=&wpos[worksize] ; worksize>0 && isspace(*p) ; p--) {
-           if (*p == '\n')
-               lines--;
-           worksize--;
-       }
-
-       /* chop last 3 lines if we have >= 5.  From above chop the
-        * last line has no CR so we use 1 less here. */
-       if (lines >= 4) {
-           for (i=0, p=wpos+worksize ; i<2 ; p--)
-               if (*p == '\n')
-                   i++;
-           worksize = p - wpos;
-       }
-
-       /* Compress out multiple whitespace in the trimmed string.  We
-        * do a copy because this is probably an original art
-        * buffer. */
-       workstring =  memcpy(xmalloc(worksize), wpos, worksize);
-       newsize = wasspace = 0;
-       p = wpos;
-       q = workstring;
-       for (i=0 ; i<worksize ; i++) {
-           if (isspace(*p)) {
-               if (!wasspace)
-                   *q++ = ' ';
-               wasspace = 1;
-           }
-           else {
-               *q++ = tolower(*p);
-               wasspace = 0;
-           }
-           p++;
-       }
-       worksize = q - workstring;
-       myhash = Hash(workstring, worksize);
-       free(workstring);
-    }
-    else
-       myhash = Hash(instring, insize);
-
-    return PyString_FromStringAndSize((const char *)&myhash, sizeof(myhash));
-}
-
-
-
-/*
-**  Make the internal INN module's functions visible to Python.
-*/
-static PyMethodDef INNPyMethods[] = {
-    {"set_filter_hook", PY_set_filter_hook,    METH_VARARGS},
-    {"havehist",       PY_havehist,            METH_VARARGS},
-    {"addhist",                PY_addhist,             METH_VARARGS},
-    {"cancel",         PY_cancel,              METH_VARARGS},
-    {"newsgroup",      PY_newsgroup,           METH_VARARGS},
-    {"head",           PY_head,                METH_VARARGS},
-    {"article",                PY_article,             METH_VARARGS},
-    {"syslog",         PY_syslog,              METH_VARARGS},
-    {"hashstring",     PY_hashstring,          METH_VARARGS},
-    {NULL,             NULL}
-};
-
-
-
-/*
-**  This runs when innd shuts down.
-*/
-void
-PYclose(void)
-{
-    PyObject   *result;
-
-    if (close_method != NULL) {
-       result = PyObject_CallFunction(close_method, NULL);
-       Py_XDECREF(result);
-    }
-}
-
-
-
-/*
-**  Check that a method exists and is callable.         Set a pointer to
-**  the corresponding PyObject, or NULL if not found.
-*/
-void
-PYdefonemethod(methptr, methname)
-    PyObject   **methptr;
-    char       *methname;
-{
-    Py_XDECREF(*methptr);
-
-    /* We check with HasAttrString() the existence of the method because
-     * otherwise, in case it does not exist, an exception is raised by Python,
-     * although the result of the function is NULL. */
-    if (PyObject_HasAttrString(PYFilterObject, (char *) methname) == 1) {
-        /* Get a pointer to given method. */
-        *methptr = PyObject_GetAttrString(PYFilterObject, (char *) methname);
-    } else {
-        *methptr = NULL;
-    }
-                
-    if (*methptr == NULL)
-       syslog(L_NOTICE, "python method %s not found", methname);
-    else if (PyCallable_Check(*methptr) == 0) {
-       syslog(L_ERROR, "python object %s found but not a function", methname);
-       Py_DECREF(*methptr);
-       *methptr = NULL;
-    }
-}
-
-
-
-/*
-**  Look up the filter methods, so we will know what's available when
-**  innd wants to call them.
-*/
-void
-PYdefmethods(void)
-{
-    PYdefonemethod(&msgid_method, "filter_messageid");
-    PYdefonemethod(&art_method, "filter_art");
-    PYdefonemethod(&mode_method, "filter_mode");
-    PYdefonemethod(&pre_reload_method, "filter_before_reload");
-    PYdefonemethod(&close_method, "filter_close");
-}
-
-
-
-/*
-**  Used by "ctlinnd reload filter.python 'reason'".
-*/
-int
-PYreadfilter(void)
-{
-    PyObject   *newmodule = NULL;
-    PyObject   *result;
-
-    if (!Py_IsInitialized()) {
-       syslog(L_ERROR, "python is not initialized");
-       return 0;
-    }
-
-    /* If there is a filter running, let it clean up first. */
-    if (pre_reload_method != NULL) {
-       result = PyObject_CallFunction(pre_reload_method, NULL);
-       Py_XDECREF(result);
-    }
-
-    /* We need to reimport the module before reloading it because otherwise,
-     * it might not be taken into account by Python.
-     * See Python API documentation:
-     *     If a module is syntactically correct but its initialization fails,
-     *     the first import statement for it does not bind its name locally,
-     *     but does store a (partially initialized) module object in
-     *     sys.modules.  To reload the module, you must first import it again
-     *     (this will bind the name to the partially initialized module object)
-     *     before you can reload() it.
-     */
-    PYFilterModule = PyImport_ImportModule((char *) _PATH_PYTHON_STARTUP_M);
-    if (PYFilterModule == NULL) {
-        syslog(L_ERROR, "failed to reimport external python module");
-    }
-
-    if ((newmodule = PyImport_ReloadModule(PYFilterModule)) == NULL) {
-       syslog(L_ERROR, "cant reload python filter module");
-       PYfilter(false);
-       return 0;
-    }
-
-    Py_XDECREF(PYFilterModule);
-    PYFilterModule = newmodule;
-
-    if (PYFilterObject == NULL) {
-       syslog(L_ERROR, "python reload error, filter object not defined");
-       PYfilter(false);
-       return 0;
-    }
-
-    PYfilter(true);
-    PYdefmethods();
-
-    return 1;
-}
-
-
-
-/*
-**  Called when innd first starts -- this gets the filters hooked in.
-*/
-void
-PYsetup(void)
-{
-    const ARTHEADER *hp;
-    int                hdrindex;
-    size_t hdrcount;
-
-    setenv("PYTHONPATH", innconf->pathfilter, 1);
-    Py_Initialize();
-
-    /* It makes Python sad when its stdout and stderr are closed. */
-    if ((fileno(stdout) == -1) || (fileno(stderr) == -1))
-       PyRun_SimpleString
-           ("import sys; sys.stdout=sys.stderr=open('/dev/null', 'a')");
-
-    if (!Py_IsInitialized ()) {
-       syslog(L_ERROR, "python interpreter NOT initialized");
-       return;
-    }
-    syslog(L_NOTICE, "python interpreter initialized OK");
-
-    Py_InitModule("INN", INNPyMethods);
-
-    PYFilterModule = PyImport_ImportModule(_PATH_PYTHON_STARTUP_M);
-    if (PYFilterModule == NULL)
-       syslog(L_ERROR, "failed to import external python module");
-
-    if (PYFilterObject == NULL) {
-       syslog(L_ERROR, "python filter object is not defined");
-       PYfilter(false);
-    } else {
-       PYfilter(true);
-       PYdefmethods();
-       syslog(L_NOTICE, "defined python methods");
-    }
-
-    /* Grab space for these so we aren't forever recreating them.  We also
-       put the body and the line count into PYheaditem, so it needs to be
-       two elements longer than the total number of headers. */
-    PYheaders = PyDict_New();
-    hdrcount = ARRAY_END(ARTheaders) - ARTheaders;
-    PYheaditem = xmalloc((hdrcount + 2) * sizeof(PyObject *));
-    PYheadkey = xmalloc(hdrcount * sizeof(PyObject *));
-
-    /* Preallocate keys for the article dictionary */
-    for (hp = ARTheaders; hp < ARRAY_END(ARTheaders); hp++)
-       PYheadkey[hp - ARTheaders] = PyString_InternFromString(hp->Name);
-    PYpathkey = PyString_InternFromString("Path");
-    PYlineskey = PyString_InternFromString("__LINES__");
-    PYbodykey = PyString_InternFromString("__BODY__");
-}
-
-#endif /* defined(DO_PYTHON) */
diff --git a/innd/rc.c b/innd/rc.c
deleted file mode 100644 (file)
index 356fed7..0000000
--- a/innd/rc.c
+++ /dev/null
@@ -1,2017 +0,0 @@
-/*  $Id: rc.c 7751 2008-04-06 14:35:40Z iulius $
-**
-**  Routines for the remote connect channel.  Create an Internet stream
-**  socket that processes connect to.  If the incoming site is not one of
-**  our feeds, then we optionally pass the connection off to the standard
-**  NNTP daemon.
-*/
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <errno.h>
-#include <netdb.h>
-
-#include "inn/innconf.h"
-#include "inn/vector.h"
-#include "innd.h"
-
-#define TEST_CONFIG(a, b) \
-    { \
-       b = ((peer_params.Keysetbit & (1 << a)) != 0) ? true : false; \
-    }
-
-#define SET_CONFIG(a) \
-    { \
-       peer_params.Keysetbit |= (1 << a); \
-    }
-
-/*
-**  A remote host has an address and a password.
-*/
-typedef struct _REMOTEHOST {
-    char       *Label;         /* Peer label */
-    char       *Name;          /* Hostname */
-    struct sockaddr_storage Address;     /* List of ip adresses */
-    char       *Password;      /* Optional password */
-    char       *Identd;        /* Optional identd */
-    bool       Streaming;      /* Streaming allowed ? */
-    bool       Skip;           /* Skip this peer ? */
-    bool       NoResendId;     /* Don't send RESEND responses ? */
-    bool       Nolist;         /* no list command allowed */
-    int                MaxCnx;         /* Max connections (per peer) */
-    char       **Patterns;     /* List of groups allowed */
-    char       *Pattern;       /* List of groups allowed (string) */
-    char        *Email;         /* Email(s) of contact */
-    char       *Comment;       /* Commentary [max size = MAXBUFF] */
-    int                HoldTime;       /* Hold time before disconnect over MaxCnx */
-    int                Keysetbit;      /* Bit to check duplicated key */
-} REMOTEHOST;
-
-typedef struct _REMOTEHOST_DATA {
-    int         key;            /* Key (as defined in the _Keywords enum) */
-    int         type;           /* Type of the value (see _Type enum) */
-    char        *value;         /* Value */
-} REMOTEHOST_DATA;
-
-typedef struct _REMOTETABLE {
-    struct sockaddr_storage Address;
-    time_t         Expires;
-} REMOTETABLE;
-
-static char            *RCslaveflag;
-static char            *RCnnrpd = NULL;
-static char            *RCnntpd = NULL;
-static CHANNEL         **RCchan;
-static int             chanlimit;
-static REMOTEHOST_DATA *RCpeerlistfile;
-static REMOTEHOST      *RCpeerlist;
-static int             RCnpeerlist;
-static char            RCbuff[BIG_BUFFER];
-
-#define PEER           "peer"
-#define GROUP          "group"
-#define HOSTNAME        "hostname:"
-#define STREAMING       "streaming:"
-#define MAX_CONN        "max-connections:"
-#define PASSWORD        "password:"
-#define IDENTD         "identd:"
-#define PATTERNS        "patterns:"
-#define EMAIL          "email:"
-#define COMMENT                "comment:"
-#define SKIP           "skip:"
-#define NORESENDID     "noresendid:"
-#define HOLD_TIME      "hold-time:"
-#define NOLIST         "nolist:"
-
-typedef enum {K_END, K_BEGIN_PEER, K_BEGIN_GROUP, K_END_PEER, K_END_GROUP,
-             K_STREAM, K_HOSTNAME, K_MAX_CONN, K_PASSWORD, K_IDENTD,
-             K_EMAIL, K_PATTERNS, K_COMMENT, K_SKIP, K_NORESENDID,
-             K_HOLD_TIME, K_NOLIST
-            } _Keywords;
-
-typedef enum {T_STRING, T_BOOLEAN, T_INTEGER} _Types;
-
-#define GROUP_NAME     "%s can't get group name in %s line %d"
-#define PEER_IN_PEER   "%s peer can't contain peer in %s line %d"
-#define PEER_NAME      "%s can't get peer name in %s line %d"
-#define LEFT_BRACE     "%s '{' expected in %s line %d"
-#define RIGHT_BRACE    "%s '}' unexpected line %d in %s"
-#define INCOMPLETE_PEER "%s incomplete peer (%s) in %s line %d"
-#define INCOMPLETE_GROUP "%s incomplete group (%s) in %s line %d"
-#define MUST_BE_BOOL    "%s Must be 'true' or 'false' in %s line %d"
-#define MUST_BE_INT    "%s Must be an integer value in %s line %d"
-#define HOST_NEEDED     "%s 'hostname' needed in %s line %d"
-#define DUPLICATE_KEY   "%s duplicate key in %s line %d"
-
-/*
-** Stuff needed for limiting incoming connects.
-*/
-static char            RCterm[] = "\r\n";
-static REMOTETABLE     remotetable[REMOTETABLESIZE];
-static int             remotecount;
-static int             remotefirst;
-
-/*
- * Check that the client has the right identd. Return true if is the
- * case, false, if not.
- */
-static bool
-GoodIdent(int fd, char *identd)
-{
-#define PORT_IDENTD 113
-    char IDENTuser[80];
-    struct sockaddr_storage ss_local;
-    struct sockaddr_storage ss_distant;
-    struct sockaddr *s_local = (struct sockaddr *)&ss_local;
-    struct sockaddr *s_distant = (struct sockaddr *)&ss_distant;
-    int ident_fd;
-    socklen_t len;
-    int port1,port2;
-    ssize_t lu;
-    char buf[80], *buf2;
-
-    if(identd[0] == '\0') {
-         return true;
-    }
-    
-    len = sizeof( ss_local );
-    if ((getsockname(fd,s_local,&len)) < 0) {
-       syslog(L_ERROR, "can't do getsockname for identd");
-       return false;
-    }
-    len = sizeof( ss_distant );
-    if ((getpeername(fd,s_distant,&len)) < 0) {
-       syslog(L_ERROR, "can't do getsockname for identd");
-       return false;
-    }
-#ifdef HAVE_INET6
-    if( s_local->sa_family == AF_INET6 )
-    {
-       struct sockaddr_in6 *s_l6 = (struct sockaddr_in6 *)s_local;
-       struct sockaddr_in6 *s_d6 = (struct sockaddr_in6 *)s_distant;
-
-       port1=ntohs(s_l6->sin6_port);
-       port2=ntohs(s_d6->sin6_port);
-       s_l6->sin6_port = 0;
-       s_d6->sin6_port = htons( PORT_IDENTD );
-       ident_fd=socket(PF_INET6, SOCK_STREAM, 0);
-    } else
-#endif
-    if( s_local->sa_family == AF_INET )
-    {
-       struct sockaddr_in *s_l = (struct sockaddr_in *)s_local;
-       struct sockaddr_in *s_d = (struct sockaddr_in *)s_distant;
-
-       port1=ntohs(s_l->sin_port);
-       port2=ntohs(s_d->sin_port);
-       s_l->sin_port = 0;
-       s_d->sin_port = htons( PORT_IDENTD );
-       ident_fd=socket(PF_INET, SOCK_STREAM, 0);
-    } else
-    {
-       syslog(L_ERROR, "Bad address family: %d\n", s_local->sa_family );
-       return false;
-    }
-    if (ident_fd < 0) {
-       syslog(L_ERROR, "can't open socket for identd (%m)");
-       return false;
-    }
-    if (bind(ident_fd,s_local,SA_LEN(s_local)) < 0) {
-       syslog(L_ERROR, "can't bind socket for identd (%m)");
-        close(ident_fd);
-       return false;
-    }
-    if (connect(ident_fd,s_distant,SA_LEN(s_distant)) < 0) {
-       syslog(L_ERROR, "can't connect to identd (%m)");
-        close(ident_fd);
-       return false;
-    }
-
-    snprintf(buf,sizeof(buf),"%d,%d\r\n",port2, port1);
-    write(ident_fd,buf, strlen(buf));
-    memset( buf, 0, 80 );
-    lu=read(ident_fd, buf, 79); /* pas encore parfait ("not yet perfect"?) */
-    if (lu<0)
-    {
-       syslog(L_ERROR, "error reading from ident server: %m" );
-       close( ident_fd );
-       return false;
-    }
-    buf[lu]='\0';
-    if ((lu>0) && (strstr(buf,"ERROR")==NULL)
-                   && ((buf2=strrchr(buf,':'))!=NULL)) 
-    {
-       buf2++;
-       while(*buf2 == ' ') buf2++;
-       strlcpy(IDENTuser, buf2, sizeof(IDENTuser));
-       buf2=strchr(IDENTuser,'\r');
-       if (!buf2) buf2=strchr(IDENTuser,'\n');
-       if (buf2) *buf2='\0';
-    } else
-        strlcpy(IDENTuser, "UNKNOWN", sizeof(IDENTuser));
-    close(ident_fd);
-
-    return strcmp(identd, IDENTuser) == 0;
-}
-
-/*
- * Split text into comma-separated fields.  Return an allocated
- * NULL-terminated array of the fields within the modified argument that
- * the caller is expected to save or free.  We don't use strchr() since
- * the text is expected to be either relatively short or "comma-dense."
- * (This function is different from CommaSplit because spaces are allowed
- * and removed here)
- */
-
-static char **
-RCCommaSplit(char *text)
-{
-    int                i;
-    char       *p;
-    char       *q;
-    char       *r;
-    char       **av;
-    char       **save;
-    /* How much space do we need? */
-    for (i = 2, p = text, q = r = xstrdup(text); *p; p++) {
-        if (*p != ' ' && *p != '\t' && *p != '\n')
-           *q++ = *p;
-        if (*p == ',')
-            i++;
-    }
-    *q = '\0';
-    free (text);
-    for (text = r, av = save = xmalloc(i * sizeof(char *)), *av++ = p = text; *p; )
-        if (*p == ',') {
-            *p++ = '\0';
-           *av++ = p;
-        }
-        else
-            p++;
-    *av = NULL;
-    return save;
-}
-
- /*
-  * Routine to disable IP-level socket options. This code was taken from 4.4BSD
-  * rlogind source, but all mistakes in it are my fault.
-  *
-  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
-  *
-  * 21-Jan-1997 smd
-  *     Code copied again, and modified for INN, all new mistakes are mine.
-  * 
-  */
-
-/* fix_options - get rid of IP-level socket options */
-#ifndef IP_OPTIONS
-#define IP_OPTIONS 1
-#endif
-
-static int
-RCfix_options(int fd, struct sockaddr_storage *remote)
-{
-#if IP_OPTIONS
-    unsigned char optbuf[BUFSIZ / 3], *cp;
-    char    lbuf[BUFSIZ], *lp;
-    socklen_t optsize = sizeof(optbuf);
-    int     ipproto;
-    struct protoent *ip;
-
-    switch (remote->ss_family) {
-    case AF_INET:
-       if ((ip = getprotobyname("ip")) != 0)
-           ipproto = ip->p_proto;
-       else
-           ipproto = IPPROTO_IP;
-       break;
-#ifdef HAVE_INET6
-    case AF_INET6:
-       if ((ip = getprotobyname("ipv6")) != 0)
-           ipproto = ip->p_proto;
-       else
-           ipproto = IPPROTO_IPV6;
-       break;
-#endif
-    default:
-       syslog(LOG_ERR, "unknown address family: %d", remote->ss_family);
-       return -1;
-    }
-
-    if (getsockopt(fd, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
-       && optsize != 0) {
-       lp = lbuf;
-       for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
-           sprintf(lp, " %2.2x", *cp);
-       syslog(LOG_NOTICE,
-              "connect from %s with IP options (ignored):%s",
-              sprint_sockaddr((struct sockaddr *)remote), lbuf);
-       if (setsockopt(fd, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
-           syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
-           return -1;
-       }
-    }
-#endif
-    return 0;
-}
-
-static bool
-RCaddressmatch(const struct sockaddr_storage *cp, const struct sockaddr_storage *rp)
-{
-#ifdef HAVE_INET6
-    struct sockaddr_in *sin_cp, *sin_rp;
-    struct sockaddr_in6        *sin6_cp, *sin6_rp;
-
-    if (cp->ss_family == AF_INET6 && rp->ss_family == AF_INET) {
-       sin6_cp = (struct sockaddr_in6 *)cp;
-       sin_rp = (struct sockaddr_in *)rp;
-       if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) &&
-               memcmp(&sin6_cp->sin6_addr.s6_addr[12],
-                   &sin_rp->sin_addr.s_addr, sizeof(struct in_addr)) == 0)
-           return true;
-    } else if (cp->ss_family == AF_INET && rp->ss_family == AF_INET6) {
-       sin_cp = (struct sockaddr_in *)cp;
-       sin6_rp = (struct sockaddr_in6 *)rp;
-       if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) &&
-               memcmp(&sin6_rp->sin6_addr.s6_addr[12],
-                   &sin_cp->sin_addr.s_addr, sizeof(struct in_addr)) == 0)
-           return true;
-    } else if (cp->ss_family == AF_INET6 && rp->ss_family == AF_INET6) {
-#ifdef HAVE_BROKEN_IN6_ARE_ADDR_EQUAL
-       if (!memcmp(&((struct sockaddr_in6 *)cp)->sin6_addr,
-                   &((struct sockaddr_in6 *)rp)->sin6_addr,
-                   sizeof(struct in6_addr)))
-#else
-       if (IN6_ARE_ADDR_EQUAL( &((struct sockaddr_in6 *)cp)->sin6_addr,
-                               &((struct sockaddr_in6 *)rp)->sin6_addr))
-#endif
-           return true;
-    } else
-#endif /* INET6 */
-       if (((struct sockaddr_in *)cp)->sin_addr.s_addr ==
-            ((struct sockaddr_in *)rp)->sin_addr.s_addr)
-           return true;
-
-    return false;
-}
-
-/*
-**  See if the site properly entered the password.
-*/
-bool
-RCauthorized(CHANNEL *cp, char *pass)
-{
-    REMOTEHOST *rp;
-    int                i;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
-       if (RCaddressmatch(&cp->Address, &rp->Address)) {
-           if (rp->Password[0] == '\0' || strcmp(pass, rp->Password) == 0)
-               return true;
-           syslog(L_ERROR, "%s (%s) bad_auth", rp->Label,
-                  sprint_sockaddr((struct sockaddr *)&cp->Address));
-           return false;
-       }
-
-    if (!AnyIncoming)
-       /* Not found in our table; this can't happen. */
-       syslog(L_ERROR, "%s not_found", sprint_sockaddr((struct sockaddr *)&cp->Address));
-
-    /* Anonymous hosts should not authenticate. */
-    return false;
-}
-
-/*
-**  See if a host is limited or not.
-*/
-bool
-RCnolimit(CHANNEL *cp)
-{
-    REMOTEHOST *rp;
-    int                i;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
-       if (RCaddressmatch(&cp->Address, &rp->Address))
-            return !rp->MaxCnx;
-
-    /* Not found in our table; this can't happen. */
-    return false;
-}
-
-/*
-**  Return the limit (max number of connections) for a host.
-*/
-int
-RClimit(CHANNEL *cp)
-{
-    REMOTEHOST *rp;
-    int                i;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
-       if (RCaddressmatch(&cp->Address, &rp->Address))
-           return rp->MaxCnx;
-    /* Not found in our table; this can't happen. */
-    return RemoteLimit;
-}
-
-
-/*
-**  Called when input is ready to read.  Shouldn't happen.
-*/
-static void
-RCrejectreader(CHANNEL *cp)
-{
-    syslog(L_ERROR, "%s internal RCrejectreader (%s)", LogName,
-          sprint_sockaddr((struct sockaddr *)&cp->Address));
-}
-
-
-/*
-**  Write-done function for rejects.
-*/
-static void
-RCrejectwritedone(CHANNEL *cp)
-{
-    switch (cp->State) {
-    default:
-       syslog(L_ERROR, "%s internal RCrejectwritedone state %d",
-           CHANname(cp), cp->State);
-       break;
-    case CSwritegoodbye:
-       CHANclose(cp, CHANname(cp));
-       break;
-    }
-}
-
-
-/*
-**  Hand off a descriptor to NNRPD.
-*/
-void
-RChandoff(int fd, HANDOFF h)
-{
-    const char **argv;
-    char buff[SMBUF];
-    int i;
-    unsigned int j;
-    struct vector *flags;
-    
-    flags = vector_split_space(innconf->nnrpdflags, NULL);
-    argv  = xmalloc( (flags->count + 6) * sizeof(char*) );
-
-    if (RCnnrpd == NULL)
-       RCnnrpd = concatpath(innconf->pathbin, "nnrpd");
-    if (RCnntpd == NULL)
-       RCnntpd = concatpath(innconf->pathbin, "nnrpd");
-#if    defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
-    /* Set KEEPALIVE to catch broken socket connections. */
-    i = 1;
-    if (setsockopt(fd, SOL_SOCKET,  SO_KEEPALIVE, (char *)&i, sizeof i) < 0)
-        syslog(L_ERROR, "fd %d cant setsockopt(KEEPALIVE) %m", fd);
-#endif /* defined(SOL_SOCKET) && defined(SO_KEEPALIVE) */
-
-    if (nonblocking(fd, false) < 0)
-       syslog(L_ERROR, "%s cant nonblock %d in RChandoff %m", LogName, fd);
-    switch (h) {
-    default:
-       syslog(L_ERROR, "%s internal RChandoff %d type %d", LogName, fd, h);
-       /* FALLTHROUGH */
-    case HOnnrpd:      argv[0] = RCnnrpd;      break;
-    case HOnntpd:      argv[0] = RCnntpd;      break;
-    }
-    argv[1] = "-s                                                ";
-    i = 2;
-    if (NNRPReason) {
-       snprintf(buff, sizeof(buff), "-r%s", NNRPReason);
-       argv[i++] = buff;
-    }
-    if (NNRPTracing)
-       argv[i++] = "-t";
-    if (RCslaveflag)
-       argv[i++] = RCslaveflag;
-
-    for(j = 0; j < flags->count; j++) {
-        argv[i++] = flags->strings[j];
-    }
-    argv[i] = NULL;
-
-    /* Call NNRP; don't send back a QUIT message if Spawn fails since  
-     * that's a major error we want to find out about quickly. */
-    (void)Spawn(innconf->nicekids, fd, fd, fd, (char * const *)argv);
-    vector_free(flags);
-    free(argv);
-}
-
-
-/*
-**  Read function.  Accept the connection and either create an NNTP channel
-**  or spawn an nnrpd to handle it.
-*/
-static void
-RCreader(CHANNEL *cp)
-{
-    int                        fd;
-    struct sockaddr_storage    remote;
-    socklen_t          size;
-    int                 i;
-    REMOTEHOST          *rp;
-    CHANNEL            *new;
-    char               *name;
-    long               reject_val = 0;
-    const char         *reject_message;
-    int                        count;
-    int                        found;
-    time_t             now;
-    CHANNEL            tempchan;
-    char               buff[SMBUF];
-
-    for (i = 0 ; i < chanlimit ; i++) {
-       if (RCchan[i] == cp) {
-           break;
-       }
-    }
-    if (i == chanlimit) {
-       syslog(L_ERROR, "%s internal RCreader wrong channel 0x%p",
-               LogName, (void *)cp);
-       return;
-    }
-
-    /* Get the connection. */
-    size = sizeof remote;
-    if ((fd = accept(cp->fd, (struct sockaddr *)&remote, &size)) < 0) {
-       if (errno != EWOULDBLOCK && errno != EAGAIN)
-           syslog(L_ERROR, "%s cant accept RCreader %m", LogName);
-       return;
-    }
-
-    /*
-    ** Clear any IP_OPTIONS, including source routing, on the socket
-    */
-    /* FIXME RCfix_options breaks IPv6 sockets, at least on Linux -lutchann */
-#ifndef HAVE_INET6
-    if (RCfix_options(fd, &remote) != 0) {
-       /* shouldn't happen, but we're bit paranoid at this point */
-       if (close(fd) < 0)
-           syslog(L_ERROR, "%s cant close %d %m", LogName, fd);
-       return;
-    }
-#endif
-
-    /* If RemoteTimer is not zero, then check the limits on incoming
-       connections on a total and per host basis.
-
-       The incoming connection table is fixed at 128 entries to make
-       calculating the index easy (i + 1) & 7, and to be pretty sure that you
-       won't run out of space.  The table is used as a ring with new entries
-       being added to the end (wrapping around) and expired entries being
-       deleted from the front (again wrapping around).  It is doubtful that
-       you will ever use even half of the table.
-
-       There are three parameters controlling the use of the table not
-       counting the starting index and count:
-
-           H = per host incoming connects per X seconds allowed
-           T = total incoming connects per X seconds allowed
-           X = number of seconds to remember a successful connect
-
-       First, one pass is made over the live entries deleting any that are
-       over X seconds old.  If the entry hasn't expired, compare the incoming
-       connection's host address with the entry's host address.  If equal,
-       increment the "found" counter.
-
-       Second, if the number of entries now in the table is equal to the T
-       parameter, reject the connection with a message indicating that the
-       server is overloaded.
-
-       Third, if the number of entries now in the table which match the
-       incoming connection's host address is equal to the H parameter, reject
-       the connection.
-
-       Finally, if neither rejection happened, add the entry to the table, and
-       continue on as a normal connect. */
-    memcpy(&tempchan.Address, &remote, SA_LEN((struct sockaddr *)&remote));
-    reject_message = NULL;
-    if (RemoteTimer != 0) {
-       now = time(NULL);
-       i = remotefirst;
-       count = remotecount;
-       found = 0;
-       while (count--) {
-           if (remotetable[i].Expires < now) {
-               remotecount--;
-               remotefirst = (remotefirst + 1) & (REMOTETABLESIZE - 1);
-               i = (i + 1) & (REMOTETABLESIZE - 1);
-               continue;
-           }
-           if (RCaddressmatch(&remotetable[i].Address, &remote))
-               found++;
-           i = (i + 1) & (REMOTETABLESIZE - 1);
-       }
-       if (remotecount == RemoteTotal) {
-           reject_val = NNTP_GOODBYE_VAL;
-           reject_message = "400 Server overloaded, try later";
-       }
-       else if (found >= RemoteLimit && !RCnolimit(&tempchan)) {
-           reject_val = NNTP_GOODBYE_VAL;
-           reject_message = "400 Connection rejected, you're making too"
-                " many connects per minute";
-       }
-       else {
-           i = (remotefirst + remotecount) & (REMOTETABLESIZE - 1);
-           memcpy(&remotetable[i].Address, &remote, SA_LEN((struct sockaddr *)&remote));
-           remotetable[i].Expires = now + RemoteTimer;
-           remotecount++;
-       }
-    }
-
-    /*
-    ** Create a reject channel to reject the connection.  This is done
-    ** to avoid a call to fork.  
-    */
-    if (reject_message) {
-       new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
-           RCrejectwritedone);
-       memcpy(&remotetable[i].Address, &remote, SA_LEN((struct sockaddr *)&remote));
-       new->Rejected = reject_val;
-       RCHANremove(new);
-       WCHANset(new, reject_message, (int)strlen(reject_message));
-       WCHANappend(new, RCterm, strlen(RCterm));
-       WCHANadd(new);
-       return;
-    }
-
-    /* See if it's one of our servers. */
-    for (name = NULL, rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
-       if (RCaddressmatch(&rp->Address, &remote)) {
-           name = rp->Name;
-           break;
-       }
-
-    /* If not a server, and not allowing anyone, hand him off unless
-       not spawning nnrpd in which case we return an error. */
-    if ((i >= 0) && !rp->Skip) {
-
-       /* We check now the identd if we have to */
-       if(! GoodIdent(fd, rp->Identd))
-       {
-           if (!innconf->noreader) {
-               RChandoff(fd, HOnntpd);
-               if (close(fd) < 0)
-                   syslog(L_ERROR, "%s cant close %d %m", LogName, fd);
-               return;
-           }
-       }
-       
-       if ((new = NCcreate(fd, rp->Password[0] != '\0', false)) != NULL) {
-            new->Streaming = rp->Streaming;
-            new->Skip = rp->Skip;
-            new->NoResendId = rp->NoResendId;
-            new->Nolist = rp->Nolist;
-            new->MaxCnx = rp->MaxCnx;
-            new->HoldTime = rp->HoldTime;
-           memcpy(&new->Address, &remote, SA_LEN((struct sockaddr *)&remote));
-           if (new->MaxCnx > 0 && new->HoldTime == 0) {
-               CHANsetActiveCnx(new);
-               if((new->ActiveCnx > new->MaxCnx) && (new->fd > 0)) {
-                   snprintf(buff, sizeof(buff),
-                             "You are limited to %d connection%s",
-                             new->MaxCnx, (new->MaxCnx != 1) ? "s" : "");
-                   NCwriteshutdown(new, buff);
-                   syslog(L_NOTICE, "too many connections from %s", rp->Label);
-               } else {
-                   NCwritereply(new, (char *)NCgreeting);
-               }
-           } else {
-               NCwritereply(new, (char *)NCgreeting);
-           }
-       }
-    } else if (AnyIncoming && !rp->Skip) {
-       if ((new = NCcreate(fd, false, false)) != NULL) {
-           NCwritereply(new, (char *)NCgreeting);
-       }
-    } else if (!innconf->noreader) {
-       RChandoff(fd, HOnntpd);
-       if (close(fd) < 0)
-           syslog(L_ERROR, "%s cant close %d %m", LogName, fd);
-       return;
-    } else {
-       reject_val = NNTP_ACCESS_VAL;
-       reject_message = NNTP_ACCESS;
-        new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
-            RCrejectwritedone);
-       memcpy(&new->Address, &remote, SA_LEN((struct sockaddr *)&remote));
-        new->Rejected = reject_val;
-        RCHANremove(new);
-        WCHANset(new, reject_message, (int)strlen(reject_message));
-        WCHANappend(new, RCterm, strlen(RCterm));
-        WCHANadd(new);
-        return;
-    }
-
-    if (new != NULL) {
-       memcpy(&new->Address, &remote, SA_LEN((struct sockaddr *)&remote));
-       syslog(L_NOTICE, "%s connected %d streaming %s",
-           name ? name : sprint_sockaddr((struct sockaddr *)&new->Address),
-          new->fd, (!StreamingOff && new->Streaming) ? "allowed" : "not allowed");
-    }
-}
-
-
-/*
-**  Write-done function.  Shouldn't happen.
-*/
-static void
-RCwritedone(CHANNEL *unused)
-{
-    unused = unused;           /* ARGSUSED */
-    syslog(L_ERROR, "%s internal RCwritedone", LogName);
-}
-
-/*
- *  New config file style. Old hosts.nntp and hosts.nntp.nolimit are merged
- *  into one file called incoming.conf (to avoid confusion).
- *  See ../samples/incoming.conf for the new syntax.
- *
- *  Fabien Tassin <fta@sofaraway.org>, 21-Dec-1997.
- */
-
-
-/*
- * Read something (a word or a double quoted string) from a file.
- */
-static char *
-RCreaddata(int *num, FILE *F, bool *toolong)
-{
-  char *p;
-  char *s;
-  char *t;
-  char *word;
-  bool flag;
-
-  *toolong = false;
-  if (*RCbuff == '\0') {
-    if (feof (F)) return (NULL);
-    fgets(RCbuff, sizeof RCbuff, F);
-    (*num)++;
-    if (strlen (RCbuff) == sizeof RCbuff) {
-      *toolong = true;
-      return (NULL); /* Line too long */
-    }
-  }
-  p = RCbuff;
-  do {
-     /* Ignore blank and comment lines. */
-     if ((p = strchr(RCbuff, '\n')) != NULL)
-       *p = '\0';
-     if ((p = strchr(RCbuff, '#')) != NULL) {
-       if (p == RCbuff || (p > RCbuff && *(p - 1) != '\\'))
-          *p = '\0';
-     }
-     for (p = RCbuff; *p == ' ' || *p == '\t' ; p++);
-     flag = true;
-     if (*p == '\0' && !feof (F)) {
-       flag = false;
-       fgets(RCbuff, sizeof RCbuff, F);
-       (*num)++;
-       if (strlen (RCbuff) == sizeof RCbuff) {
-        *toolong = true;
-        return (NULL); /* Line too long */
-       }
-       continue;
-     }
-     break;
-  } while (!feof (F) || !flag);
-
-  if (*p == '"') { /* double quoted string ? */
-    p++;
-    do {
-      for (t = p; (*t != '"' || (*t == '"' && *(t - 1) == '\\')) &&
-            *t != '\0'; t++);
-      if (*t == '\0') {
-       *t++ = '\n';
-       fgets(t, sizeof RCbuff - strlen (RCbuff), F);
-       (*num)++;
-       if (strlen (RCbuff) == sizeof RCbuff) {
-         *toolong = true;
-         return (NULL); /* Line too long */
-       }
-       if ((s = strchr(t, '\n')) != NULL)
-         *s = '\0';
-      }
-      else 
-       break;
-    } while (!feof (F));
-    *t++ = '\0';
-  }
-  else {
-    for (t = p; *t != ' ' && *t != '\t' && *t != '\0'; t++);
-    if (*t != '\0')
-      *t++ = '\0';
-  }
-  if (*p == '\0' && feof (F)) return (NULL);
-  word = xstrdup (p);
-  for (p = RCbuff; *t != '\0'; t++)
-    *p++ = *t;
-  *p = '\0';
-
-  return (word);
-}
-
-/*
- *  Add all data into RCpeerlistfile.
- */
-static void
-RCadddata(REMOTEHOST_DATA **d, int *count, int Key, int Type, char* Value)
-{
-  (*d)[*count].key = Key;
-  (*d)[*count].type = Type;
-  (*d)[*count].value = Value;
-  (*count)++;
-  *d = xrealloc(*d, (*count + 1) * sizeof(REMOTEHOST_DATA));
-}
-
-/*
-**  Read in the file listing the hosts we take news from, and fill in the
-**  global list of their Internet addresses.  A host can have multiple
-**  addresses, so we take care to add all of them to the list.
-*/
-static void
-RCreadfile (REMOTEHOST_DATA **data, REMOTEHOST **list, int *count, 
-           char *filename)
-{
-    static char                NOPASS[] = "";
-    static char                NOIDENTD[] = "";
-    static char                NOEMAIL[] = "";
-    static char                NOCOMMENT[] = "";
-    FILE               *F;
-    char               *p;
-    char               **q;
-    char               **r;
-#if     !defined( HAVE_INET6)
-    struct hostent     *hp;
-#endif
-#if    !defined(HAVE_UNIX_DOMAIN_SOCKETS) || !defined(HAVE_INET6)
-    struct in_addr      addr;
-#endif
-    int                 i;
-    int                 j;
-    int                        linecount;
-    int                        infocount;
-    int                 groupcount;
-    int                 maxgroup;
-    REMOTEHOST_DATA    *dt;
-    REMOTEHOST         *rp;
-    char               *word;
-    REMOTEHOST         *groups;
-    REMOTEHOST         *group_params = NULL;
-    REMOTEHOST         peer_params;
-    REMOTEHOST         default_params;
-    bool               flag, bit, toolong;
-    *RCbuff = '\0';
-    if (*list) {
-       for (rp = *list, i = *count; --i >= 0; rp++) {
-           free(rp->Name);
-           free(rp->Label);
-           free(rp->Email);
-           free(rp->Comment);
-           free(rp->Password);
-           free(rp->Identd);
-           if (rp->Patterns) {
-               free(rp->Patterns[0]);
-               free(rp->Patterns);
-           }
-       }
-       free(*list);
-       *list = NULL;
-       *count = 0;
-    }
-    if (*data) {
-        for (i = 0; (*data)[i].key != K_END; i++)
-           if ((*data)[i].value != NULL)
-               free((*data)[i].value);
-        free(*data);
-       *data = NULL;
-    }
-
-    *count = 0;
-    maxgroup = 0;
-    /* Open the server file. */
-    if ((F = Fopen(filename, "r", TEMPORARYOPEN)) == NULL) {
-       syslog(L_FATAL, "%s cant read %s: %m", LogName, filename);
-       exit(1);
-    }
-    dt = *data = xmalloc(sizeof(REMOTEHOST_DATA));
-    rp = *list = xmalloc(sizeof(REMOTEHOST));
-
-#if    !defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    addr.s_addr = INADDR_LOOPBACK;
-    make_sin( (struct sockaddr_in *)&rp->Address, &addr );
-    rp->Name = xstrdup("localhost");
-    rp->Label = xstrdup("localhost");
-    rp->Email = xstrdup(NOEMAIL);
-    rp->Comment = xstrdup(NOCOMMENT);
-    rp->Password = xstrdup(NOPASS);
-    rp->Identd = xstrdup(NOIDENTD);
-    rp->Patterns = NULL;
-    rp->MaxCnx = 0;
-    rp->Streaming = true;
-    rp->Skip = false;
-    rp->NoResendId = false;
-    rp->Nolist = false;
-    rp->HoldTime = 0;
-    rp++;
-    (*count)++;
-#endif /* !defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-
-    linecount = 0;
-    infocount = 0;
-    groupcount = 0; /* no group defined yet */
-    groups = 0;
-    peer_params.Label = NULL;
-    default_params.Streaming = true;
-    default_params.Skip = false;
-    default_params.NoResendId = false;
-    default_params.Nolist = false;
-    default_params.MaxCnx = 0;
-    default_params.HoldTime = 0;
-    default_params.Password = xstrdup(NOPASS);
-    default_params.Identd = xstrdup(NOIDENTD);
-    default_params.Email = xstrdup(NOEMAIL);
-    default_params.Comment = xstrdup(NOCOMMENT);
-    default_params.Pattern = NULL;
-    peer_params.Keysetbit = 0;
-
-    /* Read the file to add all the hosts. */
-    while ((word = RCreaddata (&linecount, F, &toolong)) != NULL) {
-
-      /* group */
-      if (!strncmp (word, GROUP,  sizeof GROUP)) {
-       free(word);
-       /* name of the group */
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         syslog(L_ERROR, GROUP_NAME, LogName, filename, linecount);
-         break;
-       }
-       RCadddata(data, &infocount, K_BEGIN_GROUP, T_STRING, word);
-       groupcount++;
-       if (groupcount == 1) {
-          /* First group block. */
-          group_params = groups = xmalloc(sizeof(REMOTEHOST));
-       }
-       else if (groupcount >= maxgroup) {
-          /* Alloc 5 groups for extra nested group blocks. */
-          groups = xrealloc(groups, (groupcount + 4) * sizeof(REMOTEHOST));
-          maxgroup += 5;
-          group_params = groups + groupcount - 1;
-        }
-        else {
-          /* Nested group block (no need to extend groups). */
-          group_params++;
-        }
-       group_params->Label = word;
-       group_params->Skip = groupcount > 1 ?
-         groups[groupcount - 2].Skip : default_params.Skip;
-       group_params->Streaming = groupcount > 1 ?
-         groups[groupcount - 2].Streaming : default_params.Streaming;
-       group_params->NoResendId = groupcount > 1 ?
-         groups[groupcount - 2].NoResendId : default_params.NoResendId;
-       group_params->Nolist = groupcount > 1 ?
-         groups[groupcount - 2].Nolist : default_params.Nolist;
-       group_params->Email = groupcount > 1 ?
-         groups[groupcount - 2].Email : default_params.Email;
-       group_params->Comment = groupcount > 1 ?
-         groups[groupcount - 2].Comment : default_params.Comment;
-       group_params->Pattern = groupcount > 1 ?
-         groups[groupcount - 2].Pattern : default_params.Pattern;
-       group_params->Password = groupcount > 1 ?
-         groups[groupcount - 2].Password : default_params.Password;
-       group_params->Identd = groupcount > 1 ?
-         groups[groupcount - 2].Identd : default_params.Identd;
-       group_params->MaxCnx = groupcount > 1 ?
-         groups[groupcount - 2].MaxCnx : default_params.MaxCnx;
-       group_params->HoldTime = groupcount > 1 ?
-         groups[groupcount - 2].HoldTime : default_params.HoldTime;
-
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         syslog(L_ERROR, LEFT_BRACE, LogName, filename, linecount);
-         break;
-       }
-       /* left brace */
-       if (strncmp (word, "{", 1)) {
-         free(word);
-         syslog(L_ERROR, LEFT_BRACE, LogName, filename, linecount);
-         break;
-       }
-       else
-         free(word);
-       peer_params.Keysetbit = 0;
-       continue;
-      }
-
-      /* peer */
-      if (!strncmp (word, PEER, sizeof PEER)) {
-       free(word);
-       if (peer_params.Label != NULL) {
-         /* peer can't contain peer */
-         syslog(L_ERROR, PEER_IN_PEER, LogName, 
-             filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL)
-       {
-         syslog(L_ERROR, PEER_NAME, LogName, filename, linecount);
-         break;
-       }
-       RCadddata(data, &infocount, K_BEGIN_PEER, T_STRING, word);
-       /* name of the peer */
-       peer_params.Label = word;
-       peer_params.Name = NULL;
-       peer_params.Skip = groupcount > 0 ?
-         group_params->Skip : default_params.Skip;
-       peer_params.Streaming = groupcount > 0 ?
-         group_params->Streaming : default_params.Streaming;
-       peer_params.NoResendId = groupcount > 0 ?
-         group_params->NoResendId : default_params.NoResendId;
-       peer_params.Nolist = groupcount > 0 ?
-         group_params->Nolist : default_params.Nolist;
-       peer_params.Email = groupcount > 0 ?
-         group_params->Email : default_params.Email;
-       peer_params.Comment = groupcount > 0 ?
-         group_params->Comment : default_params.Comment;
-       peer_params.Pattern = groupcount > 0 ?
-         group_params->Pattern : default_params.Pattern;
-       peer_params.Password = groupcount > 0 ?
-         group_params->Password : default_params.Password;
-       peer_params.Identd = groupcount > 0 ?
-         group_params->Identd : default_params.Identd;
-       peer_params.MaxCnx = groupcount > 0 ?
-         group_params->MaxCnx : default_params.MaxCnx;
-       peer_params.HoldTime = groupcount > 0 ?
-         group_params->HoldTime : default_params.HoldTime;
-
-       peer_params.Keysetbit = 0;
-
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL)
-       {
-         syslog(L_ERROR, LEFT_BRACE, LogName, filename, linecount);
-         break;
-       }
-       /* left brace */
-       if (strncmp (word, "{", 1)) {
-         syslog(L_ERROR, LEFT_BRACE, LogName, filename, linecount);
-         free(word);
-         break;
-       }
-       else
-         free(word);
-       continue;
-      }
-
-      /* right brace */
-      if (!strncmp (word, "}", 1)) {
-       free(word);
-       if (peer_params.Label != NULL) {
-         RCadddata(data, &infocount, K_END_PEER, T_STRING, NULL);
-
-         /* Hostname defaults to label if not given */
-         if (peer_params.Name == NULL)
-            peer_params.Name = xstrdup(peer_params.Label);
-
-         for(r = q = RCCommaSplit(xstrdup(peer_params.Name)); *q != NULL; q++) {
-#ifdef HAVE_INET6
-             struct addrinfo *res, *res0, hints;
-             int gai_ret;
-#endif
-           (*count)++;
-
-           /* Grow the array */
-           j = rp - *list;
-            *list = xrealloc(*list, *count * sizeof(REMOTEHOST));
-           rp = *list + j;
-
-#ifdef HAVE_INET6
-           memset( &hints, 0, sizeof( hints ) );
-           hints.ai_socktype = SOCK_STREAM;
-           hints.ai_family = PF_UNSPEC;
-           if ((gai_ret = getaddrinfo(*q, NULL, &hints, &res0)) != 0) {
-               syslog(L_ERROR, "%s cant getaddrinfo %s %s", LogName, *q,
-                               gai_strerror( gai_ret ) );
-               /* decrement *count, since we never got to add this record. */
-               (*count)--;
-               continue;
-           }
-           /* Count the addresses and see if we have to grow the list */
-           i = 0;
-           for (res = res0; res != NULL; res = res->ai_next)
-               i++;
-           /* Grow the array */
-           j = rp - *list;
-           *count += i - 1;
-            *list = xrealloc(*list, *count * sizeof(REMOTEHOST));
-           rp = *list + j;
-
-           /* Add all hosts */
-           for (res = res0; res != NULL; res = res->ai_next) {
-               (void)memcpy(&rp->Address, res->ai_addr, res->ai_addrlen);
-               rp->Name = xstrdup (*q);
-               rp->Label = xstrdup (peer_params.Label);
-               rp->Email = xstrdup(peer_params.Email);
-               rp->Comment = xstrdup(peer_params.Comment);
-               rp->Streaming = peer_params.Streaming;
-               rp->Skip = peer_params.Skip;
-               rp->NoResendId = peer_params.NoResendId;
-               rp->Nolist = peer_params.Nolist;
-               rp->Password = xstrdup(peer_params.Password);
-               rp->Identd = xstrdup(peer_params.Identd);
-               rp->Patterns = peer_params.Pattern != NULL ?
-                   RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL;
-               rp->MaxCnx = peer_params.MaxCnx;
-               rp->HoldTime = peer_params.HoldTime;
-               rp++;
-           }
-           freeaddrinfo(res0);
-#else /* HAVE_INET6 */
-           /* Was host specified as a dotted quad ? */
-           if (inet_aton(*q, &addr)) {
-             make_sin( (struct sockaddr_in *)&rp->Address, &addr );
-             rp->Name = xstrdup (*q);
-             rp->Label = xstrdup (peer_params.Label);
-             rp->Password = xstrdup(peer_params.Password);
-             rp->Identd = xstrdup(peer_params.Identd);
-             rp->Skip = peer_params.Skip;
-             rp->Streaming = peer_params.Streaming;
-             rp->NoResendId = peer_params.NoResendId;
-             rp->Nolist = peer_params.Nolist;
-             rp->Email = xstrdup(peer_params.Email);
-             rp->Comment = xstrdup(peer_params.Comment);
-             rp->Patterns = peer_params.Pattern != NULL ?
-                   RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL;
-             rp->MaxCnx = peer_params.MaxCnx;
-             rp->HoldTime = peer_params.HoldTime;
-             rp++;
-             continue;
-           }
-           
-           /* Host specified as a text name ? */
-           if ((hp = gethostbyname(*q)) == NULL) {
-             syslog(L_ERROR, "%s cant gethostbyname %s %m", LogName, *q);
-             /* decrement *count, since we never got to add this record. */
-             (*count)--;
-             continue;
-           }
-
-           /* Count the adresses and see if we have to grow the list */
-           for (i = 0; hp->h_addr_list[i]; i++)
-             continue;
-           if (i == 0) {
-             syslog(L_ERROR, "%s no_address %s %m", LogName, *q);
-             continue;
-           }
-           if (i == 1) {
-             char **rr;
-             int    t = 0;
-             /* Strange DNS ? try this.. */
-             for (rr = hp->h_aliases; *rr != 0; rr++) {
-                if (!inet_aton(*rr, &addr))
-                 continue;
-               (*count)++;
-               /* Grow the array */
-               j = rp - *list;
-                *list = xrealloc(*list, *count * sizeof(REMOTEHOST));
-               rp = *list + j;
-
-               make_sin( (struct sockaddr_in *)&rp->Address, &addr );
-               rp->Name = xstrdup (*q);
-               rp->Label = xstrdup (peer_params.Label);
-               rp->Email = xstrdup(peer_params.Email);
-               rp->Comment = xstrdup(peer_params.Comment);
-               rp->Streaming = peer_params.Streaming;
-               rp->Skip = peer_params.Skip;
-               rp->NoResendId = peer_params.NoResendId;
-               rp->Nolist = peer_params.Nolist;
-               rp->Password = xstrdup(peer_params.Password);
-               rp->Identd = xstrdup(peer_params.Identd);
-               rp->Patterns = peer_params.Pattern != NULL ?
-                 RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL;
-               rp->MaxCnx = peer_params.MaxCnx;
-               rp->HoldTime = peer_params.HoldTime;
-               rp++;
-               t++;
-             }
-             if (t == 0) {
-               /* Just one, no need to grow. */
-               make_sin( (struct sockaddr_in *)&rp->Address,
-                               (struct in_addr *)hp->h_addr_list[0] );
-               rp->Name = xstrdup (*q);
-               rp->Label = xstrdup (peer_params.Label);
-               rp->Email = xstrdup(peer_params.Email);
-               rp->Comment = xstrdup(peer_params.Comment);
-               rp->Streaming = peer_params.Streaming;
-               rp->Skip = peer_params.Skip;
-               rp->NoResendId = peer_params.NoResendId;
-               rp->Nolist = peer_params.Nolist;
-               rp->Password = xstrdup(peer_params.Password);
-               rp->Identd = xstrdup(peer_params.Identd);
-               rp->Patterns = peer_params.Pattern != NULL ?
-                 RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL;
-               rp->MaxCnx = peer_params.MaxCnx;
-               rp->HoldTime = peer_params.HoldTime;
-               rp++;
-               continue;
-             }
-           }
-           /* Grow the array */
-           j = rp - *list;
-           *count += i - 1;
-            *list = xrealloc(*list, *count * sizeof(REMOTEHOST));
-           rp = *list + j;
-
-           /* Add all the hosts. */
-           for (i = 0; hp->h_addr_list[i]; i++) {
-             make_sin( (struct sockaddr_in *)&rp->Address,
-                             (struct in_addr *)hp->h_addr_list[i] );
-             rp->Name = xstrdup (*q);
-             rp->Label = xstrdup (peer_params.Label);
-             rp->Email = xstrdup(peer_params.Email);
-             rp->Comment = xstrdup(peer_params.Comment);
-             rp->Streaming = peer_params.Streaming;
-             rp->Skip = peer_params.Skip;
-             rp->NoResendId = peer_params.NoResendId;
-             rp->Nolist = peer_params.Nolist;
-             rp->Password = xstrdup(peer_params.Password);
-             rp->Identd = xstrdup(peer_params.Identd);
-             rp->Patterns = peer_params.Pattern != NULL ?
-               RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL;
-             rp->MaxCnx = peer_params.MaxCnx;
-             rp->HoldTime = peer_params.HoldTime;
-             rp++;
-           }
-#endif /* HAVE_INET6 */
-         }
-         free(r[0]);
-         free(r);
-         peer_params.Label = NULL;
-       }
-       else if (groupcount > 0 && group_params->Label != NULL) {
-         RCadddata(data, &infocount, K_END_GROUP, T_STRING, NULL);
-         group_params->Label = NULL;
-         groupcount--;
-         if (groupcount == 0) {
-           /* We are now outside a group block. */
-           free(groups);
-           maxgroup = 0;
-         } else {
-           group_params--;
-         }
-       }
-       else {
-         syslog(L_ERROR, RIGHT_BRACE, LogName, linecount, filename);
-       }
-       continue;
-      }
-
-      /* streaming */
-      if (!strncmp (word, STREAMING, sizeof STREAMING)) {
-       free(word);
-       TEST_CONFIG(K_STREAM, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       if (!strcmp (word, "true"))
-         flag = true;
-       else
-         if (!strcmp (word, "false"))
-           flag = false;
-         else {
-           syslog(L_ERROR, MUST_BE_BOOL, LogName, filename, linecount);
-           break;
-         }
-       RCadddata(data, &infocount, K_STREAM, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Streaming = flag;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Streaming = flag;
-         else
-           default_params.Streaming = flag;
-       SET_CONFIG(K_STREAM);
-       continue;
-      }
-
-      /* skip */
-      if (!strncmp (word, SKIP, sizeof SKIP)) {
-       free(word);
-       TEST_CONFIG(K_SKIP, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       if (!strcmp (word, "true"))
-         flag = true;
-       else
-         if (!strcmp (word, "false"))
-           flag = false;
-         else {
-           syslog(L_ERROR, MUST_BE_BOOL, LogName, filename, linecount);
-           break;
-         }
-       RCadddata(data, &infocount, K_SKIP, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Skip = flag;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Skip = flag;
-         else
-           default_params.Skip = flag;
-       SET_CONFIG(K_SKIP);
-       continue;
-      }
-
-      /* noresendid */
-      if (!strncmp (word, NORESENDID, sizeof NORESENDID)) {
-       free(word);
-       TEST_CONFIG(K_NORESENDID, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       if (!strcmp (word, "true"))
-         flag = true;
-       else
-         if (!strcmp (word, "false"))
-           flag = false;
-         else {
-           syslog(L_ERROR, MUST_BE_BOOL, LogName, filename, linecount);
-           break;
-         }
-       RCadddata(data, &infocount, K_NORESENDID, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.NoResendId = flag;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->NoResendId = flag;
-         else
-           default_params.NoResendId = flag;
-       SET_CONFIG(K_NORESENDID);
-       continue;
-      }
-
-      /* nolist */
-      if (!strncmp (word, NOLIST, sizeof NOLIST)) {
-       free(word);
-       TEST_CONFIG(K_NOLIST, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       if (!strcmp (word, "true"))
-         flag = true;
-       else
-         if (!strcmp (word, "false"))
-           flag = false;
-         else {
-           syslog(L_ERROR, MUST_BE_BOOL, LogName, filename, linecount);
-           break;
-         }
-       RCadddata(data, &infocount, K_NOLIST, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Nolist = flag;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Nolist = flag;
-         else
-           default_params.Nolist = flag;
-       SET_CONFIG(K_NOLIST);
-       continue;
-      }
-
-      /* max-connections */
-      if (!strncmp (word, MAX_CONN, sizeof MAX_CONN)) {
-       int max;
-       free(word);
-       TEST_CONFIG(K_MAX_CONN, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_MAX_CONN, T_STRING, word);
-       for (p = word; CTYPE(isdigit, *p) && *p != '\0'; p++);
-       if (!strcmp (word, "none") || !strcmp (word, "unlimited")) {
-         max = 0;
-       } else {
-         if (*p != '\0') {
-           syslog(L_ERROR, MUST_BE_INT, LogName, filename, linecount);
-           break;
-         }
-         max = atoi(word);
-       }
-       if (peer_params.Label != NULL)
-         peer_params.MaxCnx = max;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->MaxCnx = max;
-         else
-           default_params.MaxCnx = max;
-       SET_CONFIG(K_MAX_CONN);
-       continue;
-      }
-
-      /* hold-time */
-      if (!strncmp (word, HOLD_TIME, sizeof HOLD_TIME)) {
-       free(word);
-       TEST_CONFIG(K_HOLD_TIME, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_HOLD_TIME, T_STRING, word);
-       for (p = word; CTYPE(isdigit, *p) && *p != '\0'; p++);
-       if (*p != '\0') {
-         syslog(L_ERROR, MUST_BE_INT, LogName, filename, linecount);
-         break;
-       }
-       if (peer_params.Label != NULL)
-         peer_params.HoldTime = atoi(word);
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->HoldTime = atoi(word);
-         else
-           default_params.HoldTime = atoi(word);
-       SET_CONFIG(K_HOLD_TIME);
-       continue;
-      }
-
-      /* hostname */
-      if (!strncmp (word, HOSTNAME, sizeof HOSTNAME)) {
-       free(word);
-       TEST_CONFIG(K_HOSTNAME, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_HOSTNAME, T_STRING, word);
-       peer_params.Name = word;
-       SET_CONFIG(K_HOSTNAME);
-       continue;
-      }
-
-      /* password */
-      if (!strncmp (word, PASSWORD, sizeof PASSWORD)) {
-       free(word);
-       TEST_CONFIG(K_PASSWORD, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_PASSWORD, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Password = word;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Password = word;
-         else
-           default_params.Password = word;
-       SET_CONFIG(K_PASSWORD);
-       continue;
-      }
-
-      /* identd */
-      if (!strncmp (word, IDENTD, sizeof IDENTD)) {
-       free(word);
-       TEST_CONFIG(K_IDENTD, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_IDENTD, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Identd = word;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Identd = word;
-         else
-           default_params.Identd = word;
-       SET_CONFIG(K_IDENTD);
-       continue;
-      }
-
-      /* patterns */
-      if (!strncmp (word, PATTERNS, sizeof PATTERNS)) {
-       TEST_CONFIG(K_PATTERNS, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       free(word);
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_PATTERNS, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Pattern = word;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Pattern = word;
-         else
-           default_params.Pattern = word;
-       SET_CONFIG(K_PATTERNS);
-       continue;
-      }
-
-      /* email */
-      if (!strncmp (word, EMAIL, sizeof EMAIL)) {
-       free(word);
-       TEST_CONFIG(K_EMAIL, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_EMAIL, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Email = word;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Email = word;
-         else
-           default_params.Email = word;
-       SET_CONFIG(K_EMAIL);
-       continue;
-      }
-
-      /* comment */
-      if (!strncmp (word, COMMENT, sizeof COMMENT)) {
-       free(word);
-       TEST_CONFIG(K_COMMENT, bit);
-        if (bit) {
-         syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount);
-         break;
-       }
-       if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) {
-         break;
-       }
-       RCadddata(data, &infocount, K_COMMENT, T_STRING, word);
-       if (peer_params.Label != NULL)
-         peer_params.Comment = word;
-       else
-         if (groupcount > 0 && group_params->Label != NULL)
-           group_params->Comment = word;
-         else
-           default_params.Comment = word;
-       SET_CONFIG(K_COMMENT);
-       continue;
-      }
-
-      if (toolong)
-       syslog(L_ERROR, "%s line too long at %d: %s",
-            LogName, --linecount, filename);
-      else
-       syslog(L_ERROR, "%s Unknown value line %d: %s",
-            LogName, linecount, filename);
-      free(word);
-      break;
-    }
-    free(default_params.Email);
-    free(default_params.Comment);
-    RCadddata(data, &infocount, K_END, T_STRING, NULL);
-
-    if (feof (F)) {
-      if (peer_params.Label != NULL)
-       syslog(L_ERROR, INCOMPLETE_PEER, LogName, peer_params.Label,
-              filename, linecount);
-      if (groupcount > 0 && group_params->Label != NULL)
-       syslog(L_ERROR, INCOMPLETE_GROUP, LogName, group_params->Label,
-              filename, linecount);
-    }
-    else
-      syslog(L_ERROR, "%s Syntax error in %s at or before line %d", LogName, 
-            filename, linecount);
-
-    if (Fclose(F) == EOF)
-       syslog(L_ERROR, "%s cant fclose %s %m", LogName, filename);
-
-    free(default_params.Password);
-    free(default_params.Identd);
-}
-
-
-/*
-**  Indent a line with 3 * c blanks.
-**  Used by RCwritelist().
-*/
-static void
-RCwritelistindent(FILE *F, int c)
-{
-    int                i;
-
-    for (i = 0; i < c; i++)
-        fprintf(F, "   ");
-}
-
-/*
-**  Add double quotes around a string, if needed.
-**  Used by RCwritelist().
-*/
-static void
-RCwritelistvalue(FILE *F, char *value)
-{
-    if (*value == '\0' || strchr (value, '\n') ||
-       strchr (value, ' ') || strchr (value, '\t'))
-       fprintf(F, "\"%s\"", value);
-    else
-        fprintf(F, "%s", value);
-}
-
-/*
-**  Write the incoming configuration (memory->disk)
-*/
-static void UNUSED
-RCwritelist(char *filename)
-{
-    FILE       *F;
-    int                i;
-    int                inc;
-    char       *p;
-    char       *q;
-    char       *r;
-
-    if ((F = Fopen(filename, "w", TEMPORARYOPEN)) == NULL) {
-        syslog(L_FATAL, "%s cant write %s: %m", LogName, filename);
-        return;
-    }
-
-    /* Write a standard header.. */
-
-    /* Find the filename */
-    p = concatpath(innconf->pathetc, _PATH_INNDHOSTS);
-    for (r = q = p; *p; p++)
-        if (*p == '/')
-          q = p + 1;
-
-    fprintf (F, "##  $Revision: 7751 $\n");
-    fprintf (F, "##  %s - names and addresses that feed us news\n", q);
-    free(r);
-    fprintf (F, "##\n\n");
-
-    /* ... */
-
-    inc = 0;
-    for (i = 0; RCpeerlistfile[i].key != K_END; i++) {
-        switch (RCpeerlistfile[i].key) {
-         case K_BEGIN_PEER:
-           fputc ('\n', F);
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s %s {\n", PEER, RCpeerlistfile[i].value);
-           inc++;
-           break;
-         case K_BEGIN_GROUP:
-           fputc ('\n', F);
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s %s {\n", GROUP, RCpeerlistfile[i].value);
-           inc++;
-           break;
-         case K_END_PEER:
-         case K_END_GROUP:
-           inc--;
-           RCwritelistindent (F, inc);
-           fprintf(F, "}\n");
-           break;
-         case K_STREAM:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", STREAMING);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_SKIP:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", SKIP);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_NORESENDID:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", NORESENDID);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_NOLIST:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", NOLIST);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_HOSTNAME:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", HOSTNAME);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_MAX_CONN:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", MAX_CONN);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_HOLD_TIME:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", HOLD_TIME);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_PASSWORD:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", PASSWORD);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_IDENTD:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", IDENTD);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_EMAIL:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", EMAIL);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_PATTERNS:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", PATTERNS);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         case K_COMMENT:
-           RCwritelistindent (F, inc);
-           fprintf(F, "%s\t", COMMENT);
-           RCwritelistvalue (F, RCpeerlistfile[i].value);
-           fputc ('\n', F);
-           break;
-         default:
-           fprintf(F, "# ***ERROR***\n");
-       }
-    }
-    if (Fclose(F) == EOF)
-        syslog(L_ERROR, "%s cant fclose %s %m", LogName, filename);
-
-}
-
-void
-RCreadlist(void)
-{
-    static char        *INNDHOSTS = NULL;
-
-    if (INNDHOSTS == NULL)
-       INNDHOSTS = concatpath(innconf->pathetc, _PATH_INNDHOSTS);
-    StreamingOff = false;
-    RCreadfile(&RCpeerlistfile, &RCpeerlist, &RCnpeerlist, INNDHOSTS);
-    /* RCwritelist("/tmp/incoming.conf.new"); */
-}
-
-/*
-**  Find the name of a remote host we've connected to.
-*/
-char *
-RChostname(const CHANNEL *cp)
-{
-    static char        buff[SMBUF];
-    REMOTEHOST *rp;
-    int                i;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
-       if (RCaddressmatch(&cp->Address, &rp->Address))
-           return rp->Name;
-    strlcpy(buff, sprint_sockaddr((struct sockaddr *)&cp->Address),
-            sizeof(buff));
-    return buff;
-}
-
-/*
-**  Find the label name of a remote host we've connected to.
-*/
-char *
-RClabelname(CHANNEL *cp) {
-    REMOTEHOST *rp;
-    int                i;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
-       if (RCaddressmatch(&cp->Address, &rp->Address))
-           return rp->Label;
-    }
-    return NULL;
-}
-
-/*
-**  Is the remote site allowed to post to this group?
-*/
-int
-RCcanpost(CHANNEL *cp, char *group)
-{
-    REMOTEHOST         *rp;
-    char               match;
-    char               subvalue;
-    char               **argv;
-    char               *pat;
-    int                        i;
-
-    /* Connections from lc.c are from local nnrpd and should always work */
-    if (cp->Address.ss_family == 0)
-       return 1;
-
-    for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
-       if (!RCaddressmatch(&cp->Address, &rp->Address))
-           continue;
-       if (rp->Patterns == NULL)
-           break;
-       for (match = 0, argv = rp->Patterns; (pat = *argv++) != NULL; ) {
-           subvalue = (*pat != SUB_NEGATE) && (*pat != SUB_POISON) ?
-             0 : *pat;
-           if (subvalue)
-               pat++;
-           if ((match != subvalue) && uwildmat(group, pat)) {
-               if (subvalue == SUB_POISON)
-                   return -1;
-               match = subvalue;
-           }
-       }
-       return !match;
-    }
-    return 1;
-}
-
-
-/*
-**  Create the channel.
-*/
-void
-RCsetup(int i)
-{
-#if    defined(SO_REUSEADDR)
-    int                on;
-#endif /* defined(SO_REUSEADDR) */
-    int                j;
-    CHANNEL    *rcchan;
-
-    /* This code is called only when inndstart is not being used */
-    if (i < 0) {
-#ifdef HAVE_INET6
-       syslog(L_FATAL, "%s innd MUST be started with inndstart", LogName);
-       exit(1);
-#else
-       /* Create a socket and name it. */
-       struct sockaddr_in      server;
-
-       if ((i = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-           syslog(L_FATAL, "%s cant socket RCreader %m", LogName);
-           exit(1);
-       }
-#if    defined(SO_REUSEADDR)
-       on = 1;
-       if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0)
-           syslog(L_ERROR, "%s cant setsockopt RCreader %m", LogName);
-#endif /* defined(SO_REUSEADDR) */
-       memset(&server, 0, sizeof server);
-       server.sin_port = htons(innconf->port);
-       server.sin_family = AF_INET;
-#ifdef HAVE_SOCKADDR_LEN
-       server.sin_len = sizeof( struct sockaddr_in );
-#endif
-       server.sin_addr.s_addr = htonl(INADDR_ANY);
-       if (innconf->bindaddress) {
-            if (!inet_aton(innconf->bindaddress, &server.sin_addr)) {
-                syslog(L_FATAL, "unable to determine bind ip (%s) %m",
-                       innconf->bindaddress);
-               exit(1);
-           }
-       }
-       if (bind(i, (struct sockaddr *)&server, sizeof server) < 0) {
-           syslog(L_FATAL, "%s cant bind RCreader %m", LogName);
-           exit(1);
-       }
-#endif /* HAVE_INET6 */
-    }
-
-    /* Set it up to wait for connections. */
-    if (listen(i, MAXLISTEN) < 0) {
-       j = errno;
-       syslog(L_FATAL, "%s cant listen RCreader %m", LogName);
-       /* some IPv6 systems already listening on any address will 
-          return EADDRINUSE when trying to listen on the IPv4 socket */
-       if (j == EADDRINUSE)
-          return;
-       exit(1);
-    }
-
-    rcchan = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
-    syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(rcchan));
-    RCHANadd(rcchan);
-
-    for (j = 0 ; j < chanlimit ; j++ ) {
-       if (RCchan[j] == NULL) {
-           break;
-       }
-    }
-    if (j < chanlimit) {
-       RCchan[j] = rcchan;
-    } else if (chanlimit == 0) {
-       /* assuming two file descriptors(AF_INET and AF_INET6) */
-       chanlimit = 2;
-        RCchan = xmalloc(chanlimit * sizeof(CHANNEL **));
-       for (j = 0 ; j < chanlimit ; j++ ) {
-           RCchan[j] = NULL;
-       }
-       RCchan[0] = rcchan;
-    } else {
-       /* extend to double size */
-        RCchan = xrealloc(RCchan, chanlimit * 2 * sizeof(CHANNEL **));
-       for (j = chanlimit ; j < chanlimit * 2 ; j++ ) {
-           RCchan[j] = NULL;
-       }
-       RCchan[chanlimit] = rcchan;
-       chanlimit *= 2;
-    }
-
-    /* Get the list of hosts we handle. */
-    RCreadlist();
-}
-
-
-/*
-**  Cleanly shut down the channel.
-*/
-void
-RCclose(void)
-{
-    REMOTEHOST *rp;
-    int                i;
-
-    for (i = 0 ; i < chanlimit ; i++) {
-       if (RCchan[i] != NULL) {
-           CHANclose(RCchan[i], CHANname(RCchan[i]));
-       } else {
-           break;
-       }
-    }
-    if (chanlimit != 0)
-       free(RCchan);
-    RCchan = NULL;
-    chanlimit = 0;
-    if (RCpeerlist) {
-       for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
-           free(rp->Name);
-           free(rp->Label);
-           free(rp->Email);
-           free(rp->Password);
-           free(rp->Identd);
-           free(rp->Comment);
-           if (rp->Patterns) {
-               free(rp->Patterns[0]);
-               free(rp->Patterns);
-           }
-       }
-       free(RCpeerlist);
-       RCpeerlist = NULL;
-       RCnpeerlist = 0;
-    }
-
-    if (RCpeerlistfile) {
-        for (i = 0; RCpeerlistfile[i].key != K_END; i++)
-        if (RCpeerlistfile[i].value != NULL)
-          free(RCpeerlistfile[i].value);
-       free(RCpeerlistfile);
-       RCpeerlistfile = NULL;
-    }
-}
diff --git a/innd/site.c b/innd/site.c
deleted file mode 100644 (file)
index 09c405e..0000000
+++ /dev/null
@@ -1,1246 +0,0 @@
-/*  $Id: site.c 7748 2008-04-06 13:49:56Z iulius $
-**
-**  Routines to implement site-feeding.  Mainly working with channels to
-**  do buffering and determine what to send.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-
-static int     SITEcount;
-static int     SITEhead = NOSITE;
-static int     SITEtail = NOSITE;
-static char    SITEshell[] = _PATH_SH;
-
-
-/*
-**  Called when input is ready to read.  Shouldn't happen.
-*/
-static void
-SITEreader(CHANNEL *cp)
-{
-    syslog(L_ERROR, "%s internal SITEreader: %s", LogName, CHANname(cp));
-}
-
-
-/*
-**  Called when write is done.  No-op.
-*/
-static void
-SITEwritedone(CHANNEL *cp UNUSED)
-{
-}
-
-
-/*
-**  Make a site start spooling.
-*/
-static bool
-SITEspool(SITE *sp, CHANNEL *cp)
-{
-    int                        i;
-    char               buff[SPOOLNAMEBUFF];
-    char               *name;
-
-    name = sp->SpoolName;
-    i = open(name, O_APPEND | O_CREAT | O_WRONLY, BATCHFILE_MODE);
-    if (i < 0 && errno == EISDIR) {
-       FileGlue(buff, sp->SpoolName, '/', "togo");
-       name = buff;
-       i = open(buff, O_APPEND | O_CREAT | O_WRONLY, BATCHFILE_MODE);
-    }
-    if (i < 0) {
-       i = errno;
-       syslog(L_ERROR, "%s cant open %s %m", sp->Name, name);
-       IOError("site batch file", i);
-       sp->Channel = NULL;
-       return false;
-    }
-    if (cp) {
-      if (cp->fd >= 0)
-        /* syslog(L_ERROR, "DEBUG ERROR SITEspool trashed:%d %s:%d", cp->fd, sp->Name, i);
-          CPU-eating bug, killed by kre. */
-       WCHANremove(cp);
-       RCHANremove(cp);
-       SCHANremove(cp);
-       close(cp->fd);
-       cp->fd = i;
-       return true;
-    }
-    sp->Channel = CHANcreate(i, CTfile, CSwriting, SITEreader, SITEwritedone);
-    if (sp->Channel == NULL) {
-       syslog(L_ERROR, "%s cant channel %m", sp->Name);
-       close(i);
-       return false;
-    }
-    WCHANset(sp->Channel, "", 0);
-    sp->Spooling = true;
-    return true;
-}
-
-
-/*
-**  Delete a site from the file writing list.  Can be called even if
-**  site is not on the list.
-*/
-static void
-SITEunlink(SITE *sp)
-{
-    if (sp->Next != NOSITE || sp->Prev != NOSITE
-     || (SITEhead != NOSITE && sp == &Sites[SITEhead]))
-       SITEcount--;
-
-    if (sp->Next != NOSITE)
-       Sites[sp->Next].Prev = sp->Prev;
-    else if (SITEtail != NOSITE && sp == &Sites[SITEtail])
-       SITEtail = sp->Prev;
-
-    if (sp->Prev != NOSITE)
-       Sites[sp->Prev].Next = sp->Next;
-    else if (SITEhead != NOSITE && sp == &Sites[SITEhead])
-       SITEhead = sp->Next;
-
-    sp->Next = sp->Prev = NOSITE;
-}
-
-
-/*
-**  Find the oldest "file feed" site and buffer it.
-*/
-static void
-SITEbufferoldest(void)
-{
-    SITE               *sp;
-    struct buffer       *bp;
-    struct buffer       *out;
-
-    /* Get the oldest user of a file. */
-    if (SITEtail == NOSITE) {
-       syslog(L_ERROR, "%s internal no oldest site found", LogName);
-       SITEcount = 0;
-       return;
-    }
-
-    sp = &Sites[SITEtail];
-    SITEunlink(sp);
-
-    if (sp->Buffered) {
-       syslog(L_ERROR, "%s internal oldest (%s) was buffered", LogName,
-           sp->Name);
-       return;
-    }
-
-    if (sp->Type != FTfile) {
-       syslog(L_ERROR, "%s internal oldest (%s) not FTfile", LogName,
-           sp->Name);
-       return;
-    }
-
-    /* Write out what we can. */
-    WCHANflush(sp->Channel);
-
-    /* Get a buffer for the site. */
-    sp->Buffered = true;
-    bp = &sp->Buffer;
-    bp->used = 0;
-    bp->left = 0;
-    if (bp->size == 0) {
-       bp->size = sp->Flushpoint;
-       bp->data = xmalloc(bp->size);
-    }
-    else {
-       bp->size = sp->Flushpoint;
-        bp->data = xrealloc(bp->data, bp->size);
-    }
-
-    /* If there's any unwritten data, copy it. */
-    out = &sp->Channel->Out;
-    if (out->left) {
-        buffer_set(bp, &out->data[out->used], out->left);
-       out->left = 0;
-    }
-
-    /* Now close the original channel. */
-    CHANclose(sp->Channel, sp->Name);
-    sp->Channel = NULL;
-}
-
-/*
- * *  Bilge Site's Channel out buffer.
- */
-static bool
-SITECHANbilge(SITE *sp)
-{
-    int             fd;
-    int             i;
-    char            buff[SPOOLNAMEBUFF];
-    char           *name;
-
-    name = sp->SpoolName;
-    fd = open(name, O_APPEND | O_CREAT | O_WRONLY, BATCHFILE_MODE);
-    if (fd < 0 && errno == EISDIR) {
-        FileGlue(buff, sp->SpoolName, '/', "togo");
-        name = buff;
-        fd = open(buff, O_APPEND | O_CREAT | O_WRONLY, BATCHFILE_MODE);
-    }
-    if (fd < 0) {
-       int oerrno = errno ;
-        syslog(L_ERROR, "%s cant open %s %m", sp->Name, name);
-        IOError("site batch file",oerrno);
-        sp->Channel = NULL;
-        return false;
-    }
-    while (sp->Channel->Out.left > 0) {
-        i = write(fd, &sp->Channel->Out.data[sp->Channel->Out.used],
-                  sp->Channel->Out.left);
-        if(i <= 0) {
-            syslog(L_ERROR,"%s cant spool count %lu", CHANname(sp->Channel),
-                (unsigned long) sp->Channel->Out.left);
-            close(fd);
-            return false;
-        }
-        sp->Channel->Out.left -= i;
-        sp->Channel->Out.used += i;
-    }
-    close(fd);
-    free(sp->Channel->Out.data);
-    sp->Channel->Out.data = xmalloc(SMBUF);
-    sp->Channel->Out.size = SMBUF;
-    sp->Channel->Out.left = 0;
-    sp->Channel->Out.used = 0;
-    return true;
-}
-
-/*
-**  Check if we need to write out the site's buffer.  If we're buffered
-**  or the feed is backed up, this gets a bit complicated.
-*/
-static void
-SITEflushcheck(SITE *sp, struct buffer *bp)
-{
-    int                        i;
-    CHANNEL            *cp;
-
-    /* If we're buffered, and we hit the flushpoint, do an LRU. */
-    if (sp->Buffered) {
-       if (bp->left < sp->Flushpoint)
-           return;
-       while (SITEcount >= MaxOutgoing)
-           SITEbufferoldest();
-       if (!SITEsetup(sp) || sp->Buffered) {
-           syslog(L_ERROR, "%s cant unbuffer %m", sp->Name);
-           return;
-       }
-       WCHANsetfrombuffer(sp->Channel, bp);
-       WCHANadd(sp->Channel);
-       /* Reset buffer; data has been moved. */
-       buffer_set(bp, "", 0);
-    }
-
-    if (PROCneedscan)
-       PROCscan();
-
-    /* Handle buffering. */
-    cp = sp->Channel;
-    i = cp->Out.left;
-    if (i < sp->StopWriting)
-       WCHANremove(cp);
-    if ((sp->StartWriting == 0 || i > sp->StartWriting)
-     && !CHANsleeping(cp)) {
-       if (sp->Type == FTchannel) {    /* channel feed, try the write */
-           int j;
-           if (bp->left == 0)
-               return;
-           j = write(cp->fd, &bp->data[bp->used], bp->left);
-           if (j > 0) {
-               bp->left -= j;
-               bp->used += j;
-               i = cp->Out.left;
-               /* Since we just had a successful write, we need to clear the 
-                * channel's error counts. - dave@jetcafe.org */
-               cp->BadWrites = 0;
-               cp->BlockedWrites = 0;
-           }
-           if (bp->left <= 0) {
-                /* reset Used, Left on bp, keep channel buffer size from
-                   exploding. */
-                bp->used = bp->left = 0;
-               WCHANremove(cp);
-            } else
-               WCHANadd(cp);
-       }
-       else
-           WCHANadd(cp);
-    }
-
-    cp->LastActive = Now.time;
-
-    /* If we're a channel that's getting big, see if we need to spool. */
-    if (sp->Type == FTfile || sp->StartSpooling == 0 || i < sp->StartSpooling)
-       return;
-
-    syslog(L_ERROR, "%s spooling %d bytes", sp->Name, i);
-    if(!SITECHANbilge(sp)) {
-       syslog(L_ERROR, "%s overflow %d bytes", sp->Name, i);
-       return;
-    }
-}
-
-
-/*
-**  Send a control line to an exploder.
-*/
-void
-SITEwrite(SITE *sp, const char *text)
-{
-    static char                PREFIX[] = { EXP_CONTROL, '\0' };
-    struct buffer       *bp;
-
-    if (sp->Buffered)
-       bp = &sp->Buffer;
-    else {
-       if (sp->Channel == NULL)
-           return;
-       sp->Channel->LastActive = Now.time;
-       bp = &sp->Channel->Out;
-    }
-    buffer_append(bp, PREFIX, strlen(PREFIX));
-    buffer_append(bp, text, strlen(text));
-    buffer_append(bp, "\n", 1);
-    if (sp->Channel != NULL)
-       WCHANadd(sp->Channel);
-}
-
-
-/*
-**  Send the desired data about an article down a channel.
-*/
-static void
-SITEwritefromflags(SITE *sp, ARTDATA *Data)
-{
-    HDRCONTENT         *hc = Data->HdrContent;
-    static char                ITEMSEP[] = " ";
-    static char                NL[] = "\n";
-    char               pbuff[12];
-    char               *p;
-    bool               Dirty;
-    struct buffer       *bp;
-    SITE               *spx;
-    int                        i;
-
-    if (sp->Buffered)
-       bp = &sp->Buffer;
-    else {
-       /* This should not happen, but if we tried to spool and failed,
-        * e.g., because of a bad F param for this site, we can get
-        * into this state.  We already logged a message so give up. */
-       if (sp->Channel == NULL)
-           return;
-       bp = &sp->Channel->Out;
-    }
-    for (Dirty = false, p = sp->FileFlags; *p; p++) {
-       switch (*p) {
-       default:
-           syslog(L_ERROR, "%s internal SITEwritefromflags %c", sp->Name, *p);
-           continue;
-       case FEED_BYTESIZE:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->Bytes + sizeof("Bytes: ") - 1,
-                          Data->BytesLength);
-           break;
-       case FEED_FULLNAME:
-       case FEED_NAME:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->TokenText, sizeof(TOKEN) * 2 + 2);
-           break;
-       case FEED_HASH:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, "[", 1);
-           buffer_append(bp, HashToText(*(Data->Hash)), sizeof(HASH)*2);
-           buffer_append(bp, "]", 1);
-           break;
-       case FEED_HDR_DISTRIB:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, HDR(HDR__DISTRIBUTION),
-                          HDR_LEN(HDR__DISTRIBUTION));
-           break;
-       case FEED_HDR_NEWSGROUP:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, HDR(HDR__NEWSGROUPS), HDR_LEN(HDR__NEWSGROUPS));
-           break;
-       case FEED_HEADERS:
-           if (Dirty)
-               buffer_append(bp, NL, strlen(NL));
-           buffer_append(bp, Data->Headers.data, Data->Headers.left);
-           break;
-       case FEED_OVERVIEW:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->Overview.data, Data->Overview.left);
-           break;
-       case FEED_PATH:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-            if (!Data->Hassamepath || Data->AddAlias || Pathcluster.used) {
-                if (Pathcluster.used)
-                    buffer_append(bp, Pathcluster.data, Pathcluster.used);
-                buffer_append(bp, Path.data, Path.used);
-                if (Data->AddAlias)
-                    buffer_append(bp, Pathalias.data, Pathalias.used);
-            }
-            if (Data->Hassamecluster)
-                buffer_append(bp, HDR(HDR__PATH) + Pathcluster.used,
-                              HDR_LEN(HDR__PATH) - Pathcluster.used);
-            else
-                buffer_append(bp, HDR(HDR__PATH), HDR_LEN(HDR__PATH));
-           break;
-       case FEED_REPLIC:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->Replic, Data->ReplicLength);
-           break;
-       case FEED_STOREDGROUP:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->Newsgroups.List[0],
-                          Data->StoredGroupLength);
-           break;
-       case FEED_TIMERECEIVED:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           snprintf(pbuff, sizeof(pbuff), "%ld", (long) Data->Arrived);
-           buffer_append(bp, pbuff, strlen(pbuff));
-           break;
-       case FEED_TIMEPOSTED:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           snprintf(pbuff, sizeof(pbuff), "%ld", (long) Data->Posted);
-           buffer_append(bp, pbuff, strlen(pbuff));
-           break;
-       case FEED_TIMEEXPIRED:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           snprintf(pbuff, sizeof(pbuff), "%ld", (long) Data->Expires);
-           buffer_append(bp, pbuff, strlen(pbuff));
-           break;
-       case FEED_MESSAGEID:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, HDR(HDR__MESSAGE_ID), HDR_LEN(HDR__MESSAGE_ID));
-           break;
-       case FEED_FNLNAMES:
-           if (sp->FNLnames.data) {
-               /* Funnel; write names of our sites that got it. */
-               if (Dirty)
-                   buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-               buffer_append(bp, sp->FNLnames.data, sp->FNLnames.used);
-           }
-           else {
-               /* Not funnel; write names of all sites that got it. */
-               for (spx = Sites, i = nSites; --i >= 0; spx++)
-                   if (spx->Sendit) {
-                       if (Dirty)
-                           buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-                       buffer_append(bp, spx->Name, spx->NameLength);
-                       Dirty = true;
-                   }
-           }
-           break;
-       case FEED_NEWSGROUP:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           if (sp->ng)
-               buffer_append(bp, sp->ng->Name, sp->ng->NameLength);
-           else
-               buffer_append(bp, "?", 1);
-           break;
-       case FEED_SITE:
-           if (Dirty)
-               buffer_append(bp, ITEMSEP, strlen(ITEMSEP));
-           buffer_append(bp, Data->Feedsite, Data->FeedsiteLength);
-           break;
-       }
-       Dirty = true;
-    }
-    if (Dirty) {
-       buffer_append(bp, "\n", 1);
-       SITEflushcheck(sp, bp);
-    }
-}
-
-
-/*
-**  Send one article to a site.
-*/
-void
-SITEsend(SITE *sp, ARTDATA *Data)
-{
-    int                        i;
-    char               *p;
-    char               *temp;
-    char               buff[BUFSIZ];
-    char *             argv[MAX_BUILTIN_ARGV];
-
-    switch (sp->Type) {
-    default:
-       syslog(L_ERROR, "%s internal SITEsend type %d", sp->Name, sp->Type);
-       break;
-    case FTlogonly:
-       break;
-    case FTfunnel:
-       syslog(L_ERROR, "%s funnel_send", sp->Name);
-       break;
-    case FTfile:
-    case FTchannel:
-    case FTexploder:
-       SITEwritefromflags(sp, Data);
-       break;
-    case FTprogram:
-       /* Set up the argument vector. */
-       if (sp->FNLwantsnames) {
-           i = strlen(sp->Param) + sp->FNLnames.used;
-           if (i + (sizeof(TOKEN) * 2) + 3 >= sizeof buff) {
-               syslog(L_ERROR, "%s toolong need %lu for %s",
-                   sp->Name, (unsigned long) (i + (sizeof(TOKEN) * 2) + 3),
-                   sp->Name);
-               break;
-           }
-           temp = xmalloc(i + 1);
-           p = strchr(sp->Param, '*');
-           *p = '\0';
-           strlcpy(temp, sp->Param, i + 1);
-           strlcat(temp, sp->FNLnames.data, i + 1);
-           strlcat(temp, &p[1], i + 1);
-           *p = '*';
-           snprintf(buff, sizeof(buff), temp, Data->TokenText);
-           free(temp);
-       }
-       else
-           snprintf(buff, sizeof(buff), sp->Param, Data->TokenText);
-
-       if (NeedShell(buff, (const char **)argv, (const char **)ARRAY_END(argv))) {
-           argv[0] = SITEshell;
-           argv[1] = (char *) "-c";
-           argv[2] = buff;
-           argv[3] = NULL;
-       }
-
-       /* Start the process. */
-       i = Spawn(sp->Nice, 0, (int)fileno(Errlog), (int)fileno(Errlog), argv);
-       if (i >= 0)
-           PROCwatch(i, -1);
-       break;
-    }
-}
-
-
-/*
-**  The channel was sleeping because we had to spool our output to
-**  a file.  Flush and restart.
-*/
-static void
-SITEspoolwake(CHANNEL *cp)
-{
-    SITE       *sp;
-    int                *ip;
-
-    ip = (int *) cp->Argument;
-    sp = &Sites[*ip];
-    free(cp->Argument);
-    cp->Argument = NULL;
-    if (sp->Channel != cp) {
-       syslog(L_ERROR, "%s internal SITEspoolwake %s got %d, not %d",
-           LogName, sp->Name, cp->fd, sp->Channel->fd);
-        return;
-    }
-    syslog(L_NOTICE, "%s spoolwake", sp->Name);
-    SITEflush(sp, true);
-}
-
-
-/*
-**  Start up a process for a channel, or a spool to a file if we can't.
-**  Create a channel for the site to talk to.
-*/
-static bool
-SITEstartprocess(SITE *sp)
-{
-    pid_t              i;
-    char               *argv[MAX_BUILTIN_ARGV];
-    char               *process;
-    int                        *ip;
-    int                        pan[2];
-
-#if HAVE_SOCKETPAIR
-    /* Create a socketpair. */
-    if (socketpair(PF_UNIX, SOCK_STREAM, 0, pan) < 0) {
-       syslog(L_ERROR, "%s cant socketpair %m", sp->Name);
-       return false;
-    }
-#else
-    /* Create a pipe. */
-    if (pipe(pan) < 0) {
-       syslog(L_ERROR, "%s cant pipe %m", sp->Name);
-       return false;
-    }
-#endif
-    close_on_exec(pan[PIPE_WRITE], true);
-
-    /* Set up the argument vector. */
-    process = xstrdup(sp->Param);
-    if (NeedShell(process, (const char **)argv, (const char **)ARRAY_END(argv))) {
-       argv[0] = SITEshell;
-       argv[1] = (char *) "-c";
-       argv[2] = process;
-       argv[3] = NULL;
-    }
-
-    /* Fork a child. */
-    i = Spawn(sp->Nice, pan[PIPE_READ], (int)fileno(Errlog),
-             (int)fileno(Errlog), argv);
-    if (i > 0) {
-       sp->pid = i;
-       sp->Spooling = false;
-       sp->Process = PROCwatch(i, sp - Sites);
-       close(pan[PIPE_READ]);
-       sp->Channel = CHANcreate(pan[PIPE_WRITE],
-                       sp->Type == FTchannel ? CTprocess : CTexploder,
-                       CSwriting, SITEreader, SITEwritedone);
-       free(process);
-       return true;
-    }
-
-    /* Error.  Switch to spooling. */
-    syslog(L_ERROR, "%s cant spawn spooling %m", sp->Name);
-    close(pan[PIPE_WRITE]);
-    close(pan[PIPE_READ]);
-    free(process);
-    if (!SITEspool(sp, (CHANNEL *)NULL))
-       return false;
-
-    /* We'll try to restart the channel later. */
-    syslog(L_ERROR, "%s cant spawn spooling %m", sp->Name);
-    ip = xmalloc(sizeof(int));
-    *ip = sp - Sites;
-    SCHANadd(sp->Channel, Now.time + innconf->chanretrytime, NULL,
-             SITEspoolwake, ip);
-    return true;
-}
-
-
-/*
-**  Set up a site for internal buffering.
-*/
-static void
-SITEbuffer(SITE *sp)
-{
-    struct buffer *bp;
-
-    SITEunlink(sp);
-    sp->Buffered = true;
-    sp->Channel = NULL;
-    bp = &sp->Buffer;
-    buffer_resize(bp, sp->Flushpoint);
-    buffer_set(bp, "", 0);
-    syslog(L_NOTICE, "%s buffered", sp->Name);
-}
-
-
-/*
-**  Link a site at the head of the "currently writing to a file" list
-*/
-static void
-SITEmovetohead(SITE *sp)
-{
-    if ((SITEhead == NOSITE) && ((sp->Next != NOSITE) || (sp->Prev != NOSITE)))
-       SITEunlink(sp);
-
-    if ((sp->Next = SITEhead) != NOSITE)
-       Sites[SITEhead].Prev = sp - Sites;
-    sp->Prev = NOSITE;
-
-    SITEhead = sp - Sites;
-    if (SITEtail == NOSITE)
-       SITEtail = sp - Sites;
-
-    SITEcount++;
-}
-
-
-/*
-**  Set up a site's feed.  This means opening a file or channel if needed.
-*/
-bool
-SITEsetup(SITE *sp)
-{
-    int                        fd;
-    int                        oerrno;
-
-    switch (sp->Type) {
-    default:
-       syslog(L_ERROR, "%s internal SITEsetup %d",
-           sp->Name, sp->Type);
-       return false;
-    case FTfunnel:
-    case FTlogonly:
-    case FTprogram:
-       /* Nothing to do here. */
-       break;
-    case FTfile:
-       if (SITEcount >= MaxOutgoing)
-           SITEbuffer(sp);
-       else {
-           sp->Buffered = false;
-           fd = open(sp->Param, O_APPEND | O_CREAT | O_WRONLY, BATCHFILE_MODE);
-           if (fd < 0) {
-               if (errno == EMFILE) {
-                   syslog(L_ERROR, "%s cant open %s %m", sp->Name, sp->Param);
-                   SITEbuffer(sp);
-                   break;
-               }
-               oerrno = errno;
-               syslog(L_NOTICE, "%s cant open %s %m", sp->Name, sp->Param);
-               IOError("site file", oerrno);
-               return false;
-           }
-           SITEmovetohead(sp);
-           sp->Channel = CHANcreate(fd, CTfile, CSwriting,
-                           SITEreader, SITEwritedone);
-           syslog(L_NOTICE, "%s opened %s", sp->Name, CHANname(sp->Channel));
-           WCHANset(sp->Channel, "", 0);
-       }
-       break;
-    case FTchannel:
-    case FTexploder:
-       if (!SITEstartprocess(sp))
-           return false;
-       syslog(L_NOTICE, "%s spawned %s", sp->Name, CHANname(sp->Channel));
-       WCHANset(sp->Channel, "", 0);
-       WCHANadd(sp->Channel);
-       break;
-    }
-    return true;
-}
-
-
-/*
-**  A site's channel process died; restart it.
-*/
-void
-SITEprocdied(SITE *sp, int process, PROCESS *pp)
-{
-    syslog(pp->Status ? L_ERROR : L_NOTICE, "%s exit %d elapsed %ld pid %ld",
-       sp->Name ? sp->Name : "?", pp->Status,
-       (long) (pp->Collected - pp->Started), (long) pp->Pid);
-    if (sp->Process != process || sp->Name == NULL)
-       /* We already started a new process for this channel
-        * or this site has been dropped. */
-       return;
-    if (sp->Channel != NULL)
-       CHANclose(sp->Channel, CHANname(sp->Channel));
-    sp->Working = SITEsetup(sp);
-    if (!sp->Working) {
-       syslog(L_ERROR, "%s cant restart %m", sp->Name);
-       return;
-    }
-    syslog(L_NOTICE, "%s restarted", sp->Name);
-}
-
-/*
-**  A channel is about to be closed; see if any site cares.
-*/
-void
-SITEchanclose(CHANNEL *cp)
-{
-    int                        i;
-    SITE               *sp;
-    int                        *ip;
-
-    for (i = nSites, sp = Sites; --i >= 0; sp++)
-       if (sp->Channel == cp) {
-           /* Found the site that has this channel.  Start that
-            * site spooling, copy any data that might be pending,
-            * and arrange to retry later. */
-           if (!SITEspool(sp, (CHANNEL *)NULL)) {
-               syslog(L_ERROR, "%s loss %lu bytes", sp->Name,
-                       (unsigned long) cp->Out.left);
-               return;
-           }
-           WCHANsetfrombuffer(sp->Channel, &cp->Out);
-           WCHANadd(sp->Channel);
-           ip = xmalloc(sizeof(int));
-           *ip = sp - Sites;
-           SCHANadd(sp->Channel, Now.time + innconf->chanretrytime, NULL,
-                     SITEspoolwake, ip);
-           break;
-       }
-}
-
-
-/*
-**  Flush any pending data waiting to be sent.
-*/
-void
-SITEflush(SITE *sp, const bool Restart)
-{
-    CHANNEL            *cp;
-    struct buffer       *out;
-    int                        count;
-
-    if (sp->Name == NULL)
-       return;
-
-    if (Restart)
-       SITEforward(sp, "flush");
-
-    switch (sp->Type) {
-    default:
-       syslog(L_ERROR, "%s internal SITEflush %d", sp->Name, sp->Type);
-       return;
-
-    case FTlogonly:
-    case FTprogram:
-    case FTfunnel:
-       /* Nothing to do here. */
-       return;
-
-    case FTchannel:
-    case FTexploder:
-       /* If spooling, close the file right now -- documented behavior. */
-       if (sp->Spooling && (cp = sp->Channel) != NULL) {
-           WCHANflush(cp);
-           CHANclose(cp, CHANname(cp));
-           sp->Channel = NULL;
-       }
-       break;
-
-    case FTfile:
-       /* We must ensure we have a file open for this site, so if
-        * we're buffered we HACK and pretend we have no sites
-        * for a moment. */
-       if (sp->Buffered) {
-           count = SITEcount;
-           SITEcount = 0;
-           if (!SITEsetup(sp) || sp->Buffered)
-               syslog(L_ERROR, "%s cant unbuffer to flush", sp->Name);
-           else
-               buffer_swap(&sp->Buffer, &sp->Channel->Out);
-           SITEcount += count;
-       }
-       break;
-    }
-
-    /* We're only dealing with files and channels now. */
-    if ((cp = sp->Channel) != NULL)
-       WCHANflush(cp);
-
-    /* Restart the site, copy any pending data. */
-    if (Restart) {
-       if (!SITEsetup(sp))
-           syslog(L_ERROR, "%s cant restart %m", sp->Name);
-       else if (cp != NULL) {
-           if (sp->Buffered) {
-               /* SITEsetup had to buffer us; save any residue. */
-               out = &cp->Out;
-               if (out->left)
-                   buffer_set(&sp->Buffer, &out->data[out->used], out->left);
-           }
-           else
-               WCHANsetfrombuffer(sp->Channel, &cp->Out);
-       }
-    }
-    else if (cp != NULL && cp->Out.left) {
-       if (sp->Type == FTfile || sp->Spooling) {
-           /* Can't flush a file?  Hopeless. */
-           syslog(L_ERROR, "%s dataloss %lu", sp->Name,
-                   (unsigned long) cp->Out.left);
-           return;
-       }
-       /* Must be a working channel; spool and retry. */
-       syslog(L_ERROR, "%s spooling %lu bytes", sp->Name,
-               (unsigned long) cp->Out.left);
-       if (SITEspool(sp, cp))
-           SITEflush(sp, false);
-       return;
-    }
-
-    /* Close the old channel if it was open. */
-    if (cp != NULL) {
-        /* Make sure we have no dangling pointers to it. */
-       if (!Restart)
-           sp->Channel = NULL;
-       CHANclose(cp, sp->Name);
-       if (sp->Type == FTfile)
-           SITEunlink(sp);
-    }
-}
-
-
-/*
-**  Flush all sites.
-*/
-void
-SITEflushall(const bool Restart)
-{
-    int                        i;
-    SITE               *sp;
-
-    for (i = nSites, sp = Sites; --i >= 0; sp++)
-       if (sp->Name)
-           SITEflush(sp, Restart);
-}
-
-
-/*
-**  Run down the site's pattern list and see if it wants the specified
-**  newsgroup.
-*/
-bool
-SITEwantsgroup(SITE *sp, char *name)
-{
-    bool               match;
-    bool               subvalue;
-    char               *pat;
-    char               **argv;
-
-    match = SUB_DEFAULT;
-    if (ME.Patterns) {
-       for (argv = ME.Patterns; (pat = *argv++) != NULL; ) {
-           subvalue = *pat != SUB_NEGATE && *pat != SUB_POISON;
-           if (!subvalue)
-               pat++;
-           if ((match != subvalue) && uwildmat(name, pat))
-               match = subvalue;
-       }
-    }
-    for (argv = sp->Patterns; (pat = *argv++) != NULL; ) {
-       subvalue = *pat != SUB_NEGATE && *pat != SUB_POISON;
-       if (!subvalue)
-           pat++;
-       if ((match != subvalue) && uwildmat(name, pat))
-           match = subvalue;
-    }
-    return match;
-}
-
-
-/*
-**  Run down the site's pattern list and see if specified newsgroup is
-**  considered poison.
-*/
-bool
-SITEpoisongroup(SITE *sp, char *name)
-{
-    bool               match;
-    bool               poisonvalue;
-    char               *pat;
-    char               **argv;
-
-    match = SUB_DEFAULT;
-    if (ME.Patterns) {
-       for (argv = ME.Patterns; (pat = *argv++) != NULL; ) {
-           poisonvalue = *pat == SUB_POISON;
-           if (*pat == SUB_NEGATE || *pat == SUB_POISON)
-               pat++;
-           if (uwildmat(name, pat))
-               match = poisonvalue;
-       }
-    }
-    for (argv = sp->Patterns; (pat = *argv++) != NULL; ) {
-       poisonvalue = *pat == SUB_POISON;
-       if (*pat == SUB_NEGATE || *pat == SUB_POISON)
-           pat++;
-       if (uwildmat(name, pat))
-           match = poisonvalue;
-    }
-    return match;
-}
-
-
-/*
-**  Find a site.
-*/
-SITE *
-SITEfind(const char *p)
-{
-    int                        i;
-    SITE               *sp;
-
-    for (i = nSites, sp = Sites; --i >= 0; sp++)
-       if (sp->Name && strcasecmp(p, sp->Name) == 0)
-           return sp;
-    return NULL;
-}
-
-
-/*
-**  Find the next site that matches this site.
-*/
-SITE *
-SITEfindnext(const char *p, SITE *sp)
-{
-    SITE               *end;
-
-    for (sp++, end = &Sites[nSites]; sp < end; sp++)
-       if (sp->Name && strcasecmp(p, sp->Name) == 0)
-           return sp;
-    return NULL;
-}
-
-
-/*
-**  Close a site down.
-*/
-void
-SITEfree(SITE *sp)
-{
-    SITE                *s;
-    HASHFEEDLIST       *hf, *hn;
-    int                 new;
-    int                 i;
-    
-    if (sp->Channel) {
-       CHANclose(sp->Channel, CHANname(sp->Channel));
-       sp->Channel = NULL;
-    }
-
-    SITEunlink(sp);
-
-    sp->Name = NULL;
-    if (sp->Process > 0) {
-       /* Kill the backpointer so PROCdied won't call us. */
-       PROCunwatch(sp->Process);
-       sp->Process = -1;
-    }
-    if (sp->Entry) {
-       free(sp->Entry);
-       sp->Entry = NULL;
-    }
-    if (sp->Originator) {
-       free(sp->Originator);
-       sp->Originator = NULL;
-    }
-    if (sp->Param) {
-       free(sp->Param);
-       sp->Param = NULL;
-    }
-    if (sp->SpoolName) {
-       free(sp->SpoolName);
-       sp->SpoolName = NULL;
-    }
-    if (sp->Patterns) {
-       free(sp->Patterns);
-       sp->Patterns = NULL;
-    }
-    if (sp->Exclusions) {
-       free(sp->Exclusions);
-       sp->Exclusions = NULL;
-    }
-    if (sp->Distributions) {
-       free(sp->Distributions);
-       sp->Distributions = NULL;
-    }
-    if (sp->Buffer.data) {
-       free(sp->Buffer.data);
-       sp->Buffer.data = NULL;
-       sp->Buffer.size = 0;
-    }
-    if (sp->FNLnames.data) {
-       free(sp->FNLnames.data);
-       sp->FNLnames.data = NULL;
-       sp->FNLnames.size = 0;
-    }
-    if (sp->HashFeedList) {
-       for (hf = sp->HashFeedList; hf; hf = hn) {
-           hn = hf->next;
-           free(hf);
-       }
-       sp->HashFeedList = NULL;
-    }
-
-    /* If this site was a master, find a new one. */
-    if (sp->IsMaster) {
-       for (new = NOSITE, s = Sites, i = nSites; --i >= 0; s++)
-           if (&Sites[s->Master] == sp) {
-               if (new == NOSITE) {
-                   s->Master = NOSITE;
-                   s->IsMaster = true;
-                   new = s - Sites;
-               }
-               else
-                   s->Master = new;
-            }
-       sp->IsMaster = false;
-    }
-}
-
-
-/*
-**  If a site is an exploder or funnels into one, forward a command
-**  to it.
-*/
-void
-SITEforward(SITE *sp, const char *text)
-{
-    SITE               *fsp;
-    char               buff[SMBUF];
-
-    fsp = sp;
-    if (fsp->Funnel != NOSITE)
-       fsp = &Sites[fsp->Funnel];
-    if (sp->Name == NULL || fsp->Name == NULL)
-       return;
-    if (fsp->Type == FTexploder) {
-       strlcpy(buff, text, sizeof(buff));
-       if (fsp != sp && fsp->FNLwantsnames) {
-            strlcat(buff, " ", sizeof(buff));
-            strlcat(buff, sp->Name, sizeof(buff));
-       }
-       SITEwrite(fsp, buff);
-    }
-}
-
-
-/*
-**  Drop a site.
-*/
-void
-SITEdrop(SITE *sp)
-{
-    SITEforward(sp, "drop");
-    SITEflush(sp, false);
-    SITEfree(sp);
-}
-
-
-/*
-**  Append info about the current state of the site to the buffer
-*/
-void
-SITEinfo(struct buffer *bp, SITE *sp, const bool Verbose)
-{
-    static char                FREESITE[] = "<<No name>>\n\n";
-    char               *p;
-    CHANNEL            *cp;
-    const char         *sep;
-    char               buff[BUFSIZ];
-
-    if (sp->Name == NULL) {
-       buffer_append(bp, FREESITE, strlen(FREESITE));
-       return;
-    }
-
-    p = buff;
-    snprintf(buff, sizeof(buff), "%s%s:\t", sp->Name,
-             sp->IsMaster ? "(*)" : "");
-    p += strlen(p);
-
-    if (sp->Type == FTfunnel) {
-       sp = &Sites[sp->Funnel];
-       sprintf(p, "funnel -> %s: ", sp->Name);
-       p += strlen(p);
-    }
-
-    switch (sp->Type) {
-    default:
-       sprintf(p, "unknown feed type %d", sp->Type);
-       p += strlen(p);
-       break;
-    case FTerror:
-    case FTfile:
-       p += strlen(strcpy(p, "file"));
-       if (sp->Buffered) {
-           sprintf(p, " buffered(%lu)", (unsigned long) sp->Buffer.left);
-           p += strlen(p);
-       }
-       else if ((cp = sp->Channel) == NULL)
-           p += strlen(strcpy(p, " no channel?"));
-       else {
-           sprintf(p, " open fd=%d, in mem %lu", cp->fd,
-                    (unsigned long) cp->Out.left);
-           p += strlen(p);
-       }
-       break;
-    case FTchannel:
-       p += strlen(strcpy(p, "channel"));
-       goto Common;
-    case FTexploder:
-       p += strlen(strcpy(p, "exploder"));
-Common:
-       if (sp->Process >= 0) {
-           sprintf(p, " pid=%ld", (long) sp->pid);
-           p += strlen(p);
-       }
-       if (sp->Spooling)
-           p += strlen(strcpy(p, " spooling"));
-       if ((cp = sp->Channel) == NULL)
-           p += strlen(strcpy(p, " no channel?"));
-       else {
-           sprintf(p, " fd=%d, in mem %lu", cp->fd,
-                    (unsigned long) cp->Out.left);
-           p += strlen(p);
-       }
-       break;
-    case FTfunnel:
-       p += strlen(strcpy(p, "recursive funnel"));
-       break;
-    case FTlogonly:
-       p += strlen(strcpy(p, "log only"));
-       break;
-    case FTprogram:
-       p += strlen(strcpy(p, "program"));
-       if (sp->FNLwantsnames)
-           p += strlen(strcpy(p, " with names"));
-       break;
-    }
-    *p++ = '\n';
-    if (Verbose) {
-       sep = "\t";
-       if (sp->Buffered && sp->Flushpoint) {
-           sprintf(p, "%sFlush @ %ld", sep, sp->Flushpoint);
-           p += strlen(p);
-           sep = "; ";
-       }
-       if (sp->StartWriting || sp->StopWriting) {
-           sprintf(p, "%sWrite [%ld..%ld]", sep,
-               sp->StopWriting, sp->StartWriting);
-           p += strlen(p);
-           sep = "; ";
-       }
-       if (sp->StartSpooling) {
-           sprintf(p, "%sSpool @ %ld", sep, sp->StartSpooling);
-           p += strlen(p);
-           sep = "; ";
-       }
-       if (sep[0] != '\t')
-           *p++ = '\n';
-       if (sp->Spooling && sp->SpoolName) {
-           sprintf(p, "\tSpooling to \"%s\"\n", sp->SpoolName);
-           p += strlen(p);
-       }
-       if ((cp = sp->Channel) != NULL) {
-           sprintf(p, "\tChannel created %.12s",
-               ctime(&cp->Started) + 4);
-           p += strlen(p);
-           sprintf(p, ", last active %.12s\n",
-               ctime(&cp->LastActive) + 4);
-           p += strlen(p);
-           if (cp->Waketime > Now.time) {
-               sprintf(p, "\tSleeping until %.12s\n",
-                   ctime(&cp->Waketime) + 4);
-               p += strlen(p);
-           }
-       }
-
-    }
-    buffer_append(bp, buff, p - buff);
-}
diff --git a/innd/status.c b/innd/status.c
deleted file mode 100644 (file)
index e2040c1..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*  $Id: status.c 7547 2006-08-26 06:18:14Z eagle $
-**
-**  Periodic status reporting.
-*/
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-#include "innperl.h"
-
-#define MIN_REFRESH   60  /* 1 min */
-#define HTML_STATUS
-#if defined(HTML_STATUS)
-#define STATUS_FILE    "inn_status.html"       /* will be in pathhttp */
-#else
-#define STATUS_FILE    "inn.status"            /* will be in pathlog */
-#endif
-
-typedef struct _STATUS {
-    char               name[SMBUF];
-    char               ip_addr[64];
-    bool               can_stream;
-    unsigned short     activeCxn;
-    unsigned short     sleepingCxns;
-    time_t             seconds;
-    unsigned long      accepted;
-    unsigned long      refused;
-    unsigned long      rejected;
-    unsigned long      Duplicate;
-    unsigned long      Unwanted_u;
-    unsigned long      Unwanted_d;
-    unsigned long      Unwanted_g;
-    unsigned long      Unwanted_s;
-    unsigned long      Unwanted_f;
-    float              Size;
-    float              DuplicateSize;
-    unsigned long      Check;
-    unsigned long      Check_send;
-    unsigned long      Check_deferred;
-    unsigned long      Check_got;
-    unsigned long      Check_cybercan;
-    unsigned long      Takethis;
-    unsigned long      Takethis_Ok;
-    unsigned long      Takethis_Err;
-    unsigned long      Ihave;
-    unsigned long      Ihave_Duplicate;
-    unsigned long      Ihave_Deferred;
-    unsigned long      Ihave_SendIt;
-    unsigned long      Ihave_Cybercan;
-    struct _STATUS *next;
-} STATUS;
-
-static unsigned STATUSlast_time;
-char            start_time[50];
-
-static unsigned
-STATUSgettime(void)
-{
-  static int           init = 0;
-  static struct timeval        start_tv;
-  struct timeval       tv;
-  
-  if (!init) {
-    gettimeofday(&start_tv, NULL);
-    init++;
-  }
-  gettimeofday(&tv, NULL);
-  return((tv.tv_sec - start_tv.tv_sec) * 1000 +
-        (tv.tv_usec - start_tv.tv_usec) / 1000);
-}
-
-void
-STATUSinit(void)
-{
-  time_t now;
-  
-  STATUSlast_time = STATUSgettime();   /* First invocation */
-  now = time (NULL) ;
-  strlcpy(start_time, ctime(&now), sizeof(start_time));
-}
-
-static char *
-PrettySize(float size, char *str)
-{
-  if (size > 1073741824) /* 1024*1024*1024 */
-    sprintf (str, "%.1fGb", size / 1073741824.);
-  else
-    if (size > 1048576) /* 1024*1024 */
-      sprintf (str, "%.1fMb", size / 1048576.);
-    else
-      sprintf (str, "%.1fkb", size / 1024.);
-  return (str);
-}
-
-static void
-STATUSsummary(void)
-{
-  FILE                 *F;
-  int                  i, j;
-  CHANNEL               *cp;
-  int                  activeCxn = 0;
-  int                  sleepingCxns = 0;
-  time_t               seconds = 0;
-  unsigned long                duplicate = 0;
-  unsigned long                offered;
-  unsigned long                accepted = 0;
-  unsigned long                refused = 0;
-  unsigned long                rejected = 0;
-  float                        size = 0;
-  float                        DuplicateSize = 0;
-  int                  peers = 0;
-  char                  TempString[SMBUF];
-  char                 *path;
-  STATUS               *head, *status, *tmp;
-  char                 str[9];
-  time_t               now;
-#if defined(HTML_STATUS)
-  path = concatpath(innconf->pathhttp, STATUS_FILE);
-#else
-  path = concatpath(innconf->pathlog, STATUS_FILE);
-#endif
-  if ((F = Fopen(path, "w", TEMPORARYOPEN)) == NULL) {
-    syslog(L_ERROR, "%s cannot open %s: %m", LogName, path);
-    return;
-  }
-
-#if defined(HTML_STATUS)
-  /* HTML Header */
-
-  fprintf (F,"<HTML>\n<HEAD>\n<META HTTP-EQUIV=\"Refresh\" CONTENT=\"%ld;\">\n",
-          innconf->status < MIN_REFRESH ? MIN_REFRESH : innconf->status);
-  fprintf (F, "<TITLE>%s: incoming feeds</TITLE>\n", innconf->pathhost);
-  fprintf (F, "</HEAD>\n<BODY>\n<PRE>\n") ;
-#endif /* defined(HTML_STATUS) */
-
-  fprintf (F, "%s\n", inn_version_string);
-  fprintf (F, "pid %d started %s\n", (int) getpid(), start_time);
-
-  tmp = head = NULL;
-  for (i = 0; (cp = CHANiter(&i, CTnntp)) != NULL; ) {
-    j = 0;
-    strlcpy(TempString,
-           cp->Address.ss_family == 0 ? "localhost" : RChostname(cp),
-            sizeof(TempString));
-    for (status = head ; status != NULL ; status = status->next) {
-       if (strcmp(TempString, status->name) == 0)
-           break;
-    }
-    if (status == NULL) {
-      status = xmalloc(sizeof(STATUS));
-      peers++;                                              /* a new peer */
-      strlcpy(status->name, TempString, sizeof(status->name));
-      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 =
-       status->Ihave_Deferred = status->Ihave_SendIt =
-       status->Ihave_Cybercan = 0;
-      status->Check = status->Check_send = 
-       status->Check_deferred = status->Check_got =
-       status->Check_cybercan = 0;
-      status->Takethis = status->Takethis_Ok = status->Takethis_Err = 0;
-      status->activeCxn = status->sleepingCxns = 0;
-      status->accepted = 0;
-      status->refused = status->rejected = 0;
-      status->Duplicate = status->Unwanted_u = 0;
-      status->Unwanted_d = status->Unwanted_g = 0;
-      status->Unwanted_s = status->Unwanted_f = 0;
-      status->next = NULL;
-      if (head == NULL)
-       head = status;
-      else
-       tmp->next = status;
-      tmp = status;
-    }
-    if (Now.time - cp->Started > status->seconds)
-      status->seconds = Now.time - cp->Started;
-    if (Now.time - cp->Started > seconds)
-      seconds = Now.time - cp->Started;
-    status->accepted += cp->Received;
-    accepted += cp->Received;
-    status->refused += cp->Refused;
-    refused += cp->Refused;
-    status->rejected += cp->Rejected;
-    rejected += cp->Rejected;
-    status->Duplicate += cp->Duplicate;
-    duplicate += cp->Duplicate;
-    status->Unwanted_u += cp->Unwanted_u;
-    status->Unwanted_d += cp->Unwanted_d;
-    status->Unwanted_g += cp->Unwanted_g;
-    status->Unwanted_s += cp->Unwanted_s;
-    status->Unwanted_f += cp->Unwanted_f;
-    status->Ihave += cp->Ihave;
-    status->Ihave_Duplicate += cp->Ihave_Duplicate;
-    status->Ihave_Deferred += cp->Ihave_Deferred;
-    status->Ihave_SendIt += cp->Ihave_SendIt;
-    status->Ihave_Cybercan += cp->Ihave_Cybercan;
-    status->Check += cp->Check;
-    status->Check_send += cp->Check_send;
-    status->Check_deferred += cp->Check_deferred;
-    status->Check_got += cp->Check_got;
-    status->Check_cybercan += cp->Check_cybercan;
-    status->Takethis += cp->Takethis;
-    status->Takethis_Ok += cp->Takethis_Ok;
-    status->Takethis_Err += cp->Takethis_Err;
-    status->Size += cp->Size;
-    status->DuplicateSize += cp->DuplicateSize;
-    size += cp->Size;
-    DuplicateSize += cp->DuplicateSize;
-    if (CHANsleeping(cp)) {
-      sleepingCxns++;
-      status->sleepingCxns++;
-    } else {
-      activeCxn++;
-      status->activeCxn++;
-    }
-  }
-
-  /* Header */
-  now = time (NULL);
-  strlcpy (TempString, ctime (&now), sizeof(TempString));
-  fprintf (F, "Updated: %s", TempString);
-  fprintf (F, "(peers: %d, active-cxns: %d, sleeping-cxns: %d)\n\n",
-          peers, activeCxn, sleepingCxns);
-
-  fprintf (F, "Mode: %s", Mode == OMrunning ? "running" :
-          Mode == OMpaused ? "paused" :
-          Mode == OMthrottled ? "throttled" : "Unknown");
-  if ((Mode == OMpaused) || (Mode == OMthrottled))
-    fprintf (F, " (%s)", ModeReason);
-  
-  /* Global configuration */
-  fprintf (F, "\n\nConfiguration file: %s\n\n", _PATH_CONFIG);
-
-  fprintf (F, "Global configuration parameters:\n");
-  fprintf (F, "              Largest Article: %ld bytes\n", innconf->maxartsize);
-  fprintf (F, "     Max Incoming connections: ");
-  if (innconf->maxconnections)
-    fprintf (F, "%ld\n", innconf->maxconnections);
-  else
-    fprintf (F, "unlimited\n");
-  fprintf (F, "      Max Outgoing file feeds: %d\n", MaxOutgoing);
-  fprintf (F, "                       Cutoff: ");
-  if (innconf->artcutoff)
-    fprintf (F, "%ld days\n", innconf->artcutoff);
-  else
-    fprintf (F, "none\n");
-  fprintf (F, "               Timeout period: %ld seconds\n",
-          (long)TimeOut.tv_sec);
-  if (innconf->remembertrash) {
-       fprintf (F, "               Remember Trash: Yes\n");
-  } else {
-       fprintf (F, "               Remember Trash: No\n");
-  }
-#if defined(DO_TCL)
-  fprintf (F, "                Tcl filtering: %s\n", 
-          TCLFilterActive ? "enabled" : "disabled");
-#endif /* defined(DO_TCL) */
-#if defined(DO_PERL)
-  fprintf (F, "               Perl filtering: %s\n", 
-          PerlFilterActive ? "enabled" : "disabled");
-#endif /* defined(DO_PERL) */
-
-  fputc ('\n', F) ;
-
-  /* Global values */
-  fprintf (F, "global (process)\n");
-  fprintf (F, "         seconds: %ld\n", (long) seconds);
-  offered = accepted + refused + rejected;
-  fprintf (F, "         offered: %-9ld\n", offered);
-  if (!offered) offered = 1; /* to avoid division by zero */
-  if (!size) size = 1; /* avoid divide by zero here too */
-  fprintf (F, "        accepted: %-9ld       %%accepted: %.1f%%\n",
-          accepted, (float) accepted / offered * 100);
-  fprintf (F, "         refused: %-9ld        %%refused: %.1f%%\n",
-          refused, (float) refused / offered * 100);
-  fprintf (F, "        rejected: %-9ld       %%rejected: %.1f%%\n",
-          rejected, (float) rejected / offered * 100);
-  fprintf (F, "      duplicated: %-9ld     %%duplicated: %.1f%%\n",
-          duplicate, (float) duplicate / offered * 100);
-  fprintf (F, "           bytes: %-7s\n", PrettySize (size + DuplicateSize, str));
-  fprintf (F, " duplicated size: %-7s  %%duplicated size: %.1f%%\n",
-          PrettySize(DuplicateSize, str), (float) DuplicateSize / size * 100);
-  fputc ('\n', F) ;
-  
-  /* Incoming Feeds */
-  for (status = head ; status != NULL ;) {
-    fprintf (F, "%s\n",                      status->name);
-    fprintf (F, "    seconds: %-7ld  ",      (long) status->seconds);
-    fprintf (F, "      duplicates: %-7ld ",  status->Duplicate);
-    fprintf (F, "    ip address: %s\n",      status->ip_addr);
-    fprintf (F, "    offered: %-7ld  ",
-            status->accepted + status->refused + status->rejected);
-    fprintf (F, "   uw newsgroups: %-7ld ",  status->Unwanted_g);
-    fprintf (F, "   active cxns: %d\n",      status->activeCxn);
-    fprintf (F, "   accepted: %-7ld  ",      status->accepted);
-    fprintf (F, "uw distributions: %-7ld ",  status->Unwanted_d);
-    fprintf (F, " sleeping cxns: %d\n",      status->sleepingCxns);
-    fprintf (F, "    refused: %-7ld  ",      status->refused);
-    fprintf (F, "      unapproved: %-7ld ",  status->Unwanted_u);
-    fprintf (F, "want streaming: %s\n",
-            status->can_stream ? "Yes" : "No");
-    fprintf (F, "   rejected: %-7ld  ",      status->rejected);
-    fprintf (F, "        filtered: %-7ld ",  status->Unwanted_f);
-    fprintf (F, "  is streaming: %s\n",
-            (status->Check || status->Takethis) ? "Yes" : "No");
-    fprintf (F, "       size: %-8s ",        PrettySize(status->Size, str));
-    fprintf (F, "       bad sites: %-7ld ", status->Unwanted_s);
-    fprintf (F, "duplicate size: %s\n", PrettySize(status->DuplicateSize, str));
-    fprintf (F, "  Protocol:\n");
-    fprintf (F, "      Ihave: %-6ld SendIt[%d]: %-6ld    Got[%d]: %-6ld Deferred[%d]: %ld\n",
-            status->Ihave, NNTP_SENDIT_VAL, status->Ihave_SendIt,
-            NNTP_HAVEIT_VAL, status->Ihave_Duplicate, NNTP_RESENDIT_VAL,
-            status->Ihave_Deferred);
-    fprintf (F, "      Check: %-6ld SendIt[%d]: %-6ld    Got[%d]: %-6ld Deferred[%d]: %ld\n",
-            status->Check, NNTP_OK_SENDID_VAL, status->Check_send,
-            NNTP_ERR_GOTID_VAL, status->Check_got, NNTP_RESENDID_VAL,
-            status->Check_deferred);
-    fprintf (F, "   Takethis: %-6ld     Ok[%d]: %-6ld  Error[%d]: %-6ld\n",
-            status->Takethis, NNTP_OK_RECID_VAL, status->Takethis_Ok,
-            NNTP_ERR_FAILID_VAL, status->Takethis_Err);
-    if (innconf->refusecybercancels) {
-        fprintf (F, "   Cancelrejects:    Ihave[%d]: %-6ld  Check[%d]: %-6ld\n",
-            NNTP_HAVEIT_VAL, status->Ihave_Cybercan,
-            NNTP_ERR_GOTID_VAL, status->Check_cybercan);
-    }
-    fputc ('\n', F) ;
-    tmp = status->next;
-    free(status);
-    status = tmp;
-  }
-
-#if defined(HTML_STATUS)
-  /* HTML Footer */
-  fprintf (F,"</PRE>\n</BODY>\n</HTML>\n");
-#endif /* defined(HTML_STATUS) */
-
-  Fclose(F);
-}
-
-void
-STATUSmainloophook(void)
-{
-  unsigned now;
-    
-  if (!innconf->status)
-    return;
-  now = STATUSgettime();
-  
-  if (now - STATUSlast_time > (unsigned)(innconf->status * 1000)) {
-    STATUSsummary();
-    STATUSlast_time = now;
-  }
-}
diff --git a/innd/tcl.c b/innd/tcl.c
deleted file mode 100644 (file)
index d1c8163..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*  $Id: tcl.c 6124 2003-01-14 06:03:29Z rra $
-**
-**  Support for TCL things
-**
-**  By Bob Heiney, Network Systems Laboratory, Digital Equipment Corporation
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-#if     defined(DO_TCL)
-
-Tcl_Interp       *TCLInterpreter;
-bool             TCLFilterActive;
-struct buffer    *TCLCurrArticle;
-ARTDATA          *TCLCurrData;
-
-static char      *TCLSTARTUP = NULL;
-static char      *TCLFILTER = NULL;
-
-
-void
-TCLfilter(value)
-    bool value;
-{
-    TCLFilterActive=value;
-
-    syslog(L_NOTICE, "%s tcl filtering %s", LogName,
-          TCLFilterActive ? "enabled" : "disabled");
-}
-
-
-void
-TCLreadfilter(void)
-{
-    int code;
-    
-    /* do before reload callback */
-    code = Tcl_Eval(TCLInterpreter, "filter_before_reload");
-    if (code != TCL_OK) {
-       if (strcmp(TCLInterpreter->result,
-                  "invalid command name: \"filter_before_reload\"")!=0)
-           syslog(L_ERROR, "%s Tcl filter_before_reload failed: %s",
-                  LogName, TCLInterpreter->result);
-    }
-
-    /* read the filter file */
-    if (TCLFILTER == NULL)
-       TCLFILTER = concatpath(innconf->pathfilter, _PATH_TCL_FILTER);
-    code = Tcl_EvalFile(TCLInterpreter, TCLFILTER);
-    if (code != TCL_OK) {
-       syslog(L_ERROR, "%s cant evaluate Tcl filter file: %s", LogName,
-              TCLInterpreter->result);
-       TCLfilter(false);
-    }
-
-    /* do the after callback, discarding any errors */
-    code = Tcl_Eval(TCLInterpreter, "filter_after_reload");
-    if (code != TCL_OK) {
-       if (strcmp(TCLInterpreter->result,
-                  "invalid command name: \"filter_after_reload\"")!=0)
-           syslog(L_ERROR, "%s Tcl filter_after_reload failed: %s",
-                  LogName, TCLInterpreter->result);
-    }
-}
-
-
-/* makeCheckSum
- *
- * Compute a checksum. This function does a one's-complement addition
- * of a series of 32-bit words. "buflen" is in bytes, not words. This is 
- * hard because the number of bits with which our machine can do arithmetic
- * is the same as the size of the checksum being created, but our hardware
- * is 2's-complement and C has no way to check for integer overflow.
- *
- * Note that the checksum is returned in network byte order and not host
- * byte order; this makes it suitable for putting into packets and for
- * comparing with what is found in packets.
- */
-
-static uint32_t
-makechecksum(u_char *sumbuf, int buflen)
-{
-    u_char *buf = (u_char *)sumbuf;
-    int32_t len = buflen;
-    int32_t sum;
-    uint32_t bwordl,bwordr,bword,suml,sumr;
-    int rmdr;
-    u_char tbuf[4];
-    u_char *ptbuf;
-
-    suml = 0; sumr = 0;
-
-    len = len/4;
-    rmdr = buflen - 4*len;
-
-    while (len-- > 0) {
-       bwordr = (buf[3] & 0xFF)
-           + ((buf[2] & 0xFF) << 8);
-       bwordl = (buf[1] & 0xFF)
-           + ((buf[0] & 0xFF) << 8);
-       bword = ( bwordl << 16) | bwordr;
-       bword = ntohl(bword);
-       bwordl = (bword >> 16) & 0xFFFF;
-       bwordr = bword & 0xFFFF;
-       sumr += bwordr;
-       if (sumr & ~0xFFFF) {
-           sumr &= 0xFFFF;
-           suml++;
-       }
-       suml += bwordl;
-       if (suml & ~0xFFFF) {
-           suml &= 0xFFFF;
-           sumr++;
-       }
-       buf += 4;
-    }
-    /* if buffer size was not an even multiple of 4 bytes,
-       we have work to do */
-    if (rmdr > 0) {
-       tbuf[3] = 0; tbuf[2] = 0; tbuf[1] = 0;
-       /* tbuf[0] will always be copied into, and tbuf[3] will
-        * always be zero (else this would not be a remainder)
-        */
-       ptbuf = tbuf;
-       while (rmdr--) *ptbuf++ = *buf++;
-       bwordr = (tbuf[3] & 0xFF)
-           + ((tbuf[2] & 0xFF) << 8);
-       bwordl = (tbuf[1] & 0xFF)
-           + ((tbuf[0] & 0xFF) << 8);
-       bword = ( bwordl << 16) | bwordr;
-       bword = ntohl(bword);
-       bwordl = (bword >> 16) & 0xFFFF;
-       bwordr = bword & 0xFFFF;
-       sumr += bwordr;
-       if (sumr & ~0xFFFF) {
-           sumr &= 0xFFFF;
-           suml++;
-       }
-       suml += bwordl;
-       if (suml & ~0xFFFF) {
-           suml &= 0xFFFF;
-           sumr++;
-       }
-    }
-    sum = htonl( (suml << 16) | sumr);
-    return (~sum);
-}
-
-
-int
-TCLCksumArt(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
-{
-    char buf[100];
-
-    snprintf(buf, sizeof(buf), "%08x",
-             makechecksum(TCLCurrArticle->data + TCLCurrData->Body,
-                          TCLCurrData->Body));
-    Tcl_SetResult(interp, buf, TCL_VOLATILE);
-    return TCL_OK;
-}
-
-
-void
-TCLsetup(void)
-{
-    int code;
-    
-    TCLInterpreter = Tcl_CreateInterp();
-    if (TCLSTARTUP == NULL)
-       TCLSTARTUP = concatpath(innconf->pathfilter, _PATH_TCL_STARTUP);
-    code = Tcl_EvalFile(TCLInterpreter, TCLSTARTUP);
-    if (code != TCL_OK) {
-       syslog(L_FATAL, "%s cant read Tcl startup file: %s", LogName,
-              TCLInterpreter->result);
-       exit(1);
-    }
-
-    Tcl_CreateCommand(TCLInterpreter, "checksum_article", TCLCksumArt,
-                     NULL, NULL);
-
-    TCLfilter(true);
-    TCLreadfilter();
-}
-
-
-void
-TCLclose(void)
-{
-}
-
-
-#endif /* defined(DO_TCL) */
diff --git a/innd/util.c b/innd/util.c
deleted file mode 100644 (file)
index e0b3b3f..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*  $Id: util.c 6138 2003-01-19 04:13:51Z rra $
-**
-**  Various miscellaneous utility functions for innd internal use.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "libinn.h"
-
-#include "innd.h"
-
-/*
-**  Sprintf a long into a buffer with enough leading zero's so that it
-**  takes up width characters.  Don't add trailing NUL.  Return true
-**  if it fit.  Used for updating high-water marks in the active file
-**  in-place.
-*/
-bool
-FormatLong(char *p, unsigned long value, int width)
-{
-    for (p += width - 1; width-- > 0; ) {
-        *p-- = (int)(value % 10) + '0';
-        value /= 10;
-    }
-    return value == 0;
-}
-
-
-/*
-**  Glue a string, a char, and a string together.  Useful for making
-**  filenames.
-*/
-void
-FileGlue(char *p, const char *n1, char c,
-         const char *n2)
-{
-    p += strlen(strcpy(p, n1));
-    *p++ = c;
-    strcpy(p, n2);
-}
-
-
-/*
-**  Turn any \r or \n in text into spaces.  Used to splice back multi-line
-**  headers into a single line.
-*/
-static char *
-Join(char *text)
-{
-    char       *p;
-
-    for (p = text; *p; p++)
-        if (*p == '\n' || *p == '\r')
-            *p = ' ';
-    return text;
-}
-
-
-/*
-**  Return a short name that won't overrun our bufer or syslog's buffer.
-**  q should either be p, or point into p where the "interesting" part is.
-*/
-char *
-MaxLength(const char *p, const char *q)
-{
-    static char buff[80];
-    unsigned int i;
-
-    /* Already short enough? */
-    i = strlen(p);
-    if (i < sizeof buff - 1) {
-        strlcpy(buff, p, sizeof(buff));
-        return Join(buff);
-    }
-
-    /* Simple case of just want the begining? */
-    if ((unsigned)(q - p) < sizeof buff - 4) {
-        strlcpy(buff, p, sizeof(buff) - 3);
-        strlcat(buff, "...", sizeof(buff));
-    }
-    /* Is getting last 10 characters good enough? */
-    else if ((p + i) - q < 10) {
-        strlcpy(buff, p, sizeof(buff) - 13);
-        strlcat(buff, "...", sizeof(buff) - 10);
-        strlcat(buff, &p[i - 10], sizeof(buff));
-    }
-    else {
-        /* Not in last 10 bytes, so use double elipses. */
-        strlcpy(buff, p, sizeof(buff) - 16);
-        strlcat(buff, "...", sizeof(buff) - 13);
-        strlcat(buff, &q[-5], sizeof(buff) - 3);
-        strlcat(buff, "...", sizeof(buff));
-    }
-    return Join(buff);
-}
-
-
-/*
-**  Split text into comma-separated fields.  Return an allocated
-**  NULL-terminated array of the fields within the modified argument that
-**  the caller is expected to save or free.  We don't use strchr() since
-**  the text is expected to be either relatively short or "comma-dense."
-*/
-char **
-CommaSplit(char *text)
-{
-    int i;
-    char *p;
-    char **av;
-    char **save;
-
-    /* How much space do we need? */
-    for (i = 2, p = text; *p; p++)
-        if (*p == ',')
-            i++;
-
-    for (av = save = xmalloc(i * sizeof(char *)), *av++ = p = text; *p; )
-        if (*p == ',') {
-            *p++ = '\0';
-            *av++ = p;
-        }
-        else
-            p++;
-    *av = NULL;
-    return save;
-}
-
-
-/*
-**  Set up LISTBUFFER so that data will be put into array
-**  it allocates buffer and array for data if needed, otherwise use already
-**  allocated one
-*/
-void
-SetupListBuffer(int size, LISTBUFFER *list)
-{
-  /* get space for data to be splitted */
-  if (list->Data == NULL) {
-    list->DataLength = size;
-    list->Data = xmalloc(list->DataLength + 1);
-  } else if (list->DataLength < size) {
-    list->DataLength = size;
-    list->Data = xrealloc(list->Data, list->DataLength + 1);
-  }
-  /* get an array of character pointers. */
-  if (list->List == NULL) {
-    list->ListLength = DEFAULTNGBOXSIZE;
-    list->List = xmalloc(list->ListLength * sizeof(char *));
-  }
-}
-
-
-/*
-**  Do we need a shell for the command?  If not, av is filled in with
-**  the individual words of the command and the command is modified to
-**  have NUL's inserted.
-*/
-bool
-NeedShell(char *p, const char **av, const char **end)
-{
-    static const char Metachars[] = ";<>|*?[]{}()#$&=`'\"\\~\n";
-    const char *q;
-
-    /* We don't use execvp(); works for users, fails out of /etc/rc. */
-    if (*p != '/')
-        return true;
-    for (q = p; *q; q++)
-        if (strchr(Metachars, *q) != NULL)
-            return true;
-
-    for (end--; av < end; ) {
-        /* Mark this word, check for shell meta-characters. */
-        for (*av++ = p; *p && !ISWHITE(*p); p++)
-            continue;
-
-        /* If end of list, we're done. */
-        if (*p == '\0') {
-            *av = NULL;
-            return false;
-        }
-
-        /* Skip whitespace, find next word. */
-        for (*p++ = '\0'; ISWHITE(*p); p++)
-            continue;
-        if (*p == '\0') {
-            *av = NULL;
-            return false;
-        }
-    }
-
-    /* Didn't fit. */
-    return true;
-}
-
-
-/*
-**  Spawn a process, with I/O redirected as needed.  Return the PID or -1
-**  (and a syslog'd message) on error.
-*/
-pid_t
-Spawn(int niceval, int fd0, int fd1, int fd2, char * const av[])
-{
-    static char NOCLOSE[] = "%s cant close %d in %s %m";
-    static char NODUP2[] = "%s cant dup2 %d to %d in %s %m";
-    pid_t       i;
-
-    /* Fork; on error, give up.  If not using the patched dbz, make
-     * this call fork! */
-    i = fork();
-    if (i == -1) {
-        syslog(L_ERROR, "%s cant fork %s %m", LogName, av[0]);
-        return -1;
-    }
-
-    /* If parent, do nothing. */
-    if (i > 0)
-        return i;
-
-    /* Child -- do any I/O redirection. */
-    if (fd0 != 0) {
-        if (dup2(fd0, 0) < 0) {
-            syslog(L_FATAL, NODUP2, LogName, fd0, 0, av[0]);
-            _exit(1);
-        }
-        if (fd0 != fd1 && fd0 != fd2 && close(fd0) < 0)
-            syslog(L_ERROR, NOCLOSE, LogName, fd0, av[0]);
-    }
-    if (fd1 != 1) {
-        if (dup2(fd1, 1) < 0) {
-            syslog(L_FATAL, NODUP2, LogName, fd1, 1, av[0]);
-            _exit(1);
-        }
-        if (fd1 != fd2 && close(fd1) < 0)
-            syslog(L_ERROR, NOCLOSE, LogName, fd1, av[0]);
-    }
-    if (fd2 != 2) {
-        if (dup2(fd2, 2) < 0) {
-            syslog(L_FATAL, NODUP2, LogName, fd2, 2, av[0]);
-            _exit(1);
-        }
-        if (close(fd2) < 0)
-            syslog(L_ERROR, NOCLOSE, LogName, fd2, av[0]);
-    }
-    close_on_exec(0, false);
-    close_on_exec(1, false);
-    close_on_exec(2, false);
-
-    /* Nice our child if we're supposed to. */
-    if (niceval != 0 && nice(niceval) == -1)
-        syslog(L_ERROR, "SERVER cant nice child to %d: %m", niceval);
-
-    /* Start the desired process (finally!). */
-    execv(av[0], av);
-    syslog(L_FATAL, "%s cant exec in %s %m", LogName, av[0]);
-    _exit(1);
-
-    /* Not reached. */
-    return -1;
-}
-
-/*
-**  We ran out of space or other I/O error, throttle ourselves.
-*/
-void
-ThrottleIOError(const char *when)
-{
-    char         buff[SMBUF];
-    const char * p;
-    int          oerrno;
-
-    if (Mode == OMrunning) {
-        oerrno = errno;
-        if (Reservation) {
-            free(Reservation);
-            Reservation = NULL;
-        }
-        snprintf(buff, sizeof(buff), "%s writing %s file -- throttling",
-                 strerror(oerrno), when);
-        if ((p = CCblock(OMthrottled, buff)) != NULL)
-            syslog(L_ERROR, "%s cant throttle %s", LogName, p);
-        syslog(L_FATAL, "%s throttle %s", LogName, buff);
-        errno = oerrno;
-        ThrottledbyIOError = true;
-    }
-}
-
-/*
-**  No matching storage.conf, throttle ourselves.
-*/
-void
-ThrottleNoMatchError(void)
-{
-    char buff[SMBUF];
-    const char *p;
-
-    if (Mode == OMrunning) {
-        if (Reservation) {
-            free(Reservation);
-            Reservation = NULL;
-        }
-        snprintf(buff, sizeof(buff), "%s storing article -- throttling",
-                 SMerrorstr);
-        if ((p = CCblock(OMthrottled, buff)) != NULL)
-            syslog(L_ERROR, "%s cant throttle %s", LogName, p);
-        syslog(L_FATAL, "%s throttle %s", LogName, buff);
-        ThrottledbyIOError = true;
-    }
-}
-
-void
-InndHisOpen(void)
-{
-    char *histpath;
-    int flags;
-    size_t synccount;
-
-    histpath = concatpath(innconf->pathdb, _PATH_HISTORY);
-    if (innconf->hismethod == NULL) {
-       sysdie("hismethod is not defined");
-       /*NOTREACHED*/
-    }
-
-    flags = HIS_RDWR | (INND_DBZINCORE ? HIS_MMAP : HIS_ONDISK);
-    History = HISopen(histpath, innconf->hismethod, flags);
-    if (!History) {
-       sysdie("SERVER can't open history %s", histpath);
-       /*NOTREACHED*/
-    }
-    free(histpath);
-    HISsetcache(History, 1024 * innconf->hiscachesize);
-    synccount = innconf->icdsynccount;
-    HISctl(History, HISCTLS_SYNCCOUNT, &synccount);
-}
-
-void
-InndHisClose(void)
-{
-    if (History == NULL)
-        return;
-    if (!HISclose(History)) {
-        char *histpath;
-
-       histpath = concatpath(innconf->pathdb, _PATH_HISTORY);
-       sysdie("SERVER can't close history %s", histpath);
-       free(histpath);
-    }  
-    History = NULL;
-}
-
-bool
-InndHisWrite(const char *key, time_t arrived, time_t posted, time_t expires,
-            TOKEN *token)
-{
-    bool r = HISwrite(History, key, arrived, posted, expires, token);
-
-    if (r != true)
-       IOError("history write", errno);
-    return r;
-}
-
-bool
-InndHisRemember(const char *key)
-{
-    bool r = HISremember(History, key, Now.time);
-
-    if (r != true)
-       IOError("history remember", errno);
-    return r;
-}
-
-void
-InndHisLogStats(void)
-{
-    struct histstats stats = HISstats(History);
-
-    syslog(L_NOTICE, "ME HISstats %d hitpos %d hitneg %d missed %d dne",
-          stats.hitpos, stats.hitneg, stats.misses, stats.dne);
-}
-
-
diff --git a/innd/wip.c b/innd/wip.c
deleted file mode 100644 (file)
index 7e8c8c4..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* $Id: wip.c 6124 2003-01-14 06:03:29Z rra $
-**
-** Routines for keeping track of incoming articles, articles that haven't
-** acked from a duplex channel feed, and history caching.
-**
-** WIP stands for work-in-progress
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "innd.h"
-
-#define WIPTABLESIZE        1024
-#define WIP_ARTMAX          300                /* innfeed default max send time */
-
-static WIP     *WIPtable[WIPTABLESIZE];      /* Top level of the WIP hash table */
-
-void
-WIPsetup(void)
-{
-    memset(WIPtable, '\0', sizeof(WIPtable));
-}
-
-/* Add a new entry into the table.  It is the appilications responsiblity to
-   to call WIPinprogress or WIPbyid first. */
-WIP *
-WIPnew(const char *messageid, CHANNEL *cp)
-{
-    HASH hash;
-    unsigned long bucket;
-    WIP *new;
-
-    hash = Hash(messageid, strlen(messageid));
-    memcpy(&bucket, &hash,
-          sizeof(bucket) < sizeof(hash) ? sizeof(bucket) : sizeof(hash));
-    bucket = bucket % WIPTABLESIZE;
-    
-    new = xmalloc(sizeof(WIP));
-    new->MessageID = hash;
-    new->Timestamp = Now.time;
-    new->Chan = cp;
-    /* Link the new entry into the list */
-    new->Next = WIPtable[bucket];
-    WIPtable[bucket] = new;
-    return new; 
-}
-
-void
-WIPprecomfree(CHANNEL *cp)
-{
-    WIP *cur;
-    int i;
-    if (cp == NULL)
-       return;
-
-    for (i = 0 ; i < PRECOMMITCACHESIZE ; i++) {
-       cur = cp->PrecommitWIP[i];
-       if (cur != (WIP *)NULL) {
-           WIPfree(cur);
-       }
-    }
-}
-
-void
-WIPfree(WIP *wp)
-{
-    unsigned long bucket;
-    WIP *cur;
-    WIP *prev = NULL;
-    int i;
-    /* This is good error checking, but also allows us to
-          WIPfree(WIPbymessageid(id))
-       without having to check if id exists first */
-    if (wp == NULL)
-       return;
-
-    memcpy(&bucket, &wp->MessageID,
-          sizeof(bucket) < sizeof(HASH) ? sizeof(bucket) : sizeof(HASH));
-    bucket = bucket % WIPTABLESIZE;
-
-    for (i = 0 ; i < PRECOMMITCACHESIZE ; i++) {
-       if (wp->Chan->PrecommitWIP[i] == wp) {
-           wp->Chan->PrecommitWIP[i] = (WIP *)NULL;
-           break;
-       }
-    }
-    for (cur = WIPtable[bucket]; (cur != NULL) && (cur != wp); prev = cur, cur = cur->Next);
-
-    if (cur == NULL)
-       return;
-
-    if (prev == NULL)
-       WIPtable[bucket] = cur->Next;
-    else
-       prev->Next = cur->Next;
-
-    /* unlink the entry and free the memory */
-    free(wp);
-}
-
-/* Check if the given messageid is being transfered on another channel.  If
-   Add is true then add the given message-id to the current channel */
-bool
-WIPinprogress(const char *msgid, CHANNEL *cp, bool Precommit)
-{
-    WIP *wp;
-    int i;
-    
-    if ((wp = WIPbyid(msgid)) != NULL) {
-       if(wp->Chan->ArtBeg == 0)
-           i = 0;
-       else {
-           i = wp->Chan->ArtMax;
-           if(i > WIP_ARTMAX)
-               i = WIP_ARTMAX;
-       }
-       if ((Now.time - wp->Timestamp) < (i + innconf->wipcheck))
-           return true;
-       if ((Now.time - wp->Timestamp) > (i + innconf->wipexpire)) {
-           for (i = 0 ; i < PRECOMMITCACHESIZE ; i++) {
-               if (wp->Chan->PrecommitWIP[i] == wp) {
-                   wp->Chan->PrecommitWIP[i] = (WIP *)NULL;
-                   break;
-               }
-           }
-           WIPfree(wp);
-           WIPinprogress(msgid, cp, Precommit);
-           return false;
-       }
-       if (wp->Chan == cp)
-           return true;
-       return false;
-    }
-    wp = WIPnew(msgid, cp);
-    if (Precommit) {
-       if (cp->PrecommitiCachenext == PRECOMMITCACHESIZE)
-           cp->PrecommitiCachenext = 0;
-       if (cp->PrecommitWIP[cp->PrecommitiCachenext])
-           WIPfree(cp->PrecommitWIP[cp->PrecommitiCachenext]);
-       cp->PrecommitWIP[cp->PrecommitiCachenext++] = wp;
-    } else {
-       WIPfree(WIPbyhash(cp->CurrentMessageIDHash));
-       cp->CurrentMessageIDHash = wp->MessageID;
-    }
-    return false;
-}
-
-WIP *
-WIPbyid(const char *messageid)
-{
-    HASH hash;
-    unsigned long bucket;
-    WIP *wp;
-
-    hash = Hash(messageid, strlen(messageid));
-    memcpy(&bucket, &hash,
-          sizeof(bucket) < sizeof(hash) ? sizeof(bucket) : sizeof(hash));
-    bucket = bucket % WIPTABLESIZE;
-    
-    /* Traverse the list until we find a match or find the head again */
-    for (wp = WIPtable[bucket]; wp != NULL; wp = wp->Next) 
-       if (!memcmp(&hash, &wp->MessageID, sizeof(HASH)))
-           return wp;
-
-    return NULL;
-}
-
-WIP *
-WIPbyhash(const HASH hash)
-{
-    unsigned long bucket;
-    WIP *wp;
-
-    memcpy(&bucket, &hash,
-          sizeof(bucket) < sizeof(hash) ? sizeof(bucket) : sizeof(hash));
-    bucket = bucket % WIPTABLESIZE;
-    
-    /* Traverse the list until we find a match or find the head again */
-    for (wp = WIPtable[bucket]; wp != NULL; wp = wp->Next) 
-       if (!memcmp(&hash, &wp->MessageID, sizeof(HASH)))
-           return wp;
-
-    return NULL;
-}
diff --git a/innfeed/Makefile b/innfeed/Makefile
deleted file mode 100644 (file)
index 032521f..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top            = ..
-CFLAGS         = $(GCFLAGS) $(SASLINC)
-
-ALL            = innfeed procbatch startinnfeed imapfeed
-
-SOURCES                = article.c buffer.c config_l.c config_y.c \
-                 endpoint.c host.c innlistener.c main.c misc.c \
-                 startinnfeed.c tape.c version.c
-
-INCLUDES       = article.h buffer.h configfile.h config_y.h connection.h \
-                 endpoint.h host.h innfeed.h innlistener.h misc.h tape.h
-
-# The objects linked into innfeed.  All SOURCES except startinnfeed.
-OBJECTS                = article.o buffer.o config_l.o config_y.o \
-                 endpoint.o host.o innlistener.o main.o misc.o tape.o \
-                 version.o
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPRI) innfeed $D$(PATHBIN)/innfeed
-       $(LI_XPRI) imapfeed $D$(PATHBIN)/imapfeed
-       $(CP_XPRI) procbatch $D$(PATHBIN)/procbatch
-       @ME=`$(WHOAMI)` ; \
-       if [ x"$$ME" = xroot ] ; then \
-           echo $(LI_SPRI) startinnfeed $D$(PATHBIN)/startinnfeed ; \
-           $(LI_SPRI) startinnfeed $D$(PATHBIN)/startinnfeed ; \
-       else \
-           echo $(LI_XPRI) startinnfeed $D$(PATHBIN)/startinnfeed ; \
-           $(LI_XPRI) startinnfeed $D$(PATHBIN)/startinnfeed ; \
-           echo '' ; \
-           echo '========================' ; \
-           echo 'NOTE NOTE NOTE NOTE NOTE' ; \
-           ls -l $D$(PATHBIN)/startinnfeed ; \
-           echo '$D$(PATHBIN)/startinnfeed needs to be installed setuid root' ; \
-           echo '' ; echo ; \
-       fi
-
-
-clean:
-       rm -f *.o $(ALL) version.c innfeed-convcfg
-       rm -f profiled innfeedp
-       rm -rf .libs
-
-clobber distclean: clean 
-       rm -f tags y.tab.c y.tab.h lex.yy.c config_y.c config_y.h
-
-tags: $(SOURCES) $(INCLUDES)
-       $(CTAGS) $(SOURCES) $(INCLUDES)
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Compilation rules.
-
-INNFEEDLIBS    = $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) \
-                 $(SASLLIB) $(LIBS)
-
-config_y.c config_y.h: configfile.y
-       $(YACC) -d $?
-       mv y.tab.h config_y.h
-       mv y.tab.c config_y.c
-
-config_l.c: configfile.l
-       $(LEX) $?
-       mv lex.yy.c config_l.c
-
-version.c: Makefile ../Makefile.global
-       version=`echo '$(VERSION) ($(VERSION_EXTRA))' | sed 's/ ()//'` ; \
-       echo 'const char *versionInfo = "innfeed' "$$version\" ;" > $@
-
-innfeed: $(OBJECTS) connection.o $(LIBSTORAGE) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(OBJECTS) connection.o $(INNFEEDLIBS)
-
-imapfeed: $(OBJECTS) imap_connection.o $(LIBSTORAGE) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(OBJECTS) imap_connection.o $(INNFEEDLIBS)
-
-procbatch: procbatch.in $(FIXSCRIPT)
-       $(FIXSCRIPT) procbatch.in
-
-startinnfeed: startinnfeed.o $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ startinnfeed.o $(LIBINN) $(LIBS)
-
-# Not normally built.
-innfeed-convcfg: innfeed-convcfg.in $(FIXSCRIPT)
-       $(FIXSCRIPT) -i innfeed-convcfg.in
-
-tst: config_y.c config_l.c
-       gcc -DWANT_MAIN -o tst -g -Wall config_y.c config_l.c -ly -ll
-
-
-##  Profiling.  These rules have not been checked for a while and may need
-##  some work.
-
-profiled:      innfeedp
-       date >$@
-
-innfeedp:      $(SOURCES)
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) innfeed
-       mv innfeed innfeedp
-       rm -f $(OBJECTS)
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend: Makefile $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-article.o: article.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/config.h \
-  ../include/inn/defines.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/storage.h \
-  article.h misc.h buffer.h endpoint.h
-buffer.o: buffer.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/config.h \
-  ../include/inn/defines.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/libinn.h buffer.h misc.h
-config_l.o: config_l.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/libinn.h \
-  ../include/inn/defines.h ../include/config.h configfile.h config_y.h \
-  misc.h ../include/config.h
-config_y.o: config_y.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/config.h \
-  ../include/inn/defines.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/libinn.h configfile.h misc.h
-endpoint.o: endpoint.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/config.h \
-  ../include/inn/defines.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/innconf.h \
-  ../include/inn/messages.h ../include/libinn.h buffer.h misc.h \
-  configfile.h endpoint.h host.h
-host.o: host.c innfeed.h ../include/inn/timer.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/config.h ../include/inn/defines.h \
-  ../include/clibrary.h ../include/config.h ../include/portable/socket.h \
-  ../include/config.h ../include/inn/innconf.h ../include/inn/messages.h \
-  ../include/libinn.h article.h misc.h buffer.h configfile.h connection.h \
-  endpoint.h host.h innlistener.h tape.h
-innlistener.o: innlistener.c innfeed.h ../include/inn/timer.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/config.h \
-  ../include/inn/defines.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/libinn.h article.h misc.h buffer.h \
-  configfile.h endpoint.h host.h innlistener.h ../include/nntp.h tape.h
-main.o: main.c innfeed.h ../include/inn/timer.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/config.h ../include/inn/defines.h \
-  ../include/clibrary.h ../include/config.h ../include/portable/socket.h \
-  ../include/config.h ../include/portable/time.h ../include/inn/innconf.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/storage.h \
-  article.h misc.h buffer.h configfile.h connection.h endpoint.h host.h \
-  innlistener.h tape.h
-misc.o: misc.c innfeed.h ../include/inn/timer.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/config.h ../include/inn/defines.h \
-  ../include/clibrary.h ../include/config.h ../include/inn/messages.h \
-  ../include/libinn.h endpoint.h misc.h tape.h
-startinnfeed.o: startinnfeed.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h
-tape.o: tape.c innfeed.h ../include/inn/timer.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/config.h ../include/inn/defines.h \
-  ../include/clibrary.h ../include/config.h ../include/inn/innconf.h \
-  ../include/inn/messages.h ../include/libinn.h article.h misc.h \
-  configfile.h endpoint.h tape.h
-version.o: version.c
diff --git a/innfeed/README b/innfeed/README
deleted file mode 100644 (file)
index ecdefbb..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-This is version 1.0 of the INN feeder program `innfeed.'
-It is written in ANSI C and tries to be POSIX.1 compliant. This software
-was originally written and maintained by James Brister <brister@vix.com>
-and is now part of INN. The features of it are:
-
-       1. Handles the STREAM extenstion to NNTP.
-       2. Will open multiple connections to the remote host to parallel
-          feed.
-       3. Will handle multiple remote hosts.
-       4. Will tear down idle connections.
-       5. Runs as a channel/funnel feed from INN, or by reading a funnel 
-          file.
-       6. Will stop issuing CHECK commands and go straight to TAKETHIS if
-          the remote responds affermatively to enough CHECKs.
-       7. It will go back to issuing CHECKs if enough TAKETHIS commands fail.
-
-
-Changes for 0.10.1
-
-       1. Config file inclusion now works via the syntax:
-
-               $INCLUDE pathname
-
-          Config files can be included up to a nesting depth of 10.  Line
-          numbers and file names are not properly reported yet on errors
-          when includes are used, though.
-
-       2. Signal handling is tidied up a bit. If your compiler doesn't 
-          support the ``volatile'' keyword, then see the comment in
-          sysconfig.h.
-
-       3. If you have a stdio library that hash limit on open files lower
-          then the process limit for open plain files (all flavours of
-          SunOS), then a new config file variable ``stdio-fdmax'' can be
-          used to give that upper bound. When set, all new network
-          connections will be limited to file descriptors over this value,
-          leaving the lower file descriptors free for stdio. See
-          innfeed.conf(5) for more details. Remember that the config file
-          value overrides any compiled in value.
-       
-Changes for 0.10
-
-       1. A major change has been made to the config file. The new format
-          is quite extensible and will let new data items be added in the
-          future without changing the basic format. There's a new option
-          ``-C'' (for ``check'') that will make innfeed read the config
-          file and report on any errors and then exit. This will let you
-          verify things before locking them into a newsfeeds file entry. A
-          program has been added ``innfeed-convcfg'' that will read your
-          old config off the command line (or stdin), and will write a new
-          version to stdout. 
-
-          The new config file structure permits non-peer-specific items to
-          be declared (like the location of the status file, or whether to
-          wrap the generated status file in HTML). This is part of the
-          included sample:
-
-                   use-mmap:               true
-                   news-spool:             /var/news/spool/articles
-                   backlog-directory:      /var/news/spool/innfeed
-                   pid-file:               innfeed.pid
-                   status-file:            innfeed.status
-                   gen-html:               false
-                   log-file:               innfeed.log
-                   backlog-factor:         1.10
-                   connection-stats:       false
-                   max-reconnect-time:     3600
-
-          so only option you'll probably need now is the ``-c'' option to
-          locate the config file, and as this is also compiled in, you may
-          not even need that.
-
-          See the innfeed.conf(5) man page for more details on config file
-          structure.
-          
-       2. The backlog file handling is changed slightly:
-
-               - The .output file is always kept open (until rotation time).
-               - The .output file is allowed to grow for at least 30
-                 seconds (or the value defined by the key
-                 backlog-rotate-period in the config file). This prevents
-                 thrashing of backlog files.
-               - The hand-prepared file is checked for only every 600
-                 seconds maximum (or the value defined by the key 
-                 backlog-new), not every time the files are rotated.
-               - The stating of the three backlog files is reduced
-                 dramatically.
-
-       3. Signal handling is changed so that they are more synchronous
-          with other activity. This should stop the frequent core-dumps
-          that occured when running in funnel file mode and sending 
-          SIGTERM or SIGALRM.
-
-       4. A bug related to zero-length articles was fixed. They will now be
-          logged.
-
-       5. More information is in the innfeed.status file, including the
-          reasons return by the remote when it is throttled.
-
-       6. SIGEMT is now a trigger for closing and reopening all the
-          backlog files. If you have scripts that need to fool with the
-          backlogs, then have the scripts move the backlogs out of the way
-          and then send the SIGEMT.
-
-Changes for 0.9.3
-
-       1. If your system supports mmap() *and* if you have your articles
-          stored on disk in NNTP-ready format (rare), then you can have
-          innfeed mmap article data to save on memory (thanks to Dave
-          Lawrence). There is an important issue with this:
-
-               if you try to have innfeed handle too many articles (by
-               running many connections and/or high max-check values in 
-               innfeed.conf) at once, then your system (not your process)
-               may run out of free vnodes (global file descriptors), as a
-               vnode is used as long as the file is mmaped. So be careful.
-
-          If your articles are not in NNTP format then this will be
-          noticed and the article will be pulled into memory for fixing up
-          (and then immediately munmap'd).  You can disable use of MMAP if
-          you've built it in by using the '-M' flag. I tried mixing
-          mmap'ing and articles not in NNTP format and it was a real
-          performance loss. I'll be trying it differently later.
-
-       2. If innfeed is asked to send an article to a host it knows
-          nothing about, or which it cannot acquire the required lock for
-          (which causes the "ME locked cannot setup peer ..." and "ME
-          unconfigured peer" syslog messages), then innfeed will deposit
-          the article information into a file matching the pattern
-          innfeed-dropped.* in the backlog directory (TAPE_DIRECTORY in
-          config.h). This file will not be processed in any manner -- it's
-          up to you to decide what to do with it (wait for innfeed to exit
-          before doing anything with it, or send innfeed a SIGHUP to get
-          it to reread its config file, which will roll this file).
-
-       4. The output backlog files will now be kept below a certain byte
-          limit. This happens via the ``-e'' option. If, after writing to
-          an output file, the new length is bigger than the given limit
-          (multiplied by a fudge factor defined in config.h -- default of
-          1.10) then the file will be shrunk down to this size (or slightly
-          smaller to find the end of line boundary). The front of the file
-          will be removed to do this. This means lost articles for the
-          entries removed.
-
-       3. A SIGHUP will make the config be reloaded. 
-
-       4. The .checkpoint files have been dropped in favour of scribbling
-          the offset into the input file itself.
-
-       5. When the process exits normally a final syslog entry covering
-          all of the peers over the life of the process is written. It
-          looks like:
-
-               Jan 12 15:51:53 data innfeed.tester[24189]: ME global
-                       seconds 2472 offered 43820 accepted 10506 
-                       refused 31168 rejected 1773 missing 39
-
-       6. SIGALARM now rolls the input file, rather than the log
-          file. This is useful in funnel file mode when you move the input
-          file and tell innd to flush it, then send innfeed the signal.
-
-       7. The location of the pid file, config file and status file, can
-          now be relative, in which case they're relative to the backlog
-          directory. 
-
-       8. stdin stdout and stderr are initialized properly when innfeed is
-          started by a process that has closed them.
-
-       9. Various values in config.h have changed (paths to look more like
-          values used in inn 1.5 and others to support point #7 above 
-          more easily.)
-
-       10. procbatch.pl can now 'require' innshellvars.pl that comes with
-           1.5. The default is not to. You nead to do a one line tweak if
-           you want it to. The defaults in procbatch.pl match the new
-           defaults of innfeed.
-
-       11. Core files that get generated on purpose will be done so in
-           CORE_DIRECTORY (as defined in config.h), if that is defined to a
-           pathname. If CORE_DIRECTORY is defined to be NULL (the default
-           now), then the core will be generated in the backlog directory (as
-           possibly modified by the '-b' option).
-
-
-Changes for 0.9.2
-
-       1. Now includes David Lawrence's patches to handle funnel files.
-
-       2. EAGAIN errors on read and writes are caught and dealt with (of
-          interest to Solaris `victims').
-
-       3. It is now much faster at servicing the file descriptor attached
-          to innd. This means it is faster at recognising it has been
-          flushed and at dropping connections. This means fewer
-          conflicts with new innfeeds starting before the old one has
-          finished up. It is still a good net-citizen and it finishes the
-          commands already started, so the fast response is only as fast
-          as your slowest peer, but it no longer tries to send
-          everything it had queued internally, and locks get released much
-          quicker.
-
-       4. Includes Michael Hucka's patch to make the innfeed.status output
-          neater.
-
-       5. Includes Andy Vasilyev's HTML-in-innfeed.status patch (but you
-          have to enable it in config.h).
-
-       6. Added a '-a' (top of news spool) and a '-p' (pid file path)
-          option.
-
-Changes for 0.9
-
-       1. Format of innfeed.conf file changed slightly (for per-peer
-          streaming specs).
-       2. Including Greg Patten's innlog.pl (taken from 
-               ftp://loose.apana.org.au/pub/local/innlog/innlog.pl)
-       3. Added Christophe Wolfhugel's patch to permit a per-peer
-          restriction on using streaming.
-       4. More robust handling of peers that return bad responses (no long
-          just calling abort).
-
-Changes for 0.8.5
-
-       1. Massive syslog messages cleanup courtesy of kre.
-       2. The innlog.awk-patch hash been dropped from the distribution
-          until the new syslog messages are dealt with.
-       3. State machine more robust in the face of unexpected responses
-          from remote. Connection gets torn down and bad response's
-          logged.
-       4. The fixed timers (article reception timeout, read timeout,
-          and flush timeout) are all adjusted by up to +/-10% so that
-          things aren't quite so synchronised.
-       5. The innfeed.status file has been expanded and reformatted to
-          include more information. 
-
-Changes for 0.8.4
-       
-       1. A change in the handing off of articles to connections in order to
-          encourage connections that were opened due to activity spikes,
-          to close down sooner.
-       2. The backlog files are no longer concatenated together at process
-          startup, but the .input is simply used if it exists, and if not
-          then the hand-dropped file is used first and the .output file
-          second.
-       3. The innfeed.status is no longer updated by a innfeed that is in
-          its death-throws.
-       4. Specifically catch the 480 response code from NNRPD when we try
-          to give it an IHAVE.
-       5. The connection reestablishment time gets properly increased when
-          the connection fails to go through (up to and including the
-          reading of the banner message).
-       6. Bug fix that occasionally had articles sit in a connection and
-          never get processed.
-       7. Bug fix in the counter of number of sleeping connections.
-       8. Bug fix in config file parsing.
-       9. Procbatch.pl included.
-
-Changes for version 0.8.1
-
-       1. various bug fixes.
-       2. core files generated by ASSERT are (possibly) put in a seperate
-          directory to ease debugging are
-
-Changes for version 0.8
-
-       1. The implicit state machine in the Connection objects has been
-          made explicit.
-       2. Various bug fixes.
-
-Changes for version 0.7.1
-
-       1. Pulled the source to inet_addr.c from the bind distribution.
-          (Solaris and some others don't have it).
-
-Changes for version 0.7
-
-       1. The backlog file mechanism has been completely reworked. There are
-           now only two backlog files: one for output and on for input. The
-           output file becomes the input file when the input file is
-           exhausted.
-       2. Much less strenuous use of writev. Solaris and other sv4r
-           machines have an amazingly low value for the maximum number of
-           iovecs that can be passed into writev.
-       3. Proper connection cleanup (QUIT issued) at shutdown.
-       4. A lock is taken out in the backlog directory for each peer. To feed
-           the same peer from two different instances of innfeed (with a
-           batch file for example), then you must use another directory.
-       5. Creating a file in the backlog directory with the same name as the
-           peer, the that file will be used next time backlog files are
-           processed. Its format must be:
-
-               pathname msgid
-
-          where pathname is absolute, or relative to the top of the news
-           spool.
-       6. More command line options.
-       7. Dynamic peer creation. If the proper command line option is
-           used (-y) and innfeed is to told to feed a peer that it doesn't
-           have in its config file, then it will create a new binding to
-           the new peer. The ip name must be the same as the peername,
-          i.e. if innd tells innfeed about a peer fooBarBat, then
-          gethostbyname("fooBarBat") better work.
-       8. Connections will be periodically torn down (1 hour is the
-          default), even if they're active, so that non-innd peers don't
-           have problems with their history files being kept open for too
-           long.
-       9. The input backlog files are checkpointed every 30 seconds
-           so that a crash while processing a large backlog doesn't require
-           starting over from the beginning.
-
-Changes for version 0.6
-
-       1. Logging of spooling of backlog only happens once per
-          stats-logging period.
-
-Bugs/Problems/Notes etc:
-
-       1. There is no graceful handling of file descriptor exhaustion.
-
-       2. If the following situation occurs:
-
-               - articles on disk are NOT in NNTP-ready format.
-               - innfeed was built with HAVE_MMAP defined.
-               - memory usage is higher than expected
-
-          try running innfeed with the '-M' flag (or recompiling with
-          HAVE_MMAP undefined). Solaris, and possibly other SVR4 machines,
-          waste a lot of swap space.
-
-       3. On the stats logging the 'offered' may not equal the sum of the
-          other fields. This is because the stats at that moment were
-          generated while waiting for a response to a command to come
-          back. Innfeed considers an article ``offered'' when it sends the
-          command, not when it gets a response back. Perhaps this should
-          change.
-
-       4. If all the Connections for a peer are idle and a new backlog file
-          is dropped in by hand, then it will not be picked up until the
-          next time it gets an article from innd for that peer. This will
-          be fixed in a later version, but for now, if the peer is likely
-          to be idle for a long time, then flush the process.
-
-       5. Adding a backlog file by hand does not cause extra Connections to
-          be automatically created, only the existing Connections will use
-          the file. If the extra load requires new Connections to be built
-          when innd delivers new articles for tranmission, then they too
-          will use the file, but this a side effect and not a direct
-          consequence. This means if you want to run in '-x' mode, then
-          make sure your config file entry states the correct number of
-          initial connections, as they're all the Connections that will be
-          created.
-         
-       6. If '-x' is used and the config file has an entry for a peer that
-          has no batch file to process, then innfeed will not exit after
-          all batch files have been finished--it will just site there idle.
-
-       7. If the remote is running inn and only has you in the nnrp.access
-          file, then innfeed will end up talking to nnrpd. Innfeed will
-          try every 30 seconds to reconnect to a server that will accept
-          IHAVE commands. i.e. there is no exponential back of retry
-          attempt. This is because the connection is considered good once
-          the MODE STREAM command has been accepted or rejected (and nnrpd
-          rejects it).
-
-Futures:
-
-       1. Innfeed will eventually take exploder commands.
-
-       2. The config file will be revamped to allow for more global
-          options etc and run-time configuration. Too much is compile-time
-          dependant at the moment.
-
-       3. The connection retry time will get more sophisticated to catch
-          problems like the nnrpd issue mentioned above.
-
-       4. Include the number of takesthis/check/ihave commands issued in
-           the log entries.
-
-       5. Heaps more stuff requested that's buried in my mail folders.
-
-
-Any compliments, complaints, requests, porting issues etc. should go to
-inn-bugs@isc.org.
-
-Many thanks to the following people for extra help (above and beyond the
-call of duty) with pateches, beta testing and/or suggestions:
-
-    Christophe Wolfhugel <wolf@pasteur.fr> 
-    Robert Elz <kre@munnari.oz.au>
-    Russell Vincent <vincent@ucthpx.uct.ac.za>
-    Paul Vixie <paul@vix.com>
-    Stephen Stuart <stuart@pa.dec.com>
-    John T. Stapleton <stapes@mro.dec.com>
-    Alan Barrett <apb@iafrica.com>
-    Lee McLoughlin <lmjm@doc.ic.ac.uk>
-    Dan Ellis <ellis@mail.microserve.net>
-    Katsuhiro Kondou <kondou@uxd.fc.nec.co.jp>
-    Marc G. Fournier <scrappy@ki.net>
-    Steven Bauer <sbauer@msmailgw.sdsmt.edu>
-    Richard Perini <rpp@ci.com.au>
-    Per Hedeland <per@erix.ericsson.se>
-    Clayton O'Neill <coneill@premier.net> 
-    Dave Pascoe <dave@mathworks.com>
-    Michael Handler <handler@netaxs.com>
-    Petr Lampa <lampa@fee.vutbr.cz>
-    David Lawrence <tale@uu.net>
-    Don Lewis <Don.Lewis@tsc.tdk.com>  
-    Landon Curt Noll <noll@sgi.com>
-
-If I've forgotten anybody, please let me know.
-
-Thanks also to the ISC for sponsoring this work.
diff --git a/innfeed/article.c b/innfeed/article.c
deleted file mode 100644 (file)
index 9896362..0000000
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*  $Id: article.c 7285 2005-06-07 06:38:24Z eagle $
-**
-**  The Article class for innfeed.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The implementation of the Article class. Articles are the abstraction for
-**  the actual news articles. They are a reference counted object because they
-**  need to be shared by multiple Host and Connection objects. When an Article
-**  is created it verifies that the actual file exists. When a Connection
-**  wants the article's contents for transmission the Article reads the data
-**  off disk and returns a set of Buffer objects. The Article holds onto these
-**  Buffers so that the next Connection that wants to transmit it won't have
-**  to wait for a disk read to be done again.
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <sys/stat.h>
-#include <syslog.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "storage.h"
-
-#include "article.h"
-#include "buffer.h"
-#include "endpoint.h"
-
-#if defined (NDEBUG)
-#define VALIDATE_HASH_TABLE() (void (0))
-#else
-#define VALIDATE_HASH_TABLE() hashValidateTable ()
-#endif
-
-extern bool useMMap ;
-
-struct map_info_s {
-    ARTHANDLE *arthandle;
-    const void *mMapping;
-    size_t size;
-    int refCount;
-    struct map_info_s *next;
-};
-
-typedef struct map_info_s *MapInfo;
-
-struct article_s 
-{
-    int refCount ;              /* the reference count on this article */
-    char *fname ;               /* the file name of the article */
-    char *msgid ;               /* the msgid of the article (INN tells us) */
-    Buffer contents ;           /* the buffer of the actual on disk stuff */
-    Buffer *nntpBuffers ;       /* list of buffers for transmisson */
-    MapInfo mapInfo;           /* arthandle and mMapping */
-    bool loggedMissing ;        /* true if article is missing and we logged */
-    bool articleOk ;            /* true until we know otherwise. */
-    bool inWireFormat ;         /* true if ->contents is \r\n/dot-escaped */
-} ;
-
-struct hash_entry_s {
-    struct hash_entry_s *next ;
-    struct hash_entry_s *prev ;
-    struct hash_entry_s *nextTime ;
-    struct hash_entry_s *prevTime ;
-    unsigned int hash ;
-    Article article ;
-};
-
-typedef struct hash_entry_s *HashEntry ;
-
-  /*
-   * Private functions
-   */
-
-static Buffer artGetContents (Article article) ;  /* Return the buffer that
-                                                     fillContents() filled
-                                                     up. */
-
-  /* Log statistics on article memory usage. */
-static void logArticleStats (TimeoutId id, void *data) ;
-
-static bool fillContents (Article article) ;  /* Read the article's bits
-                                                 off the disk. */
-
-  /* Append buffer B to the buffer array BUFFS. */
-static void appendBuffer (Buffer b, Buffer **buffs, int *newSpot, int *curLen);
-
-static bool prepareArticleForNNTP (Article article) ;  /* Do the necessary
-                                                          CR-LF stuff */
-
-static bool artFreeContents (Article art) ;  /* Tell the Article to release
-                                                its contents buffer if
-                                                possible. */
-
-static void artUnmap (Article art) ; /* munmap an mmap()ed
-                                                     article */
-
-
-  /*
-   * Hash table routine declarations.
-   */
-
-  /* Returns a has value for the given string */
-static unsigned int hashString (const char *string) ;
-
-  /* Locates the article with the given message ID, in the has table. */
-static Article hashFindArticle (const char *msgid) ;
-
-  /* Puts the given article in the hash table. */
-static void hashAddArticle (Article article) ;
-
-  /* Removes the given article from the has table */
-static bool hashRemoveArticle (Article article) ;
-
-  /* Does some simple-minded hash table validation */
-static void hashValidateTable (void) ;
-
-
-
-  /*
-   * Private data
-   */
-
-
-static unsigned int missingArticleCount ;  /* Number of articles that were missing */
-
-static bool logMissingArticles ;  /* if true then we log the details on a
-                                     missing article. */ 
-
-static unsigned int preparedBytes ;  /* The number of areticle bytes read in so
-                                 far of disk (will wrap around) */
-
-static unsigned int preparedNewlines ; /* The number of newlines found in all the
-                                   preparedBytes */
-
-static unsigned int avgCharsPerLine ;  /* The average number of characters per
-                                   line over all articles. */
-
-static bool rolledOver ;  /* true if preparedBytes wrapped around */
-
-static unsigned int bytesInUse ;   /* count of article contents bytes in use--just
-                               the amount read from the article files, not
-                               all memory involved in. */
-
-static unsigned int maxBytesInUse ;   /* the limit we want to stay under for total
-                                  bytes resident in memory dedicated to
-                                  article contents. */
-
-static unsigned int articlesInUse ;  /* number of articles currently allocated. */
-
-static unsigned int byteTotal ;        /* number of bytes for article contents
-                                   allocated totally since last log. */
-
-static unsigned int articleTotal ; /* number of articles alloced since last log. */
-
-static TimeoutId articleStatsId ; /* The timer callback id. */
-
-static MapInfo mapInfo;
-
-  /*
-   * Hash Table data
-   */
-
-static HashEntry *hashTable ;   /* the has table itself */
-static HashEntry chronList ;    /* chronologically ordered. Points at newest */
-
-#define TABLE_SIZE 2048          /* MUST be a power of 2 */
-#define HASH_MASK (TABLE_SIZE - 1)
-#define TABLE_ENTRY(hash) ((hash) & HASH_MASK)
-
-
-
-  /*******************************************************************/
-  /**                       PUBLIC FUNCTIONS                        **/
-  /*******************************************************************/
-
-  /* Create a new article object. First looks to see if one with the given
-     message id already exists in the hash table and if so returns that
-     (after incrementing the reference count). */
-Article newArticle (const char *filename, const char *msgid)
-{
-  Article newArt = NULL ;
-  
-  TMRstart(TMR_NEWARTICLE);
-  if (hashTable == NULL)
-    {                           /* first-time through initialization. */
-      int i ;
-      
-      ASSERT ((TABLE_SIZE & HASH_MASK) == 0) ;
-      hashTable = xmalloc (sizeof(HashEntry) * TABLE_SIZE) ;
-      
-      addPointerFreedOnExit ((char *)hashTable) ;
-
-      for (i = 0 ; i < TABLE_SIZE ; i++)
-        hashTable [i] = NULL ;
-
-      if (ARTICLE_STATS_PERIOD > 0)
-        articleStatsId = prepareSleep (logArticleStats,ARTICLE_STATS_PERIOD,0);
-    }
-
-    /* now look for it in the hash table. We presume the disk file is still
-       ok */
-  if ((newArt = hashFindArticle (msgid)) == NULL)
-    {
-      newArt = xcalloc (1, sizeof(struct article_s)) ;
-
-      newArt->fname = xstrdup (filename) ;
-      newArt->msgid = xstrdup (msgid) ;
-      
-      newArt->contents = NULL ;
-      newArt->mapInfo = NULL ;
-      newArt->refCount = 1 ;
-      newArt->loggedMissing = false ;
-      newArt->articleOk = true ;
-      newArt->inWireFormat = false ;
-      
-      d_printf (3,"Adding a new article(%p): %s\n", (void *)newArt, msgid) ;
-      
-      articlesInUse++ ;
-      articleTotal++ ;
-      
-      hashAddArticle (newArt) ;
-    }
-  else
-    {
-      if (strcmp (filename,newArt->fname) != 0)
-        warn ("ME two filenames for same article: %s, %s", filename,
-              newArt->fname) ;
-      
-      newArt->refCount++ ;
-      d_printf (2,"Reusing existing article for %s\nx",msgid) ;
-    }
-  TMRstop(TMR_NEWARTICLE);
-  return newArt ;
-}
-
-
-  /* Decrement the reference count on the article and free up its memory if
-     the ref count gets to 0. */
-void delArticle (Article article)
-{
-  if (article == NULL)
-    return ;
-
-  ASSERT (article->refCount > 0) ;
-
-  if (--(article->refCount) == 0)
-    {
-      bool removed = hashRemoveArticle (article) ;
-
-      ASSERT (removed == true) ;
-
-      d_printf (2,"Cleaning up article (%p): %s\n", 
-          (void *)article, article->msgid) ;
-
-      if (article->contents != NULL)
-        {
-          if (article->mapInfo)
-            artUnmap(article);
-          else
-            bytesInUse -= bufferDataSize (article->contents) ;
-      
-          if (article->nntpBuffers != NULL)
-            freeBufferArray (article->nntpBuffers) ;
-
-          delBuffer (article->contents) ;
-        }
-
-      articlesInUse-- ;
-
-      free (article->fname) ;
-      free (article->msgid) ;
-      free (article) ;
-    }
-
-  VALIDATE_HASH_TABLE () ;
-}
-
-
-void gPrintArticleInfo (FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sGlobal Article information : (count %d) {\n",
-           indent, articlesInUse) ;
-
-  fprintf (fp,"%s  missingArticleCount : %d\n",indent,missingArticleCount) ;
-  fprintf (fp,"%s  logMissingArticles : %d\n",indent,logMissingArticles) ;
-  fprintf (fp,"%s  preparedBytes : %d\n",indent,preparedBytes) ;
-  fprintf (fp,"%s  preparedNewlines : %d\n",indent,preparedNewlines) ;
-  fprintf (fp,"%s  avgCharsPerLine : %d\n",indent,avgCharsPerLine) ;
-  fprintf (fp,"%s  rolledOver : %s\n",indent,boolToString (rolledOver)) ;
-  fprintf (fp,"%s  bytesInUse : %d\n",indent,bytesInUse) ;
-  fprintf (fp,"%s  maxBytesInUse : %d\n",indent,maxBytesInUse) ;
-  fprintf (fp,"%s  articlesInUse : %d\n",indent,articlesInUse) ;
-  fprintf (fp,"%s  byteTotal : %d\n",indent,byteTotal) ;
-  fprintf (fp,"%s  articleTotal : %d\n",indent,articleTotal) ;
-  fprintf (fp,"%s  articleStatsId : %d\n",indent,articleStatsId) ;
-  
-  {
-    HashEntry he ;
-
-    for (he = chronList ; he != NULL ; he = he->nextTime)
-      printArticleInfo (he->article,fp,indentAmt + INDENT_INCR) ;
-  }
-
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-void printArticleInfo (Article art, FILE *fp, unsigned int indentAmt)
-{
-  Buffer *b ;
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-  
-  fprintf (fp,"%sArticle : %p {\n",indent,(void *) art) ;
-  fprintf (fp,"%s    article ok : %s\n",indent,boolToString (art->articleOk)) ;
-  fprintf (fp,"%s    refcount : %d\n",indent,art->refCount) ;
-  fprintf (fp,"%s    filename : %s\n",indent,art->fname) ;
-  fprintf (fp,"%s    msgid : %s\n",indent,art->msgid) ;
-
-  fprintf (fp,"%s    contents buffer : {\n",indent) ;
-#if 0
-  printBufferInfo (art->contents,fp,indentAmt + INDENT_INCR) ;
-#else
-  fprintf (fp,"%s    %p\n",indent,(void *) art->contents) ;
-#endif
-
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    nntp buffers : {\n",indent) ;
-  for (b = art->nntpBuffers ; b != NULL && *b != NULL ; b++)
-#if 0
-    printBufferInfo (*b,fp,indentAmt + INDENT_INCR) ;
-#else
-  fprintf (fp,"%s    %p\n",indent,(void *) *b) ;
-#endif
-  
-  fprintf (fp,"%s    }\n", indent) ;
-
-  fprintf (fp,"%s    logged missing : %s\n",
-           indent,boolToString (art->loggedMissing));
-  fprintf (fp,"%s}\n", indent) ;
-  
-}
-
-  /* return true if we have or are able to get the contents off the disk */
-bool artContentsOk (Article article)
-{
-  bool rval = false ;
-
-  if ( prepareArticleForNNTP (article) )
-    rval = true ;
-
-  return rval ;
-}
-
-
-  /* bump reference count on the article. */
-Article artTakeRef (Article article) 
-{
-  if (article != NULL)
-    article->refCount++ ;
-
-  return article ;
-}
-
-
-  /* return the filename of the article */
-const char *artFileName (Article article)
-{
-  if (article == NULL)
-    return NULL ;
-  else
-    return article->fname ;
-}
-
-
-  /* Get a NULL terminated array of Buffers that is ready for sending via NNTP */
-
-Buffer *artGetNntpBuffers (Article article)
-{
-  if ( !prepareArticleForNNTP (article) )
-    return NULL ;
-
-  return dupBufferArray (article->nntpBuffers) ;
-}
-
-
-  /* return the message id of the article */
-const char *artMsgId (Article article)
-{
-  return article->msgid ;
-}
-
-  /* return size of the article */
-int artSize (Article article)
-{
-  if (article == NULL || article->contents == NULL)
-    return (int)0 ;
-  return (int)bufferDataSize(article->contents);
-}
-
-
-  /* return how many NNTP-ready buffers the article contains */
-unsigned int artNntpBufferCount (Article article)
-{
-  if ( !prepareArticleForNNTP (article) )
-    return 0 ;
-  
-  return bufferArrayLen (article->nntpBuffers) ;
-}
-
-
-  /* if VAL is true then all missing articles will be logged. */
-void artLogMissingArticles (bool val)
-{
-  logMissingArticles = val ;
-}
-
-
-  /* set the limit we want to stay under. */
-void artSetMaxBytesInUse (unsigned int val)
-{
-  ASSERT (maxBytesInUse > 0) ;  /* can only set one time. */
-  ASSERT (val > 0) ;
-  
-  maxBytesInUse = val ;
-}
-
-
-  /**********************************************************************/
-  /**                            STATIC FUNCTIONS                      **/
-  /**********************************************************************/
-
-
-  /* return a single buffer that contains the disk image of the article (i.e.
-     not fixed up for NNTP). */
-static Buffer artGetContents (Article article)
-{
-  Buffer rval = NULL ;
-
-  if (article->articleOk)
-    {
-      if (article->contents == NULL)
-        fillContents (article) ;
-
-      if (article->contents != NULL)
-        rval = bufferTakeRef (article->contents) ;
-    }
-
-  return rval ;
-}
-
-  /* arthandle/mMapping needs to be refcounted since a buffer
-     may exist referencing it after delArticle if the remote
-     host sends the return status too soon (diablo, 439). */
-
-static MapInfo getMapInfo(ARTHANDLE *arthandle,
-               const void *mMapping, size_t size)
-{
-  MapInfo m;
-
-  for (m = mapInfo; m; m = m->next) {
-    if (m->arthandle == arthandle &&
-        m->mMapping == mMapping) {
-      m->refCount++;
-      return m;
-    }
-  }
-
-  m = xmalloc(sizeof(struct map_info_s));
-  m->refCount = 1;
-  m->arthandle = arthandle;
-  m->mMapping = mMapping;
-  m->size = size;
-  m->next = mapInfo;
-  mapInfo = m;
-
-  return m;
-}
-
-static void delMapInfo(void *vm)
-{
-    MapInfo i, prev;
-    MapInfo m = (MapInfo)vm;
-
-    if (m == NULL)
-      return;
-
-    if (--(m->refCount) > 0)
-      return;
-
-    if (m->arthandle)
-      SMfreearticle(m->arthandle);
-    else
-      if (munmap(m->mMapping, m->size) < 0)
-       syslog (LOG_NOTICE, "munmap article: %m");
-
-    prev = NULL;
-    for (i = mapInfo; i != m; i = i->next)
-      prev = i;
-
-    if (prev)
-      prev->next = m->next;
-    else
-      mapInfo = m->next;
-
-    free(m);
-}
-
-static void artUnmap (Article article) {
-
-    delMapInfo(article->mapInfo);
-    article->mapInfo = NULL;
-}
-
-
-
-static void logArticleStats (TimeoutId id, void *data UNUSED)
-{
-  ASSERT (id == articleStatsId) ;
-
-  notice ("ME articles active %d bytes %d", articlesInUse, bytesInUse) ;
-  notice ("ME articles total %d bytes %d", articleTotal, byteTotal) ;
-  
-  byteTotal = 0 ;
-  articleTotal = 0 ;
-
-  articleStatsId = prepareSleep (logArticleStats,ARTICLE_STATS_PERIOD,0) ;
-}
-
-
-  /* do the actual read of the article off disk into a Buffer that is stored
-     in the Article object. The Article will end up with its contents field
-     having a buffer with the article data in it. This buffer may be
-     holding a mmapped pointer, or it may be simply a regular buffer with
-     the data read off disk into it. In the regular buffer case the
-     contents may be copied around after reading to insert a carriage
-     return before each newline. */
-
-static bool fillContents (Article article)
-{
-    int fd = -1;
-    char *p;
-    static bool maxLimitNotified ;
-    bool opened;
-    size_t articlesize = 0;
-    char *buffer = NULL ;
-    int amt = 0 ;
-    size_t idx = 0, amtToRead ;
-    size_t newBufferSize ;
-    HashEntry h ;
-    ARTHANDLE *arthandle = NULL;
-    const void *mMapping = NULL;
-
-    ASSERT (article->contents == NULL) ;
-    
-    TMRstart(TMR_READART);
-    if (maxBytesInUse == 0)
-       maxBytesInUse = SOFT_ARTICLE_BYTE_LIMIT ;
-    
-    if (avgCharsPerLine == 0)
-       avgCharsPerLine = 75 ;      /* roughly number of characters per line */
-    
-    if (IsToken(article->fname)) {
-       opened = ((arthandle = SMretrieve(TextToToken(article->fname), RETR_ALL)) != NULL) ? true : false;
-       if (opened)
-           articlesize = arthandle->len;
-       else {
-           if (SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT) {
-               syslog(LOG_ERR, "Could not retrieve %s: %s",
-                      article->fname, SMerrorstr);
-               article->articleOk = false;
-               TMRstop(TMR_READART); 
-               return false;
-           }
-       }
-    } else {
-       struct stat sb ;
-       
-       opened = ((fd = open (article->fname,O_RDONLY,0)) >= 0) ? true : false;
-       arthandle = NULL;
-       if (opened) {
-           if (fstat (fd, &sb) < 0) {
-               article->articleOk = false ;
-                syswarn ("ME oserr fstat %s", article->fname) ;
-               TMRstop(TMR_READART);
-               return false;
-           }
-           if (!S_ISREG (sb.st_mode)) {
-               article->articleOk = false ;
-                warn ("ME article file-type: %s", article->fname) ;
-               TMRstop(TMR_READART);
-               return false;
-           }
-           if (sb.st_size == 0) {
-               article->articleOk = false ;
-                warn ("ME article 0 bytes: %s", article->fname) ;
-               TMRstop(TMR_READART);
-               return false;
-           }
-           articlesize = sb.st_size;
-       }
-    }
-    
-    if (!opened) {
-       article->articleOk = false ;
-       missingArticleCount++ ;
-       
-       if (logMissingArticles && !article->loggedMissing)
-       {
-            notice ("ME article missing: %s, %s", article->msgid,
-                    article->fname) ;
-           article->loggedMissing = true ;
-       }
-       TMRstop(TMR_READART);
-       return false;
-    }
-    amtToRead = articlesize ;
-    newBufferSize = articlesize ;
-    
-    if (arthandle || useMMap) {
-       if (arthandle)
-           mMapping = arthandle->data;
-       else 
-           mMapping = mmap(NULL, articlesize, PROT_READ,
-                                     MAP_SHARED, fd, 0);
-       
-       if (mMapping == MAP_FAILED) {
-           /* dunno, but revert to plain reading */
-           mMapping = NULL ;
-            syswarn ("ME mmap failure %s (%s)",
-                     article->fname,
-                     strerror(errno)) ;
-       } else {
-           article->contents = newBufferByCharP(mMapping,
-                                                articlesize,
-                                                articlesize);
-           article->mapInfo = getMapInfo(arthandle, mMapping, articlesize);
-           article->mapInfo->refCount++; /* one more for the buffer */
-           bufferSetDeletedCbk(article->contents, delMapInfo, article->mapInfo);
-
-           buffer = bufferBase (article->contents) ;
-           if ((p = strchr(buffer, '\n')) == NULL) {
-               article->articleOk = false;
-               delBuffer (article->contents) ;
-               article->contents = NULL ;
-                warn ("ME munged article %s", article->fname) ;
-           } else {
-               if (p[-1] == '\r') {
-                   article->inWireFormat = true ;
-               } else {
-                   /* we need to copy the contents into a buffer below */
-                   delBuffer (article->contents) ;
-                   article->contents = NULL ;
-               }
-           }
-       }
-    }
-       
-    if (article->contents == NULL && article->articleOk) {
-       /* an estimate to give some room for nntpPrepareBuffer to use. */
-       newBufferSize *= (1.0 + (1.0 / avgCharsPerLine)) ;
-       newBufferSize ++ ;
-       
-       /* if we're going over the limit try to free up some older article's
-          contents.  */
-       if (amtToRead + bytesInUse > maxBytesInUse)
-       {
-           for (h = chronList ; h != NULL ; h = h->nextTime)
-           {
-               if (artFreeContents (h->article))
-                   if (amtToRead + bytesInUse <= maxBytesInUse)
-                       break ;
-           }
-       }
-       
-       /* we we couldn't get below, then log it (one time only) */
-       if ((amtToRead + bytesInUse) > maxBytesInUse && maxLimitNotified == false) {
-           maxLimitNotified = true ;
-            notice ("ME exceeding maximum article byte limit: %d (max),"
-                    " %lu (cur)", maxBytesInUse, 
-                    (unsigned long) (amtToRead + bytesInUse)) ;
-       }
-       
-       if ((article->contents = newBuffer (newBufferSize)) == NULL)
-           amtToRead = 0 ;
-       else {
-           buffer = bufferBase (article->contents) ;
-           bytesInUse += articlesize ;
-           byteTotal += articlesize ;
-       }
-       
-       if (mMapping && buffer != NULL) {               
-           memcpy(buffer, mMapping, articlesize);
-           artUnmap(article) ;
-           amtToRead = 0;
-       }
-       
-       while (amtToRead > 0) {
-           if ((amt = read (fd, buffer + idx,amtToRead)) <= 0) {
-                syswarn ("ME article read error: %s", article->fname) ;
-               bytesInUse -= articlesize ;
-               byteTotal -= articlesize ;
-               amtToRead = 0 ;
-               
-               delBuffer (article->contents) ;
-               article->contents = NULL ;
-           }
-           else {
-               idx += amt ;
-               amtToRead -= amt ;
-           }
-       }
-       
-       if (article->contents != NULL) {
-           bufferSetDataSize (article->contents, articlesize) ;
-           
-           if ((p = strchr(buffer, '\n')) == NULL) {                  
-               article->articleOk = false;
-                warn ("ME munged article %s", article->fname) ;
-           }
-           else if (p[-1] == '\r') {
-               article->inWireFormat = true ;
-           }
-           else {
-               if ( nntpPrepareBuffer (article->contents) ) {
-                   size_t diff =
-                       (bufferDataSize (article->contents) - articlesize) ;
-                   
-                   if (((unsigned int) UINT_MAX) - diff <= preparedBytes) {
-                       d_printf (2,"Newline ratio so far: %02.2f\n",
-                                ((double) preparedBytes / preparedNewlines)) ;
-                        notice ("ME newline to file size ratio: %0.2f (%d/%d)",
-                               ((double) preparedBytes)/preparedNewlines,
-                               preparedBytes,preparedNewlines) ;
-                       preparedBytes = 0 ;
-                       preparedNewlines = 0 ;
-                       rolledOver = true ;
-                   }
-                   
-                   preparedBytes += articlesize ;
-                   preparedNewlines += diff ;
-                   bytesInUse += diff ;
-                   byteTotal += diff ;
-                   
-                   if (preparedBytes > (1024 * 1024)) {
-                       avgCharsPerLine =
-                           ((double) preparedBytes) / preparedNewlines ;
-                       avgCharsPerLine++ ;
-                   }
-                   article->inWireFormat = true ;
-               } else {
-                    warn ("ME internal failed to prepare buffer for NNTP") ;
-                   bytesInUse -= articlesize ;
-                   byteTotal -= articlesize ;
-                   
-                   delBuffer (article->contents) ;
-                   article->contents = NULL ;
-               }
-           }
-       }
-    }
-
-    
-    /* If we're not useing storage api, we should close a valid file descriptor */
-    if (!arthandle && (fd >= 0))
-       close (fd) ;
-
-    TMRstop(TMR_READART);
-    return (article->contents != NULL ? true : false) ;
-}
-
-
-
-  /* stick the buffer B into the Buffer array pointed at by BUFFS *BUFFS is
-     reallocated if necessary. NEWSPOT points at the index where B should be
-     put (presumably the end). CURLEN points at the length of the BUFFS and
-     it will get updated if BUFFS is reallocated.  */
-static void appendBuffer (Buffer b, Buffer **buffs, int *newSpot, int *curLen)
-{
-  if (*newSpot == *curLen)
-    {
-      *curLen += 10 ;
-      *buffs = xrealloc (*buffs, sizeof(Buffer) * *curLen) ;
-    }
-  (*buffs) [(*newSpot)++] = b ;
-}
-
-
-
-  /* Takes the articles contents buffer and overlays a set of new buffers on
-     top of it. These buffers insert the required carriage return and dot
-     characters as needed */
-static bool prepareArticleForNNTP (Article article)
-{
-  static Buffer dotFirstBuffer ;
-  static Buffer dotBuffer ;
-  static Buffer crlfBuffer ;
-  Buffer *nntpBuffs = NULL ;
-  int buffLen = 0 ;
-  int buffIdx = 0 ;
-  char *start, *end ;
-  Buffer contents ;
-
-  contents = artGetContents (article) ; /* returns a reference */
-
-  TMRstart(TMR_PREPART);
-  if (contents == NULL) {
-    TMRstop(TMR_PREPART);
-    return false ;
-  }
-  else if (article->nntpBuffers != NULL)
-    {
-      delBuffer (contents) ;
-      TMRstop(TMR_PREPART);
-      return true ;               /* already done */
-    }
-
-  if (dotBuffer == NULL)
-    {
-      dotBuffer = newBufferByCharP (".\r\n",3,3) ;
-      dotFirstBuffer = newBufferByCharP ("\r\n.",3,3) ;
-      crlfBuffer = newBufferByCharP ("\r\n",2,2) ;
-    }
-
-  /* overlay a set of buffers on top of the articles contents buffer. This
-     is a real speed loss at the moment, so by default it's disabled (by
-     calling artBitFiddleContents(true) in main(). */
-  if (article->inWireFormat == false)
-    {
-      end = bufferBase (contents) ;
-      do 
-        {
-          start = end ;
-          
-          while (*end && *end != '\n')
-            end++ ;
-          
-          appendBuffer (newBufferByCharP (start, (size_t) (end - start),
-                                          (size_t) (end - start)),
-                        &nntpBuffs,&buffIdx,&buffLen) ;
-          
-          if (*end != '\0')
-            end++ ;
-          
-        }
-      while (*end != '\0') ;
-      
-      appendBuffer (bufferTakeRef (dotBuffer), &nntpBuffs,&buffIdx,&buffLen) ;
-      appendBuffer (NULL,&nntpBuffs,&buffIdx,&buffLen) ;
-    }
-  else
-    {
-      /* we already fixed the contents up when we read in the article */
-      nntpBuffs = xmalloc (sizeof(Buffer) * 3) ;
-      nntpBuffs [0] = newBufferByCharP (bufferBase (contents),
-                                        bufferDataSize (contents),
-                                        bufferDataSize (contents)) ;
-      if (article->mapInfo) {
-       article->mapInfo->refCount++;
-       bufferSetDeletedCbk(nntpBuffs[0], delMapInfo, article->mapInfo);
-      }
-      nntpBuffs [1] = NULL ;
-    }
-  
-      
-  delBuffer (contents) ;    /* the article is still holding a reference */
-  article->nntpBuffers = nntpBuffs ;
-  TMRstop(TMR_PREPART);
-  return true ;
-}
-
-
-  /* free the contents of the buffers if article is the only thing holding a
-     reference. Returns true if it could, false if it couldn't */
-static bool artFreeContents (Article art)
-{
-  if (art->contents == NULL)
-    return false ;
-
-  if (art->nntpBuffers != NULL)
-    {
-    if (bufferRefCount (art->nntpBuffers[0]) > 1)
-      return false ;
-    else
-      {
-        freeBufferArray (art->nntpBuffers) ;    
-        art->nntpBuffers = NULL ;
-      }
-    }
-
-  ASSERT (bufferRefCount (art->contents) == 1) ;
-
-  if (art->mapInfo)
-    artUnmap(art);
-  else
-    bytesInUse -= bufferDataSize (art->contents) ;
-  
-  delBuffer (art->contents) ;
-
-  art->contents = NULL ;
-
-  return true ;
-}
-
-
-
-
-
-
-
-
-  /**********************************************************************/
-  /*         Private hash table and routines for storing articles       */
-  /**********************************************************************/
-
-
-
-
-  /* Hash function lifted from perl 5 */
-static unsigned int hashString (const char *string)
-{
-  unsigned int i ;
-
-  for (i = 0 ; string && *string ; string++)
-    i = 33 * i + (u_char) *string ;
-
-  return i ;
-}
-
-
-  /* find the article in the has table and return it. */
-static Article hashFindArticle (const char *msgid)
-{
-  unsigned int hash = hashString (msgid) ;
-  HashEntry h ;
-
-  for (h = hashTable [TABLE_ENTRY(hash)] ; h != NULL ; h = h->next)
-    if (hash == h->hash && strcmp (msgid,h->article->msgid) == 0)
-      break ;
-
-  return (h == NULL ? NULL : h->article) ;
-}
-
-
-  /* add the article to the hash table. */
-static void hashAddArticle (Article article)
-{
-  unsigned int hash = hashString (article->msgid) ;
-  HashEntry h ;
-  HashEntry ne ;
-
-  h = hashTable [TABLE_ENTRY(hash)] ;
-
-  ne = xmalloc (sizeof(struct hash_entry_s));
-
-  ne->article = article ;
-  ne->hash = hash ;
-  ne->next = hashTable [TABLE_ENTRY(hash)] ;
-  ne->prev = NULL ;
-
-  if (h != NULL)
-    h->prev = ne ;
-
-  hashTable [TABLE_ENTRY(hash)] = ne ;
-
-  ne->nextTime = chronList ;
-  ne->prevTime = NULL ;
-
-  if (chronList != NULL)
-    chronList->prevTime = ne ;
-
-  chronList = ne ;
-}
-
-
-  /* remove the article from the hash table and chronological list.
-     Does not delete the article itself. */
-static bool hashRemoveArticle (Article article)
-{
-  unsigned int hash = hashString (article->msgid) ;
-  HashEntry h ;
-
-  for (h = hashTable [TABLE_ENTRY(hash)] ; h != NULL ; h = h->next)
-    if (hash == h->hash && strcmp (article->msgid,h->article->msgid) == 0)
-      break ;
-
-  if (h == NULL)
-    return false ;
-
-  if (h == hashTable [TABLE_ENTRY(hash)])
-    {
-      hashTable [TABLE_ENTRY(hash)] = h->next ;
-      if (h->next != NULL)
-        h->next->prev = NULL ;
-    }
-  else
-    {
-      h->prev->next = h->next ;
-      if (h->next != NULL)
-        h->next->prev = h->prev ;
-    }
-
-  if (chronList == h)
-    {
-      chronList = h->nextTime ;
-      if (chronList != NULL)
-        chronList->prevTime = NULL ;
-    }
-  else
-    {
-      h->prevTime->nextTime = h->nextTime ;
-      if (h->nextTime != NULL)
-        h->nextTime->prevTime = h->prevTime ;
-    }
-
-  free (h) ;
-  
-  return true ;
-}
-
-#define HASH_VALIDATE_BUCKET_COUNT 1 /* hash buckets to check per call */
-
-static void hashValidateTable (void)
-{
-  static int hbn = 0 ;
-  int i ;
-  HashEntry he ;
-
-#if ! defined (NDEBUG)
-  for (i = 0 ; i < HASH_VALIDATE_BUCKET_COUNT ; i++)
-    {
-      for (he = hashTable [hbn] ; he != NULL ; he = he->next)
-        ASSERT (he->article->refCount > 0) ;
-      if (++hbn >= TABLE_SIZE)
-        hbn = 0 ;
-    }
-#endif
-}
diff --git a/innfeed/article.h b/innfeed/article.h
deleted file mode 100644 (file)
index ece277d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*  $Id: article.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  The public interface to articles.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The public interface to articles. The articles are implemented via
-**  reference counting.  This interface provides the methods for getting the
-**  contents of the article.
-**
-**  When an Article is created there's a chance that another copy of it
-**  already exists.  For example if the Article is pulled out of a Tape for a
-**  particular host it may already be in existance in some other host.  This
-**  class will manage this situation to prevent multiple copies of the article
-**  being in core.
-*/
-
-#if ! defined ( article_h__ )
-#define article_h__
-
-#include <stdio.h>
-
-#include "misc.h"
-
-
-  /* Create a new Article object. FILENAME is the path of the file the */
-  /* article is in. MSGID is the news message id of the article */
-Article newArticle (const char *filename, const char *msgid) ;
-
-  /* delete the given article. Just decrements refcount and then FREEs if the
-     refcount is 0. */
-void delArticle (Article article) ;
-
-void gPrintArticleInfo (FILE *fp, unsigned int indentAmt) ;
-
-  /* print some debugging info about the article. */
-void printArticleInfo (Article art, FILE *fp, unsigned int indentAmt) ;
-
-  /* return true if this article's file still exists. */
-bool artFileIsValid (Article article) ;
-
-  /* return true if we have the article's contents (calling this may trigger
-     the reading off the disk). */
-bool artContentsOk (Article article) ;
-
-  /* increments reference count and returns a copy of article that can be
-     kept (or passed off to someone else) */
-Article artTakeRef (Article article) ;
-
-  /* return the pathname of the file the article is in. */
-const char *artFileName (Article article) ;
-
-  /* return a list of buffers suitable for giving to an endpoint. The return
-     value can (must) be given to freeBufferArray */
-Buffer *artGetNntpBuffers (Article article) ;
-
-  /* return the message id stoed in the article object */
-const char *artMsgId (Article article) ;
-
-  /* return size of the article */
-int artSize (Article article) ;
-
-  /* return the number of buffers that artGetNntpBuffers() would return. */
-unsigned int artNntpBufferCount (Article article) ;
-
-  /* tell the Article class to log (or not) missing articles as they occur. */
-void artLogMissingArticles (bool val) ;
-
-  /* if VAL is true, then when an article is read off disk the necesary
-     carriage returns are inserted instead of setting up iovec-style buffers
-     for writev. Useful for systems like solaris that have very small max
-     number of iovecs that writev can take. Must be called only once before
-     the first article is created.  */
-void artBitFiddleContents (bool val) ;
-
-  /* set the limit on the number of bytes in all articles (this is not a hard
-     limit). Can only be called one time before any articles are created. */
-void artSetMaxBytesInUse (unsigned int val) ;
-
-#endif /* article_h__ */
diff --git a/innfeed/buffer.c b/innfeed/buffer.c
deleted file mode 100644 (file)
index 25a3478..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-/*  $Id: buffer.c 7285 2005-06-07 06:38:24Z eagle $
-**
-**  The Buffer class for innfeed.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The implementation of the Buffer class.  Buffers are reference counted
-**  objects that abstract memory regions in a way similar to struct iovec.
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include <assert.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "buffer.h"
-
-
-static Buffer gBufferList = NULL ;
-static Buffer bufferPool = NULL ;
-static unsigned int bufferCount = 0 ;
-static unsigned int bufferByteCount = 0 ;
-
-
-struct buffer_s 
-{
-    int refCount ;
-    char *mem ;
-    size_t memSize ;            /* the length of mem */
-    size_t dataSize ;           /* amount that has actual data in it. */
-    bool deletable ;
-    void (*bufferDeletedCbk)(void *);
-    void *bufferDeletedCbkData;
-    struct buffer_s *next ;
-    struct buffer_s *prev ;
-};
-
-#define BUFFER_POOL_SIZE ((4096 - 2 * (sizeof (void *))) / (sizeof (struct buffer_s)))
-
-static void fillBufferPool (void)
-{
-  unsigned int i ;
-
-  bufferPool = xmalloc (sizeof(struct buffer_s) * BUFFER_POOL_SIZE) ;
-
-  for (i = 0; i < BUFFER_POOL_SIZE - 1; i++)
-    bufferPool[i] . next = &(bufferPool [i + 1]) ;
-  bufferPool [BUFFER_POOL_SIZE-1] . next = NULL ;
-}
-
-
-Buffer newBuffer (size_t size)
-{
-  Buffer nb ;
-
-  if (bufferPool == NULL)
-    fillBufferPool() ;
-
-  nb = bufferPool;
-  ASSERT (nb != NULL) ;
-  bufferPool = bufferPool->next ;
-
-  nb->refCount = 1 ;
-
-  nb->mem = xmalloc (size + 1) ;
-  
-  nb->mem [size] = '\0' ;
-  nb->memSize = size ;
-  nb->dataSize = 0 ;
-  nb->deletable = true ;
-  nb->bufferDeletedCbk = NULL;
-  nb->bufferDeletedCbkData = NULL;
-
-  bufferByteCount += size + 1 ;
-  bufferCount++ ;
-
-  nb->next = gBufferList ;
-  nb->prev = NULL;
-  if (gBufferList != NULL)
-     gBufferList->prev = nb ;
-  gBufferList = nb ;
-  
-#if 0
-  d_printf (1,"Creating a DELETABLE buffer %p\n",nb) ;
-#endif
-
-  return nb ;
-}
-
-
-Buffer newBufferByCharP (const char *ptr, size_t size, size_t dataSize)
-{
-  Buffer nb ;
-
-  if (bufferPool == NULL)
-    fillBufferPool() ;
-
-  nb = bufferPool;
-  ASSERT (nb != NULL) ;
-  bufferPool = bufferPool->next ;
-  
-  nb->refCount = 1 ;
-  nb->mem = (char *) ptr ;      /* cast away const */
-  nb->memSize = size ;
-  nb->dataSize = dataSize ;
-  nb->deletable = false ;
-  nb->bufferDeletedCbk = NULL;
-  nb->bufferDeletedCbkData = NULL;
-
-  nb->next = gBufferList ;
-  nb->prev = NULL;
-  if (gBufferList != NULL)
-     gBufferList->prev = nb ;
-  gBufferList = nb ;
-
-  bufferCount++ ;
-#if 0
-  d_printf (1,"Creating a NON-DELETABLE buffer %p\n",nb) ;
-#endif
-  
-  return nb ;
-}
-
-
-void delBuffer (Buffer buff) 
-{
-  if (buff != NULL && --(buff->refCount) == 0)
-    {
-#if 0
-      d_printf (1,"Freeing a %s buffer (%p)\n",
-               (buff->deletable ? "DELETABLE" : "NON-DELETABLE"), buff) ;
-#endif
-
-      bufferCount-- ;
-      if (buff->deletable)
-        {
-          bufferByteCount -= (buff->memSize + 1) ;
-          free (buff->mem) ;
-          buff->mem = NULL ;
-        }
-
-      if (buff->bufferDeletedCbk) {
-        (buff->bufferDeletedCbk)(buff->bufferDeletedCbkData);
-       buff->bufferDeletedCbk = NULL;
-       buff->bufferDeletedCbkData = NULL;
-      }
-
-      if (buff->next != NULL)
-        buff->next->prev = buff->prev ;
-      if (buff->prev != NULL)
-        buff->prev->next = buff->next ;
-      else
-        {
-          ASSERT(gBufferList == buff) ;
-          gBufferList = buff->next ;
-        }
-
-      buff->next = bufferPool ;
-      bufferPool = buff ;
-    }
-}
-
-Buffer bufferTakeRef (Buffer buff) 
-{
-  ASSERT (buff != NULL) ;
-  
-  if (buff != NULL)
-    buff->refCount++ ;
-
-  return buff ;
-}
-
-
-void gPrintBufferInfo (FILE *fp, unsigned int indentAmt)
-{
-  Buffer b ;
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-  
-  fprintf (fp,"%sGlobal Buffer List : (count %d) {\n",indent,bufferCount) ;
-  
-  for (b = gBufferList ; b != NULL ; b = b->next)
-    printBufferInfo (b,fp,indentAmt + INDENT_INCR) ;
-
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-void printBufferInfo (Buffer buffer, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  char bufferStart [256] ;
-  unsigned int i ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-  
-  fprintf (fp,"%sBuffer : %p {\n",indent,(void *) buffer) ;
-
-  if (buffer == NULL)
-    {
-      fprintf (fp,"%s}\n",indent) ;
-      return ;
-    }
-
-  i = MIN(sizeof (bufferStart) - 1,buffer->dataSize) ;
-  memcpy (bufferStart,buffer->mem,i) ;
-  bufferStart[i] = '\0';
-  
-  fprintf (fp,"%s    refcount : %d\n",indent,buffer->refCount) ;
-  fprintf (fp,"%s    data-size : %ld\n",indent,(long) buffer->dataSize) ;
-  fprintf (fp,"%s    mem-size : %ld\n",indent,(long) buffer->memSize) ;
-  fprintf (fp,"%s    base : %p\n", indent,(void *) buffer->mem) ;
-  fprintf (fp,"%s    deletable : %s\n",indent,boolToString(buffer->deletable));
-  fprintf (fp,"%s    buffer [0:%ld] : \"%s\"\n",
-           indent, (long) i, bufferStart) ;
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-void *bufferBase (Buffer buff) 
-{
-  return buff->mem ;
-}
-
-size_t bufferSize (Buffer buff) 
-{
-  return buff->memSize ;
-}
-
-size_t bufferDataSize (Buffer buff) 
-{
-  return buff->dataSize ;
-}
-
-void bufferIncrDataSize (Buffer buff, size_t size) 
-{
-  if (buff->dataSize + size > buff->memSize)
-    die ("Trying to make a buffer data size bigger than its memory alloc");
-  else
-    buff->dataSize += size ;
-}
-
-void bufferDecrDataSize (Buffer buff, size_t size) 
-{
-  ASSERT (size > buff->dataSize) ;
-  
-  buff->dataSize -= size ;
-}
-
-void bufferSetDataSize (Buffer buff, size_t size) 
-{
-  buff->dataSize = size ;
-
-  ASSERT (buff->dataSize <= buff->memSize) ;
-}
-
-void bufferSetDeletedCbk (Buffer buff, void (*cbk)(void *), void *data)
-{
-  ASSERT(buff->bufferDeletedCbk == NULL &&
-        buff->bufferDeletedCbk != cbk);
-  ASSERT(buff->bufferDeletedCbkData == NULL &&
-        buff->bufferDeletedCbkData != data);
-  buff->bufferDeletedCbk = cbk;
-  buff->bufferDeletedCbkData = data;
-}
-
-void freeBufferArray (Buffer *buffs)
-{
-  Buffer *b = buffs ;
-  
-  while (b && *b)
-    {
-      delBuffer (*b) ;
-      b++ ;
-    }
-
-  if (buffs)
-    free (buffs) ;
-}
-
-
-  /* Allocate an array and put all the arguments (the last of which must be
-     NULL) into it. The terminating NULL is put in the returned array. */
-Buffer *makeBufferArray (Buffer buff, ...)
-{
-  va_list ap ;
-  size_t cLen = 10, idx = 0 ;
-  Buffer *ptr, p ;
-
-  ptr = xcalloc (cLen, sizeof(Buffer)) ;
-
-  ptr [idx++] = buff ;
-
-  va_start (ap, buff) ;
-  do
-    {
-      p = va_arg (ap, Buffer) ;
-      if (idx == cLen)
-        {
-          cLen += 10 ;
-          ptr = xrealloc (ptr, sizeof(Buffer) * cLen) ;
-        }
-      ptr [idx++] = p ;
-    }
-  while (p != NULL) ;
-  va_end (ap) ;
-
-  return ptr ;
-}
-
-
-bool isDeletable (Buffer buff)
-{
-  return buff->deletable ;
-}
-
-
-
-  /* Dups the array including taking out references on the Buffers inside */
-Buffer *dupBufferArray (Buffer *array)
-{
-  Buffer *newArr ;
-  int count = 0 ;
-
-  while (array && array [count] != NULL)
-    count++ ;
-
-  newArr = xmalloc (sizeof(Buffer) * (count + 1)) ;
-
-  for (count = 0 ; array [count] != NULL ; count++)
-    newArr [count] = bufferTakeRef (array [count]) ;
-
-  newArr [count] = NULL ;
-
-  return newArr ;
-}
-
-
-unsigned int bufferArrayLen (Buffer *array)
-{
-  unsigned int count = 0 ;
-
-  if (array != NULL)
-    while (*array != NULL)
-      {
-        count++ ;
-        array++ ;
-      }
-
-  return count ;
-}
-
-
-bool copyBuffer (Buffer dest, Buffer src)
-{
-  char *baseDest = bufferBase (dest) ;
-  char *baseSrc = bufferBase (src) ;
-  unsigned int amt = bufferDataSize (src) ;
-
-  if (amt > bufferSize (dest))
-    return false ;
-
-  memcpy (baseDest, baseSrc, amt) ;
-
-  bufferSetDataSize (dest,amt) ;
-
-  return true ;
-}
-
-
-unsigned int bufferRefCount (Buffer buf)
-{
-  return buf->refCount ;
-}
-
-
-void bufferAddNullByte (Buffer buff) 
-{
-  char *p = bufferBase (buff) ;
-
-  p [buff->dataSize] = '\0' ;
-}
-
-
-  /* append the src buffer to the dest buffer growing the dest as needed.
-     Can only be done to deletable buffers. */
-bool concatBuffer (Buffer dest, Buffer src)
-{
-  ASSERT (dest->deletable) ;
-
-  if ( !dest->deletable )
-    return false ;              /* yeah, i know this is taken care of above */
-      
-  if ((dest->dataSize + src->dataSize) > dest->memSize)
-    {
-      char *newMem = xcalloc (dest->dataSize + src->dataSize + 1, 1) ;
-
-      bufferByteCount += ((dest->dataSize + src->dataSize) - dest->memSize) ;
-      
-      memcpy (newMem, dest->mem, dest->dataSize) ;
-
-      ASSERT (dest->mem != NULL) ;
-      free (dest->mem) ;
-
-      dest->mem = newMem ;
-      dest->memSize = dest->dataSize + src->dataSize ; /* yep. 1 less */
-    }
-
-  memcpy (&dest->mem[dest->dataSize], src->mem, dest->dataSize) ;
-
-  dest->dataSize += src->dataSize ;
-
-  return true ;
-}
-
-
-  /* realloc the buffer's memory to increase the size by AMT */
-bool expandBuffer (Buffer buff, size_t amt)
-{
-  d_printf (2,"Expanding buffer....\n") ;
-  
-  if (!buff->deletable)
-    return false ;
-
-  bufferByteCount += amt ;
-  buff->memSize += amt ;
-
-  buff->mem = xrealloc (buff->mem, buff->memSize + 1) ;
-
-  return true ;
-}
-
-
-  /* Take a buffer and shift the contents around to add the necessary CR
-     before every line feed and a '.' before every '.' at the start of a
-     line. */
-bool nntpPrepareBuffer (Buffer buffer)
-{
-  int msize, newDsize, dsize, extra ;
-  char *base, p, *src, *dst ;
-  bool needfinal = false ;
-
-  ASSERT (buffer != NULL) ;
-
-  dsize = buffer->dataSize ;
-  msize = buffer->memSize - 1 ;
-  base = buffer->mem ;
-
-  extra = 3 ;
-  p = '\0' ;
-  for (src = base + dsize - 1 ; src > base ; )
-    {
-      if (*src == '\n')
-        {
-          extra++ ;
-          if (p == '.')
-            extra++ ;
-        }
-      p = *src-- ;
-    }
-  if (*src == '\n')
-    {
-      extra++ ;
-      if (p == '.')
-        extra++ ;
-    }
-
-  if (dsize > 0 && base [dsize - 1] != '\n')
-    {
-      needfinal = true ;
-      extra += 2 ;
-    }
-    
-  newDsize = dsize + extra ;
-  
-  if (msize - dsize < extra)
-    {
-      d_printf (2,"Expanding buffer in nntpPrepareBuffer (from %d to %d)\n",
-               msize, msize + (extra - (msize - dsize))) ;
-
-      if ( !expandBuffer (buffer, extra - (msize - dsize)) )
-        {
-          d_printf (1,"Expand failed...\n") ;
-          return false ;
-        }
-      
-      ASSERT (dsize == (int) buffer->dataSize) ;
-
-      base = buffer->mem ;
-    }
-
-  base [newDsize] = '\0' ;
-  base [newDsize - 1] = '\n' ;
-  base [newDsize - 2] = '\r' ;
-  base [newDsize - 3] = '.' ;
-  newDsize -= 3 ;
-  extra -= 3 ;
-  
-  if (needfinal)
-    {
-      base [newDsize - 1] = '\n' ;
-      base [newDsize - 2] = '\r' ;
-      newDsize -= 2 ;
-      extra -= 2 ;
-    }
-  
-  if (extra)
-    {
-      p = '\0';
-      src = base + dsize - 1 ;
-      dst = base + newDsize - 1 ;
-      while (1)
-        {
-          if (*src == '\n')
-            {
-              if (p == '.')
-                {
-                  *dst-- = '.' ;
-                  extra-- ;
-                }
-              *dst-- = '\n' ;
-              *dst = '\r' ;
-              if (--extra <= 0)
-                 break ;
-              p = '\0' ;
-              dst-- ;
-              src-- ;
-            }
-          else
-            p = *dst-- = *src-- ;
-        }
-      ASSERT(dst >= base && src >= base) ; 
-    }
-
-  newDsize += 3;
-  if (needfinal)
-    newDsize += 2 ;
-  
-  bufferSetDataSize (buffer,newDsize) ;
-  
-  return true ;
-}
diff --git a/innfeed/buffer.h b/innfeed/buffer.h
deleted file mode 100644 (file)
index 9e9ed96..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*  $Id: buffer.h 7285 2005-06-07 06:38:24Z eagle $
-**
-**  The public interface to the Buffer class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The Buffer class encapsulates a region of memory. It provides reference
-**  counting so that redundant memory allocation and copying is minimized. A
-**  good example of this is the need to write the same data (e.g. an article
-**  body) out more than one socket. The data is stored in a Buffer and the
-**  Buffer is given to each EndPoint that is to write it. With the Refcount
-**  appropriately set the EndPoints can release their references at will and
-**  the Buffer will be cleaned up when necessary.
-*/
-
-#if ! defined ( buffer_h__ )
-#define buffer_h__
-
-
-#include <sys/types.h>
-#include <stdio.h>
-
-#include "misc.h"
-
-
-/*
- * Create a new Buffer object and initialize it.
- */
-Buffer newBuffer (size_t size) ;
-
-/* Create a new Buffer object around the preallocted PTR, which is SIZE
-   bytes long. The data size of the Buffer is set to DATASIZE. When then
-   buffer is released it will not delete the ptr (this is useful to have
-   Buffers around contant strings, or Buffers around other Buffers) */
-Buffer newBufferByCharP (const char *ptr, size_t size, size_t dataSize) ;
-
-/*
- * give up interest in the Buffer. Decrement refcount and delete if no
- * more referants
- */
-void delBuffer (Buffer buff) ;
-
-  /* print some debugging information about the buffer. */
-void printBufferInfo (Buffer buffer, FILE *fp, unsigned int indentAmt) ;
-
-  /* print debugging information about all outstanding buffers. */
-void gPrintBufferInfo (FILE *fp, unsigned int indentAmt) ;
-
-/* increment reference counts so that the buffer object can be */
-/* handed off to another function without it being deleted when that */
-/* function calls bufferDelete(). Returns buff, so the call can be */
-/* used in function arg list. */
-Buffer bufferTakeRef (Buffer buff) ;
-
-/* returns the address of the base of the memory owned by the Buffer */
-void *bufferBase (Buffer buff) ;
-
-/* returns the size of the memory buffer has available. This always returns
-   1 less than the real size so that there's space left for a null byte
-   when needed. The extra byte is accounted for when the newBuffer function
-   is called. */
-size_t bufferSize (Buffer) ;
-
-/* return the amount of data actually in the buffer */
-size_t bufferDataSize (Buffer buff) ;
-
-/* increment the size of the buffer's data region */
-void bufferIncrDataSize (Buffer buff, size_t size) ;
-
-/* decrement the size of the buffer's data region */
-void bufferDecrDataSize (Buffer buff, size_t size) ;
-
-/* set the size of the data actually in the buffer */
-void bufferSetDataSize (Buffer buff, size_t size) ;
-
-/* callback to be called when buffer gets deleted */
-void bufferSetDeletedCbk (Buffer buff, void (*cbk)(void *), void *data);
-
-/* walk down the BUFFS releasing each buffer and then freeing BUFFS itself */
-void freeBufferArray (Buffer *buffs) ;
-
-/* All arguments are non-NULL Buffers, except for the last which must be
-   NULL. Creates a free'able array and puts all the buffers into it (does
-   not call bufferTakeRef on them). */
-Buffer *makeBufferArray (Buffer buff, ...) ;
-
-/* returns true if the buffer was created via
-   newBuffer (vs. newBufferByCharP) */
-bool isDeletable (Buffer buff) ;
-
-/* Dups the array including taking out references on the Buffers
-   inside. Return value must be freed (or given to freeBufferArray) */
-Buffer *dupBufferArray (Buffer *array) ;
-
-/* return the number of non-NULL elements in the array. */
-unsigned int bufferArrayLen (Buffer *array) ;
-
-/* copies the contents of the SRC buffer into the DEST buffer and sets the
-   data size appropriately. Returns false if src is bigger than dest. */
-bool copyBuffer (Buffer dest, Buffer src) ;
-
-/* return the ref count on the buffer */
-unsigned int bufferRefCount (Buffer buff) ;
-
-/* insert a null byte at the end of the data region */
-void bufferAddNullByte (Buffer buff) ;
-
-/* append the data of src to the data of dest, if dest is big enough */
-bool concatBuffer (Buffer dest, Buffer src) ;
-
-/* expand the buffer's memory by the given AMT */
-bool expandBuffer (Buffer buff, size_t amt) ;
-
-/* Expand the buffer (if necessary) and insert carriage returns before very
-   line feed. Adjusts the data size. The base address may change
-   afterwards. */
-bool nntpPrepareBuffer (Buffer buffer) ;
-
-#endif /* buffer_h__ */
diff --git a/innfeed/config_l.c b/innfeed/config_l.c
deleted file mode 100644 (file)
index 34d4c00..0000000
+++ /dev/null
@@ -1,1861 +0,0 @@
-/* A lexical scanner generated by flex */
-
-/* Scanner skeleton version:
- * $Header$
- */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-
-#include <stdio.h>
-#include <errno.h>
-
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
-#endif
-#endif
-
-
-#ifdef __cplusplus
-
-#include <stdlib.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else  /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_PROTOS
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#define YY_USE_CONST
-#define YY_USE_PROTOS
-#endif
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#define YY_BUF_SIZE 16384
-
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-
-extern int yyleng;
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-/* The funky do-while in the following #define is used to turn the definition
- * int a single C statement (which needs a semi-colon terminator).  This
- * avoids problems with code like:
- *
- *     if ( condition_holds )
- *             yyless( 5 );
- *     else
- *             do_something_else();
- *
- * Prior to using the do-while the compiler would get upset at the
- * "else" because it interpreted the "if" statement as being all
- * done when it reached the ';' after the yyless() call.
- */
-
-/* Return all but the first 'n' matched characters back to the input stream. */
-
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-               *yy_cp = yy_hold_char; \
-               YY_RESTORE_YY_MORE_OFFSET \
-               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
-               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-               } \
-       while ( 0 )
-
-#define unput(c) yyunput( c, yytext_ptr )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-typedef unsigned int yy_size_t;
-
-
-struct yy_buffer_state
-       {
-       FILE *yy_input_file;
-
-       char *yy_ch_buf;                /* input buffer */
-       char *yy_buf_pos;               /* current position in input buffer */
-
-       /* Size of input buffer in bytes, not including room for EOB
-        * characters.
-        */
-       yy_size_t yy_buf_size;
-
-       /* Number of characters read into yy_ch_buf, not including EOB
-        * characters.
-        */
-       int yy_n_chars;
-
-       /* Whether we "own" the buffer - i.e., we know we created it,
-        * and can realloc() it to grow it, and should free() it to
-        * delete it.
-        */
-       int yy_is_our_buffer;
-
-       /* Whether this is an "interactive" input source; if so, and
-        * if we're using stdio for input, then we want to use getc()
-        * instead of fread(), to make sure we stop fetching input after
-        * each newline.
-        */
-       int yy_is_interactive;
-
-       /* Whether we're considered to be at the beginning of a line.
-        * If so, '^' rules will be active on the next match, otherwise
-        * not.
-        */
-       int yy_at_bol;
-
-       /* Whether to try to fill the input buffer when we reach the
-        * end of it.
-        */
-       int yy_fill_buffer;
-
-       int yy_buffer_status;
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-       /* When an EOF's been seen but there's still some text to process
-        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-        * shouldn't try reading from the input source any more.  We might
-        * still have a bunch of tokens to match, though, because of
-        * possible backing-up.
-        *
-        * When we actually see the EOF, we change the status to "new"
-        * (via yyrestart()), so that the user can continue scanning by
-        * just pointing yyin at a new input file.
-        */
-#define YY_BUFFER_EOF_PENDING 2
-       };
-
-static YY_BUFFER_STATE yy_current_buffer = 0;
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- */
-#define YY_CURRENT_BUFFER yy_current_buffer
-
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-
-static int yy_n_chars;         /* number of characters read into yy_ch_buf */
-
-
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1;                /* whether we need to initialize */
-static int yy_start = 0;       /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart YY_PROTO(( FILE *input_file ));
-
-void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
-void yy_load_buffer_state YY_PROTO(( void ));
-YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
-void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
-void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
-
-YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
-YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
-
-static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
-static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
-static void yy_flex_free YY_PROTO(( void * ));
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-       { \
-       if ( ! yy_current_buffer ) \
-               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
-       yy_current_buffer->yy_is_interactive = is_interactive; \
-       }
-
-#define yy_set_bol(at_bol) \
-       { \
-       if ( ! yy_current_buffer ) \
-               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
-       yy_current_buffer->yy_at_bol = at_bol; \
-       }
-
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
-
-typedef unsigned char YY_CHAR;
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-typedef int yy_state_type;
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state YY_PROTO(( void ));
-static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
-static int yy_get_next_buffer YY_PROTO(( void ));
-static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-       yytext_ptr = yy_bp; \
-       yyleng = (int) (yy_cp - yy_bp); \
-       yy_hold_char = *yy_cp; \
-       *yy_cp = '\0'; \
-       yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 19
-#define YY_END_OF_BUFFER 20
-static yyconst short int yy_accept[55] =
-    {   0,
-        0,    0,    7,    7,   20,   18,   11,    1,   15,   10,
-       19,   16,    2,   18,   18,    3,    4,   18,    8,    7,
-       19,   18,   11,   15,   10,    0,    0,   17,   16,   18,
-       18,   18,    8,    7,   13,    0,    0,   17,   18,   18,
-       18,    0,   12,   18,    5,   18,    0,    9,   18,   14,
-       18,   18,    6,    0
-    } ;
-
-static yyconst int yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    5,    6,    1,    1,    7,    1,
-        1,    1,    1,    1,    8,    9,    1,   10,   10,   10,
-       10,   10,   10,   10,   10,   10,   10,   11,    1,    1,
-        1,    1,    1,    1,    1,    1,   12,   13,   14,    1,
-       15,    1,   16,    1,    1,   17,    1,   18,   19,   20,
-        1,   21,    1,    1,   22,    1,    1,    1,    1,    1,
-        1,   23,    1,    1,    1,    1,   24,   24,    1,    1,
-
-       25,   24,   15,    1,    1,    1,    1,    1,    1,   24,
-       19,   20,    1,   26,    1,   24,   27,   24,    1,    1,
-        1,    1,   28,    1,   29,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static yyconst int yy_meta[30] =
-    {   0,
-        1,    2,    3,    4,    5,    1,    6,    1,    1,    7,
-        5,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    7,    7,    1,    7,    1,    1,    1
-    } ;
-
-static yyconst short int yy_base[62] =
-    {   0,
-        0,  100,   28,   30,  105,    0,  102,  107,    0,    0,
-       80,   25,  107,   15,   23,    0,    0,   86,    0,   99,
-      107,    0,   98,    0,    0,   92,   32,   88,   34,   78,
-       24,   78,    0,   87,  107,   78,   75,   65,   18,   25,
-       57,   54,  107,   43,    0,   45,   54,    0,   38,  107,
-       37,   33,    0,  107,   51,   58,   65,   72,   79,   86,
-       88
-    } ;
-
-static yyconst short int yy_def[62] =
-    {   0,
-       54,    1,   55,   55,   54,   56,   54,   54,   57,   58,
-       59,   56,   54,   56,   56,   56,   56,   56,   60,   54,
-       54,   56,   54,   57,   58,   54,   61,   56,   56,   56,
-       56,   56,   60,   54,   54,   54,   54,   56,   56,   56,
-       56,   54,   54,   56,   56,   56,   54,   56,   56,   54,
-       56,   56,   56,    0,   54,   54,   54,   54,   54,   54,
-       54
-    } ;
-
-static yyconst short int yy_nxt[137] =
-    {   0,
-        6,    7,    8,    9,   10,    6,   11,   12,    6,   12,
-       13,    6,    6,    6,   14,    6,    6,    6,    6,   15,
-        6,    6,    6,    6,    6,    6,    6,   16,   17,   20,
-       21,   20,   21,   28,   29,   30,   31,   40,   35,   44,
-       30,   36,   28,   29,   44,   45,   53,   31,   40,   52,
-       45,   19,   19,   19,   19,   19,   19,   19,   22,   51,
-       50,   49,   48,   47,   22,   24,   24,   24,   46,   24,
-       24,   24,   25,   25,   38,   25,   25,   25,   25,   26,
-       26,   43,   26,   26,   26,   26,   33,   42,   34,   33,
-       33,   33,   33,   37,   37,   41,   39,   38,   35,   23,
-
-       34,   32,   27,   23,   54,   18,    5,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54
-    } ;
-
-static yyconst short int yy_chk[137] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    3,
-        3,    4,    4,   12,   12,   14,   15,   31,   27,   39,
-       14,   27,   29,   29,   39,   40,   52,   15,   31,   51,
-       40,   55,   55,   55,   55,   55,   55,   55,   56,   49,
-       47,   46,   44,   42,   56,   57,   57,   57,   41,   57,
-       57,   57,   58,   58,   38,   58,   58,   58,   58,   59,
-       59,   37,   59,   59,   59,   59,   60,   36,   34,   60,
-       60,   60,   60,   61,   61,   32,   30,   28,   26,   23,
-
-       20,   18,   11,    7,    5,    2,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54
-    } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "configfile.l"
-#define INITIAL 0
-#line 2 "configfile.l"
-/*  $Id: config_l.c 6145 2003-01-19 19:42:22Z rra $
-**
-**  A flex input file for the innfeed config file.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "libinn.h"
-
-#include "configfile.h"
-#include "config_y.h"
-#include "misc.h"
-
-#if ! defined (FLEX_SCANNER)
-#error "You must use FLEX to process the lex input file."
-#endif
-
-#if defined (FLEX_DEBUG)
-#define YY_USER_INIT yy_flex_debug = (getenv ("YYDEBUG") == NULL ? 0 : 1)
-#endif
-
-/* We never use this function but flex always defines it, so silence the
-   warnings about it. */
-static void yyunput(int, char *) UNUSED;
-
-char *strPtr = 0 ;
-int strPtrLen = 0 ;
-int strIdx = 0 ;
-int sawBsl ;
-int lineCount = 0 ;
-int current ;
-
-static void strAppend (int ch);
-static void strAppend (int ch)
-{
-  if (strIdx == strPtrLen)
-    {
-      if (strPtr == 0)
-        strPtr = xmalloc (strPtrLen = 50) ;
-      else
-        strPtr = xrealloc (strPtr,strPtrLen += 10) ;
-    }
-  strPtr [strIdx++] = ch ;
-}
-
-#define MAX_INCLUDE_DEPTH 11
-struct includeFile {
-    YY_BUFFER_STATE state;
-    char *name ;
-} include_stack[MAX_INCLUDE_DEPTH];
-int include_stack_ptr = 0;
-
-#define incl 1
-
-#line 474 "lex.yy.c"
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap YY_PROTO(( void ));
-#else
-extern int yywrap YY_PROTO(( void ));
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-static void yyunput YY_PROTO(( int c, char *buf_ptr ));
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
-#else
-static int input YY_PROTO(( void ));
-#endif
-#endif
-
-#if YY_STACK_USED
-static int yy_start_stack_ptr = 0;
-static int yy_start_stack_depth = 0;
-static int *yy_start_stack = 0;
-#ifndef YY_NO_PUSH_STATE
-static void yy_push_state YY_PROTO(( int new_state ));
-#endif
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state YY_PROTO(( void ));
-#endif
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state YY_PROTO(( void ));
-#endif
-
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
-
-#ifdef YY_MALLOC_DECL
-YY_MALLOC_DECL
-#else
-#if __STDC__
-#ifndef __cplusplus
-#include <stdlib.h>
-#endif
-#else
-/* Just try to get by without declaring the routines.  This will fail
- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
- * or sizeof(void*) != sizeof(int).
- */
-#endif
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-       if ( yy_current_buffer->yy_is_interactive ) \
-               { \
-               int c = '*', n; \
-               for ( n = 0; n < max_size && \
-                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-                       buf[n] = (char) c; \
-               if ( c == '\n' ) \
-                       buf[n++] = (char) c; \
-               if ( c == EOF && ferror( yyin ) ) \
-                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
-               result = n; \
-               } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL int yylex YY_PROTO(( void ))
-#endif
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-       if ( yyleng > 0 ) \
-               yy_current_buffer->yy_at_bol = \
-                               (yytext[yyleng - 1] == '\n'); \
-       YY_USER_ACTION
-
-YY_DECL
-       {
-       register yy_state_type yy_current_state;
-       register char *yy_cp, *yy_bp;
-       register int yy_act;
-
-#line 67 "configfile.l"
-
-
-#line 642 "lex.yy.c"
-
-       if ( yy_init )
-               {
-               yy_init = 0;
-
-#ifdef YY_USER_INIT
-               YY_USER_INIT;
-#endif
-
-               if ( ! yy_start )
-                       yy_start = 1;   /* first start state */
-
-               if ( ! yyin )
-                       yyin = stdin;
-
-               if ( ! yyout )
-                       yyout = stdout;
-
-               if ( ! yy_current_buffer )
-                       yy_current_buffer =
-                               yy_create_buffer( yyin, YY_BUF_SIZE );
-
-               yy_load_buffer_state();
-               }
-
-       while ( 1 )             /* loops until end-of-file is reached */
-               {
-               yy_cp = yy_c_buf_p;
-
-               /* Support of yytext. */
-               *yy_cp = yy_hold_char;
-
-               /* yy_bp points to the position in yy_ch_buf of the start of
-                * the current run.
-                */
-               yy_bp = yy_cp;
-
-               yy_current_state = yy_start;
-               yy_current_state += YY_AT_BOL();
-yy_match:
-               do
-                       {
-                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
-                       if ( yy_accept[yy_current_state] )
-                               {
-                               yy_last_accepting_state = yy_current_state;
-                               yy_last_accepting_cpos = yy_cp;
-                               }
-                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                               {
-                               yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 55 )
-                                       yy_c = yy_meta[(unsigned int) yy_c];
-                               }
-                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-                       ++yy_cp;
-                       }
-               while ( yy_base[yy_current_state] != 107 );
-
-yy_find_action:
-               yy_act = yy_accept[yy_current_state];
-               if ( yy_act == 0 )
-                       { /* have to back up */
-                       yy_cp = yy_last_accepting_cpos;
-                       yy_current_state = yy_last_accepting_state;
-                       yy_act = yy_accept[yy_current_state];
-                       }
-
-               YY_DO_BEFORE_ACTION;
-
-
-do_action:     /* This label is used only to access EOF actions. */
-
-
-               switch ( yy_act )
-       { /* beginning of action switch */
-                       case 0: /* must back up */
-                       /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = yy_hold_char;
-                       yy_cp = yy_last_accepting_cpos;
-                       yy_current_state = yy_last_accepting_state;
-                       goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 69 "configfile.l"
-lineCount++ ;
-       YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 71 "configfile.l"
-{ return (COLON) ; }
-       YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 73 "configfile.l"
-{ return (LBRACE) ; }
-       YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 75 "configfile.l"
-{ return (RBRACE) ; }
-       YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 77 "configfile.l"
-{ return (PEER) ; }
-       YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 79 "configfile.l"
-BEGIN(incl);
-       YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 81 "configfile.l"
-/* eat the whitespace before include filename */
-       YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 83 "configfile.l"
-{
-  if (include_stack_ptr == MAX_INCLUDE_DEPTH - 1)
-    {
-      int i ;
-      fprintf( stderr, "Includes nested too deeply:\n" );
-      for (i = 1 ; i <= include_stack_ptr ; i++)
-        fprintf (stderr,"\t%s\n",include_stack[i].name) ;
-      
-      syslog (LOG_ERR, "includes nested to deeply") ;
-      exit( 1 );
-    }
-
-  if ((yyin = fopen(yytext,"r")) == NULL)
-    {
-      syslog (LOG_CRIT,"include file fopen failed: %s %s",
-              yytext,strerror(errno));
-      fprintf (stderr,"include file fopen failed: %s %s\n",
-               yytext,strerror(errno));
-      exit (1) ;
-    }
-  else
-    {
-      d_printf (1,"Including (%d) from %s\n",
-               include_stack_ptr + 1,yytext) ;
-      include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
-      include_stack[++include_stack_ptr].name = xstrdup (yytext) ;
-      yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-    }
-
-  BEGIN(INITIAL);
-}
-       YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(incl):
-#line 115 "configfile.l"
-{
-  if ( include_stack_ptr <= 0 )
-    yyterminate();
-  else
-    {
-      free (include_stack[include_stack_ptr].name) ;
-      yy_delete_buffer(YY_CURRENT_BUFFER);
-      yy_switch_to_buffer(include_stack[--include_stack_ptr].state);
-    }
-}
-       YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 126 "configfile.l"
-{ return (GROUP) ; }
-       YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 128 "configfile.l"
-{ (void) 0 ; }
-       YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 130 "configfile.l"
-{ (void) 1 ; }
-       YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 132 "configfile.l"
-{
-       switch (yytext[2]) {
-               case '\\': yylval.chr = '\\' ; break ;
-               case 'a': yylval.chr = 007 ; break ;
-               case 'b': yylval.chr = 010 ; break ;
-               case 'f': yylval.chr = 014 ; break ;
-               case 'n': yylval.chr = 012 ; break ;
-               case 'r': yylval.chr = 015 ; break ;
-               case 't': yylval.chr = 011 ; break ;
-               case 'v': yylval.chr = 013 ; break ;
-       }
-       return (CHAR) ; }
-       YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 145 "configfile.l"
-{ yylval.chr = yytext[1] ; return (CHAR) ; }
-       YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 147 "configfile.l"
-{ yylval.chr = (char)strtol(&yytext[2], (char **)NULL, 8);
-                         return (CHAR) ;}
-       YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 150 "configfile.l"
-{{
-       int i ;
-
-       for (i = 1, strIdx = 0, sawBsl = 0 ; ; i++)
-          {
-            if (i < yyleng)
-              current = yytext [i] ;
-            else
-              current = input() ;
-            
-            if (current != EOF)
-              {
-                switch (current)
-                  {
-                    case '\\': 
-                      if (sawBsl)
-                        {
-                          strAppend (current) ;
-                          sawBsl = 0 ;
-                        }
-                      else
-                        sawBsl = 1 ;
-                      break ;
-
-                    case '\n': 
-                      if (!sawBsl)
-                        strAppend(current) ;
-                      sawBsl = 0 ;
-                      lineCount++ ;
-                      break ;
-
-                    case '\"': 
-                      if (sawBsl)
-                        { 
-                          strAppend (current) ;
-                          sawBsl = 0 ;
-                        }
-                      else
-                        {
-                          strAppend ('\0') ;
-                          yylval.string = strPtr ;
-                          strPtr = 0 ;
-                          strPtrLen = strIdx = 0 ;
-                          return (XSTRING) ;
-                        }
-                      break ;
-
-                    case 'a':
-                    case 'b':
-                    case 'f':
-                    case 'n':
-                    case 'r':
-                    case 't':
-                    case 'v':
-                      if (sawBsl)
-                        {
-                          switch (current) 
-                            {
-                              case 'a': strAppend (007) ; break ;
-                              case 'b': strAppend (010) ; break ;
-                              case 'f': strAppend (014) ; break ;
-                              case 'n': strAppend (012) ; break ;
-                              case 'r': strAppend (015) ; break ;
-                              case 't': strAppend (011) ; break ;
-                              case 'v': strAppend (013) ; break ;
-                            }
-                          sawBsl = 0 ;
-                        }
-                      else
-                        strAppend (current) ;
-                      break ;
-
-                    default:   
-                      strAppend (current) ;
-                      sawBsl = 0 ;
-                      break ;
-                  }
-              }
-            else
-              {
-                return (XSTRING) ;
-              }
-          }
-}}
-       YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 235 "configfile.l"
-{ yylval.integer = atoi (yytext) ; return (IVAL) ; }
-       YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 237 "configfile.l"
-{ yylval.real = atof (yytext) ; return (RVAL) ; }
-       YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 239 "configfile.l"
-{
-  yylval.name = xstrdup (yytext) ;
-  if (strcasecmp (yylval.name,"false") == 0)
-    return (FALSEBVAL) ;
-  else if (strcasecmp (yylval.name,"true") == 0)
-    return (TRUEBVAL) ;
-  else
-  return (WORD) ;
-}
-       YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 249 "configfile.l"
-ECHO;
-       YY_BREAK
-#line 968 "lex.yy.c"
-
-       case YY_END_OF_BUFFER:
-               {
-               /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
-
-               /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = yy_hold_char;
-               YY_RESTORE_YY_MORE_OFFSET
-
-               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
-                       {
-                       /* We're scanning a new file or input source.  It's
-                        * possible that this happened because the user
-                        * just pointed yyin at a new source and called
-                        * yylex().  If so, then we have to assure
-                        * consistency between yy_current_buffer and our
-                        * globals.  Here is the right place to do so, because
-                        * this is the first action (other than possibly a
-                        * back-up) that will match for the new input source.
-                        */
-                       yy_n_chars = yy_current_buffer->yy_n_chars;
-                       yy_current_buffer->yy_input_file = yyin;
-                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
-                       }
-
-               /* Note that here we test for yy_c_buf_p "<=" to the position
-                * of the first EOB in the buffer, since yy_c_buf_p will
-                * already have been incremented past the NUL character
-                * (since all states make transitions on EOB to the
-                * end-of-buffer state).  Contrast this with the test
-                * in input().
-                */
-               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
-                       { /* This was really a NUL. */
-                       yy_state_type yy_next_state;
-
-                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
-
-                       yy_current_state = yy_get_previous_state();
-
-                       /* Okay, we're now positioned to make the NUL
-                        * transition.  We couldn't have
-                        * yy_get_previous_state() go ahead and do it
-                        * for us because it doesn't know how to deal
-                        * with the possibility of jamming (and we don't
-                        * want to build jamming into it because then it
-                        * will run more slowly).
-                        */
-
-                       yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-                       yy_bp = yytext_ptr + YY_MORE_ADJ;
-
-                       if ( yy_next_state )
-                               {
-                               /* Consume the NUL. */
-                               yy_cp = ++yy_c_buf_p;
-                               yy_current_state = yy_next_state;
-                               goto yy_match;
-                               }
-
-                       else
-                               {
-                               yy_cp = yy_c_buf_p;
-                               goto yy_find_action;
-                               }
-                       }
-
-               else switch ( yy_get_next_buffer() )
-                       {
-                       case EOB_ACT_END_OF_FILE:
-                               {
-                               yy_did_buffer_switch_on_eof = 0;
-
-                               if ( yywrap() )
-                                       {
-                                       /* Note: because we've taken care in
-                                        * yy_get_next_buffer() to have set up
-                                        * yytext, we can now set up
-                                        * yy_c_buf_p so that if some total
-                                        * hoser (like flex itself) wants to
-                                        * call the scanner after we return the
-                                        * YY_NULL, it'll still work - another
-                                        * YY_NULL will get returned.
-                                        */
-                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
-
-                                       yy_act = YY_STATE_EOF(YY_START);
-                                       goto do_action;
-                                       }
-
-                               else
-                                       {
-                                       if ( ! yy_did_buffer_switch_on_eof )
-                                               YY_NEW_FILE;
-                                       }
-                               break;
-                               }
-
-                       case EOB_ACT_CONTINUE_SCAN:
-                               yy_c_buf_p =
-                                       yytext_ptr + yy_amount_of_matched_text;
-
-                               yy_current_state = yy_get_previous_state();
-
-                               yy_cp = yy_c_buf_p;
-                               yy_bp = yytext_ptr + YY_MORE_ADJ;
-                               goto yy_match;
-
-                       case EOB_ACT_LAST_MATCH:
-                               yy_c_buf_p =
-                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
-
-                               yy_current_state = yy_get_previous_state();
-
-                               yy_cp = yy_c_buf_p;
-                               yy_bp = yytext_ptr + YY_MORE_ADJ;
-                               goto yy_find_action;
-                       }
-               break;
-               }
-
-       default:
-               YY_FATAL_ERROR(
-                       "fatal flex scanner internal error--no action found" );
-       } /* end of action switch */
-               } /* end of scanning one token */
-       } /* end of yylex */
-
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *     EOB_ACT_LAST_MATCH -
- *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *     EOB_ACT_END_OF_FILE - end of file
- */
-
-static int yy_get_next_buffer()
-       {
-       register char *dest = yy_current_buffer->yy_ch_buf;
-       register char *source = yytext_ptr;
-       register int number_to_move, i;
-       int ret_val;
-
-       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
-               YY_FATAL_ERROR(
-               "fatal flex scanner internal error--end of buffer missed" );
-
-       if ( yy_current_buffer->yy_fill_buffer == 0 )
-               { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
-                       {
-                       /* We matched a single character, the EOB, so
-                        * treat this as a final EOF.
-                        */
-                       return EOB_ACT_END_OF_FILE;
-                       }
-
-               else
-                       {
-                       /* We matched some text prior to the EOB, first
-                        * process it.
-                        */
-                       return EOB_ACT_LAST_MATCH;
-                       }
-               }
-
-       /* Try to read more data. */
-
-       /* First move last chars to start of buffer. */
-       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
-
-       for ( i = 0; i < number_to_move; ++i )
-               *(dest++) = *(source++);
-
-       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-               /* don't do the read, it's not guaranteed to return an EOF,
-                * just force an EOF
-                */
-               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
-
-       else
-               {
-               int num_to_read =
-                       yy_current_buffer->yy_buf_size - number_to_move - 1;
-
-               while ( num_to_read <= 0 )
-                       { /* Not enough room in the buffer - grow it. */
-#ifdef YY_USES_REJECT
-                       YY_FATAL_ERROR(
-"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-#else
-
-                       /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = yy_current_buffer;
-
-                       int yy_c_buf_p_offset =
-                               (int) (yy_c_buf_p - b->yy_ch_buf);
-
-                       if ( b->yy_is_our_buffer )
-                               {
-                               int new_size = b->yy_buf_size * 2;
-
-                               if ( new_size <= 0 )
-                                       b->yy_buf_size += b->yy_buf_size / 8;
-                               else
-                                       b->yy_buf_size *= 2;
-
-                               b->yy_ch_buf = (char *)
-                                       /* Include room in for 2 EOB chars. */
-                                       yy_flex_realloc( (void *) b->yy_ch_buf,
-                                                        b->yy_buf_size + 2 );
-                               }
-                       else
-                               /* Can't grow it, we don't own it. */
-                               b->yy_ch_buf = 0;
-
-                       if ( ! b->yy_ch_buf )
-                               YY_FATAL_ERROR(
-                               "fatal error - scanner input buffer overflow" );
-
-                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-                       num_to_read = yy_current_buffer->yy_buf_size -
-                                               number_to_move - 1;
-#endif
-                       }
-
-               if ( num_to_read > YY_READ_BUF_SIZE )
-                       num_to_read = YY_READ_BUF_SIZE;
-
-               /* Read in more data. */
-               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
-                       yy_n_chars, num_to_read );
-
-               yy_current_buffer->yy_n_chars = yy_n_chars;
-               }
-
-       if ( yy_n_chars == 0 )
-               {
-               if ( number_to_move == YY_MORE_ADJ )
-                       {
-                       ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart( yyin );
-                       }
-
-               else
-                       {
-                       ret_val = EOB_ACT_LAST_MATCH;
-                       yy_current_buffer->yy_buffer_status =
-                               YY_BUFFER_EOF_PENDING;
-                       }
-               }
-
-       else
-               ret_val = EOB_ACT_CONTINUE_SCAN;
-
-       yy_n_chars += number_to_move;
-       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
-       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
-       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
-
-       return ret_val;
-       }
-
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-static yy_state_type yy_get_previous_state()
-       {
-       register yy_state_type yy_current_state;
-       register char *yy_cp;
-
-       yy_current_state = yy_start;
-       yy_current_state += YY_AT_BOL();
-
-       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
-               {
-               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-               if ( yy_accept[yy_current_state] )
-                       {
-                       yy_last_accepting_state = yy_current_state;
-                       yy_last_accepting_cpos = yy_cp;
-                       }
-               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                       {
-                       yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 55 )
-                               yy_c = yy_meta[(unsigned int) yy_c];
-                       }
-               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-               }
-
-       return yy_current_state;
-       }
-
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *     next_state = yy_try_NUL_trans( current_state );
- */
-
-#ifdef YY_USE_PROTOS
-static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
-#else
-static yy_state_type yy_try_NUL_trans( yy_current_state )
-yy_state_type yy_current_state;
-#endif
-       {
-       register int yy_is_jam;
-       register char *yy_cp = yy_c_buf_p;
-
-       register YY_CHAR yy_c = 1;
-       if ( yy_accept[yy_current_state] )
-               {
-               yy_last_accepting_state = yy_current_state;
-               yy_last_accepting_cpos = yy_cp;
-               }
-       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-               {
-               yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 55 )
-                       yy_c = yy_meta[(unsigned int) yy_c];
-               }
-       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 54);
-
-       return yy_is_jam ? 0 : yy_current_state;
-       }
-
-
-#ifndef YY_NO_UNPUT
-#ifdef YY_USE_PROTOS
-static void yyunput( int c, register char *yy_bp )
-#else
-static void yyunput( c, yy_bp )
-int c;
-register char *yy_bp;
-#endif
-       {
-       register char *yy_cp = yy_c_buf_p;
-
-       /* undo effects of setting up yytext */
-       *yy_cp = yy_hold_char;
-
-       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
-               { /* need to shift things up to make room */
-               /* +2 for EOB chars. */
-               register int number_to_move = yy_n_chars + 2;
-               register char *dest = &yy_current_buffer->yy_ch_buf[
-                                       yy_current_buffer->yy_buf_size + 2];
-               register char *source =
-                               &yy_current_buffer->yy_ch_buf[number_to_move];
-
-               while ( source > yy_current_buffer->yy_ch_buf )
-                       *--dest = *--source;
-
-               yy_cp += (int) (dest - source);
-               yy_bp += (int) (dest - source);
-               yy_current_buffer->yy_n_chars =
-                       yy_n_chars = yy_current_buffer->yy_buf_size;
-
-               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
-                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
-               }
-
-       *--yy_cp = (char) c;
-
-
-       yytext_ptr = yy_bp;
-       yy_hold_char = *yy_cp;
-       yy_c_buf_p = yy_cp;
-       }
-#endif /* ifndef YY_NO_UNPUT */
-
-
-#ifdef __cplusplus
-static int yyinput()
-#else
-static int input()
-#endif
-       {
-       int c;
-
-       *yy_c_buf_p = yy_hold_char;
-
-       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
-               {
-               /* yy_c_buf_p now points to the character we want to return.
-                * If this occurs *before* the EOB characters, then it's a
-                * valid NUL; if not, then we've hit the end of the buffer.
-                */
-               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
-                       /* This was really a NUL. */
-                       *yy_c_buf_p = '\0';
-
-               else
-                       { /* need more input */
-                       int offset = yy_c_buf_p - yytext_ptr;
-                       ++yy_c_buf_p;
-
-                       switch ( yy_get_next_buffer() )
-                               {
-                               case EOB_ACT_LAST_MATCH:
-                                       /* This happens because yy_g_n_b()
-                                        * sees that we've accumulated a
-                                        * token and flags that we need to
-                                        * try matching the token before
-                                        * proceeding.  But for input(),
-                                        * there's no matching to consider.
-                                        * So convert the EOB_ACT_LAST_MATCH
-                                        * to EOB_ACT_END_OF_FILE.
-                                        */
-
-                                       /* Reset buffer status. */
-                                       yyrestart( yyin );
-
-                                       /* fall through */
-
-                               case EOB_ACT_END_OF_FILE:
-                                       {
-                                       if ( yywrap() )
-                                               return EOF;
-
-                                       if ( ! yy_did_buffer_switch_on_eof )
-                                               YY_NEW_FILE;
-#ifdef __cplusplus
-                                       return yyinput();
-#else
-                                       return input();
-#endif
-                                       }
-
-                               case EOB_ACT_CONTINUE_SCAN:
-                                       yy_c_buf_p = yytext_ptr + offset;
-                                       break;
-                               }
-                       }
-               }
-
-       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
-       *yy_c_buf_p = '\0';     /* preserve yytext */
-       yy_hold_char = *++yy_c_buf_p;
-
-       yy_current_buffer->yy_at_bol = (c == '\n');
-
-       return c;
-       }
-
-
-#ifdef YY_USE_PROTOS
-void yyrestart( FILE *input_file )
-#else
-void yyrestart( input_file )
-FILE *input_file;
-#endif
-       {
-       if ( ! yy_current_buffer )
-               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
-
-       yy_init_buffer( yy_current_buffer, input_file );
-       yy_load_buffer_state();
-       }
-
-
-#ifdef YY_USE_PROTOS
-void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-#else
-void yy_switch_to_buffer( new_buffer )
-YY_BUFFER_STATE new_buffer;
-#endif
-       {
-       if ( yy_current_buffer == new_buffer )
-               return;
-
-       if ( yy_current_buffer )
-               {
-               /* Flush out information for old buffer. */
-               *yy_c_buf_p = yy_hold_char;
-               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
-               yy_current_buffer->yy_n_chars = yy_n_chars;
-               }
-
-       yy_current_buffer = new_buffer;
-       yy_load_buffer_state();
-
-       /* We don't actually know whether we did this switch during
-        * EOF (yywrap()) processing, but the only time this flag
-        * is looked at is after yywrap() is called, so it's safe
-        * to go ahead and always set it.
-        */
-       yy_did_buffer_switch_on_eof = 1;
-       }
-
-
-#ifdef YY_USE_PROTOS
-void yy_load_buffer_state( void )
-#else
-void yy_load_buffer_state()
-#endif
-       {
-       yy_n_chars = yy_current_buffer->yy_n_chars;
-       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
-       yyin = yy_current_buffer->yy_input_file;
-       yy_hold_char = *yy_c_buf_p;
-       }
-
-
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-#else
-YY_BUFFER_STATE yy_create_buffer( file, size )
-FILE *file;
-int size;
-#endif
-       {
-       YY_BUFFER_STATE b;
-
-       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_buf_size = size;
-
-       /* yy_ch_buf has to be 2 characters longer than the size given because
-        * we need to put in 2 end-of-buffer characters.
-        */
-       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
-       if ( ! b->yy_ch_buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_is_our_buffer = 1;
-
-       yy_init_buffer( b, file );
-
-       return b;
-       }
-
-
-#ifdef YY_USE_PROTOS
-void yy_delete_buffer( YY_BUFFER_STATE b )
-#else
-void yy_delete_buffer( b )
-YY_BUFFER_STATE b;
-#endif
-       {
-       if ( ! b )
-               return;
-
-       if ( b == yy_current_buffer )
-               yy_current_buffer = (YY_BUFFER_STATE) 0;
-
-       if ( b->yy_is_our_buffer )
-               yy_flex_free( (void *) b->yy_ch_buf );
-
-       yy_flex_free( (void *) b );
-       }
-
-
-#ifndef _WIN32
-#include <unistd.h>
-#else
-#ifndef YY_ALWAYS_INTERACTIVE
-#ifndef YY_NEVER_INTERACTIVE
-extern int isatty YY_PROTO(( int ));
-#endif
-#endif
-#endif
-
-#ifdef YY_USE_PROTOS
-void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
-#else
-void yy_init_buffer( b, file )
-YY_BUFFER_STATE b;
-FILE *file;
-#endif
-
-
-       {
-       yy_flush_buffer( b );
-
-       b->yy_input_file = file;
-       b->yy_fill_buffer = 1;
-
-#if YY_ALWAYS_INTERACTIVE
-       b->yy_is_interactive = 1;
-#else
-#if YY_NEVER_INTERACTIVE
-       b->yy_is_interactive = 0;
-#else
-       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-#endif
-#endif
-       }
-
-
-#ifdef YY_USE_PROTOS
-void yy_flush_buffer( YY_BUFFER_STATE b )
-#else
-void yy_flush_buffer( b )
-YY_BUFFER_STATE b;
-#endif
-
-       {
-       if ( ! b )
-               return;
-
-       b->yy_n_chars = 0;
-
-       /* We always need two end-of-buffer characters.  The first causes
-        * a transition to the end-of-buffer state.  The second causes
-        * a jam in that state.
-        */
-       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-       b->yy_buf_pos = &b->yy_ch_buf[0];
-
-       b->yy_at_bol = 1;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       if ( b == yy_current_buffer )
-               yy_load_buffer_state();
-       }
-
-
-#ifndef YY_NO_SCAN_BUFFER
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
-#else
-YY_BUFFER_STATE yy_scan_buffer( base, size )
-char *base;
-yy_size_t size;
-#endif
-       {
-       YY_BUFFER_STATE b;
-
-       if ( size < 2 ||
-            base[size-2] != YY_END_OF_BUFFER_CHAR ||
-            base[size-1] != YY_END_OF_BUFFER_CHAR )
-               /* They forgot to leave room for the EOB's. */
-               return 0;
-
-       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
-       b->yy_buf_pos = b->yy_ch_buf = base;
-       b->yy_is_our_buffer = 0;
-       b->yy_input_file = 0;
-       b->yy_n_chars = b->yy_buf_size;
-       b->yy_is_interactive = 0;
-       b->yy_at_bol = 1;
-       b->yy_fill_buffer = 0;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       yy_switch_to_buffer( b );
-
-       return b;
-       }
-#endif
-
-
-#ifndef YY_NO_SCAN_STRING
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
-#else
-YY_BUFFER_STATE yy_scan_string( yy_str )
-yyconst char *yy_str;
-#endif
-       {
-       int len;
-       for ( len = 0; yy_str[len]; ++len )
-               ;
-
-       return yy_scan_bytes( yy_str, len );
-       }
-#endif
-
-
-#ifndef YY_NO_SCAN_BYTES
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
-#else
-YY_BUFFER_STATE yy_scan_bytes( bytes, len )
-yyconst char *bytes;
-int len;
-#endif
-       {
-       YY_BUFFER_STATE b;
-       char *buf;
-       yy_size_t n;
-       int i;
-
-       /* Get memory for full buffer, including space for trailing EOB's. */
-       n = len + 2;
-       buf = (char *) yy_flex_alloc( n );
-       if ( ! buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-       for ( i = 0; i < len; ++i )
-               buf[i] = bytes[i];
-
-       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
-
-       b = yy_scan_buffer( buf, n );
-       if ( ! b )
-               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-       /* It's okay to grow etc. this buffer, and we should throw it
-        * away when we're done.
-        */
-       b->yy_is_our_buffer = 1;
-
-       return b;
-       }
-#endif
-
-
-#ifndef YY_NO_PUSH_STATE
-#ifdef YY_USE_PROTOS
-static void yy_push_state( int new_state )
-#else
-static void yy_push_state( new_state )
-int new_state;
-#endif
-       {
-       if ( yy_start_stack_ptr >= yy_start_stack_depth )
-               {
-               yy_size_t new_size;
-
-               yy_start_stack_depth += YY_START_STACK_INCR;
-               new_size = yy_start_stack_depth * sizeof( int );
-
-               if ( ! yy_start_stack )
-                       yy_start_stack = (int *) yy_flex_alloc( new_size );
-
-               else
-                       yy_start_stack = (int *) yy_flex_realloc(
-                                       (void *) yy_start_stack, new_size );
-
-               if ( ! yy_start_stack )
-                       YY_FATAL_ERROR(
-                       "out of memory expanding start-condition stack" );
-               }
-
-       yy_start_stack[yy_start_stack_ptr++] = YY_START;
-
-       BEGIN(new_state);
-       }
-#endif
-
-
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
-       {
-       if ( --yy_start_stack_ptr < 0 )
-               YY_FATAL_ERROR( "start-condition stack underflow" );
-
-       BEGIN(yy_start_stack[yy_start_stack_ptr]);
-       }
-#endif
-
-
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
-       {
-       return yy_start_stack[yy_start_stack_ptr - 1];
-       }
-#endif
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
-#else
-static void yy_fatal_error( msg )
-char msg[];
-#endif
-       {
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-       }
-
-
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-               yytext[yyleng] = yy_hold_char; \
-               yy_c_buf_p = yytext + n; \
-               yy_hold_char = *yy_c_buf_p; \
-               *yy_c_buf_p = '\0'; \
-               yyleng = n; \
-               } \
-       while ( 0 )
-
-
-/* Internal utility routines. */
-
-#ifndef yytext_ptr
-#ifdef YY_USE_PROTOS
-static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
-#else
-static void yy_flex_strncpy( s1, s2, n )
-char *s1;
-yyconst char *s2;
-int n;
-#endif
-       {
-       register int i;
-       for ( i = 0; i < n; ++i )
-               s1[i] = s2[i];
-       }
-#endif
-
-#ifdef YY_NEED_STRLEN
-#ifdef YY_USE_PROTOS
-static int yy_flex_strlen( yyconst char *s )
-#else
-static int yy_flex_strlen( s )
-yyconst char *s;
-#endif
-       {
-       register int n;
-       for ( n = 0; s[n]; ++n )
-               ;
-
-       return n;
-       }
-#endif
-
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_alloc( yy_size_t size )
-#else
-static void *yy_flex_alloc( size )
-yy_size_t size;
-#endif
-       {
-       return (void *) malloc( size );
-       }
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_realloc( void *ptr, yy_size_t size )
-#else
-static void *yy_flex_realloc( ptr, size )
-void *ptr;
-yy_size_t size;
-#endif
-       {
-       /* The cast to (char *) in the following accommodates both
-        * implementations that use char* generic pointers, and those
-        * that use void* generic pointers.  It works with the latter
-        * because both ANSI C and C++ allow castless assignment from
-        * any pointer type to void*, and deal with argument conversions
-        * as though doing an assignment.
-        */
-       return (void *) realloc( (char *) ptr, size );
-       }
-
-#ifdef YY_USE_PROTOS
-static void yy_flex_free( void *ptr )
-#else
-static void yy_flex_free( ptr )
-void *ptr;
-#endif
-       {
-       free( ptr );
-       }
-
-#if YY_MAIN
-int main()
-       {
-       yylex();
-       return 0;
-       }
-#endif
-#line 249 "configfile.l"
-
-
-
-
diff --git a/innfeed/configfile.h b/innfeed/configfile.h
deleted file mode 100644 (file)
index 7d97266..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*  $Id: configfile.h 5801 2002-10-07 07:36:12Z rra $
-**
-**  Interface to innfeed's configuration file parser.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#if ! defined ( configfile_h__ )
-#define configfile_h__
-
-/* Avoid conflicts with parsedate.y's generated yacc code. */
-#define yy_yyv innfeed_yy_yyv
-#define yyact  innfeed_yyact
-#define yychk  innfeed_yychk
-#define yydef  innfeed_yydef
-#define yyexca innfeed_yyexca
-#define yylval innfeed_yylval
-#define yypact innfeed_yypact
-#define yypgo  innfeed_yypgo
-#define yyr1   innfeed_yyr1
-#define yyr2   innfeed_yyr2
-#define yys    innfeed_yys
-#define yyv    innfeed_yyv
-#define yyval  innfeed_yyval
-
-/* pointer to function taking void-star param and returning int. */
-typedef int (*PFIVP)(void *) ;
-
-typedef enum { intval, charval, boolval, realval, stringval, scopeval } tag ;
-  
-typedef struct _scope {
-    struct _value *me ;
-    char *scope_type ;
-    int value_count ;
-    int value_idx ;
-    struct _value **values ;
-    struct _scope *parent ;
-} scope ;
-
-typedef struct _value {
-    char *name ;
-    struct _scope *myscope ;
-    tag type ;
-    union {
-        char *charp_val ;
-        char char_val ;
-        double real_val ;
-        int bool_val ;
-        long int_val ;
-        struct _scope *scope_val ;
-    } v ;
-} value ;
-
-extern scope *topScope ;
-extern char *errbuff ;
-
-int isWord (scope *s, const char *name, int inherit) ;
-int isName (scope *s, const char *name, int inherit) ;
-
-int getReal (scope *s, const char *name, double *rval, int inherit) ;
-int getInteger (scope *s, const char *name, long *rval, int inherit) ;
-int getBool (scope *s, const char *name, int *rval, int inherit) ;
-int getString (scope *s, const char *name, char **rval, int inherit) ;
-int getWord (scope *s, const char *name, char **rval, int inherit) ;
-
-void freeScopeTree (scope *s) ;
-char *addInteger (scope *s, const char *name, long val) ;
-char *addChar (scope *s, const char *name, char val) ;
-char *addBoolean (scope *s, const char *name, int val) ;
-char *addName (scope *s, const char *name, char *val) ;
-char *addWord (scope *s, const char *name, char *val) ;
-char *addReal (scope *s, const char *name, double val) ;
-char *addString (scope *s, const char *name, const char *val) ;
-scope *findScope (scope *s, const char *name, int mustExist) ;
-value *findValue (scope *s, const char *name, int inherit) ;
-value *findPeer (const char *name) ;
-value *getNextPeer (int *cookie) ;
-void configAddLoadCallback (PFIVP func,void *arg) ;
-void configRemoveLoadCallback (PFIVP func) ;
-int readConfig (const char *file, FILE *errorDest, int justCheck, int dump) ;
-int buildPeerTable (FILE *fp, scope *currScope);
-void configCleanup (void) ;
-
-#define ARTICLE_TIMEOUT "article-timeout"
-#define BACKLOG_LIMIT "backlog-limit"
-#define INITIAL_CONNECTIONS "initial-connections"
-#define IP_NAME "ip-name"
-#define MAX_CONNECTIONS "max-connections"
-#define MAX_QUEUE_SIZE "max-queue-size"
-#define NO_CHECK_HIGH "no-check-high"
-#define NO_CHECK_LOW "no-check-low"
-#define PORT_NUMBER "port-number"
-#define RESP_TIMEOUT "response-timeout"
-#define STREAMING "streaming"
-#define DROP_DEFERRED "drop-deferred"
-
-#define ISPEER(V) (ISSCOPE(V) && strcmp ((V)->v.scope_val->scope_type,"peer") == 0)
-#define ISSCOPE(V) (V->type == scopeval)
-
-#define INHERIT 1
-#define NO_INHERIT 0
-
-/* Interface between lexer and parser. */
-int yylex (void) ; 
-
-#endif /* configfile_h__ */
diff --git a/innfeed/configfile.l b/innfeed/configfile.l
deleted file mode 100644 (file)
index 07fee4c..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-%{
-/*  $Id: configfile.l 6145 2003-01-19 19:42:22Z rra $
-**
-**  A flex input file for the innfeed config file.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "libinn.h"
-
-#include "configfile.h"
-#include "config_y.h"
-#include "misc.h"
-
-#if ! defined (FLEX_SCANNER)
-#error "You must use FLEX to process the lex input file."
-#endif
-
-#if defined (FLEX_DEBUG)
-#define YY_USER_INIT yy_flex_debug = (getenv ("YYDEBUG") == NULL ? 0 : 1)
-#endif
-
-/* We never use this function but flex always defines it, so silence the
-   warnings about it. */
-static void yyunput(int, char *) UNUSED;
-
-char *strPtr = 0 ;
-int strPtrLen = 0 ;
-int strIdx = 0 ;
-int sawBsl ;
-int lineCount = 0 ;
-int current ;
-
-static void strAppend (int ch);
-static void strAppend (int ch)
-{
-  if (strIdx == strPtrLen)
-    {
-      if (strPtr == 0)
-        strPtr = xmalloc (strPtrLen = 50) ;
-      else
-        strPtr = xrealloc (strPtr,strPtrLen += 10) ;
-    }
-  strPtr [strIdx++] = ch ;
-}
-
-#define MAX_INCLUDE_DEPTH 11
-struct includeFile {
-    YY_BUFFER_STATE state;
-    char *name ;
-} include_stack[MAX_INCLUDE_DEPTH];
-int include_stack_ptr = 0;
-
-%}
-
-%x incl
-
-ID     [a-zA-Z][-a-zA-Z0-9._/]+
-
-%%
-
-\n                     lineCount++ ;
-
-":"                    { return (COLON) ; }
-
-"{"                    { return (LBRACE) ; }
-
-"}"                    { return (RBRACE) ; }
-
-[pP][eE][eE][rR]       { return (PEER) ; }
-
-^"$INCLUDE"            BEGIN(incl);
-
-<incl>[ \t]*           /* eat the whitespace before include filename */
-
-<incl>[^ \t\n]+                {
-  if (include_stack_ptr == MAX_INCLUDE_DEPTH - 1)
-    {
-      int i ;
-      fprintf( stderr, "Includes nested too deeply:\n" );
-      for (i = 1 ; i <= include_stack_ptr ; i++)
-        fprintf (stderr,"\t%s\n",include_stack[i].name) ;
-      
-      syslog (LOG_ERR, "includes nested to deeply") ;
-      exit( 1 );
-    }
-
-  if ((yyin = fopen(yytext,"r")) == NULL)
-    {
-      syslog (LOG_CRIT,"include file fopen failed: %s %s",
-              yytext,strerror(errno));
-      fprintf (stderr,"include file fopen failed: %s %s\n",
-               yytext,strerror(errno));
-      exit (1) ;
-    }
-  else
-    {
-      d_printf (1,"Including (%d) from %s\n",
-               include_stack_ptr + 1,yytext) ;
-      include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
-      include_stack[++include_stack_ptr].name = xstrdup (yytext) ;
-      yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-    }
-
-  BEGIN(INITIAL);
-}
-
-<<EOF>> {
-  if ( include_stack_ptr <= 0 )
-    yyterminate();
-  else
-    {
-      free (include_stack[include_stack_ptr].name) ;
-      yy_delete_buffer(YY_CURRENT_BUFFER);
-      yy_switch_to_buffer(include_stack[--include_stack_ptr].state);
-    }
-}
-
-[gG][rR][oO][uU][pP]   { return (GROUP) ; }
-
-#[^\n]*                        { (void) 0 ; }
-
-[ \t]+                 { (void) 1 ; }
-
-'\\[\\abfnrtv]'                {
-       switch (yytext[2]) {
-               case '\\': yylval.chr = '\\' ; break ;
-               case 'a': yylval.chr = 007 ; break ;
-               case 'b': yylval.chr = 010 ; break ;
-               case 'f': yylval.chr = 014 ; break ;
-               case 'n': yylval.chr = 012 ; break ;
-               case 'r': yylval.chr = 015 ; break ;
-               case 't': yylval.chr = 011 ; break ;
-               case 'v': yylval.chr = 013 ; break ;
-       }
-       return (CHAR) ; }
-
-'.'                    { yylval.chr = yytext[1] ; return (CHAR) ; }
-
-'\\[0-9][0-9][0-9]'    { yylval.chr = (char)strtol(&yytext[2], (char **)NULL, 8);
-                         return (CHAR) ;}
-
-\"[^\"]*       {{
-       int i ;
-
-       for (i = 1, strIdx = 0, sawBsl = 0 ; ; i++)
-          {
-            if (i < yyleng)
-              current = yytext [i] ;
-            else
-              current = input() ;
-            
-            if (current != EOF)
-              {
-                switch (current)
-                  {
-                    case '\\': 
-                      if (sawBsl)
-                        {
-                          strAppend (current) ;
-                          sawBsl = 0 ;
-                        }
-                      else
-                        sawBsl = 1 ;
-                      break ;
-
-                    case '\n': 
-                      if (!sawBsl)
-                        strAppend(current) ;
-                      sawBsl = 0 ;
-                      lineCount++ ;
-                      break ;
-
-                    case '\"': 
-                      if (sawBsl)
-                        { 
-                          strAppend (current) ;
-                          sawBsl = 0 ;
-                        }
-                      else
-                        {
-                          strAppend ('\0') ;
-                          yylval.string = strPtr ;
-                          strPtr = 0 ;
-                          strPtrLen = strIdx = 0 ;
-                          return (XSTRING) ;
-                        }
-                      break ;
-
-                    case 'a':
-                    case 'b':
-                    case 'f':
-                    case 'n':
-                    case 'r':
-                    case 't':
-                    case 'v':
-                      if (sawBsl)
-                        {
-                          switch (current) 
-                            {
-                              case 'a': strAppend (007) ; break ;
-                              case 'b': strAppend (010) ; break ;
-                              case 'f': strAppend (014) ; break ;
-                              case 'n': strAppend (012) ; break ;
-                              case 'r': strAppend (015) ; break ;
-                              case 't': strAppend (011) ; break ;
-                              case 'v': strAppend (013) ; break ;
-                            }
-                          sawBsl = 0 ;
-                        }
-                      else
-                        strAppend (current) ;
-                      break ;
-
-                    default:   
-                      strAppend (current) ;
-                      sawBsl = 0 ;
-                      break ;
-                  }
-              }
-            else
-              {
-                return (XSTRING) ;
-              }
-          }
-}}
-
-[-0-9][0-9]*           { yylval.integer = atoi (yytext) ; return (IVAL) ; }
-
-[-0-9][0-9]*\.[0-9]*   { yylval.real = atof (yytext) ; return (RVAL) ; }
-
-[^#:\'\" \t\n]+        {
-  yylval.name = xstrdup (yytext) ;
-  if (strcasecmp (yylval.name,"false") == 0)
-    return (FALSEBVAL) ;
-  else if (strcasecmp (yylval.name,"true") == 0)
-    return (TRUEBVAL) ;
-  else
-  return (WORD) ;
-}
-
-%%
-
-
-
diff --git a/innfeed/configfile.y b/innfeed/configfile.y
deleted file mode 100644 (file)
index 007bf0e..0000000
+++ /dev/null
@@ -1,1103 +0,0 @@
-%{
-/*  $Id: configfile.y 6372 2003-05-31 19:48:28Z rra $
-**
-**  A yacc input file for the innfeed config file.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  This file contains the heart of the innfeed configuration parser, written
-**  in yacc.  It uses an external lexer generated by flex.
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <ctype.h>
-#include <syslog.h>
-
-#if defined(_HPUX_SOURCE)
-# include <alloca.h>
-#endif
-  
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "configfile.h"
-#include "misc.h"
-
-#define UNKNOWN_SCOPE_TYPE "line %d: unknown scope type: %s"
-#define SYNTAX_ERROR "line %d: syntax error"
-
-extern int lineCount ;
-scope *topScope = NULL ;
-static scope *currScope = NULL ;
-char *errbuff = NULL ;
-
-static void appendName (scope *s, char *p, size_t len) ;
-static char *valueScopedName (value *v) ;
-static void freeValue (value *v) ;
-static char *checkName (scope *s, const char *name) ;
-static void addValue (scope *s, value *v) ;
-static char *addScope (scope *s, const char *name, scope *val) ;
-static void printScope (FILE *fp, scope *s, int indent) ;
-static void printValue (FILE *fp, value *v, int indent) ;
-static scope *newScope (const char *type) ;
-#if 0
-static int strNCaseCmp (const char *a, const char *b, size_t len) ;
-#endif 
-
-int yyerror (const char *s) ;
-int yywrap (void) ;
-int yyparse (void) ;
-
-
-#if 0
-int isString (scope *s, const char *name, int inherit)
-{
-  value *v = findValue (s,name,inherit) ;
-
-  return (v != NULL && v->type == stringval) ;
-}
-#endif 
-
-int getBool (scope *s, const char *name, int *rval, int inherit)
-{
-  value *v = findValue (s,name,inherit) ;
-
-  if (v == NULL)
-    return 0 ;
-  else if (v->type != boolval)
-    return 0 ;
-
-  *rval = v->v.bool_val ;
-  return 1 ;
-}
-
-
-int getString (scope *s, const char *name, char **rval, int inherit)
-{
-  value *v = findValue (s,name,inherit) ;
-
-  if (v == NULL)
-    return 0 ;
-  else if (v->type != stringval)
-    return 0 ;
-
-  *rval = xstrdup (v->v.charp_val) ;
-  return 1 ;
-}
-
-
-int getReal (scope *s, const char *name, double *rval, int inherit)
-{
-  value *v = findValue (s,name,inherit) ;
-
-  if (v == NULL)
-    return 0 ;
-  else if (v->type != realval)
-    return 0 ;
-
-  *rval = v->v.real_val ;
-  return 1 ;
-}
-
-int getInteger (scope *s, const char *name, long *rval, int inherit)
-{
-  value *v = findValue (s,name,inherit) ;
-
-  if (v == NULL)
-    return 0 ;
-  else if (v->type != intval)
-    return 0 ;
-
-  *rval = v->v.int_val ;
-  return 1 ;
-}
-
-void freeScopeTree (scope *s)
-{
-  int i ;
-
-  if (s == NULL)
-    return ;
-
-  if (s->parent == NULL && s->me != NULL) 
-    {                           /* top level scope */
-      free (s->me->name) ;
-      free (s->me) ;
-    }
-  
-  
-  for (i = 0 ; i < s->value_idx ; i++)
-    if (s->values[i] != NULL)
-       freeValue (s->values [i]) ;
-
-  free (s->values) ;
-  free (s->scope_type) ;
-
-  s->parent = NULL ;
-  s->values = NULL ;
-
-  free (s) ;
-}
-
-
-char *addInteger (scope *s, const char *name, long val) 
-{
-  value *v ;
-  char *error ;
-  
-  if ((error = checkName (currScope,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = intval ;
-  v->v.int_val = val ;
-  
-  addValue (s,v) ;
-
-  return NULL ;
-}
-
-char *addChar (scope *s, const char *name, char val) 
-{
-  value *v ;
-  char *error ;
-  
-  if ((error = checkName (currScope,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = charval ;
-  v->v.char_val = val ;
-  
-  addValue (s,v) ;
-
-  return NULL ;
-}
-
-char *addBoolean (scope *s, const char *name, int val) 
-{
-  value *v ;
-  char *error ;
-  
-  if ((error = checkName (currScope,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = boolval ;
-  v->v.bool_val = val ;
-  
-  addValue (s,v) ;
-
-  return NULL ;
-}
-
-char *addReal (scope *s, const char *name, double val)
-{
-  value *v ;
-  char *error ;
-
-  if ((error = checkName (currScope,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = realval ;
-  v->v.real_val = val ;
-  
-  addValue (s,v) ;
-
-  return NULL ;
-}
-
-char *addString (scope *s, const char *name, const char *val)
-{
-  value *v ;
-  char *error ;
-
-  if ((error = checkName (currScope,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = stringval ;
-  v->v.charp_val = xstrdup (val) ;
-  
-  addValue (s,v) ;
-
-  return NULL ;
-}
-
-value *findValue (scope *s, const char *name, int inherit) 
-{
-  const char *p ;
-  
-  if (name == NULL || *name == '\0')
-    return NULL ;
-
-  if (*name == ':')
-    return findValue (topScope,name + 1,0) ;
-  else if (s == NULL)
-    return findValue (topScope,name,0) ;
-  else 
-    {
-      int i ;
-      
-      if ((p = strchr (name,':')) == NULL)
-        p = name + strlen (name) ;
-
-      for (i = 0 ; i < s->value_idx ; i++)
-        {
-          if (strlen (s->values[i]->name) == (size_t) (p - name) &&
-              strncmp (s->values[i]->name,name,p - name) == 0)
-            {
-              if (*p == '\0')     /* last segment of name */
-                return s->values[i] ;
-              else if (s->values[i]->type != scopeval)
-                errbuff = xstrdup ("Component not a scope") ;
-              else
-                return findValue (s->values[i]->v.scope_val,p + 1,0) ;
-            }
-        }
-
-      /* not in this scope. Go up if inheriting values and only if no ':'
-         in name */
-      if (inherit && *p == '\0')
-        return findValue (s->parent,name,inherit) ;
-    }
-
-  return NULL ;
-}
-
-/* find the scope that name belongs to. If mustExist is true then the name
-   must be a fully scoped name of a value. relative scopes start at s.  */
-scope *findScope (scope *s, const char *name, int mustExist)
-{
-  scope *p = NULL ;
-  char *q ;
-  int i ;
-
-  
-  if ((q = strchr (name,':')) == NULL)
-    {
-      if (!mustExist)
-        p = s ;
-      else
-        for (i = 0 ; p == NULL && i < s->value_idx ; i++)
-          if (strcmp (s->values[i]->name,name) == 0)
-            p = s ;
-      
-      return p ;
-    }
-  else if (*name == ':')
-    {
-      while (s->parent != NULL)
-        s = s->parent ;
-
-      return findScope (s,name + 1,mustExist) ;
-    }
-  else
-    {
-      for (i = 0 ; i < s->value_idx ; i++)
-        if (strncmp (s->values[i]->name,name,q - name) == 0)
-          if (s->values[i]->type == scopeval)
-            return findScope (s->values[i]->v.scope_val,q + 1,mustExist) ;
-    }
-
-  return NULL ;
-}
-
-/****************************************************************************/
-/*                                                                          */
-/****************************************************************************/
-
-
-static void appendName (scope *s, char *p, size_t len)
-{
-  if (s == NULL)
-    return ;
-  else
-    {
-      appendName (s->parent,p,len) ;
-      strlcat (p,s->me->name,len) ;
-      strlcat (p,":",len) ;
-    }
-}
-
-static char *valueScopedName (value *v)
-{
-  scope *p = v->myscope ;
-  int len = strlen (v->name) ;
-  char *q ;
-  
-  while (p != NULL)
-    {
-      len += strlen (p->me->name) + 1 ;
-      p = p->parent ;
-    }
-  len++;
-
-  q = xmalloc (len) ;
-  q [0] = '\0' ;
-  appendName (v->myscope,q,len) ;
-  strlcat (q,v->name,len) ;
-
-  return q ;
-}
-
-static void freeValue (value *v)
-{
-  free (v->name) ;
-  switch (v->type)
-    {
-      case scopeval:
-        freeScopeTree (v->v.scope_val) ;
-        break ;
-
-      case stringval:
-        free (v->v.charp_val) ;
-        break ;
-
-      default:
-        break ;
-    }
-  free (v) ;
-}
-
-static char *checkName (scope *s, const char *name)
-{
-  int i ;      
-  char *error = NULL ;
-
-  if (s == NULL)
-    return NULL ;
-  
-  for (i = 0 ; i < s->value_idx ; i++)
-    {
-      char *n = NULL ;
-      
-      if (strcmp (name,s->values [i]->name) == 0) {
-        n = valueScopedName (s->values[i]) ;
-        error = concat ("Two definitions of ", n, (char *) 0) ;
-        free (n) ;
-        return error ;
-      }
-    }
-  
-  return error ;
-}
-
-
-static void addValue (scope *s, value *v) 
-{
-  v->myscope = s ;
-  
-  if (s == NULL)
-    return ;
-      
-  if (s->value_count == s->value_idx)
-    {
-      if (s->values == 0)
-        {
-          s->values = (value **) calloc (10,sizeof (value *)) ;
-          s->value_count = 10 ;
-        }
-      else
-        {
-          s->value_count += 10 ;
-          s->values = (value **) realloc (s->values,
-                                          sizeof (value *) * s->value_count);
-        }
-    }
-  
-  s->values [s->value_idx++] = v ;
-}
-
-
-
-static char *addScope (scope *s, const char *name, scope *val)
-{
-  value *v ;
-  char *error ;
-
-  if ((error = checkName (s,name)) != NULL)
-    return error ;
-
-  v = (value *) calloc (1,sizeof (value)) ;
-  v->name = xstrdup (name) ;
-  v->type = scopeval ;
-  v->v.scope_val = val ;
-  val->me = v ;
-  val->parent = s ;
-
-  addValue (s,v) ;
-
-  currScope = val ;
-
-  return NULL ;
-}
-
-
-static void printScope (FILE *fp, scope *s, int indent)
-{
-  int i ;
-  for (i = 0 ; i < s->value_idx ; i++)
-    printValue (fp,s->values [i],indent + 5) ;
-}
-
-static void printValue (FILE *fp, value *v, int indent) 
-{
-  int i ;
-  
-  for (i = 0 ; i < indent ; i++)
-    fputc (' ',fp) ;
-  
-  switch (v->type) 
-    {
-      case intval:
-        fprintf (fp,"%s : %ld # INTEGER\n",v->name,v->v.int_val) ;
-        break ;
-        
-      case stringval:
-        fprintf (fp,"%s : \"",v->name) ;
-        {
-          char *p = v->v.charp_val ;
-          while (*p) 
-            {
-              if (*p == '"' || *p == '\\')
-                fputc ('\\',fp) ;
-              fputc (*p,fp) ;
-              p++ ;
-            }
-        }
-        fprintf (fp,"\" # STRING\n") ;
-        break ;
-
-      case charval:
-        fprintf (fp,"%s : %c",v->name,047) ;
-        switch (v->v.char_val)
-          {
-            case '\\':
-              fprintf (fp,"\\\\") ;
-              break ;
-
-            default:
-              if (CTYPE (isprint, v->v.char_val))
-                fprintf (fp,"%c",v->v.char_val) ;
-              else
-                fprintf (fp,"\\%03o",v->v.char_val) ;
-          }
-        fprintf (fp,"%c # CHARACTER\n",047) ;
-        break ;
-        
-      case realval:
-        fprintf (fp,"%s : %f # REAL\n",v->name,v->v.real_val) ;
-        break ;
-
-      case boolval:
-        fprintf (fp,"%s : %s # BOOLEAN\n",
-                 v->name,(v->v.bool_val ? "true" : "false")) ;
-        break ;
-        
-      case scopeval:
-        fprintf (fp,"%s %s { # SCOPE\n",v->v.scope_val->scope_type,v->name) ;
-        printScope (fp,v->v.scope_val,indent + 5) ;
-        for (i = 0 ; i < indent ; i++)
-          fputc (' ',fp) ;
-        fprintf (fp,"}\n") ;
-        break ;
-
-      default:
-        fprintf (fp,"UNKNOWN value type: %d\n",v->type) ;
-        exit (1) ;
-    }
-}
-
-  
-
-static scope *newScope (const char *type)
-{
-  scope *t ;
-  int i ;
-  
-  t = (scope *) calloc (1,sizeof (scope)) ;
-  t->parent = NULL ;
-  t->scope_type = xstrdup (type) ;
-
-  for (i = 0 ; t->scope_type[i] != '\0' ; i++)
-    t->scope_type[i] = tolower (t->scope_type[i]) ;
-
-  return t ;
-}
-
-
-
-#if 0
-static int strNCaseCmp (const char *a, const char *b, size_t len)
-{
-  while (a && b && *a && *b && (tolower (*a) == tolower (*b)) && len > 0)
-    a++, b++, len-- ;
-
-  if (a == NULL && b == NULL)
-    return 0 ;
-  else if (a == NULL)
-    return 1 ;
-  else if (b == NULL)
-    return -1 ;
-  else if (*a == '\0' && *b == '\0')
-    return 0 ;
-  else if (*a == '\0')
-    return 1 ;
-  else if (*b == '\0')
-    return -1 ;
-  else if (*a < *b)
-    return 1 ;
-  else if (*a > *b)
-    return -1 ;
-  else
-    return 0 ;
-
-  abort () ;
-}
-#endif
-
-#define BAD_KEY "line %d: illegal key name: %s"
-#define NON_ALPHA "line %d: keys must start with a letter: %s"
-
-static char *keyOk (const char *key) 
-{
-  const char *p = key ;
-  char *rval ;
-
-  if (key == NULL)
-    {
-      rval = xmalloc (strlen ("line : NULL key") + 15) ;
-      sprintf (rval,"line %d: NULL key", lineCount) ;
-      return rval ;
-    }
-  else if (*key == '\0')
-    {
-      rval = xmalloc (strlen ("line : EMPTY KEY") + 15) ;
-      sprintf (rval,"line %d: EMPTY KEY", lineCount) ;
-      return rval ;
-    }
-  
-  if (!CTYPE(isalpha, *p))
-    {
-      rval = xmalloc (strlen (NON_ALPHA) + strlen (key) + 15) ;
-      sprintf (rval,NON_ALPHA,lineCount, key) ;
-      return rval ;
-    }
-
-  p++ ;
-  while (*p)
-    {
-      if (!(CTYPE (isalnum, *p) || *p == '_' || *p == '-'))
-        {
-          rval = xmalloc (strlen (BAD_KEY) + strlen (key) + 15) ;
-          sprintf (rval,BAD_KEY,lineCount,key) ;
-          return rval ;
-        }
-      p++ ;
-    }
-
-  return NULL ;
-}
-
-static PFIVP *funcs = NULL ;
-static void **args = NULL ;
-static int funcCount ;
-static int funcIdx ;
-
-void configAddLoadCallback (PFIVP func,void *arg)
-{
-  if (func == NULL)
-    return ;
-
-  if (funcIdx == funcCount)
-    {
-      funcCount += 10 ;
-      if (funcs == NULL)
-        {
-          funcs = xmalloc (sizeof (PFIVP) * funcCount);
-          args = xmalloc (sizeof (void *) * funcCount) ;
-        }
-      else
-        {
-          funcs = xrealloc (funcs,sizeof (PFIVP) * funcCount);
-          args = xrealloc (args,sizeof (void *) * funcCount) ;
-        }
-    }
-
-  args [funcIdx] = arg ;
-  funcs [funcIdx++] = func ;
-  
-}
-
-
-void configRemoveLoadCallback (PFIVP func)
-{
-  int i, j ;
-
-  for (i = 0 ; i < funcIdx ; i++)
-    if (funcs [i] == func)
-      break ;
-
-  for (j = i ; j < funcIdx - 1 ; j++)
-    {
-      funcs [j] = funcs [j + 1] ;
-      args [j] = args [j + 1] ;
-    }
-
-  if (funcIdx > 1 && i < funcIdx)
-    {
-      funcs [i - 2] = funcs [i - 1] ;
-      args [i - 2] = args [i - 1] ;
-    }
-
-  if (funcIdx > 0 && i < funcIdx)
-    funcIdx-- ;
-}
-
-
-static int doCallbacks (void)
-{
-  int i ;
-  int rval = 1 ;
-  
-  for (i = 0 ; i < funcIdx ; i++)
-    if (funcs [i] != NULL)
-      rval = (funcs[i](args [i]) && rval) ;
-
-  return rval ;
-}
-
-
-
-
-
-static char *key ;
-%}
-
-%union{
-    scope *scp ;
-    value *val ;
-    char *name ;
-    int integer ;
-    double real ;
-    char *string ;
-    char chr ;
-}
-
-%token PEER
-%token GROUP
-%token IVAL
-%token RVAL
-%token NAME
-%token XSTRING
-%token SCOPE
-%token COLON
-%token LBRACE
-%token RBRACE
-%token TRUEBVAL
-%token FALSEBVAL
-%token CHAR
-%token WORD
-%token IP_ADDRESS
-
-%type <integer> IVAL
-%type <real> RVAL
-%type <string> XSTRING
-%type <chr> CHAR
-%type <name> TRUEBVAL FALSEBVAL WORD
-
-%%
-input: {       
-               lineCount = 1 ;
-               addScope (NULL,"",newScope ("")) ;
-               topScope = currScope ;
-       } entries { if (!doCallbacks()) YYABORT ; } ;
-
-scope: entries ;
-
-entries:       
-       | entries entry
-       | entries error {
-               errbuff = xmalloc (strlen(SYNTAX_ERROR) + 12) ;
-               sprintf (errbuff,SYNTAX_ERROR,lineCount) ;
-               YYABORT ;
-       }
-       ;
-
-entry: PEER WORD LBRACE {
-               errbuff = addScope (currScope,$2,newScope ("peer")) ;
-                free ($2) ;
-               if (errbuff != NULL) YYABORT ;
-       } scope RBRACE {
-               currScope = currScope->parent ;
-       }
-       | GROUP WORD LBRACE {
-               errbuff = addScope (currScope,$2,newScope ("group")) ;
-                free ($2) ;
-               if (errbuff != NULL) YYABORT ;
-       } scope RBRACE {
-               currScope = currScope->parent ;
-       }
-       | WORD WORD LBRACE {
-               errbuff = xmalloc (strlen(UNKNOWN_SCOPE_TYPE) + 15 +
-                                         strlen ($1)) ;
-               sprintf (errbuff,UNKNOWN_SCOPE_TYPE,lineCount,$1) ;
-                free ($1) ;
-                free ($2) ;
-               YYABORT ;
-       }
-       | WORD { 
-               if ((errbuff = keyOk($1)) != NULL) {
-                       YYABORT ;
-               } else
-                       key = $1 ;
-       } COLON value ;
-
-value: WORD {
-               if ((errbuff = addString (currScope, key, $1)) != NULL)
-                       YYABORT ;
-                free (key) ;
-                free ($1) ;
-       }
-       | IVAL {
-               if ((errbuff = addInteger(currScope, key, $1)) != NULL)
-                       YYABORT; 
-                free (key) ;
-       }
-       | TRUEBVAL {
-               if ((errbuff = addBoolean (currScope, key, 1)) != NULL)
-                       YYABORT ; 
-                free (key) ;
-                free ($1) ;
-       }
-       | FALSEBVAL {
-               if ((errbuff = addBoolean (currScope, key, 0)) != NULL)
-                       YYABORT ; 
-                free (key) ;
-                free ($1) ;
-       }
-       | RVAL {
-               if ((errbuff = addReal (currScope, key, $1)) != NULL)
-                       YYABORT ; 
-                free (key) ;
-       }
-       | XSTRING { 
-               if ((errbuff = addString (currScope, key, $1)) != NULL)
-                       YYABORT;
-                free (key) ;
-       }
-       | CHAR {
-               if ((errbuff = addChar (currScope, key, $1)) != NULL)
-                       YYABORT ;
-                free (key) ;
-        }
-;
-       
-%%
-
-int yyerror (const char *s)
-{
-#undef FMT
-#define FMT "line %d: %s"
-  
-  errbuff = xmalloc (strlen (s) + strlen (FMT) + 20) ;
-  sprintf (errbuff,FMT,lineCount,s) ;
-
-  return 0 ;
-}
-
-int yywrap (void)
-{
-  return 1 ;
-}
-
-extern FILE *yyin ;
-int yydebug ;
-
-#define NO_INHERIT 0
-
-
-#if ! defined (WANT_MAIN)
-
-struct peer_table_s
-{
-    char *peerName ;
-    value *peerValue ;
-} ;
-
-static struct peer_table_s *peerTable ;
-static int peerTableCount ;
-static int peerTableIdx ;
-
-void configCleanup (void)
-{
-  int i ;
-
-  for (i = 0 ; i < peerTableIdx ; i++)
-    free (peerTable[i].peerName) ;
-  free (peerTable) ;
-  
-  freeScopeTree (topScope);
-  free (funcs) ;
-  free (args) ;
-}
-  
-
-int buildPeerTable (FILE *fp, scope *s)
-{
-  int rval = 1 ;
-  int i, j ;
-
-  for (i = 0 ; i < s->value_idx ; i++)
-    {
-      if (ISSCOPE (s->values[i]) && ISPEER (s->values[i]))
-        {
-          for (j = 0 ; j < peerTableIdx ; j++)
-            {
-              if (strcmp (peerTable[j].peerName,s->values[i]->name) == 0)
-                {
-                  logOrPrint (LOG_ERR,fp,
-                              "ME config: two peers with the same name: %s",
-                              peerTable[j].peerName) ;
-                  rval = 0 ;
-                  break ;
-                }
-            }
-
-          if (j == peerTableIdx)
-            {
-              if (peerTableCount == peerTableIdx) 
-                {
-                  peerTableCount += 10 ;
-                  if (peerTable == NULL)
-                    peerTable = xmalloc (sizeof(struct peer_table_s)
-                                         * peerTableCount) ;
-                  else
-                    peerTable = xrealloc (peerTable,
-                                          sizeof(struct peer_table_s)
-                                          * peerTableCount) ;
-                }
-  
-              peerTable[peerTableIdx].peerName = xstrdup (s->values[i]->name);
-              peerTable[peerTableIdx].peerValue = s->values[i] ;
-              peerTableIdx++ ;
-            }
-        }
-      else if (ISSCOPE (s->values[i]))
-        rval = (buildPeerTable (fp,s->values[i]->v.scope_val) && rval) ;
-    }
-
-  return rval ;  
-}
-
-
-/* read the config file. Any errors go to errorDest if it is non-NULL,
-   otherwise they are syslogged. If justCheck is true then return after
-   parsing */
-static int inited = 0 ;
-int readConfig (const char *file, FILE *errorDest, int justCheck, int dump)
-{
-  scope *oldTop = topScope ;
-  FILE *fp ;
-  int rval ;
-
-  if (!inited)
-    {
-      inited = 1 ;
-      yydebug = (getenv ("YYDEBUG") == NULL ? 0 : 1) ;
-      if (yydebug)
-        atexit (configCleanup) ;
-    }
-
-  if (file == NULL || strlen (file) == 0 || !fileExistsP (file))
-    {
-      logOrPrint (LOG_ERR,errorDest,
-                  "ME config aborting, no such config file: %s",
-                  file ? file : "(null)") ;
-      d_printf (1,"No such config file: %s\n", file ? file : "(null)") ;
-      exit (1) ;
-    }
-
-  if ((fp = fopen (file,"r")) == NULL)
-    {
-      logOrPrint (LOG_ERR,errorDest, "ME config aborting fopen %s: %s",
-                  file, strerror (errno)) ;
-      exit (1) ;
-    }
-
-  logOrPrint (LOG_NOTICE,errorDest,"loading %s", file) ;
-
-  yyin = fp ;
-
-  topScope = NULL ;
-
-  rval = yyparse () ;
-
-  fclose (fp) ;
-  
-  if (rval != 0)                /* failure */
-    {
-      freeScopeTree (topScope) ;
-      if (justCheck)
-        freeScopeTree (oldTop) ;
-      else
-        topScope = oldTop ;
-      topScope = NULL ;
-
-      if (errbuff != NULL)
-        {
-          if (errorDest != NULL)
-            fprintf (errorDest,"config file error: %s\n",errbuff) ;
-          else
-            warn ("ME config file error: %s", errbuff) ;
-          
-          free (errbuff) ;
-        }
-      
-      return 0 ;
-    }
-  
-  if (dump)
-    {
-      fprintf (errorDest ? errorDest : stderr,"Parsed config file:\n") ;
-      printScope (errorDest ? errorDest : stderr,topScope,-5) ;
-      fprintf (errorDest ? errorDest : stderr,"\n") ;
-    }
-  
-  if (justCheck)
-    {
-      freeScopeTree (topScope) ;
-      freeScopeTree (oldTop) ;
-
-      topScope = NULL ;
-    }
-  else
-    {
-      for (peerTableIdx-- ; peerTableIdx >= 0 ; peerTableIdx--)
-        {
-          free (peerTable [peerTableIdx].peerName) ;
-          peerTable [peerTableIdx].peerName = NULL ;
-          peerTable [peerTableIdx].peerValue = NULL ;
-        }
-      peerTableIdx = 0 ;
-      
-      if (!buildPeerTable (errorDest,topScope))
-        logAndExit (1,"Failed to build list of peers") ;
-    }
-  
-  return 1 ;
-}
-
-
-value *getNextPeer (int *cookie)
-{
-  value *rval ;
-
-  if (*cookie < 0 || *cookie >= peerTableIdx)
-    return NULL ;
-
-  rval = peerTable[*cookie].peerValue ;
-
-  (*cookie)++ ;
-
-  return rval ;
-}
-
-
-value *findPeer (const char *name)
-{
-  value *v = NULL ;
-  int i ;
-
-  for (i = 0 ; i < peerTableIdx ; i++)
-    if (strcmp (peerTable[i].peerName,name) == 0)
-      {
-        v = peerTable[i].peerValue ;
-        break ;
-      }
-  
-  return v ;
-}
-
-#endif
-
-#if defined (WANT_MAIN)
-int main (int argc, char **argv) {
-  if ( yyparse() )
-    printf ("parsing failed: %s\n",errbuff ? errbuff : "NONE") ;
-  else
-    {
-      printScope (stdout,topScope,-5) ;
-
-      if (argc == 3)
-        {
-#if 0
-          printf ("Looking for %s of type %s: ",argv[2],argv[1]) ;
-          if (strncmp (argv[1],"int",3) == 0)
-            {
-              int i = 0 ;
-          
-              if (!getInteger (topScope,argv[2],&i))
-                printf ("wasn't found.\n") ;
-              else
-                printf (" %d\n",i) ;
-            }
-          else if (strncmp (argv[1],"real",4) == 0)
-            {
-              double d = 0.0 ;
-
-              if (!getReal (topScope,argv[2],&d))
-                printf ("wasn't found.\n") ;
-              else
-                printf (" %0.5f\n",d) ;
-            }
-#else
-          value *v = findValue (topScope,argv[1],1) ;
-
-          if (v == NULL)
-            printf ("Can't find %s\n",argv[1]) ;
-          else
-            {
-              long ival = 987654 ;
-              
-              if (getInteger (v->v.scope_val,argv[2],&ival,1))
-                printf ("Getting %s : %ld",argv[2],ival) ;
-              else
-                printf ("Name is not legal: %s\n",argv[2]) ;
-            }
-#endif
-        }
-      else if (argc == 2)
-        {
-#if 1
-          value *v = findValue (topScope,argv[1],1) ;
-
-          if (v == NULL)
-            printf ("Can't find %s\n",argv[1]) ;
-          else
-            {
-              printf ("Getting %s : ",argv[1]) ;
-              printValue (stdout,v,0) ;
-            }
-#else
-          if (findScope (topScope,argv[1],1) == NULL)
-            printf ("Can't find the scope of %s\n",argv[1]) ;
-#endif
-        }
-    }
-  
-  freeScopeTree (topScope) ;
-
-  return 0 ;
-}
-#endif /* defined (WANT_MAIN) */
diff --git a/innfeed/connection.c b/innfeed/connection.c
deleted file mode 100644 (file)
index 59d95cc..0000000
+++ /dev/null
@@ -1,4904 +0,0 @@
-/*  $Id: connection.c 7793 2008-04-26 08:15:40Z iulius $
-**
-**  The implementation of the innfeed Connection class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The Connection object is what manages the NNTP protocol. If the remote
-**  doesn't do streaming, then the standard IHAVE lock-step protcol is
-**  performed. In the streaming situation we have two cases. One where we must
-**  send CHECK commands, and the other where we can directly send TAKETHIS
-**  commands without a prior CHECK.
-**
-**  The Connection object maintains four article queues. The first one is
-**  where new articles are put if they need to have an IHAVE or CHECK command
-**  sent for them. The second queue is where the articles move from the first
-**  after their IHAVE/CHECK command is sent, but the reply has not yet been
-**  seen. The third queue is where articles go after the IHAVE/CHECK reply has
-**  been seen (and the reply says to send the article). It is articles in the
-**  third queue that have the TAKETHIS command sent, or the body of an IHAVE.
-**  The third queue is also where new articles go if the connection is running
-**  in no-CHECK mode. The fourth queue is where the articles move to from the
-**  third queue after their IHAVE-body or TAKETHIS command has been sent. When
-**  the response to the IHAVE-body or TAKETHIS is received the articles are
-**  removed from the fourth queue and the Host object controlling this
-**  Connection is notified of the success or failure of the transfer.
-**
-**  The whole system is event-driven by the EndPoint class and the Host via
-**  calls to prepareRead() and prepareWrite() and prepareSleep().
-**
-**
-**  We should probably store the results of gethostbyname in the connection so
-**  we can rotate through the address when one fails for connecting. Perhaps
-**  the gethostbyname should be done in the Host and the connection should
-**  just be given the address to use.
-**
-**  Should we worry about articles being stuck on a queue for ever if the
-**  remote forgets to send a response to a CHECK?
-**
-**  Perhaps instead of killing the connection on some of the more simple
-**  errors, we should perhaps try to flush the input and keep going.
-**
-**  Worry about counter overflow.
-**
-**  Worry about stats gathering when switch to no-check mode.
-**
-**  XXX if issueQUIT() has a problem and the state goes to cxnDeadS this is
-**  not handled properly everywhere yet.
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <signal.h>
-#include <syslog.h>
-
-#if defined (__FreeBSD__)
-# include <sys/ioctl.h>
-#endif
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "article.h"
-#include "buffer.h"
-#include "configfile.h"
-#include "connection.h"
-#include "endpoint.h"
-#include "host.h"
-
-#if defined (NDEBUG)
-#define VALIDATE_CONNECTION(x) ((void) 0)
-#else
-#define VALIDATE_CONNECTION(x) validateConnection (x)
-#endif
-
-extern char **PointersFreedOnExit ;
-extern const char *pidFile ;
-
-/*
- * Private types.
- */
-
-/* We keep a linked list of articles the connection is trying to transmit */
-typedef struct art_holder_s
-{
-    Article article ;
-    struct art_holder_s *next ;
-} *ArtHolder ;
-
-
-typedef enum {
-  cxnStartingS,                 /* the connection's start state. */
-  cxnWaitingS,                  /* not connected. Waiting for an article. */
-  cxnConnectingS,               /* in the middle of connecting */
-  cxnIdleS,                    /* open and ready to feed, has empty queues */
-  cxnIdleTimeoutS,             /* timed out in the idle state */
-  cxnFeedingS,                  /* in the processes of feeding articles */
-  cxnSleepingS,                 /* blocked on reestablishment timer */
-  cxnFlushingS,                 /* am waiting for queues to drain to bounce connection. */
-  cxnClosingS,                  /* have been told to close down permanently when queues drained */
-  cxnDeadS                      /* connection is dead. */
-} CxnState ;
-
-/* The Connection class */
-struct connection_s
-{
-    Host myHost ;               /* the host who owns the connection */
-    EndPoint myEp ;             /* the endpoint the connection talks through */
-    unsigned int ident ;               /* an identifier for syslogging. */
-    CxnState state ;            /* the state the connection is in */
-
-
-    /*
-     * The Connection maintains 4 queue of articles.
-     */
-    ArtHolder checkHead ;       /* head of article list to do CHECK/IHAVE */
-    ArtHolder checkRespHead ;   /* head of list waiting on CHECK/IHAVE
-                                   response */
-    ArtHolder takeHead ;        /* head of list of articles to send
-                                   TAKETHIS/IHAVE-body */
-    ArtHolder takeRespHead ;    /* list of articles waiting on
-                                   TAKETHIS/IHAVE-body response */
-    unsigned int articleQTotal ;       /* number of articles in all four queues */
-    ArtHolder missing ;         /* head of missing list */
-
-
-    Buffer respBuffer ;         /* buffer all responses are read into */
-
-    char *ipName ;              /* the ip name (possibly quad) of the remote */
-
-    unsigned int maxCheck ;            /* the max number of CHECKs to send */
-    unsigned short port ;              /* the port number to use */
-
-    /*
-     * Timeout values and their callback IDs
-     */
-
-    /* Timer for max amount of time between receiving articles from the
-       Host */
-    unsigned int articleReceiptTimeout ;
-    TimeoutId artReceiptTimerId ;
-
-    /* Timer for the max amount of time to wait for a response from the
-       remote */
-    unsigned int readTimeout ;
-    TimeoutId readBlockedTimerId ;
-
-    /* Timer for the max amount of time to wait for a any amount of data
-       to be written to the remote */
-    unsigned int writeTimeout ;
-    TimeoutId writeBlockedTimerId ;
-
-    /* Timer for the max number of seconds to keep the network connection
-       up (long lasting connections give older nntp servers problems). */
-    unsigned int flushTimeout ;
-    TimeoutId flushTimerId ;
-
-    /* Timer for the number of seconds to sleep before attempting a
-       reconnect. */
-    unsigned int sleepTimeout ;
-    TimeoutId sleepTimerId ;
-
-
-    bool loggedNoCr ;           /* true if we logged the NOCR_MSG */
-    bool immedRecon ;           /* true if we recon immediately after flushing. */
-    bool doesStreaming ;        /* true if remote will handle streaming */
-    bool authenticated ;        /* true if remote authenticated */
-    bool quitWasIssued ;          /* true if QUIT command was sent. */
-    bool needsChecks ;          /* true if we issue CHECK commands in
-                                   streaming mode (rather than just sending
-                                   TAKETHIS commands) */
-
-    time_t timeCon ;            /* the time the connect happened (including
-                                   the MODE STREAM command). */
-
-    /*
-     * STATISTICS
-     */
-    unsigned int artsTaken ;           /* the number of articles INN gave this cxn */
-    unsigned int checksIssued ;        /* the number of CHECKS/IHAVES we
-                                   sent. Note that if we're running in
-                                   no-CHECK mode, then we add in the
-                                   TAKETHIS commands too */
-    unsigned int checksRefused ;       /* the number of response 435/438 */
-    unsigned int takesRejected ;       /* the number of response 437/439 recevied */
-    unsigned int takesOkayed ;         /* the number of response 235/239 received */
-
-    double takesSizeRejected ;
-    double takesSizeOkayed ;
-
-    double onThreshold ;        /* for no-CHECK mode */
-    double offThreshold ;       /* for no-CHECK mode */
-    double filterValue ;        /* current value of IIR filter */
-    double lowPassFilter ;      /* time constant for IIR filter */
-
-    Connection next ;           /* for global list. */
-};
-
-static Connection gCxnList = NULL ;
-static unsigned int gCxnCount = 0 ;
-static unsigned int max_reconnect_period = MAX_RECON_PER ;
-static unsigned int init_reconnect_period = INIT_RECON_PER ;
-#if 0
-static bool inited = false ;
-#endif
-static Buffer dotFirstBuffer ;
-static Buffer dotBuffer ;
-static Buffer crlfBuffer ;
-
-
-/***************************************************
- *
- * Private function declarations.
- *
- ***************************************************/
-
-
-/* I/O Callbacks */
-static void connectionDone (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void getBanner (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void getAuthUserResponse (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void getAuthPassResponse (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void getModeResponse (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void responseIsRead (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void quitWritten (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void ihaveBodyDone (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void commandWriteDone (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void modeCmdIssued (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void authUserIssued (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void authPassIssued (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-static void writeProgress (EndPoint e, IoStatus i, Buffer *b, void *d) ;
-
-
-/* Timer callbacks */
-static void responseTimeoutCbk (TimeoutId id, void *data) ;
-static void writeTimeoutCbk (TimeoutId id, void *data) ;
-static void reopenTimeoutCbk (TimeoutId id, void *data) ;
-static void flushCxnCbk (TimeoutId, void *data) ;
-static void articleTimeoutCbk (TimeoutId id, void *data) ;
-
-/* Work callbacks */
-static void cxnWorkProc (EndPoint ep, void *data) ;
-
-
-static void cxnSleepOrDie (Connection cxn) ;
-
-/* Response processing. */
-static void processResponse205 (Connection cxn, char *response) ;
-static void processResponse238 (Connection cxn, char *response) ;
-static void processResponse431 (Connection cxn, char *response) ;
-static void processResponse438 (Connection cxn, char *response) ;
-static void processResponse239 (Connection cxn, char *response) ;
-static void processResponse439 (Connection cxn, char *response) ;
-static void processResponse235 (Connection cxn, char *response) ;
-static void processResponse335 (Connection cxn, char *response) ;
-static void processResponse400 (Connection cxn, char *response) ;
-static void processResponse435 (Connection cxn, char *response) ;
-static void processResponse436 (Connection cxn, char *response) ;
-static void processResponse437 (Connection cxn, char *response) ;
-static void processResponse480 (Connection cxn, char *response) ;
-static void processResponse503 (Connection cxn, char *response) ;
-
-
-/* Misc functions */
-static void cxnSleep (Connection cxn) ;
-static void cxnDead (Connection cxn) ;
-static void cxnIdle (Connection cxn) ;
-static void noSuchMessageId (Connection cxn, unsigned int responseCode,
-                           const char *msgid, const char *response) ;
-static void abortConnection (Connection cxn) ;
-static void resetConnection (Connection cxn) ;
-static void deferAllArticles (Connection cxn) ;
-static void deferQueuedArticles (Connection cxn) ;
-static void doSomeWrites (Connection cxn) ;
-static bool issueIHAVE (Connection cxn) ;
-static void issueIHAVEBody (Connection cxn) ;
-static bool issueStreamingCommands (Connection cxn) ;
-static Buffer buildCheckBuffer (Connection cxn) ;
-static Buffer *buildTakethisBuffers (Connection cxn, Buffer checkBuffer) ;
-static void issueQUIT (Connection cxn) ;
-static void initReadBlockedTimeout (Connection cxn) ;
-static int prepareWriteWithTimeout (EndPoint endp, Buffer *buffers,
-                                    EndpRWCB done, Connection cxn) ;
-static void delConnection (Connection cxn) ;
-static void incrFilter (Connection cxn) ;
-static void decrFilter (Connection cxn) ;
-static bool writesNeeded (Connection cxn) ;
-static void validateConnection (Connection cxn) ;
-static const char *stateToString (CxnState state) ;
-
-static void issueModeStream (EndPoint e, Connection cxn) ;
-static void issueAuthUser (EndPoint e, Connection cxn) ;
-static void issueAuthPass (EndPoint e, Connection cxn) ;
-
-static void prepareReopenCbk (Connection cxn) ;
-
-
-/* Article queue management routines. */
-static ArtHolder newArtHolder (Article art) ;
-static void delArtHolder (ArtHolder artH) ;
-static bool remArtHolder (ArtHolder art, ArtHolder *head, unsigned int *count) ;
-static void appendArtHolder (ArtHolder artH, ArtHolder *head, unsigned int *count) ;
-static ArtHolder artHolderByMsgId (const char *msgid, ArtHolder head) ;
-
-static int fudgeFactor (int initVal) ;
-
-
-
-
-/***************************************************
- *
- * Public functions implementation.
- *
- ***************************************************/
-
-
-int cxnConfigLoadCbk (void *data UNUSED)
-{
-  long iv ;
-  int rval = 1 ;
-  FILE *fp = (FILE *) data ;
-
-  if (getInteger (topScope,"max-reconnect-time",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld", "max-reconnect-time",
-                      iv,"global scope",(long) MAX_RECON_PER);
-          iv = MAX_RECON_PER ;
-        }
-    }
-  else
-    iv = MAX_RECON_PER ;
-  max_reconnect_period = (unsigned int) iv ;
-
-  if (getInteger (topScope,"initial-reconnect-time",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld", "initial-reconnect-time",
-                      iv,"global scope",(long)INIT_RECON_PER);
-          iv = INIT_RECON_PER ;
-        }
-    }
-  else
-    iv = INIT_RECON_PER ;
-  init_reconnect_period = (unsigned int) iv ;
-
-  return rval ;
-}
-  
-
-
-
-\f
-/*
- * Create a new Connection object and return it. All fields are
- * initialized to reasonable values.
- */
-Connection newConnection (Host host,
-                          unsigned int id,
-                          const char *ipname,
-                          unsigned int articleReceiptTimeout,
-                          unsigned int portNum,
-                          unsigned int respTimeout,
-                          unsigned int flushTimeout,
-                          double lowPassLow,
-                          double lowPassHigh,
-                         double lowPassFilter)
-{
-  Connection cxn ;
-  bool croak = false ;
-
-  if (ipname == NULL)
-    {
-      d_printf (1,"NULL ipname in newConnection\n") ;
-      croak = true ;
-    }
-
-  if (ipname && strlen (ipname) == 0)
-    {
-      d_printf (1,"Empty ipname in newConnection\n") ;
-      croak = true ;
-    }
-
-  if (croak)
-    return NULL ;
-
-  cxn = xcalloc (1, sizeof(struct connection_s));
-
-  cxn->myHost = host ;
-  cxn->myEp = NULL ;
-  cxn->ident = id ;
-
-  cxn->checkHead = NULL ;
-  cxn->checkRespHead = NULL ;
-  cxn->takeHead = NULL ;
-  cxn->takeRespHead = NULL ;
-
-  cxn->articleQTotal = 0 ;
-  cxn->missing = NULL ;
-
-  cxn->respBuffer = newBuffer (BUFFER_SIZE) ;
-  ASSERT (cxn->respBuffer != NULL) ;
-
-  cxn->ipName = xstrdup (ipname) ;
-  cxn->port = portNum ;
-
-  /* Time out the higher numbered connections faster */
-  cxn->articleReceiptTimeout = articleReceiptTimeout * 10.0 / (10.0 + id) ;
-  cxn->artReceiptTimerId = 0 ;
-
-  cxn->readTimeout = respTimeout ;
-  cxn->readBlockedTimerId = 0 ;
-
-  cxn->writeTimeout = respTimeout ; /* XXX should be a separate value */
-  cxn->writeBlockedTimerId = 0 ;
-
-  cxn->flushTimeout = fudgeFactor (flushTimeout) ;
-  cxn->flushTimerId = 0 ;
-
-  cxn->onThreshold = lowPassHigh * lowPassFilter / 100.0 ;
-  cxn->offThreshold = lowPassLow * lowPassFilter / 100.0 ;
-  cxn->lowPassFilter = lowPassFilter;
-
-  cxn->sleepTimerId = 0 ;
-  cxn->sleepTimeout = init_reconnect_period ;
-
-  resetConnection (cxn) ;
-
-  cxn->next = gCxnList ;
-  gCxnList = cxn ;
-  gCxnCount++ ;
-
-  cxn->state = cxnStartingS ;
-
-  return cxn ;
-}
-
-
-
-
-\f
-/* Create a new endpoint hooked to a non-blocking socket that is trying to
- * connect to the host info stored in the Connection. On fast machines
- * connecting locally the connect() may have already succeeded when this
- * returns, but typically the connect will still be running and when it
- * completes. The Connection will be notified via a write callback setup by
- * prepareWrite below. If nothing goes wrong then this will return true
- * (even if the connect() has not yet completed). If something fails
- * (hostname lookup etc.) then it returns false (and the Connection is left
- * in the sleeping state)..
- *
- * Pre-state           Reason cxnConnect called
- * ---------           ------------------------
- * cxnStartingS                Connection owner issued call.
- * cxnWaitingS         side effect of cxnTakeArticle() call
- * cxnConnecting       side effect of cxnFlush() call
- * cxnSleepingS                side effect of reopenTimeoutCbk() call.
- */
-bool cxnConnect (Connection cxn)
-{
-  const struct sockaddr_storage cxnAddr, cxnSelf ;
-  const struct sockaddr *retAddr;
-  int fd, rval ;
-  const char *peerName = hostPeerName (cxn->myHost) ;
-  char msgbuf[100];
-  const struct sockaddr_in *bind_addr = hostBindAddr (cxn->myHost) ;
-  int family = 0;
-#ifdef HAVE_INET6
-  char paddr[INET6_ADDRSTRLEN];
-  const struct sockaddr_in6 *bind_addr6 = hostBindAddr6 (cxn->myHost) ;
-#endif
-
-  ASSERT (cxn->myEp == NULL) ;
-
-  if (!(cxn->state == cxnStartingS ||
-        cxn->state == cxnWaitingS ||
-        cxn->state == cxnFlushingS ||
-        cxn->state == cxnSleepingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return false;
-    }
-  
-  if (cxn->state == cxnWaitingS)
-    ASSERT (cxn->articleQTotal == 1) ;
-  else
-    ASSERT (cxn->articleQTotal == 0) ;
-
-  cxn->state = cxnConnectingS ;
-
-#ifdef HAVE_INET6
-  family = hostAddrFamily (cxn->myHost);
-#endif
-  retAddr = hostIpAddr (cxn->myHost, family) ;
-
-  if (retAddr == NULL)
-    {
-      cxnSleepOrDie (cxn) ;
-      return false ;
-    }
-
-  memcpy( (void *)&cxnAddr, retAddr, SA_LEN(retAddr) );
-
-#ifdef HAVE_INET6
-  if( cxnAddr.ss_family == AF_INET6 )
-  {
-    ((struct sockaddr_in6 *)&cxnAddr)->sin6_port = htons(cxn->port) ;
-    fd = socket (PF_INET6, SOCK_STREAM, 0);
-  }
-  else
-#endif
-  {
-    ((struct sockaddr_in *)&cxnAddr)->sin_port = htons(cxn->port) ;
-    fd = socket (PF_INET, SOCK_STREAM, 0);
-  }
-  if (fd < 0)
-    {
-      syswarn ("%s:%d cxnsleep can't create socket", peerName, cxn->ident) ;
-      d_printf (1,"Can't get a socket: %s\n", strerror (errno)) ;
-
-      cxnSleepOrDie (cxn) ;
-
-      return false ;
-    }
-
-#ifdef HAVE_INET6
-  /* bind to a specified IPv6 address */
-  if( (cxnAddr.ss_family == AF_INET6) && bind_addr6 )
-    {
-      memcpy( (void *)&cxnSelf, bind_addr6, sizeof(struct sockaddr_in6) );
-      if (bind (fd, (struct sockaddr *) &cxnSelf,
-                 sizeof(struct sockaddr_in6)) < 0)
-       {
-          snprintf(msgbuf, sizeof(msgbuf), "bind (%s): %%m",
-                   inet_ntop(AF_INET6, bind_addr6->sin6_addr.s6_addr,
-                             paddr, sizeof(paddr)) );
-
-         syslog (LOG_ERR, msgbuf) ;
-
-         cxnSleepOrDie (cxn) ;
-
-         return false ;
-       }
-    }
-  else
-#endif
-  /* bind to a specified IPv4 address */
-#ifdef HAVE_INET6
-  if ( (cxnAddr.ss_family == AF_INET) && bind_addr )
-#else
-  if (bind_addr)
-#endif
-    {
-      memcpy( (void *)&cxnSelf, bind_addr, sizeof(struct sockaddr_in) );
-      if (bind (fd, (struct sockaddr *) &cxnSelf,
-                 sizeof(struct sockaddr_in) ) < 0)
-       {
-          snprintf(msgbuf, sizeof(msgbuf), "bind (%s): %%m",
-                   inet_ntoa(bind_addr->sin_addr));
-         syslog (LOG_ERR, msgbuf) ;
-
-         cxnSleepOrDie (cxn) ;
-
-         return false ;
-       }
-    }
-
-  /* set our file descriptor to non-blocking */
-#if defined (O_NONBLOCK)
-  rval = fcntl (fd, F_GETFL, 0) ;
-  if (rval >= 0)
-    rval = fcntl (fd, F_SETFL, rval | O_NONBLOCK) ;
-#else
-  {
-    int state = 1 ;
-    rval = ioctl (fd, FIONBIO, (char *) &state) ;
-  }
-#endif
-
-  if (rval < 0)
-    {
-      syswarn ("%s:%d cxnsleep can't set socket non-blocking", peerName,
-               cxn->ident) ;
-      close (fd) ;
-
-      cxnSleepOrDie (cxn) ;
-
-      return false ;
-    }
-
-  rval = connect (fd, (struct sockaddr *) &cxnAddr,
-                 SA_LEN((struct sockaddr *)&cxnAddr)) ;
-  if (rval < 0 && errno != EINPROGRESS)
-    {
-      syswarn ("%s:%d connect", peerName, cxn->ident) ;
-      hostIpFailed (cxn->myHost) ;
-      close (fd) ;
-
-      cxnSleepOrDie (cxn) ;
-
-      return false ;
-    }
-
-  if ((cxn->myEp = newEndPoint (fd)) == NULL)
-    {
-      /* If this happens, then fd was bigger than what select could handle,
-         so endpoint.c refused to create the new object. */
-      close (fd) ;
-      cxnSleepOrDie (cxn) ;
-      return false ;
-    }
-  
-
-  if (rval < 0)
-    /* when the write callback gets done the connection went through */
-    prepareWrite (cxn->myEp, NULL, NULL, connectionDone, cxn) ;
-  else
-    connectionDone (cxn->myEp, IoDone, NULL, cxn) ;
-
-  /* connectionDone() could set state to sleeping */
-  return (cxn->state == cxnConnectingS ? true : false) ;
-}
-
-
-
-
-\f
-/* Put the Connection into the wait state.
- *
- * Pre-state           Reason cxnWait called
- * ---------           ------------------------
- * cxnStartingS                - Connection owner called cxnWait()
- * cxnSleepingS                - side effect of cxnFlush() call.
- * cxnConnectingS      - side effect of cxnFlush() call.
- * cxnFlushingS                - side effect of receiving response 205
- *                       and Connection had no articles when
- *                       cxnFlush() was issued.
- *                     - prepareRead failed.
- *                     - I/O failed.
- *
- */
-void cxnWait (Connection cxn)
-{
-  ASSERT (cxn->state == cxnStartingS ||
-          cxn->state == cxnSleepingS ||
-          cxn->state == cxnConnectingS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnFlushingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  abortConnection (cxn) ;
-
-  cxn->state = cxnWaitingS ;
-
-  hostCxnWaiting (cxn->myHost,cxn) ;   /* tell our Host we're waiting */
-}
-
-
-
-
-\f
-/* Tells the Connection to flush itself (i.e. push out all articles,
- * issue a QUIT and drop the network connection. If necessary a
- * reconnect will be done immediately after. Called by the Host, or
- * by the timer callback.
- *
- * Pre-state           Reason cxnFlush called
- * ---------           ------------------------
- * ALL (except cxnDeadS        - Connection owner called cxnFlush()
- *  and cxnStartingS)
- * cxnFeedingS         - side effect of flushCxnCbk() call.
- */
-void cxnFlush (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state != cxnStartingS) ;
-  ASSERT (cxn->state != cxnDeadS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  switch (cxn->state)
-    {
-      case cxnSleepingS:
-        cxnWait (cxn) ;
-        break ;
-
-      case cxnConnectingS:
-        cxnWait (cxn) ;
-        cxnConnect (cxn) ;
-        break ;
-
-      case cxnIdleTimeoutS:
-      case cxnIdleS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        if (cxn->state != cxnIdleTimeoutS)
-          clearTimer (cxn->artReceiptTimerId) ;
-        clearTimer (cxn->flushTimerId) ;
-        cxn->state = cxnFlushingS ;
-        issueQUIT (cxn) ;
-        break ;
-
-      case cxnClosingS:
-      case cxnFlushingS:
-      case cxnWaitingS:
-        if (cxn->articleQTotal == 0 && !writeIsPending (cxn->myEp))
-          issueQUIT (cxn) ;
-        break ;
-
-      case cxnFeedingS:
-        /* we only reconnect immediately if we're not idle when cxnFlush()
-           is called. */
-        if (!cxn->immedRecon)
-          {
-            cxn->immedRecon = (cxn->articleQTotal > 0 ? true : false) ;
-            d_printf (1,"%s:%d immediate reconnect for a cxnFlush()\n",
-                     hostPeerName (cxn->myHost), cxn->ident) ;
-          }
-        
-        clearTimer (cxn->flushTimerId) ;
-
-        cxn->state = cxnFlushingS ;
-
-        if (cxn->articleQTotal == 0 && !writeIsPending (cxn->myEp))
-          issueQUIT (cxn) ;
-        break ;
-
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-}
-
-
-\f
-/*
- * Tells the Connection to dump all articles that are queued and to issue a
- * QUIT as quickly as possible. Much like cxnClose, except queued articles
- * are not sent, but are given back to the Host.
- */
-void cxnTerminate (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state != cxnDeadS) ;
-  ASSERT (cxn->state != cxnStartingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-  
-  switch (cxn->state)
-    {
-      case cxnFeedingS:
-        d_printf (1,"%s:%d Issuing terminate\n",
-                 hostPeerName (cxn->myHost), cxn->ident) ;
-
-        clearTimer (cxn->flushTimerId) ;
-
-        cxn->state = cxnClosingS ;
-
-        deferQueuedArticles (cxn) ;
-        if (cxn->articleQTotal == 0)
-          issueQUIT (cxn) ; /* send out the QUIT if we can */
-        break ;
-
-      case cxnIdleTimeoutS:
-      case cxnIdleS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        if (cxn->state != cxnIdleTimeoutS)
-          clearTimer (cxn->artReceiptTimerId) ;
-        clearTimer (cxn->flushTimerId) ;
-        cxn->state = cxnClosingS ;
-        issueQUIT (cxn) ;
-        break ;
-
-      case cxnFlushingS: /* we are in the middle of a periodic close. */
-        d_printf (1,"%s:%d Connection already being flushed\n",
-                 hostPeerName (cxn->myHost),cxn->ident);
-        cxn->state = cxnClosingS ;
-        if (cxn->articleQTotal == 0)
-          issueQUIT (cxn) ; /* send out the QUIT if we can */
-        break ;
-
-      case cxnClosingS:
-        d_printf (1,"%s:%d Connection already closing\n",
-                 hostPeerName (cxn->myHost),cxn->ident) ;
-        break ;
-
-      case cxnWaitingS:
-      case cxnConnectingS:
-      case cxnSleepingS:
-        cxnDead (cxn) ;
-        break ;
-
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (cxn->state == cxnDeadS)
-    {
-      d_printf (1,"%s:%d Deleting connection\n",hostPeerName (cxn->myHost),
-               cxn->ident) ;
-
-      delConnection (cxn) ;
-    }
-}
-
-
-\f
-/* Tells the Connection to do a disconnect and then when it is
- * disconnected to delete itself.
- *
- * Pre-state           Reason cxnClose called
- * ---------           ------------------------
- * ALL (except cxnDeadS        - Connecton owner called directly.
- * and cxnStartingS).
- */
-void cxnClose (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state != cxnDeadS) ;
-  ASSERT (cxn->state != cxnStartingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  switch (cxn->state)
-    {
-      case cxnFeedingS:
-        d_printf (1,"%s:%d Issuing disconnect\n",
-                 hostPeerName (cxn->myHost), cxn->ident) ;
-
-        clearTimer (cxn->flushTimerId) ;
-
-        cxn->state = cxnClosingS ;
-
-        if (cxn->articleQTotal == 0)
-          issueQUIT (cxn) ; /* send out the QUIT if we can */
-        break ;
-
-      case cxnIdleS:
-      case cxnIdleTimeoutS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        if (cxn->state != cxnIdleTimeoutS)
-          clearTimer (cxn->artReceiptTimerId) ;
-        clearTimer (cxn->flushTimerId) ;
-        cxn->state = cxnClosingS ;
-        issueQUIT (cxn) ;
-        break ;
-
-      case cxnFlushingS: /* we are in the middle of a periodic close. */
-        d_printf (1,"%s:%d Connection already being flushed\n",
-                 hostPeerName (cxn->myHost),cxn->ident);
-        cxn->state = cxnClosingS ;
-        if (cxn->articleQTotal == 0)
-          issueQUIT (cxn) ; /* send out the QUIT if we can */
-        break ;
-
-      case cxnClosingS:
-        d_printf (1,"%s:%d Connection already closing\n",
-                 hostPeerName (cxn->myHost),cxn->ident) ;
-        break ;
-
-      case cxnWaitingS:
-      case cxnConnectingS:
-      case cxnSleepingS:
-        cxnDead (cxn) ;
-        break ;
-
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (cxn->state == cxnDeadS)
-    {
-      d_printf (1,"%s:%d Deleting connection\n",hostPeerName (cxn->myHost),
-               cxn->ident) ;
-
-      delConnection (cxn) ;
-    }
-}
-
-
-
-
-\f
-/* This is what the Host calls to get us to tranfer an article. If
- * we're running the IHAVE sequence, then we can't take it if we've
- * got an article already. If we're running the CHECK/TAKETHIS
- * sequence, then we'll take as many as we can (up to our MAXCHECK
- * limit).
- */
-bool cxnTakeArticle (Connection cxn, Article art)
-{
-  bool rval = true ;
-
-  ASSERT (cxn != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  if ( !cxnQueueArticle (cxn,art) ) /* might change cxnIdleS to cxnFeedingS */
-    return false ;
-
-  if (!(cxn->state == cxnConnectingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnWaitingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return false ;
-    }
-  
-  if (cxn->state != cxnWaitingS) /* because articleQTotal == 1 */
-    VALIDATE_CONNECTION (cxn) ;
-  else
-    ASSERT (cxn->articleQTotal == 1) ;
-
-  switch (cxn->state)
-    {
-      case cxnWaitingS:
-        cxnConnect (cxn) ;
-        break ;
-
-      case cxnFeedingS:
-        doSomeWrites (cxn) ;
-        break ;
-
-      case cxnConnectingS:
-        break ;
-
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-
-  return rval ;
-}
-
-
-
-
-\f
-/* if there's room in the Connection then stick the article on the
- * queue, otherwise return false.
- */
-bool cxnQueueArticle (Connection cxn, Article art)
-{
-  ArtHolder newArt ;
-  bool rval = false ;
-
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state != cxnStartingS) ;
-  ASSERT (cxn->state != cxnDeadS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  switch (cxn->state)
-    {
-      case cxnClosingS:
-        d_printf (5,"%s:%d Refusing article due to closing\n",
-                 hostPeerName (cxn->myHost),cxn->ident) ;
-        break ;
-
-      case cxnFlushingS:
-        d_printf (5,"%s:%d Refusing article due to flushing\n",
-                 hostPeerName (cxn->myHost),cxn->ident) ;
-        break ;
-
-      case cxnSleepingS:
-        d_printf (5,"%s:%d Refusing article due to sleeping\n",
-                 hostPeerName (cxn->myHost),cxn->ident) ;
-        break ;
-
-      case cxnWaitingS:
-        rval = true ;
-        newArt = newArtHolder (art) ;
-        appendArtHolder (newArt, &cxn->checkHead, &cxn->articleQTotal) ;
-        break ;
-
-      case cxnConnectingS:
-        if (cxn->articleQTotal != 0)
-          break ;
-        rval = true ;
-        newArt = newArtHolder (art) ;
-        appendArtHolder (newArt, &cxn->checkHead, &cxn->articleQTotal) ;
-        break ;
-
-      case cxnIdleS:
-      case cxnFeedingS:
-        if (cxn->articleQTotal >= cxn->maxCheck)
-          d_printf (5, "%s:%d Refusing article due to articleQTotal >= maxCheck (%d > %d)\n",
-                   hostPeerName (cxn->myHost), cxn->ident,
-                   cxn->articleQTotal, cxn->maxCheck) ;
-        else
-          {
-            rval = true ;
-            newArt = newArtHolder (art) ;
-            if (cxn->needsChecks)
-              appendArtHolder (newArt, &cxn->checkHead, &cxn->articleQTotal) ;
-            else
-              appendArtHolder (newArt, &cxn->takeHead, &cxn->articleQTotal) ;
-            if (cxn->state == cxnIdleS)
-              {
-                cxn->state = cxnFeedingS ;
-                clearTimer (cxn->artReceiptTimerId) ;
-              }
-          }
-        break ;
-
-      default:
-        die ("Invalid state: %s\n", stateToString (cxn->state)) ;
-    }
-
-  if (rval)
-    {
-      d_printf (5,"%s:%d accepting article %s\n",hostPeerName (cxn->myHost),
-               cxn->ident,artMsgId (art)) ;
-
-      cxn->artsTaken++ ;
-    }
-
-  return rval ;
-}
-
-
-
-
-\f
-/*
- * generate a log message for activity. Usually called by the Connection's
- * owner
- */
-void cxnLogStats (Connection cxn, bool final)
-{
-  const char *peerName ;
-  time_t now = theTime() ;
-
-  ASSERT (cxn != NULL) ;
-
-  /* only log stats when in one of these three states. */
-  switch (cxn->state)
-    {
-      case cxnFeedingS:
-      case cxnFlushingS:
-      case cxnClosingS:
-        break ;
-
-      default:
-        return ;
-    }
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  notice ("%s:%d %s seconds %ld offered %d accepted %d refused %d"
-          " rejected %d accsize %.0f rejsize %.0f", peerName, cxn->ident,
-          (final ? "final" : "checkpoint"), (long) (now - cxn->timeCon),
-          cxn->checksIssued, cxn->takesOkayed, cxn->checksRefused,
-          cxn->takesRejected, cxn->takesSizeOkayed, cxn->takesSizeRejected) ;
-
-  if (final)
-    {
-      cxn->artsTaken = 0 ;
-      cxn->checksIssued = 0 ;
-      cxn->checksRefused = 0 ;
-      cxn->takesRejected = 0 ;
-      cxn->takesOkayed = 0 ;
-      cxn->takesSizeRejected = 0 ;
-      cxn->takesSizeOkayed = 0 ;
-
-      if (cxn->timeCon > 0)
-        cxn->timeCon = theTime() ;
-    }
-}
-
-
-
-
-\f
-/*
- * return the number of articles the connection will accept.
- */
-size_t cxnQueueSpace (Connection cxn)
-{
-  int rval = 0 ;
-
-  ASSERT (cxn != NULL) ;
-
-  if (cxn->state == cxnFeedingS ||
-      cxn->state == cxnIdleS ||
-      cxn->state == cxnConnectingS ||
-      cxn->state == cxnWaitingS)
-    rval = cxn->maxCheck - cxn->articleQTotal ;
-
-  return rval ;
-}
-
-
-
-
-\f
-/*
- * Print info on all the connections that currently exist.
- */
-void gPrintCxnInfo (FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  Connection cxn ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sGlobal Connection list : (count %d) {\n",
-           indent,gCxnCount) ;
-  for (cxn = gCxnList ; cxn != NULL ; cxn = cxn->next)
-    printCxnInfo (cxn,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-
-
-\f
-/*
- * Print the info about the given connection.
- */
-void printCxnInfo (Connection cxn, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  ArtHolder artH ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sConnection : %p {\n",indent, (void *) cxn) ;
-  fprintf (fp,"%s    host : %p\n",indent, (void *) cxn->myHost) ;
-  fprintf (fp,"%s    endpoint : %p\n",indent, (void *) cxn->myEp) ;
-  fprintf (fp,"%s    state : %s\n",indent, stateToString (cxn->state)) ;
-  fprintf (fp,"%s    ident : %d\n",indent,cxn->ident) ;
-  fprintf (fp,"%s    ip-name : %s\n", indent, cxn->ipName) ;
-  fprintf (fp,"%s    port-number : %d\n",indent,cxn->port) ;
-  fprintf (fp,"%s    max-checks : %d\n",indent,cxn->maxCheck) ;
-  fprintf (fp,"%s    does-streaming : %s\n",indent,
-           boolToString (cxn->doesStreaming)) ;
-  fprintf (fp,"%s    authenticated : %s\n",indent,
-           boolToString (cxn->authenticated)) ;
-  fprintf (fp,"%s    quitWasIssued : %s\n",indent,
-           boolToString (cxn->quitWasIssued)) ;
-  fprintf (fp,"%s    needs-checks : %s\n",indent,
-           boolToString (cxn->needsChecks)) ;
-
-  fprintf (fp,"%s    time-connected : %ld\n",indent,(long) cxn->timeCon) ;
-  fprintf (fp,"%s    articles from INN : %d\n",indent,cxn->artsTaken) ;
-  fprintf (fp,"%s    articles offered : %d\n",indent,
-           cxn->checksIssued) ;
-  fprintf (fp,"%s    articles refused : %d\n",indent,
-           cxn->checksRefused) ;
-  fprintf (fp,"%s    articles rejected : %d\n",indent,
-           cxn->takesRejected) ;
-  fprintf (fp,"%s    articles accepted : %d\n",indent,
-           cxn->takesOkayed) ;
-  fprintf (fp,"%s    low-pass upper limit : %0.6f\n", indent,
-           cxn->onThreshold) ;
-  fprintf (fp,"%s    low-pass lower limit : %0.6f\n", indent,
-           cxn->offThreshold) ;
-  fprintf (fp,"%s    low-pass filter tc : %0.6f\n", indent,
-           cxn->lowPassFilter) ;
-  fprintf (fp,"%s    low-pass filter : %0.6f\n", indent,
-           cxn->filterValue) ;
-
-  fprintf (fp,"%s    article-timeout : %d\n",indent,cxn->articleReceiptTimeout) ;
-  fprintf (fp,"%s    article-callback : %d\n",indent,cxn->artReceiptTimerId) ;
-
-  fprintf (fp,"%s    response-timeout : %d\n",indent,cxn->readTimeout) ;
-  fprintf (fp,"%s    response-callback : %d\n",indent,cxn->readBlockedTimerId) ;
-
-  fprintf (fp,"%s    write-timeout : %d\n",indent,cxn->writeTimeout) ;
-  fprintf (fp,"%s    write-callback : %d\n",indent,cxn->writeBlockedTimerId) ;
-
-  fprintf (fp,"%s    flushTimeout : %d\n",indent,cxn->flushTimeout) ;
-  fprintf (fp,"%s    flushTimerId : %d\n",indent,cxn->flushTimerId) ;
-
-  fprintf (fp,"%s    reopen wait : %d\n",indent,cxn->sleepTimeout) ;
-  fprintf (fp,"%s    reopen id : %d\n",indent,cxn->sleepTimerId) ;
-
-  fprintf (fp,"%s    CHECK queue {\n",indent) ;
-  for (artH = cxn->checkHead ; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    CHECK Response queue {\n",indent) ;
-  for (artH = cxn->checkRespHead ; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    TAKE queue {\n",indent) ;
-  for (artH = cxn->takeHead ; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    TAKE response queue {\n",indent) ;
-  for (artH = cxn->takeRespHead ; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    response buffer {\n",indent) ;
-  printBufferInfo (cxn->respBuffer,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-
-
-\f
-/*
- * return the number of articles the connection will accept.
- */
-bool cxnCheckstate (Connection cxn)
-{
-  bool rval = false ;
-
-  ASSERT (cxn != NULL) ;
-
-  if (cxn->state == cxnFeedingS ||
-      cxn->state == cxnIdleS ||
-      cxn->state == cxnConnectingS)
-    rval = true ;
-
-  return rval ;
-}
-
-
-
-
-\f
-/**********************************************************************/
-/**                       STATIC PRIVATE FUNCTIONS                   **/
-/**********************************************************************/
-
-
-/*
- * ENDPOINT CALLBACK AREA.
- *
- * All the functions in this next section are callbacks fired by the
- * EndPoint objects/class (either timers or i/o completion callbacks)..
- */
-
-\f
-/*
- * this is the first stage of the NNTP FSM. This function is called
- * when the tcp/ip network connection is setup and we should get
- * ready to read the banner message. When this function returns the
- * state of the Connection will still be cxnConnectingS unless
- * something broken, in which case it probably went into the
- * cxnSleepingS state.
- */
-static void connectionDone (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Buffer *readBuffers ;
-  Connection cxn = (Connection) d ;
-  const char *peerName ;
-  int optval;
-  socklen_t size ;
-
-  ASSERT (b == NULL) ;
-  ASSERT (cxn->state == cxnConnectingS) ;
-  ASSERT (!writeIsPending (cxn->myEp)) ;
-
-  size = sizeof (optval) ;
-  peerName = hostPeerName (cxn->myHost) ;
-
-  if (i != IoDone)
-    {
-      errno = endPointErrno (e) ;
-      syswarn ("%s:%d cxnsleep i/o failed", peerName, cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (getsockopt (endPointFd (e), SOL_SOCKET, SO_ERROR,
-                       (char *) &optval, &size) != 0)
-    {
-      /* This is bad. Can't even get the SO_ERROR value out of the socket */
-      syswarn ("%s:%d cxnsleep internal getsockopt", peerName, cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (optval != 0)
-    {
-      /* if the connect failed then the only way to know is by getting
-         the SO_ERROR value out of the socket. */
-      errno = optval ;
-      syswarn ("%s:%d cxnsleep connect", peerName, cxn->ident) ;
-      hostIpFailed (cxn->myHost) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else
-    {
-      readBuffers = makeBufferArray (bufferTakeRef (cxn->respBuffer), NULL) ;
-
-      if ( !prepareRead (e, readBuffers, getBanner, cxn, 1) )
-        {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-
-          cxnSleepOrDie (cxn) ;
-        }
-      else
-        {
-          initReadBlockedTimeout (cxn) ;
-
-          /* set up the callback for closing down the connection at regular
-             intervals (due to problems with long running nntpd). */
-          if (cxn->flushTimeout > 0)
-            cxn->flushTimerId = prepareSleep (flushCxnCbk,
-                                              cxn->flushTimeout,cxn) ;
-
-          /* The state doesn't change yet until we've read the banner and
-             tried the MODE STREAM command. */
-        }
-    }
-  VALIDATE_CONNECTION (cxn) ;
-}
-
-
-
-
-\f
-/*
- * This is called when we are so far in the connection setup that
- * we're confident it'll work.  If the connection is IPv6, remove
- * the IPv4 addresses from the address list.
- */
-static void connectionIfIpv6DeleteIpv4Addr (Connection cxn)
-{
-#ifdef HAVE_INET6
-  struct sockaddr_storage ss;
-  socklen_t len = sizeof(ss);
-
-  if (getpeername (endPointFd (cxn->myEp), (struct sockaddr *)&ss, &len) < 0)
-    return;
-  if (ss.ss_family != AF_INET6)
-    return;
-
-  hostDeleteIpv4Addr (cxn->myHost);
-#endif
-}
-
-
-
-
-/*
- * Called when the banner message has been read off the wire and is
- * in the buffer(s). When this function returns the state of the
- * Connection will still be cxnConnectingS unless something broken,
- * in which case it probably went into the cxnSleepiongS state.
- */
-static void getBanner (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Buffer *readBuffers ;
-  Connection cxn = (Connection) d ;
-  char *p = bufferBase (b[0]) ;
-  int code ;
-  bool isOk = false ;
-  const char *peerName ;
-  char *rest ;
-
-  ASSERT (e == cxn->myEp) ;
-  ASSERT (b[0] == cxn->respBuffer) ;
-  ASSERT (b[1] == NULL) ;
-  ASSERT (cxn->state == cxnConnectingS) ;
-  ASSERT (!writeIsPending (cxn->myEp));
-
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  bufferAddNullByte (b[0]) ;
-
-  if (i != IoDone)
-    {
-      errno = endPointErrno (cxn->myEp) ;
-      syswarn ("%s:%d cxnsleep can't read banner", peerName, cxn->ident) ;
-      hostIpFailed (cxn->myHost) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (strchr (p, '\n') == NULL)
-    {                           /* partial read. expand buffer and retry */
-      expandBuffer (b[0], BUFFER_EXPAND_AMOUNT) ;
-      readBuffers = makeBufferArray (bufferTakeRef (b[0]), NULL) ;
-
-      if ( !prepareRead (e, readBuffers, getBanner, cxn, 1) )
-        {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-
-          cxnSleepOrDie (cxn) ;
-        }
-    }
-  else if ( !getNntpResponse (p, &code, &rest) )
-    {
-      trim_ws (p) ;
-
-      warn ("%s:%d cxnsleep response format: %s", peerName, cxn->ident, p) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else
-    {
-      trim_ws (p) ;
-
-      switch (code)
-        {
-          case 200:             /* normal */
-          case 201:             /* can transfer but not post -- old nntpd */
-            isOk = true ;
-            break ;
-
-          case 400:
-            cxnSleepOrDie (cxn) ;
-            hostIpFailed (cxn->myHost) ;
-            hostCxnBlocked (cxn->myHost, cxn, rest) ;
-            break ;
-
-          case 502:
-            warn ("%s:%d cxnsleep no permission to talk: %s", peerName,
-                  cxn->ident, p) ;
-            cxnSleepOrDie (cxn) ;
-            hostIpFailed (cxn->myHost) ;
-            hostCxnBlocked (cxn->myHost, cxn, rest) ;
-            break ;
-
-          default:
-            warn ("%s:%d cxnsleep response unknown banner: %d %s", peerName,
-                  cxn->ident, code, p) ;
-            d_printf (1,"%s:%d Unknown response code: %d: %s\n",
-                     hostPeerName (cxn->myHost),cxn->ident, code, p) ;
-            cxnSleepOrDie (cxn) ;
-            hostIpFailed (cxn->myHost) ;
-            hostCxnBlocked (cxn->myHost, cxn, rest) ;
-            break ;
-        }
-
-      if ( isOk )
-       {
-      /* If we got this far and the connection is IPv6, remove
-         the IPv4 addresses from the address list. */
-      connectionIfIpv6DeleteIpv4Addr (cxn);
-
-         if (hostUsername (cxn->myHost) != NULL
-             && hostPassword (cxn->myHost) != NULL)
-           issueAuthUser (e,cxn);
-         else
-           issueModeStream (e,cxn);
-       }
-    }
-  freeBufferArray (b) ;
-}
-
-
-
-
-\f
-static void issueAuthUser (EndPoint e, Connection cxn)
-{
-  Buffer authUserBuffer;
-  Buffer *authUserCmdBuffers,*readBuffers;
-  size_t lenBuff = 0 ;
-  char *t ;
-
-  /* 17 == strlen("AUTHINFO USER \r\n\0") */
-  lenBuff = (17 + strlen (hostUsername (cxn->myHost))) ;
-  authUserBuffer = newBuffer (lenBuff) ;
-  t = bufferBase (authUserBuffer) ;
-
-  sprintf (t, "AUTHINFO USER %s\r\n", hostUsername (cxn->myHost)) ;
-  bufferSetDataSize (authUserBuffer, strlen (t)) ;
-
-  authUserCmdBuffers = makeBufferArray (authUserBuffer, NULL) ;
-
-  if ( !prepareWriteWithTimeout (e, authUserCmdBuffers, authUserIssued,
-                                cxn) )
-    {
-      die ("%s:%d fatal prepare write for authinfo user failed",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-    }
-
-  bufferSetDataSize (cxn->respBuffer, 0) ;
-
-  readBuffers = makeBufferArray (bufferTakeRef(cxn->respBuffer),NULL);
-
-  if ( !prepareRead (e, readBuffers, getAuthUserResponse, cxn, 1) )
-    {
-      warn ("%s:%d cxnsleep prepare read failed", hostPeerName (cxn->myHost),
-            cxn->ident) ;
-      freeBufferArray (readBuffers) ;
-      cxnSleepOrDie (cxn) ;
-    }
-
-}
-
-
-
-
-
-\f
-static void issueAuthPass (EndPoint e, Connection cxn)
-{
-  Buffer authPassBuffer;
-  Buffer *authPassCmdBuffers,*readBuffers;
-  size_t lenBuff = 0 ;
-  char *t ;
-
-  /* 17 == strlen("AUTHINFO PASS \r\n\0") */
-  lenBuff = (17 + strlen (hostPassword (cxn->myHost))) ;
-  authPassBuffer = newBuffer (lenBuff) ;
-  t = bufferBase (authPassBuffer) ;
-
-  sprintf (t, "AUTHINFO PASS %s\r\n", hostPassword (cxn->myHost)) ;
-  bufferSetDataSize (authPassBuffer, strlen (t)) ;
-
-  authPassCmdBuffers = makeBufferArray (authPassBuffer, NULL) ;
-
-  if ( !prepareWriteWithTimeout (e, authPassCmdBuffers, authPassIssued,
-                                cxn) )
-    {
-      die ("%s:%d fatal prepare write for authinfo pass failed",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-    }
-
-  bufferSetDataSize (cxn->respBuffer, 0) ;
-
-  readBuffers = makeBufferArray (bufferTakeRef(cxn->respBuffer),NULL);
-
-  if ( !prepareRead (e, readBuffers, getAuthPassResponse, cxn, 1) )
-    {
-      warn ("%s:%d cxnsleep prepare read failed", hostPeerName (cxn->myHost),
-            cxn->ident) ;
-      freeBufferArray (readBuffers) ;
-      cxnSleepOrDie (cxn) ;
-    }
-
-}
-
-
-
-
-
-\f
-static void issueModeStream (EndPoint e, Connection cxn)
-{
-  Buffer *modeCmdBuffers,*readBuffers ;
-  Buffer modeBuffer ;
-  char *p;
-
-#define  MODE_CMD "MODE STREAM\r\n"
-
-  modeBuffer = newBuffer (strlen (MODE_CMD) + 1) ;
-  p = bufferBase (modeBuffer) ;
-
-  /* now issue the MODE STREAM command */
-  d_printf (1,"%s:%d Issuing the streaming command: %s\n",
-           hostPeerName (cxn->myHost),cxn->ident,MODE_CMD) ;
-
-  strcpy (p, MODE_CMD) ;
-
-  bufferSetDataSize (modeBuffer, strlen (p)) ;
-
-  modeCmdBuffers = makeBufferArray (modeBuffer, NULL) ;
-
-  if ( !prepareWriteWithTimeout (e, modeCmdBuffers, modeCmdIssued,
-                                cxn) )
-    {
-      die ("%s:%d fatal prepare write for mode stream failed",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-    }
-
-  bufferSetDataSize (cxn->respBuffer, 0) ;
-
-  readBuffers = makeBufferArray (bufferTakeRef(cxn->respBuffer),NULL);
-
-  if ( !prepareRead (e, readBuffers, getModeResponse, cxn, 1) )
-    {
-      warn ("%s:%d cxnsleep prepare read failed", hostPeerName (cxn->myHost),
-            cxn->ident) ;
-      freeBufferArray (readBuffers) ;
-      cxnSleepOrDie (cxn) ;
-    }
-}
-
-
-
-
-\f
-/*
- *
- */
-static void getAuthUserResponse (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  int code ;
-  char *p = bufferBase (b[0]) ;
-  Buffer *buffers ;
-  const char *peerName ;
-
-  ASSERT (e == cxn->myEp) ;
-  ASSERT (b [0] == cxn->respBuffer) ;
-  ASSERT (b [1] == NULL) ;      /* only ever one buffer on this read */
-  ASSERT (cxn->state == cxnConnectingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  bufferAddNullByte (b[0]) ;
-
-  d_printf (1,"%s:%d Processing authinfo user response: %s", /* no NL */
-           hostPeerName (cxn->myHost), cxn->ident, p) ;
-
-  if (i == IoDone && writeIsPending (cxn->myEp))
-    {
-      /* badness. should never happen */
-      warn ("%s:%d cxnsleep authinfo command still pending", peerName,
-            cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (i != IoDone)
-    {
-      if (i != IoEOF)
-       {
-         errno = endPointErrno (e) ;
-          syswarn ("%s:%d cxnsleep can't read response", peerName, cxn->ident);
-       }
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (strchr (p, '\n') == NULL)
-    {
-      /* partial read */
-      expandBuffer (b [0], BUFFER_EXPAND_AMOUNT) ;
-
-      buffers = makeBufferArray (bufferTakeRef (b [0]), NULL) ;
-      if ( !prepareRead (e, buffers, getAuthUserResponse, cxn, 1) )
-       {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-         freeBufferArray (buffers) ;
-         cxnSleepOrDie (cxn) ;
-       }
-    }
-  else
-    {
-      clearTimer (cxn->readBlockedTimerId) ;
-
-      if ( !getNntpResponse (p, &code, NULL) )
-       {
-          warn ("%s:%d cxnsleep response to AUTHINFO USER: %s", peerName,
-                cxn->ident, p) ;
-
-         cxnSleepOrDie (cxn) ;
-       }
-      else
-       {
-          notice ("%s:%d connected", peerName, cxn->ident) ;
-
-         switch (code)
-           {
-           case 381:
-             issueAuthPass (e,cxn);
-             break ;
-
-           default:
-              warn ("%s:%d cxnsleep response to AUTHINFO USER: %s", peerName,
-                    cxn->ident, p) ;
-             cxn->authenticated = true;
-             issueModeStream (e,cxn);
-             break ;
-           }
-
-       }
-    }
-}
-
-
-
-
-\f
-/*
- *
- */
-static void getAuthPassResponse (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  int code ;
-  char *p = bufferBase (b[0]) ;
-  Buffer *buffers ;
-  const char *peerName ;
-
-  ASSERT (e == cxn->myEp) ;
-  ASSERT (b [0] == cxn->respBuffer) ;
-  ASSERT (b [1] == NULL) ;      /* only ever one buffer on this read */
-  ASSERT (cxn->state == cxnConnectingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  bufferAddNullByte (b[0]) ;
-
-  d_printf (1,"%s:%d Processing authinfo pass response: %s", /* no NL */
-           hostPeerName (cxn->myHost), cxn->ident, p) ;
-
-  if (i == IoDone && writeIsPending (cxn->myEp))
-    {
-      /* badness. should never happen */
-      warn ("%s:%d cxnsleep authinfo command still pending", peerName,
-            cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (i != IoDone)
-    {
-      if (i != IoEOF)
-       {
-         errno = endPointErrno (e) ;
-          syswarn ("%s:%d cxnsleep can't read response", peerName, cxn->ident);
-       }
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (strchr (p, '\n') == NULL)
-    {
-      /* partial read */
-      expandBuffer (b [0], BUFFER_EXPAND_AMOUNT) ;
-
-      buffers = makeBufferArray (bufferTakeRef (b [0]), NULL) ;
-      if ( !prepareRead (e, buffers, getAuthPassResponse, cxn, 1) )
-       {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-         freeBufferArray (buffers) ;
-         cxnSleepOrDie (cxn) ;
-       }
-    }
-  else
-    {
-      clearTimer (cxn->readBlockedTimerId) ;
-
-      if ( !getNntpResponse (p, &code, NULL) )
-       {
-          warn ("%s:%d cxnsleep response to AUTHINFO PASS: %s", peerName,
-                cxn->ident, p) ;
-
-         cxnSleepOrDie (cxn) ;
-       }
-      else
-       {
-         switch (code)
-           {
-           case 281:
-              notice ("%s:%d authenticated", peerName, cxn->ident) ;
-             cxn->authenticated = true ;
-             issueModeStream (e,cxn);
-             break ;
-
-           default:
-              warn ("%s:%d cxnsleep response to AUTHINFO PASS: %s", peerName,
-                    cxn->ident, p) ;
-             cxnSleepOrDie (cxn) ;
-             break ;
-           }
-
-       }
-    }
-}
-
-
-
-
-\f
-/*
- * Process the remote's response to our MODE STREAM command. This is where
- * the Connection moves into the cxnFeedingS state. If the remote has given
- * us a good welcome banner, but then immediately dropped the connection,
- * we'll arrive here with the MODE STREAM command still queued up.
- */
-static void getModeResponse (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  int code ;
-  char *p = bufferBase (b[0]) ;
-  Buffer *buffers ;
-  const char *peerName ;
-
-  ASSERT (e == cxn->myEp) ;
-  ASSERT (b [0] == cxn->respBuffer) ;
-  ASSERT (b [1] == NULL) ;      /* only ever one buffer on this read */
-  ASSERT (cxn->state == cxnConnectingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  bufferAddNullByte (b[0]) ;
-
-  d_printf (1,"%s:%d Processing mode response: %s", /* no NL */
-           hostPeerName (cxn->myHost), cxn->ident, p) ;
-
-  if (i == IoDone && writeIsPending (cxn->myEp))
-    {                           /* badness. should never happen */
-      warn ("%s:%d cxnsleep mode stream command still pending", peerName,
-            cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (i != IoDone)
-    {
-      if (i != IoEOF)
-        {
-          errno = endPointErrno (e) ;
-          syswarn ("%s:%d cxnsleep can't read response", peerName, cxn->ident);
-        }
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (strchr (p, '\n') == NULL)
-    {                           /* partial read */
-      expandBuffer (b [0], BUFFER_EXPAND_AMOUNT) ;
-
-      buffers = makeBufferArray (bufferTakeRef (b [0]), NULL) ;
-      if ( !prepareRead (e, buffers, getModeResponse, cxn, 1) )
-        {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-          freeBufferArray (buffers) ;
-          cxnSleepOrDie (cxn) ;
-        }
-    }
-  else
-    {
-      clearTimer (cxn->readBlockedTimerId) ;
-
-      if ( !getNntpResponse (p, &code, NULL) )
-        {
-          warn ("%s:%d cxnsleep response to MODE STREAM: %s", peerName,
-                cxn->ident, p) ;
-
-          cxnSleepOrDie (cxn) ;
-        }
-      else
-        {
-         if (!cxn->authenticated)
-            notice ("%s:%d connected", peerName, cxn->ident) ;
-          
-          switch (code)
-            {
-              case 203:             /* will do streaming */
-                hostRemoteStreams (cxn->myHost, cxn, true) ;
-
-                if (hostWantsStreaming (cxn->myHost))
-                  {
-                    cxn->doesStreaming = true ;
-                    cxn->maxCheck = hostMaxChecks (cxn->myHost) ;
-                  }
-                else
-                  cxn->maxCheck = 1 ;
-            
-                break ;
-                
-              default:                      /* won't do it */
-                hostRemoteStreams (cxn->myHost, cxn, false) ;
-                cxn->maxCheck = 1 ;
-                break ;
-            }
-          
-          /* now we consider ourselves completly connected. */
-          cxn->timeCon = theTime () ;
-          if (cxn->articleQTotal == 0)
-            cxnIdle (cxn) ;
-          else
-            cxn->state = cxnFeedingS ;
-          
-              /* one for the connection and one for the buffer array */
-          ASSERT (cxn->authenticated || bufferRefCount (cxn->respBuffer) == 2) ;
-          
-          /* there was only one line in there, right? */
-          bufferSetDataSize (cxn->respBuffer, 0) ;
-          buffers = makeBufferArray (bufferTakeRef (cxn->respBuffer), NULL) ;
-          
-              /* sleepTimeout get changed at each failed attempt, so reset. */
-          cxn->sleepTimeout = init_reconnect_period ;
-          
-          if ( !prepareRead (cxn->myEp, buffers, responseIsRead, cxn, 1) )
-            {
-              freeBufferArray (buffers) ;
-              
-              cxnSleepOrDie (cxn) ;
-            }
-          else
-            {
-              /* now we wait for articles from our Host, or we have some
-                 articles already. On infrequently used connections, the
-                 network link is torn down and rebuilt as needed. So we may
-                 be rebuilding the connection here in which case we have an
-                 article to send. */
-              if (writesNeeded (cxn) || hostGimmeArticle (cxn->myHost,cxn))
-                doSomeWrites (cxn) ;
-            }
-        }
-    }
-  
-  freeBufferArray (b) ;
-}
-
-
-
-
-\f
-/*
- * called when a response has been read from the socket. This is
- * where the bulk of the processing starts.
- */
-static void responseIsRead (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  char *response ;
-  char *endr ;
-  char *bufBase ;
-  unsigned int respSize ;
-  int code ;
-  char *rest = NULL ;
-  Buffer buf ;
-  Buffer *bArr ;
-  const char *peerName ;
-
-  ASSERT (e == cxn->myEp) ;
-  ASSERT (b != NULL) ;
-  ASSERT (b [1] == NULL) ;
-  ASSERT (b [0] == cxn->respBuffer) ;
-  ASSERT (cxn->state == cxnFeedingS ||
-          cxn->state == cxnIdleS    ||
-          cxn->state == cxnClosingS ||
-          cxn->state == cxnFlushingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  bufferAddNullByte (b [0]) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  if (i != IoDone)
-    {                           /* uh oh. */
-      if (i != IoEOF)
-        {
-          errno = endPointErrno (e) ;
-          syswarn ("%s:%d cxnsleep can't read response", peerName, cxn->ident);
-        }
-      freeBufferArray (b) ;
-
-      cxnLogStats (cxn,true) ;
-
-      if (cxn->state == cxnClosingS)
-        {
-          cxnDead (cxn) ;
-          delConnection (cxn) ;
-        }
-      else
-        cxnSleep (cxn) ;
-
-      return ;
-    }
-
-  buf = b [0] ;
-  bufBase = bufferBase (buf) ;
-
-  /* check that we have (at least) a full line response. If not expand
-     the buffer and resubmit the read. */
-  if (strchr (bufBase, '\n') == 0)
-    {
-      if (!expandBuffer (buf, BUFFER_EXPAND_AMOUNT))
-        {
-          warn ("%s:%d cxnsleep can't expand input buffer", peerName,
-                cxn->ident) ;
-          freeBufferArray (b) ;
-
-          cxnSleepOrDie (cxn) ;
-        }
-      else if ( !prepareRead (cxn->myEp, b, responseIsRead, cxn, 1))
-        {
-          warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-          freeBufferArray (b) ;
-
-          cxnSleepOrDie (cxn) ;
-        }
-
-      return ;
-    }
-
-
-  freeBufferArray (b) ; /* connection still has reference to buffer */
-
-  
-  /*
-   * Now process all the full responses that we have.
-   */
-  response = bufBase ;
-  respSize = bufferDataSize (cxn->respBuffer) ;
-
-  while ((endr = strchr (response, '\n')) != NULL)
-    {
-      char *next = endr + 1 ;
-
-      if (*next == '\r')
-        next++ ;
-
-      endr-- ;
-      if (*endr != '\r')
-        endr++ ;
-
-      if (next - endr != 2 && !cxn->loggedNoCr)
-        {
-          /* only a newline there. we'll live with it */
-          warn ("%s:%d remote not giving out CR characters", peerName,
-                cxn->ident) ;
-          cxn->loggedNoCr = true ;
-        }
-
-      *endr = '\0' ;
-
-      if ( !getNntpResponse (response, &code, &rest) )
-        {
-          warn ("%s:%d cxnsleep response format: %s", peerName, cxn->ident,
-                response) ;
-          cxnSleepOrDie (cxn) ;
-
-          return ;
-        }
-      
-      d_printf (5,"%s:%d Response %d: %s\n", peerName, cxn->ident, code, response) ;
-
-      /* now handle the response code. I'm not using symbolic names on
-         purpose--the numbers are all you see in the RFC's. */
-      switch (code)
-        {
-          case 205:             /* OK response to QUIT. */
-            processResponse205 (cxn, response) ;
-            break ;
-
-
-
-            /* These three are from the CHECK command */
-          case 238:             /* no such article found */
-           /* Do not incrFilter (cxn) now, wait till after
-              subsequent TAKETHIS */
-            processResponse238 (cxn, response) ;
-            break ;
-
-          case 431:             /* try again later (also for TAKETHIS) */
-            decrFilter (cxn) ;
-            if (hostDropDeferred (cxn->myHost))
-                processResponse438 (cxn, response) ;
-            else
-                processResponse431 (cxn, response) ;
-            break ;
-
-          case 438:             /* already have it */
-            decrFilter (cxn) ;
-            processResponse438 (cxn, response) ;
-            break ;
-
-
-
-            /* These are from the TAKETHIS command */
-          case 239:             /* article transferred OK */
-            incrFilter (cxn) ;
-            processResponse239 (cxn, response) ;
-            break ;
-
-          case 439:             /* article rejected */
-            decrFilter (cxn) ;
-            processResponse439 (cxn, response) ;
-            break ;
-
-
-
-            /* These are from the IHAVE command */
-          case 335:             /* send article */
-            processResponse335 (cxn, response) ;
-            break ;
-
-          case 435:             /* article not wanted */
-            processResponse435 (cxn, response) ;
-            break ;
-
-          case 436:             /* transfer failed try again later */
-            if (cxn->takeRespHead == NULL && hostDropDeferred (cxn->myHost))
-                processResponse435 (cxn, response) ;
-            else
-                processResponse436 (cxn, response) ;
-            break ;
-
-          case 437:             /* article rejected */
-            processResponse437 (cxn, response) ;
-            break ;
-
-          case 400:             /* has stopped accepting articles */
-            processResponse400 (cxn, response) ;
-            break ;
-
-            
-
-          case 235:             /* article transfered OK (IHAVE-body) */
-            processResponse235 (cxn, response) ;
-            break ;
-
-
-          case 480:             /* Transfer permission denied. */
-            processResponse480  (cxn,response) ;
-            break ;
-            
-          case 503:             /* remote timeout. */
-            processResponse503  (cxn,response) ;
-            break ;
-
-          default:
-            warn ("%s:%d cxnsleep response unknown: %d %s", peerName,
-                  cxn->ident, code, response) ;
-            cxnSleepOrDie (cxn) ;
-            break ;
-        }
-
-      VALIDATE_CONNECTION (cxn) ;
-
-      if (cxn->state != cxnFeedingS && cxn->state != cxnClosingS &&
-          cxn->state != cxnFlushingS && cxn->state != cxnIdleS /* XXX */)
-        break ;                 /* connection is terminated */
-
-      response = next ;
-    }
-
-  d_printf (5,"%s:%d done with responses\n",hostPeerName (cxn->myHost),
-           cxn->ident) ;
-
-  switch (cxn->state)
-    {
-      case cxnIdleS:
-      case cxnFeedingS:
-      case cxnClosingS:
-      case cxnFlushingS:
-        /* see if we need to drop in to or out of no-CHECK mode */
-        if (cxn->state == cxnFeedingS && cxn->doesStreaming)
-          {
-            if ((cxn->filterValue > cxn->onThreshold) && cxn->needsChecks) {
-             cxn->needsChecks = false;
-              hostLogNoCheckMode (cxn->myHost, true,
-                                 cxn->offThreshold/cxn->lowPassFilter,
-                                 cxn->filterValue/cxn->lowPassFilter,
-                                 cxn->onThreshold/cxn->lowPassFilter) ;
-             /* on and log */
-            } else if ((cxn->filterValue < cxn->offThreshold) &&
-                     !cxn->needsChecks) {
-             cxn->needsChecks = true;
-              hostLogNoCheckMode (cxn->myHost, false,
-                                 cxn->offThreshold/cxn->lowPassFilter,
-                                 cxn->filterValue/cxn->lowPassFilter,
-                                 cxn->onThreshold/cxn->lowPassFilter) ;
-             /* off and log */
-           }
-          }
-
-        /* Now handle possible remaining partial reponse and set up for
-           next read. */
-        if (*response != '\0')
-          {                       /* partial response */
-            unsigned int leftAmt = respSize - (response - bufBase) ;
-
-            d_printf (2,"%s:%d handling a partial response\n",
-                     hostPeerName (cxn->myHost),cxn->ident) ;
-
-            /* first we shift what's left in the buffer down to the
-               bottom, if needed, or just expand the buffer */
-            if (response != bufBase)
-              {
-                /* so next read appends */
-                memmove (bufBase, response, leftAmt) ;
-                bufferSetDataSize (cxn->respBuffer, leftAmt) ;
-              }
-            else if (!expandBuffer (cxn->respBuffer, BUFFER_EXPAND_AMOUNT))
-              die ("%s:%d cxnsleep can't expand input buffer", peerName,
-                   cxn->ident) ;
-          }
-        else
-          bufferSetDataSize (cxn->respBuffer, 0) ;
-
-        bArr = makeBufferArray (bufferTakeRef (cxn->respBuffer), NULL) ;
-
-        if ( !prepareRead (e, bArr, responseIsRead, cxn, 1) )
-          {
-            warn ("%s:%d cxnsleep prepare read failed", peerName, cxn->ident) ;
-            freeBufferArray (bArr) ;
-            cxnWait (cxn) ;
-            return ;
-          }
-        else
-          {
-            /* only setup the timer if we're still waiting for a response
-               to something. There's not necessarily a 1-to-1 mapping
-               between reads and writes in streaming mode. May have been
-               set already above (that would be unlikely I think). */
-            VALIDATE_CONNECTION (cxn) ;
-
-            d_printf (5,"%s:%d about to do some writes\n",
-                     hostPeerName (cxn->myHost),cxn->ident) ;
-
-            doSomeWrites (cxn) ;
-
-            /* If the read timer is (still) running, update it to give
-               those terminally slow hosts that take forever to drain
-               the network buffers and just dribble out responses the
-               benefit of the doubt.  XXX - maybe should just increase
-              timeout for these! */
-            if (cxn->readBlockedTimerId)
-              cxn->readBlockedTimerId = updateSleep (cxn->readBlockedTimerId,
-                                                     responseTimeoutCbk,
-                                                     cxn->readTimeout,
-                                                     cxn) ;
-          }
-        VALIDATE_CONNECTION (cxn) ;
-        break ;
-
-      case cxnWaitingS:         /* presumably after a code 205 or 400 */
-      case cxnConnectingS:      /* presumably after a code 205 or 400 */
-      case cxnSleepingS:        /* probably after a 480 */
-        break ;
-
-      case cxnDeadS:
-        delConnection (cxn) ;
-        break ;
-
-      case cxnStartingS:
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-}
-
-
-
-
-\f
-/*
- * called when the write of the QUIT command has completed.
- */
-static void quitWritten (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  const char *peerName ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  ASSERT (cxn->myEp == e) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (i != IoDone)
-    {
-      errno = endPointErrno (e) ;
-      syswarn ("%s:%d cxnsleep can't write QUIT", peerName, cxn->ident) ;
-      if (cxn->state == cxnClosingS)
-        {
-          cxnDead (cxn) ;
-          delConnection (cxn) ;
-        }
-      else
-        cxnWait (cxn) ;
-    }
-  else
-    /* The QUIT command has been sent, so start the response timer. */
-    initReadBlockedTimeout (cxn) ;
-
-  freeBufferArray (b) ;
-}
-
-
-
-
-\f
-/*
- * called when the write of the IHAVE-body data is finished
- */
-static void ihaveBodyDone (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-
-  ASSERT (e == cxn->myEp) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  if (i != IoDone)
-    {
-      errno = endPointErrno (e) ;
-      syswarn ("%s:%d cxnsleep can't write IHAVE body",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      cxnLogStats (cxn,true) ;
-
-      if (cxn->state == cxnClosingS)
-        {
-          cxnDead (cxn) ;
-          delConnection (cxn) ;
-        }
-      else
-        cxnSleep (cxn) ;
-    }
-  else
-    /* The article has been sent, so start the response timer. */
-    initReadBlockedTimeout (cxn) ;
-
-
-  freeBufferArray (b) ;
-
-  return ;
-}
-
-
-
-
-\f
-/*
- * Called when a command set (IHAVE, CHECK, TAKETHIS) has been
- * written to the remote.
- */
-static void commandWriteDone (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-  const char *peerName ;
-
-  ASSERT (e == cxn->myEp) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  freeBufferArray (b) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  if (i != IoDone)
-    {
-      errno = endPointErrno (e) ;
-      syswarn ("%s:%d cxnsleep can't write command", peerName, cxn->ident) ;
-
-      cxnLogStats (cxn,true) ;
-
-      if (cxn->state == cxnClosingS)
-        {
-          cxnDead (cxn) ;
-          delConnection (cxn) ;
-        }
-      else
-        {
-         /* XXX - so cxnSleep() doesn't die in VALIDATE_CONNECTION () */
-          deferAllArticles (cxn) ;
-          cxnIdle (cxn) ;
-
-          cxnSleep (cxn) ;
-        }
-    }
-  else
-    {
-      /* Some(?) hosts return the 439 response even before we're done
-         sending, so don't go idle until here */
-      if (cxn->state == cxnFeedingS && cxn->articleQTotal == 0)
-        cxnIdle (cxn) ;
-      else
-        /* The command set has been sent, so start the response timer.
-           XXX - we'd like finer grained control */
-        initReadBlockedTimeout (cxn) ;
-
-      if ( cxn->doesStreaming )
-        doSomeWrites (cxn) ;        /* pump data as fast as possible */
-                                    /* XXX - will clear the read timeout */
-    }
-}
-
-
-
-
-\f
-/*
- * Called when the MODE STREAM command has been written down the pipe.
- */
-static void modeCmdIssued (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-
-  ASSERT (e == cxn->myEp) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  /* The mode command has been sent, so start the response timer */
-  initReadBlockedTimeout (cxn) ;
-
-  if (i != IoDone)
-    {
-      d_printf (1,"%s:%d MODE STREAM command failed to write\n",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      syswarn ("%s:%d cxnsleep can't write MODE STREAM",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-
-  freeBufferArray (b) ;
-}
-
-
-
-
-\f
-/*
- * Called when the AUTHINFO USER command has been written down the pipe.
- */
-static void authUserIssued (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-
-  ASSERT (e == cxn->myEp) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  /* The authinfo user command has been sent, so start the response timer */
-  initReadBlockedTimeout (cxn) ;
-
-  if (i != IoDone)
-    {
-      d_printf (1,"%s:%d AUTHINFO USER command failed to write\n",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      syswarn ("%s:%d cxnsleep can't write AUTHINFO USER",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-
-  freeBufferArray (b) ;
-}
-
-
-
-
-
-\f
-/*
- * Called when the AUTHINFO USER command has been written down the pipe.
- */
-static void authPassIssued (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-  Connection cxn = (Connection) d ;
-
-  ASSERT (e == cxn->myEp) ;
-
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  /* The authinfo pass command has been sent, so start the response timer */
-  initReadBlockedTimeout (cxn) ;
-
-  if (i != IoDone)
-    {
-      d_printf (1,"%s:%d AUTHINFO PASS command failed to write\n",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      syswarn ("%s:%d cxnsleep can't write AUTHINFO PASS",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      cxnSleepOrDie (cxn) ;
-    }
-
-  freeBufferArray (b) ;
-}
-
-
-
-
-
-\f
-/*
- * Called whenever some amount of data has been written to the pipe but
- * more data remains to be written
- */
-static void writeProgress (EndPoint e UNUSED, IoStatus i, Buffer *b UNUSED,
-                           void *d)
-{
-  Connection cxn = (Connection) d ;
-
-  ASSERT (i == IoProgress) ;
-
-  if (cxn->writeTimeout > 0)
-    cxn->writeBlockedTimerId = updateSleep (cxn->writeBlockedTimerId,
-                                            writeTimeoutCbk, cxn->writeTimeout,
-                                            cxn) ;
-}
-
-
-
-
-\f
-/*
- * Timers.
- */
-
-/*
- * This is called when the timeout for the reponse from the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void responseTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-  const char *peerName ;
-
-  ASSERT (id == cxn->readBlockedTimerId) ;
-  ASSERT (cxn->state == cxnConnectingS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnFlushingS ||
-          cxn->state == cxnClosingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  /* XXX - let abortConnection clear readBlockedTimerId, otherwise
-     VALIDATE_CONNECTION() will croak */
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  warn ("%s:%d cxnsleep non-responsive connection", peerName, cxn->ident) ;
-  d_printf (1,"%s:%d shutting down non-repsonsive connection\n",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-
-  cxnLogStats (cxn,true) ;
-
-  if (cxn->state == cxnClosingS)
-    {
-      abortConnection (cxn) ;
-      delConnection (cxn) ;
-    }
-  else  
-    cxnSleep (cxn) ;              /* will notify the Host */
-}
-
-
-
-
-\f
-/*
- * This is called when the data write timeout for the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void writeTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-  const char *peerName ;
-
-  ASSERT (id == cxn->writeBlockedTimerId) ;
-  ASSERT (cxn->state == cxnConnectingS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnFlushingS ||
-          cxn->state == cxnClosingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  /* XXX - let abortConnection clear writeBlockedTimerId, otherwise
-     VALIDATE_CONNECTION() will croak */
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  warn ("%s:%d cxnsleep write timeout", peerName, cxn->ident) ;
-  d_printf (1,"%s:%d shutting down non-responsive connection\n",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-
-  cxnLogStats (cxn,true) ;
-
-  if (cxn->state == cxnClosingS)
-    {
-      abortConnection (cxn) ;
-      delConnection (cxn) ;
-    }
-  else  
-    cxnSleep (cxn) ;              /* will notify the Host */
-}
-
-
-
-
-\f
-/*
- * Called by the EndPoint class when the timer goes off
- */
-void reopenTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  ASSERT (id == cxn->sleepTimerId) ;
-
-  cxn->sleepTimerId = 0 ;
-  
-  if (cxn->state != cxnSleepingS)
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else
-    cxnConnect (cxn) ;
-}
-
-
-
-
-\f
-/*
- * timeout callback to close down long running connection.
- */
-static void flushCxnCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  ASSERT (id == cxn->flushTimerId) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  cxn->flushTimerId = 0 ;
-
-  if (!(cxn->state == cxnFeedingS || cxn->state == cxnConnectingS ||
-        cxn->state == cxnIdleS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else
-    {
-      d_printf (1,"%s:%d Handling periodic connection close.\n",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-
-      notice ("%s:%d periodic close", hostPeerName (cxn->myHost), cxn->ident) ;
-
-      cxnFlush (cxn) ;
-    }
-}
-
-
-
-
-\f
-/*
- * Timer callback for when the connection has not received an
- * article from INN. When that happens we tear down the network
- * connection to help recycle fds
- */
-static void articleTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-  const char *peerName = hostPeerName (cxn->myHost) ;
-
-  ASSERT (cxn->artReceiptTimerId == id) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  cxn->artReceiptTimerId = 0 ;
-
-  if (cxn->state != cxnIdleS)
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-
-      return ;
-    }
-
-  /* it's doubtful (right?) that this timer could go off and there'd
-     still be articles in the queue. */
-  if (cxn->articleQTotal > 0)
-    {
-      warn ("%s:%d idle connection still has articles", peerName, cxn->ident) ;
-    }
-  else
-    {
-      notice ("%s:%d idle tearing down connection", peerName, cxn->ident) ;
-      cxn->state = cxnIdleTimeoutS ;
-      cxnFlush (cxn) ;
-    }
-}
-
-
-
-
-\f
-/*
- * function to be called when the fd is not ready for reading, but there is
- * an article on tape or in the queue to be done. Things are done this way
- * so that a Connection doesn't hog time trying to find the next good
- * article for writing. With a large backlog of expired articles that would
- * take a long time. Instead the Connection just tries its next article on
- * tape or queue, and if that's no good then it registers this callback so
- * that other Connections have a chance of being serviced.
- */
-static void cxnWorkProc (EndPoint ep UNUSED, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  d_printf (2,"%s:%d calling work proc\n",
-           hostPeerName (cxn->myHost),cxn->ident) ;
-
-  if (writesNeeded (cxn))
-    doSomeWrites (cxn) ;        /* may re-register the work proc... */
-  else if (cxn->state == cxnFlushingS || cxn->state == cxnClosingS)
-    {
-      if (cxn->articleQTotal == 0)
-        issueQUIT (cxn) ;
-    }
-  else
-    d_printf (2,"%s:%d no writes were needed....\n",
-             hostPeerName (cxn->myHost), cxn->ident) ;
-}
-
-
-
-/****************************************************************************
- *
- * END EndPoint callback area.
- *
- ****************************************************************************/
-
-
-
-
-\f
-/****************************************************************************
- *
- * REPONSE CODE PROCESSING.
- *
- ***************************************************************************/
-
-
-/*
- * A connection needs to sleep, but if it's closing it needs to die instead.
- */
-static void cxnSleepOrDie (Connection cxn)
-{
-  if (cxn->state == cxnClosingS)
-    cxnDead (cxn) ;
-  else
-    cxnSleep (cxn) ;
-}
-
-
-/*
- * Handle the response 205 to our QUIT command, which means the
- * remote is going away and we can happily cleanup
- */
-static void processResponse205 (Connection cxn, char *response UNUSED)
-{
-  bool immedRecon ;
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (!(cxn->state == cxnFeedingS ||
-        cxn->state == cxnIdleS ||
-        cxn->state == cxnFlushingS ||
-        cxn->state == cxnClosingS)) 
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  switch (cxn->state)
-    {
-      case cxnFlushingS:
-      case cxnClosingS:
-        ASSERT (cxn->articleQTotal == 0) ;
-
-        cxnLogStats (cxn,true) ;
-
-        immedRecon = cxn->immedRecon ;
-
-        hostCxnDead (cxn->myHost,cxn) ;
-
-        if (cxn->state == cxnFlushingS && immedRecon)
-          {
-            abortConnection (cxn) ;
-            if (!cxnConnect (cxn))
-              notice ("%s:%d flush re-connect failed",
-                      hostPeerName (cxn->myHost), cxn->ident) ;
-          }
-        else if (cxn->state == cxnFlushingS)
-          cxnWait (cxn) ;
-        else
-          cxnDead (cxn) ;
-        break ;
-
-      case cxnIdleS:
-      case cxnFeedingS:
-        /* this shouldn't ever happen... */
-        warn ("%s:%d cxnsleep response unexpected: %d",
-              hostPeerName (cxn->myHost), cxn->ident, 205) ;
-        cxnSleepOrDie (cxn) ;
-        break ;
-
-      default:
-        die ("Bad connection state: %s\n",stateToString (cxn->state)) ;
-    }
-}
-
-
-
-
-\f
-/*
- * Handle a response code of 238 which is the "no such article"
- * reply to the CHECK command (i.e. remote wants it).
- */
-static void processResponse238 (Connection cxn, char *response)
-{
-  char *msgid ;
-  ArtHolder artHolder ;
-
-  if (!cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected streaming response for non-streaming"
-            " connection: %s", hostPeerName (cxn->myHost), cxn->ident,
-            response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  msgid = getMsgId (response) ;
-
-  if (cxn->checkRespHead == NULL) /* peer is confused */
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,238) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (msgid == NULL || strlen (msgid) == 0 ||
-           (artHolder = artHolderByMsgId (msgid, cxn->checkRespHead)) == NULL)
-    noSuchMessageId (cxn,238,msgid,response) ;
-  else
-    {
-      /* now remove the article from the check queue and move it onto the
-         transmit queue. Another function wil take care of transmitting */
-      remArtHolder (artHolder, &cxn->checkRespHead, &cxn->articleQTotal) ;
-      if (cxn->state != cxnClosingS)
-        appendArtHolder (artHolder, &cxn->takeHead, &cxn->articleQTotal) ;
-      else
-        {
-          hostTakeBackArticle (cxn->myHost, cxn, artHolder->article) ;
-          delArtHolder (artHolder) ;
-        }
-    }
-
-  if (msgid != NULL)
-    free (msgid) ;
-}
-
-
-
-
-\f
-/*
- * process the response "try again later" to the CHECK command If this
- * returns true then the connection is still usable.
- */
-static void processResponse431 (Connection cxn, char *response)
-{
-  char *msgid ;
-  ArtHolder artHolder ;
-
-  if (!cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected streaming response for non-streaming"
-            " connection: %s", hostPeerName (cxn->myHost), cxn->ident,
-            response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  VALIDATE_CONNECTION (cxn) ;
-
-  msgid = getMsgId (response) ;
-
-  if (cxn->checkRespHead == NULL) /* peer is confused */
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,431) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (msgid == NULL || strlen (msgid) == 0 ||
-           (artHolder = artHolderByMsgId (msgid, cxn->checkRespHead)) == NULL)
-    noSuchMessageId (cxn,431,msgid,response) ;
-  else
-    {
-      remArtHolder (artHolder, &cxn->checkRespHead, &cxn->articleQTotal) ;
-      if (cxn->articleQTotal == 0)
-        cxnIdle (cxn) ;
-      hostArticleDeferred (cxn->myHost, cxn, artHolder->article) ;
-      delArtHolder (artHolder) ;
-    }
-
-  if (msgid != NULL)
-    free (msgid) ;
-}
-
-
-
-
-\f
-/*
- * process the "already have it" response to the CHECK command.  If this
- * returns true then the connection is still usable.
- */
-static void processResponse438 (Connection cxn, char *response)
-{
-  char *msgid ;
-  ArtHolder artHolder ;
-
-  if (!cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected streaming response for non-streaming"
-            " connection: %s", hostPeerName (cxn->myHost), cxn->ident,
-            response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  VALIDATE_CONNECTION (cxn) ;
-
-  msgid = getMsgId (response) ;
-
-  if (cxn->checkRespHead == NULL) /* peer is confused */
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,438) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (msgid == NULL || strlen (msgid) == 0 ||
-           (artHolder = artHolderByMsgId (msgid, cxn->checkRespHead)) == NULL)
-    noSuchMessageId (cxn,438,msgid,response) ;
-  else
-    {
-      cxn->checksRefused++ ;
-
-      remArtHolder (artHolder, &cxn->checkRespHead, &cxn->articleQTotal) ;
-      if (cxn->articleQTotal == 0)
-        cxnIdle (cxn) ;
-      hostArticleNotWanted (cxn->myHost, cxn, artHolder->article);
-      delArtHolder (artHolder) ;
-    }
-
-  if (msgid != NULL)
-    free (msgid) ;
-}
-
-
-
-
-\f
-/*
- * process the "article transferred ok" response to the TAKETHIS.
- */
-static void processResponse239 (Connection cxn, char *response)
-{
-  char *msgid ;
-  ArtHolder artHolder ;
-
-  if (!cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected streaming response for non-streaming"
-            " connection: %s", hostPeerName (cxn->myHost), cxn->ident,
-            response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  msgid = getMsgId (response) ;
-
-  if (cxn->takeRespHead == NULL) /* peer is confused */
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,239) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else if (msgid == NULL || strlen (msgid) == 0 ||
-           (artHolder = artHolderByMsgId (msgid, cxn->takeRespHead)) == NULL)
-    noSuchMessageId (cxn,239,msgid,response) ;
-  else
-    {
-      cxn->takesOkayed++ ;
-      cxn->takesSizeOkayed += artSize(artHolder->article);
-
-      remArtHolder (artHolder, &cxn->takeRespHead, &cxn->articleQTotal) ;
-      if (cxn->articleQTotal == 0)
-        cxnIdle (cxn) ;
-      hostArticleAccepted (cxn->myHost, cxn, artHolder->article) ;
-      delArtHolder (artHolder) ;
-    }
-
-  if (msgid != NULL)
-    free (msgid) ;
-}
-
-
-\f
-/*
- *  Set the thresholds for no-CHECK mode; negative means leave existing value
- */
-
-void cxnSetCheckThresholds (Connection cxn,
-                           double lowFilter, double highFilter,
-                           double lowPassFilter)
-{
-  /* Adjust current value for new scaling */
-  if (cxn->lowPassFilter > 0.0)
-    cxn->filterValue = cxn->filterValue / cxn->lowPassFilter * lowPassFilter;
-
-  /* Stick in new values */
-  if (highFilter >= 0)
-    cxn->onThreshold = highFilter * lowPassFilter / 100.0;
-  if (lowFilter >= 0)
-    cxn->offThreshold = lowFilter * lowPassFilter / 100.0;
-  cxn->lowPassFilter = lowPassFilter;
-}
-
-\f
-/*
- *  Blow away the connection gracelessly and immedately clean up
- */
-void cxnNuke (Connection cxn)
-{
-  abortConnection (cxn) ;
-  hostCxnDead (cxn->myHost,cxn) ;
-  delConnection(cxn) ;
-}
-
-\f
-/*
- * process a "article rejected do not try again" response to the
- * TAKETHIS.
- */
-static void processResponse439 (Connection cxn, char *response)
-{
-  char *msgid ;
-  ArtHolder artHolder ;
-
-  if (!cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected streaming response for non-streaming"
-            " connection: %s", hostPeerName (cxn->myHost), cxn->ident,
-            response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-  
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  msgid = getMsgId (response) ;
-
-  if (cxn->takeRespHead == NULL) /* peer is confused */
-    {
-      /* NNTPRelay return 439 for check <messid> if messid is bad */
-      if (cxn->checkRespHead == NULL) /* peer is confused */
-        {
-          warn ("%s:%d cxnsleep response unexpected: %d",
-                hostPeerName (cxn->myHost),cxn->ident,439) ;
-          cxnSleepOrDie (cxn) ;
-        }
-      else
-        {
-          if ((artHolder = artHolderByMsgId (msgid, cxn->checkRespHead)) == NULL)
-            noSuchMessageId (cxn,439,msgid,response) ;
-          else
-            {
-              cxn->checksRefused++ ;
-              remArtHolder (artHolder, &cxn->checkRespHead, &cxn->articleQTotal) ;
-              if (cxn->articleQTotal == 0)
-                cxnIdle (cxn) ;
-              hostArticleNotWanted (cxn->myHost, cxn, artHolder->article);
-              delArtHolder (artHolder) ;
-            }
-        }
-    }
-  else if (msgid == NULL || strlen (msgid) == 0 ||
-           (artHolder = artHolderByMsgId (msgid, cxn->takeRespHead)) == NULL)
-    noSuchMessageId (cxn,439,msgid,response) ;
-  else
-    {
-      cxn->takesRejected++ ;
-      cxn->takesSizeRejected += artSize(artHolder->article);
-
-      remArtHolder (artHolder, &cxn->takeRespHead, &cxn->articleQTotal) ;
-      /* Some(?) hosts return the 439 response even before we're done
-          sending */
-      if (cxn->articleQTotal == 0 && !writeIsPending(cxn->myEp))
-        cxnIdle (cxn) ;
-      hostArticleRejected (cxn->myHost, cxn, artHolder->article) ;
-      delArtHolder (artHolder) ;
-    }
-
-  if (msgid != NULL)
-    free (msgid) ;
-}
-
-
-
-
-
-\f
-/*
- * process the "article transferred ok" response to the IHAVE-body.
- */
-static void processResponse235 (Connection cxn, char *response UNUSED)
-{
-  ArtHolder artHolder ;
-
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  ASSERT (cxn->articleQTotal == 1) ;
-  ASSERT (cxn->takeRespHead != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (cxn->takeRespHead == NULL) /* peer is confused */
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,235) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else
-    {
-      /* now remove the article from the queue and tell the Host to forget
-         about it. */
-      artHolder = cxn->takeRespHead ;
-      
-      cxn->takeRespHead = NULL ;
-      cxn->articleQTotal = 0 ;
-      cxn->takesOkayed++ ;
-      cxn->takesSizeOkayed += artSize(artHolder->article);
-      
-      if (cxn->articleQTotal == 0)
-        cxnIdle (cxn) ;
-
-      hostArticleAccepted (cxn->myHost, cxn, artHolder->article) ;
-      delArtHolder (artHolder) ;
-    }
-}
-
-
-
-
-\f
-/*
- * process the "send article to be transfered" reponse to the IHAVE.
- */
-static void processResponse335 (Connection cxn, char *response UNUSED)
-{
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (cxn->checkRespHead == NULL)
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost),cxn->ident,335) ;
-      cxnSleepOrDie (cxn) ;
-    }
-  else 
-    {
-      VALIDATE_CONNECTION (cxn) ;
-      /* now move the article into the third queue */
-      cxn->takeHead = cxn->checkRespHead ;
-      cxn->checkRespHead = NULL ;
-      
-      issueIHAVEBody (cxn) ;
-    }
-}
-
-
-
-
-\f
-/*
- * process the "not accepting articles" response. This could be to any of
- * the IHAVE/CHECK/TAKETHIS command, but not the banner--that's handled
- * elsewhere.
- */
-static void processResponse400 (Connection cxn, char *response)
-{
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnIdleS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  /* We may get a response 400 multiple times when in streaming mode. */
-  notice ("%s:%d remote cannot accept articles: %s",
-          hostPeerName(cxn->myHost), cxn->ident, response) ;
-  
-  /* right here there may still be data queued to write and so we'll fail
-     trying to issue the quit ('cause a write will be pending). Furthermore,
-     the data pending may be half way through an command, and so just
-     tossing the buffer is nt sufficient. But figuring out where we are and
-     doing a tidy job is hard */
-  if (writeIsPending (cxn->myEp))
-    cxnSleepOrDie (cxn) ;
-  else
-    {
-      if (cxn->articleQTotal > 0)
-        {
-          /* Defer the articles here so that cxnFlush() doesn't set up an
-             immediate reconnect. */
-          deferAllArticles (cxn) ;
-          clearTimer (cxn->readBlockedTimerId) ;
-         /* XXX - so cxnSleep() doesn't die when it validates the connection */
-          cxnIdle (cxn) ;
-        }
-      /* XXX - it would be nice if we QUIT first, but we'd have to go
-         into a state where we just search for the 205 response, and
-         only go into the sleep state at that point */
-      cxnSleepOrDie (cxn) ;
-    }
-}
-
-
-
-
-\f
-/*
- * process the "not wanted" reponse to the IHAVE.
- */
-static void processResponse435 (Connection cxn, char *response UNUSED)
-{
-  ArtHolder artHolder ;
-
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  /* Some servers, such as early versions of Diablo, had a bug where they'd
-     respond with a 435 code (which should only be used for refusing an
-     article before it was offered) after an article has been sent. */
-  if (cxn->checkRespHead == NULL)
-    {
-      warn ("%s:%d cxnsleep response unexpected: %d",
-            hostPeerName (cxn->myHost), cxn->ident, 435) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  ASSERT (cxn->articleQTotal == 1) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  cxn->articleQTotal-- ;
-  cxn->checksRefused++ ;
-
-  artHolder = cxn->checkRespHead ;
-  cxn->checkRespHead = NULL ;
-
-  if (cxn->articleQTotal == 0 && !writeIsPending(cxn->myEp))
-    cxnIdle (cxn) ;
-
-  hostArticleNotWanted (cxn->myHost, cxn, artHolder->article) ;
-  delArtHolder (artHolder) ;
-
-#if 0
-  d_printf (1,"%s:%d On exiting 435 article queue total is %d (%d %d %d %d)\n",
-           hostPeerName (cxn->myHost), cxn->ident,
-           cxn->articleQTotal,
-           (int) (cxn->checkHead != NULL),
-           (int) (cxn->checkRespHead != NULL),
-           (int) (cxn->takeHead != NULL),
-           (int) (cxn->takeRespHead != NULL));
-#endif
-}
-
-
-
-
-\f
-/*
- * process the "transfer failed" response to the IHAVE-body, (seems this
- * can come from the IHAVE too).
- */
-static void processResponse436 (Connection cxn, char *response UNUSED)
-{
-  ArtHolder artHolder ;
-
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  ASSERT (cxn->articleQTotal == 1) ;
-  ASSERT (cxn->takeRespHead != NULL || cxn->checkRespHead != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  cxn->articleQTotal-- ;
-
-  if (cxn->takeRespHead != NULL) /* IHAVE-body command barfed */
-    {
-      artHolder = cxn->takeRespHead ;
-      cxn->takeRespHead = NULL ;
-    }
-  else                          /* IHAVE command barfed */
-    {
-      artHolder = cxn->checkRespHead ;
-      cxn->checkRespHead = NULL ;
-    }
-
-  if (cxn->articleQTotal == 0 && !writeIsPending(cxn->myEp))
-    cxnIdle (cxn) ;
-  
-  hostArticleDeferred (cxn->myHost, cxn, artHolder->article) ;
-  delArtHolder (artHolder) ;
-}
-
-
-
-
-\f
-/*
- * Process the "article rejected do not try again" response to the
- * IHAVE-body.
- */
-static void processResponse437 (Connection cxn, char *response UNUSED)
-{
-  ArtHolder artHolder ;
-
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  ASSERT (cxn->articleQTotal == 1) ;
-  ASSERT (cxn->takeRespHead != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  cxn->articleQTotal-- ;
-  cxn->takesRejected++ ;
-
-  artHolder = cxn->takeRespHead ;
-  cxn->takeRespHead = NULL ;
-  cxn->takesSizeRejected += artSize(artHolder->article);
-
-  /* Some servers return the 437 response before we're done sending. */
-  if (cxn->articleQTotal == 0 && !writeIsPending (cxn->myEp))
-    cxnIdle (cxn) ;
-
-  hostArticleRejected (cxn->myHost, cxn, artHolder->article) ;
-  delArtHolder (artHolder) ;
-}
-
-
-/* Process the response 480 Transfer permission defined. We're probably
-   talking to a remote nnrpd on a system that forgot to put us in
-   the hosts.nntp */
-static void processResponse480 (Connection cxn, char *response UNUSED)
-{
-  if (cxn->doesStreaming)
-    {
-      warn ("%s:%d cxnsleep unexpected non-streaming response for"
-            " streaming connection: %s", hostPeerName (cxn->myHost),
-            cxn->ident,response) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (!(cxn->state == cxnFlushingS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  warn ("%s:%d cxnsleep transfer permission denied",
-        hostPeerName (cxn->myHost), cxn->ident) ;
-  
-  if (cxn->state == cxnClosingS)
-    cxnDead (cxn) ;
-  else
-    cxnSleep (cxn) ;
-}
-
-
-
-
-\f
-/*
- * Handle the response 503, which means the timeout of nnrpd.
- */
-static void processResponse503 (Connection cxn, char *response UNUSED)
-{
-  bool immedRecon ;
-
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (!(cxn->state == cxnFeedingS ||
-       cxn->state == cxnIdleS ||
-       cxn->state == cxnFlushingS ||
-       cxn->state == cxnClosingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  if (cxn->articleQTotal != 0)
-    notice ("%s:%d flush re-connect failed", hostPeerName (cxn->myHost),
-            cxn->ident) ;
-
-  cxnLogStats (cxn,true) ;
-
-  immedRecon = cxn->immedRecon ;
-
-  hostCxnDead (cxn->myHost,cxn) ;
-
-  if (cxn->state == cxnFlushingS && immedRecon)
-    {
-      abortConnection (cxn) ;
-      if (!cxnConnect (cxn))
-        notice ("%s:%d flush re-connect failed", hostPeerName (cxn->myHost),
-                cxn->ident) ;
-    }
-  else if (cxn->state == cxnFlushingS)
-    cxnWait (cxn) ;
-  else
-    cxnDead (cxn) ;
-
-}
-
-
-
-
-\f
-/****************************************************************************
- *
- * END REPONSE CODE PROCESSING.
- *
- ***************************************************************************/
-
-
-
-
-\f
-/*
- * puts the Connection into the sleep state.
- */
-static void cxnSleep (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state == cxnFlushingS ||
-          cxn->state == cxnIdleS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnConnectingS) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  abortConnection (cxn) ;
-
-  prepareReopenCbk (cxn) ;  /* XXX - we don't want to reopen if idle */
-  cxn->state = cxnSleepingS ;
-
-  /* tell our Host we're asleep so it doesn't try to give us articles */
-  hostCxnSleeping (cxn->myHost,cxn) ;
-}
-
-
-
-static void cxnDead (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  abortConnection (cxn) ;
-  cxn->state = cxnDeadS ;
-}
-
-
-
-/*
- * Sets the idle timer. If no articles arrive before the timer expires, the
- * connection will be closed.
- */
-static void cxnIdle (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->state == cxnFeedingS || cxn->state == cxnConnectingS ||
-          cxn->state == cxnFlushingS || cxn->state == cxnClosingS) ;
-  ASSERT (cxn->articleQTotal == 0) ;
-  ASSERT (cxn->writeBlockedTimerId == 0) ;
-  ASSERT (!writeIsPending (cxn->myEp)) ;
-  ASSERT (cxn->sleepTimerId == 0) ;
-
-  if (cxn->state == cxnFeedingS || cxn->state == cxnConnectingS)
-    {
-      if (cxn->articleReceiptTimeout > 0)
-        {
-          clearTimer (cxn->artReceiptTimerId) ;
-          cxn->artReceiptTimerId = prepareSleep (articleTimeoutCbk,
-                                                 cxn->articleReceiptTimeout,
-                                                 cxn) ;
-        }
-
-      if (cxn->readTimeout > 0 && cxn->state == cxnFeedingS)
-        clearTimer (cxn->readBlockedTimerId) ;
-
-      cxn->state = cxnIdleS ;
-ASSERT (cxn->readBlockedTimerId == 0) ;
-    }
-}
-
-
-
-
-\f
-/*
- * Called when a response from the remote refers to a non-existant
- * message-id. The network connection is aborted and the Connection
- * object goes into sleep mode.
- */
-static void noSuchMessageId (Connection cxn, unsigned int responseCode,
-                             const char *msgid, const char *response)
-{
-  const char *peerName = hostPeerName (cxn->myHost) ;
-
-  if (msgid == NULL || strlen (msgid) == 0)
-    warn ("%s:%d cxnsleep message-id missing in reponse code %d: %s",
-          peerName, cxn->ident, responseCode, response) ;
-  else
-    warn ("%s:%d cxnsleep message-id invalid message-id in reponse code"
-          " %d: %s", peerName, cxn->ident, responseCode, msgid) ;
-
-  cxnLogStats (cxn,true) ;
-
-  if (cxn->state != cxnClosingS)
-    cxnSleep (cxn) ;
-  else
-    cxnDead (cxn) ;
-}
-
-
-
-
-\f
-/*
- * a processing error has occured (for example in parsing a response), or
- * we're at the end of the FSM and we're cleaning up.
- */
-static void abortConnection (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  /* cxn->myEp could be NULL if we get here during cxnConnect (via
-     cxnWait()) */
-  if (cxn->myEp != NULL)
-    {
-
-      delEndPoint (cxn->myEp) ;
-      cxn->myEp = NULL ;
-    }
-
-  clearTimer (cxn->sleepTimerId) ;
-  clearTimer (cxn->artReceiptTimerId) ;
-  clearTimer (cxn->readBlockedTimerId) ;
-  clearTimer (cxn->writeBlockedTimerId) ;
-  clearTimer (cxn->flushTimerId) ;
-
-  deferAllArticles (cxn) ;      /* give any articles back to Host */
-
-  bufferSetDataSize (cxn->respBuffer,0) ;
-
-  resetConnection (cxn) ;
-  
-  if (cxn->state == cxnFeedingS ||
-      cxn->state == cxnIdleS ||
-      cxn->state == cxnFlushingS ||
-      cxn->state == cxnClosingS)
-    hostCxnDead (cxn->myHost,cxn) ;
-}
-
-
-
-
-/*
- * Set up the callback used when the Connection is sleeping (i.e. will try
- * to reopen the connection).
- */
-static void prepareReopenCbk (Connection cxn)
-{
-  ASSERT (cxn->sleepTimerId == 0) ;
-
-  if (!(cxn->state == cxnConnectingS ||
-        cxn->state == cxnIdleS ||
-        cxn->state == cxnFeedingS ||
-        cxn->state == cxnFlushingS ||
-        cxn->state == cxnStartingS))
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            stateToString (cxn->state)) ;
-      cxnSleepOrDie (cxn) ;
-      return ;
-    }
-
-  d_printf (1,"%s:%d Setting up a reopen callback\n",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-
-  cxn->sleepTimerId = prepareSleep (reopenTimeoutCbk, cxn->sleepTimeout, cxn) ;
-
-  /* bump the sleep timer amount each time to wait longer and longer. Gets
-     reset in resetConnection() */
-  cxn->sleepTimeout *= 2 ;
-  if (cxn->sleepTimeout > max_reconnect_period)
-    cxn->sleepTimeout = max_reconnect_period ;
-}
-
-
-
-
-\f
-/*
- * (re)set all state variables to inital condition.
- */
-static void resetConnection (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-
-  bufferSetDataSize (cxn->respBuffer,0) ;
-
-  cxn->loggedNoCr = false ;
-  cxn->maxCheck = 1 ;
-  cxn->immedRecon = false ;
-  cxn->doesStreaming = false ;  /* who knows, next time around maybe... */
-  cxn->authenticated = false ;
-  cxn->quitWasIssued = false ;
-  cxn->needsChecks = true ;
-  cxn->timeCon = 0 ;
-
-  cxn->artsTaken = 0 ;
-  cxn->checksIssued = 0 ;
-  cxn->checksRefused = 0 ;
-  cxn->takesRejected = 0 ;
-  cxn->takesOkayed = 0 ;
-  cxn->takesSizeRejected = 0 ;
-  cxn->takesSizeOkayed = 0 ;
-
-  cxn->filterValue = 0.0 ;
-}
-
-
-\f
-/*
- * Give back all articles that are queued, but not actually in progress.
- * XXX merge come of this with deferAllArticles
- */
-static void deferQueuedArticles (Connection cxn)
-{
-  ArtHolder p, q ;
-
-  for (q = NULL, p = cxn->checkHead ; p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->checkHead = NULL ;
-
-  for (q = NULL, p = cxn->takeHead ; cxn->doesStreaming && p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->takeHead = NULL ;
-}
-
-
-\f
-/*
- * Give back any articles we have to the Host for later retrys.
- */
-static void deferAllArticles (Connection cxn)
-{
-  ArtHolder p, q ;
-
-  for (q = NULL, p = cxn->checkHead ; p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->checkHead = NULL ;
-
-  for (q = NULL, p = cxn->checkRespHead ; p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->checkRespHead = NULL ;
-
-  for (q = NULL, p = cxn->takeHead ; p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->takeHead = NULL ;
-
-  for (q = NULL, p = cxn->takeRespHead ; p != NULL ; p = q)
-    {
-      q = p->next ;
-      hostTakeBackArticle (cxn->myHost, cxn, p->article) ;
-      delArtHolder (p) ;
-      cxn->articleQTotal-- ;
-    }
-  cxn->takeRespHead = NULL ;
-
-  ASSERT (cxn->articleQTotal == 0) ;
-}
-
-
-
-
-\f
-/*
- * Called when there's an article to be pushed out to the remote. Even if
- * the Connection has an article it's possible that nothing will be written
- * (e.g. if the article on the queue doesn't exist any more)
- */
-static void doSomeWrites (Connection cxn)
-{
-  bool doneSome = false ;
-
-  /* If there's a write pending we can't do anything now. */
-  if ( writeIsPending (cxn->myEp) )
-    return ;
-  else if ( writesNeeded (cxn) ) /* something on a queue. */
-    {
-      if (cxn->doesStreaming)
-        doneSome = issueStreamingCommands (cxn) ;
-      else
-        doneSome = issueIHAVE (cxn) ;
-
-      /* doneSome will be false if article(s) were gone, but if the Host
-         has something available, then it would have been put on the queue
-         for next time around. */
-      if (!doneSome)
-        {
-          if (writesNeeded (cxn)) /* Host gave us something */
-            addWorkCallback (cxn->myEp,cxnWorkProc,cxn) ; /* for next time. */
-          else if (cxn->articleQTotal == 0)
-            {
-              /* if we were in cxnFeedingS, then issueStreamingCommands
-                 already called cxnIdle(). */
-              if (cxn->state == cxnClosingS || cxn->state == cxnFlushingS)
-                issueQUIT (cxn) ; /* and nothing to wait for... */
-            }
-        }
-    }
-  else if (cxn->state == cxnClosingS || cxn->state == cxnFlushingS)
-    {                           /* nothing to do... */
-      if (cxn->articleQTotal == 0)
-        issueQUIT (cxn) ;       /* and nothing to wait for before closing */
-    }
-}
-
-
-
-
-\f
-/* Queue up a buffer with the IHAVE command in it for the article at
- * the head of the transmisson queue.
- *
- * If the article is missing, then the Host will be notified and
- * another article may be put on the Connections queue. This new
- * article is ignored for now, but a work callback is registered so
- * that it can be looked at later.
- */
-static bool issueIHAVE (Connection cxn)
-{
-  Buffer ihaveBuff, *writeArr ;
-  ArtHolder artH ;
-  Article article ;
-  const char *msgid ;
-  char *p ;
-  unsigned int tmp ;
-  size_t bufLen = 256 ;
-  bool rval = false ;
-
-  ASSERT (!cxn->doesStreaming) ;
-  ASSERT (cxn->state == cxnFlushingS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnClosingS) ;
-  ASSERT (cxn->articleQTotal == 1) ;
-  ASSERT (cxn->checkHead != NULL) ;
-  ASSERT (writeIsPending (cxn->myEp) == false) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  artH = cxn->checkHead ;
-  article = cxn->checkHead->article ;
-  msgid = artMsgId (artH->article) ;
-
-  ASSERT (msgid != NULL) ;
-  ASSERT (article != NULL) ;
-  
-      if ((tmp = (strlen (msgid) + 10)) > bufLen)
-        bufLen = tmp ;
-
-      ihaveBuff = newBuffer (bufLen) ;
-
-      ASSERT (ihaveBuff != NULL) ;
-
-      p = bufferBase (ihaveBuff) ;
-      sprintf (p, "IHAVE %s\r\n", msgid) ;
-      bufferSetDataSize (ihaveBuff, strlen (p)) ;
-
-      d_printf (5,"%s:%d Command IHAVE %s\n",
-               hostPeerName (cxn->myHost),cxn->ident,msgid) ;
-
-      writeArr = makeBufferArray (ihaveBuff, NULL) ;
-      if ( !prepareWriteWithTimeout (cxn->myEp, writeArr, commandWriteDone,
-                                     cxn) )
-        {
-          die ("%s:%d fatal prepare write for IHAVE failed",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-        }
-
-      /* now move the article to the second queue */
-      cxn->checkRespHead = cxn->checkHead ;
-      cxn->checkHead = NULL ;
-
-      cxn->checksIssued++ ;
-      hostArticleOffered (cxn->myHost, cxn) ;
-
-      rval = true ;
-
-  return rval ;
-}
-
-
-
-
-\f
-/*
- * Do a prepare write with the article body as the body portion of the
- * IHAVE command
- */
-static void issueIHAVEBody (Connection cxn)
-{
-  Buffer *writeArray ;
-  Article article ;
-
-  ASSERT (cxn != NULL) ;
-  ASSERT (!cxn->doesStreaming) ;
-  ASSERT (cxn->state == cxnFlushingS ||
-          cxn->state == cxnFeedingS ||
-          cxn->state == cxnClosingS) ;
-  ASSERT (cxn->articleQTotal == 1) ;
-  ASSERT (cxn->takeHead != NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  article = cxn->takeHead->article ;
-  ASSERT (article != NULL) ;
-  
-  if (cxn->state != cxnClosingS)
-    writeArray = artGetNntpBuffers (article) ;
-  else
-    writeArray = NULL ;
-
-  if (writeArray == NULL)
-    {
-      /* missing article (expired for example) will get us here. */
-      if (dotBuffer == NULL)
-        {
-          dotBuffer = newBufferByCharP (".\r\n",3,3) ;
-          dotFirstBuffer = newBufferByCharP ("\r\n.",3,3) ;
-          crlfBuffer = newBufferByCharP ("\r\n",2,2) ;
-        }
-
-      /* we'll just write the empty buffer and the remote will complain
-         with 437 */
-      writeArray = makeBufferArray  (bufferTakeRef (dotBuffer),NULL) ;
-    }
-  
-
-  if ( !prepareWriteWithTimeout (cxn->myEp, writeArray, ihaveBodyDone, cxn) )
-    {
-      die ("%s:%d fatal prepare write failed in issueIHAVEBody",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-    }
-  else
-    {
-      d_printf (5,"%s:%d prepared write for IHAVE body.\n",
-               hostPeerName (cxn->myHost),cxn->ident) ;
-    }
-  
-  /* now move the article to the last queue */
-  cxn->takeRespHead = cxn->takeHead ;
-  cxn->takeHead = NULL ;
-
-  return ;
-}
-
-
-
-
-\f
-/* Process the two command queues. Slaps all the CHECKs together and
- * then does the TAKETHIS commands.
- *
- * If no articles on the queue(s) are valid, then the Host is
- * notified. It may queue up new articles on the Connection, but
- * these are ignored for now. A work proc is registered so the
- * articles can be processed later.
- */
-static bool issueStreamingCommands (Connection cxn)
-{
-  Buffer checkBuffer = NULL ;   /* the buffer with the CHECK commands in it. */
-  Buffer *writeArray = NULL ;
-  ArtHolder p, q ;
-  bool rval = false ;
-
-  ASSERT (cxn != NULL) ;
-  ASSERT (cxn->myEp != NULL) ;
-  ASSERT (cxn->doesStreaming) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  checkBuffer = buildCheckBuffer (cxn) ; /* may be null if none to issue */
-
-  if (checkBuffer != NULL)
-    {
-      /* Now shift the articles to their new queue. */
-      for (p = cxn->checkRespHead ; p != NULL && p->next != NULL ; p = p->next)
-        /* nada--finding end of queue*/ ;
-
-      if (p == NULL)
-        cxn->checkRespHead = cxn->checkHead ;
-      else
-        p->next = cxn->checkHead ;
-      
-      cxn->checkHead = NULL ;
-    }
-  
-
-  writeArray = buildTakethisBuffers (cxn,checkBuffer) ; /* may be null */
-
-  /* If not null, then writeArray will have checkBuffer (if it wasn't NULL)
-     in the first spot and the takethis buffers after that. */
-  if (writeArray)
-    {
-      if ( !prepareWriteWithTimeout (cxn->myEp, writeArray,
-                                     commandWriteDone, cxn) )
-        {
-          die ("%s:%d fatal prepare write for STREAMING commands failed",
-               hostPeerName (cxn->myHost), cxn->ident) ;
-        }
-
-      rval = true ;
-
-      /* now shift articles over to their new queue. */
-      for (p = cxn->takeRespHead ; p != NULL && p->next != NULL ; p = p->next)
-        /* nada--finding end of queue */ ;
-
-      if (p == NULL)
-        cxn->takeRespHead = cxn->takeHead ;
-      else
-        p->next = cxn->takeHead ;
-      
-      cxn->takeHead = NULL ;
-    }
-
-  /* we defer the missing article notification to here because if there
-     was a big backlog of missing articles *and* we're running in
-     no-CHECK mode, then the Host would be putting bad articles on the
-     queue we're taking them off of. */
-  if (cxn->missing && cxn->articleQTotal == 0)
-    cxnIdle (cxn) ;
-  for (p = cxn->missing ; p != NULL ; p = q)
-    {
-      hostArticleIsMissing (cxn->myHost, cxn, p->article) ;
-      q = p->next ;
-      delArtHolder (p) ;
-    }
-  cxn->missing = NULL ;
-
-  return rval ;
-}
-
-
-
-
-\f
-/*
- * build up the buffer of all the CHECK commands.
- */
-static Buffer buildCheckBuffer (Connection cxn)
-{
-  ArtHolder p ;
-  size_t lenBuff = 0 ;
-  Buffer checkBuffer = NULL ;
-  const char *peerName = hostPeerName (cxn->myHost) ;
-
-  p = cxn->checkHead ;
-  while (p != NULL)
-    {
-      Article article = p->article ;
-      const char *msgid ;
-
-      msgid = artMsgId (article) ;
-
-      lenBuff += (8 + strlen (msgid)) ; /* 8 == strlen("CHECK \r\n") */
-      p = p->next ;
-    }
-
-  if (lenBuff > 0)
-    lenBuff++ ;                 /* for the null byte */
-
-  /* now build up the single buffer that contains all the CHECK commands */
-  if (lenBuff > 0)
-    {
-      char *t ;
-      size_t tlen = 0 ;
-
-      checkBuffer = newBuffer (lenBuff) ;
-      t = bufferBase (checkBuffer) ;
-
-      p = cxn->checkHead ;
-      while (p != NULL)
-        {
-          const char *msgid = artMsgId (p->article) ;
-
-          sprintf (t,"CHECK %s\r\n", msgid) ;
-          d_printf (5,"%s:%d Command %s\n", peerName, cxn->ident, t) ;
-
-          tlen += strlen (t) ;
-
-          while ( *t ) t++ ;
-
-          cxn->checksIssued++ ;
-          hostArticleOffered (cxn->myHost,cxn) ;
-
-          p = p->next ;
-        }
-
-      ASSERT (tlen + 1 == lenBuff) ;
-
-      bufferSetDataSize (checkBuffer, tlen) ;
-    }
-
-  return checkBuffer ;
-}
-
-
-
-
-
-\f
-/*
- * Construct and array of TAKETHIS commands and the command bodies. Any
- * articles on the queue that are missing will be removed and the Host will
- * be informed.
- */
-static Buffer *buildTakethisBuffers (Connection cxn, Buffer checkBuffer)
-{
-  size_t lenArray = 0 ;
-  ArtHolder p, q ;
-  Buffer *rval = NULL ;
-  const char *peerName = hostPeerName (cxn->myHost) ;
-
-  if (checkBuffer != NULL)
-    lenArray++ ;
-
-  if (cxn->takeHead != NULL)    /* some TAKETHIS commands to be done. */
-    {
-      Buffer takeBuffer ;
-      unsigned int takeBuffLen  ;
-      unsigned int writeIdx = 0 ;
-
-      /* count up all the buffers we'll be writing. One extra each time for
-         the TAKETHIS command buffer*/
-      for (p = cxn->takeHead ; p != NULL ; p = p->next)
-        if (artContentsOk (p->article))
-            lenArray += (1 + artNntpBufferCount (p->article)) ;
-
-      /* now allocate the array for the buffers and put them all in it */
-      /* 1 for the terminator */
-      rval = xmalloc (sizeof(Buffer) * (lenArray + 1)) ;
-
-      if (checkBuffer != NULL)
-        rval [writeIdx++] = checkBuffer ;
-
-      q = NULL ;
-      p = cxn->takeHead ;
-      while (p != NULL)
-        {
-          char *t ;
-          const char *msgid ;
-          Article article ;
-          Buffer *articleBuffers ;
-          int i, nntpLen ;
-
-          article = p->article ;
-          nntpLen = artNntpBufferCount (article) ;
-          msgid = artMsgId (article) ;
-
-          if (nntpLen == 0)
-            {                   /* file no longer valid so drop from queue */
-              ArtHolder ta = p ;
-
-              if (q == NULL)    /* it's the first in the queue */
-                cxn->takeHead = p->next ;
-              else
-                q->next = p->next ;
-
-              p = p->next ;
-              ASSERT (cxn->articleQTotal > 0) ;
-              cxn->articleQTotal-- ;
-
-              ta->next = cxn->missing ;
-              cxn->missing = ta ;
-            }
-          else
-            {
-              articleBuffers = artGetNntpBuffers (article) ;
-
-              /* set up the buffer with the TAKETHIS command in it.
-                 12 == strlen ("TAKETHIS \n\r") */
-              takeBuffLen = 12 + strlen (msgid) ;
-              takeBuffer = newBuffer (takeBuffLen) ;
-              t = bufferBase (takeBuffer) ;
-
-              sprintf (t, "TAKETHIS %s\r\n", msgid) ;
-              bufferSetDataSize (takeBuffer, strlen (t)) ;
-
-              d_printf (5,"%s:%d Command %s\n", peerName, cxn->ident, t) ;
-
-              ASSERT (writeIdx <= lenArray) ;
-              rval [writeIdx++] = takeBuffer ;
-
-              /* now add all the buffers that make up the body of the TAKETHIS
-                 command  */
-              for (i = 0 ; i < nntpLen ; i++)
-                {
-                  ASSERT (writeIdx <= lenArray) ;
-                  rval [writeIdx++] = bufferTakeRef (articleBuffers [i]) ;
-                }
-
-              freeBufferArray (articleBuffers) ;
-
-              if ( !cxn->needsChecks )
-                {
-                  /* this isn't quite right. An article may be counted
-                     twice if we switch to no-CHECK mode after its
-                     CHECK was issued, but before its TAKETHIS was done
-                     just now. I'm not going to worry unless someone
-                     complains. */
-
-                  cxn->checksIssued++ ;
-                  hostArticleOffered (cxn->myHost,cxn) ;
-                }
-
-              q = p ;
-              p = p->next ;
-            }
-        }
-
-      if (writeIdx > 0)
-        rval [writeIdx] = NULL ;
-      else
-        {                       /* all articles were missing and no CHECKS */
-          free (rval) ;
-          rval = NULL ;
-        }
-    }
-  else if (checkBuffer != NULL) /* no TAKETHIS to do, but some CHECKS */
-    rval = makeBufferArray (checkBuffer, NULL) ;
-
-  return rval ;
-}
-
-
-
-
-\f
-/*
- * for one reason or another we need to disconnect gracefully. We send a
- * QUIT command.
- */
-static void issueQUIT (Connection cxn)
-{
-  Buffer quitBuffer, *writeArray ;
-  const char *peerName = hostPeerName (cxn->myHost) ;
-
-  ASSERT (cxn->takeHead == NULL) ;
-  ASSERT (cxn->checkHead == NULL) ;
-  VALIDATE_CONNECTION (cxn) ;
-
-  if (cxn->quitWasIssued)
-    return ;
-  
-  if (writeIsPending (cxn->myEp))
-    {
-      warn ("%s:%d internal QUIT while write pending", peerName,
-            cxn->ident) ;
-
-      if (cxn->state == cxnClosingS)
-        cxnDead (cxn) ;
-      else
-        cxnWait (cxn) ;
-    }
-  else
-    {
-      quitBuffer = newBuffer (7) ;
-      strcpy (bufferBase (quitBuffer), "QUIT\r\n") ;
-      bufferSetDataSize (quitBuffer, 6) ;
-
-      writeArray = makeBufferArray (quitBuffer, NULL) ;
-
-      d_printf (1,"%s:%d Sending a quit command\n",
-               hostPeerName (cxn->myHost),cxn->ident) ;
-
-      cxn->quitWasIssued = true ; /* not exactly true, but good enough */
-
-      if ( !prepareWriteWithTimeout (cxn->myEp, writeArray, quitWritten,
-                                     cxn) ) 
-        {
-          die ("%s:%d fatal prepare write for QUIT command failed", peerName,
-               cxn->ident) ;
-        }
-    }
-}
-
-
-
-
-\f
-/*
- * Set up the timer for the blocked reads
- */
-static void initReadBlockedTimeout (Connection cxn)
-{
-  ASSERT (cxn != NULL) ;
-ASSERT (cxn->state != cxnIdleS ) ;
-
-  /* set up the response timer. */
-  clearTimer (cxn->readBlockedTimerId) ;
-
-  if (cxn->readTimeout > 0)
-    cxn->readBlockedTimerId = prepareSleep (responseTimeoutCbk, cxn->readTimeout, cxn) ;
-}
-
-
-
-
-\f
-/*
- * Set up the timer for the blocked reads
- */
-static int prepareWriteWithTimeout (EndPoint endp,
-                                    Buffer *buffers,
-                                    EndpRWCB done,
-                                    Connection cxn) 
-{
-  /* Clear the read timer, since we can't expect a response until everything
-     is sent.
-     XXX - would be nice to have a timeout for reponses if we're sending a
-     string of commands. */
-  clearTimer (cxn->readBlockedTimerId) ;
-
-  /* set up the write timer. */
-  clearTimer (cxn->writeBlockedTimerId) ;
-
-  if (cxn->writeTimeout > 0)
-    cxn->writeBlockedTimerId = prepareSleep (writeTimeoutCbk, cxn->writeTimeout,
-                                             cxn) ;
-
-  /* set up the write. */
-  return prepareWrite (endp, buffers, writeProgress, done, cxn) ;
-}
-
-
-
-
-\f
-/*
- * Does the actual deletion of a connection and all its private data.
- */
-static void delConnection (Connection cxn)
-{
-  bool shutDown;
-  Connection c, q;
-
-  if (cxn == NULL)
-    return ;
-
-  d_printf (1,"Deleting connection: %s:%d\n",
-           hostPeerName (cxn->myHost),cxn->ident) ;
-
-  for (c = gCxnList, q = NULL ; c != NULL ; q = c, c = c->next)
-    if (c == cxn)
-      {
-        if (gCxnList == c)
-          gCxnList = gCxnList->next ;
-        else
-          q->next = c->next ;
-        break ;
-      }
-  
-  ASSERT (c != NULL) ;
-  if (cxn->myEp != NULL)
-    delEndPoint (cxn->myEp) ;
-
-  ASSERT (cxn->checkHead == NULL) ;
-  ASSERT (cxn->checkRespHead == NULL) ;
-  ASSERT (cxn->takeHead == NULL) ;
-  ASSERT (cxn->takeRespHead == NULL) ;
-
-  delBuffer (cxn->respBuffer) ;
-
-  /* tell the Host we're outta here. */
-  shutDown = hostCxnGone (cxn->myHost, cxn) ;
-
-  cxn->ident = 0 ;
-  cxn->timeCon = 0 ;
-
-  free (cxn->ipName) ;
-
-  clearTimer (cxn->artReceiptTimerId) ;
-  clearTimer (cxn->readBlockedTimerId) ;
-  clearTimer (cxn->writeBlockedTimerId) ;
-  clearTimer (cxn->flushTimerId) ;
-
-  free (cxn) ;
-
-  if (shutDown)
-    {
-      /* exit program if that was the last connexion for the last host */
-      /* XXX what about if there are ever multiple listeners?
-        XXX    this will be executed if all hosts on only one of the 
-        XXX    listeners have gone */
-      time_t now = theTime () ;
-      char dateString [30] ;
-      char **p = PointersFreedOnExit ;
-
-      /* finish out all outstanding memory */
-      while (*p) 
-       free (*p++) ;
-      free (PointersFreedOnExit) ;
-      freeTimeoutQueue () ;
-
-      strlcpy (dateString,ctime (&now), sizeof(dateString)) ;
-
-      notice ("ME finishing at %s", dateString) ;
-
-      exit (0) ;
-    }
-}
-
-
-
-
-\f
-/*
- * Bump up the value of the low pass filter on the connection.
- */
-static void incrFilter (Connection cxn)
-{
-  cxn->filterValue *= (1.0 - (1.0 / cxn->lowPassFilter)) ;
-  cxn->filterValue += 1.0 ;
-}
-
-
-
-
-\f
-/*
- * decrement the value of the low pass filter on the connection.
- */
-static void decrFilter (Connection cxn)
-{
-  cxn->filterValue *= (1.0 - (1.0 / cxn->lowPassFilter)) ;
-}
-
-
-
-
-\f
-/*
- * return true if we have articles we need to issue commands for.
- */
-static bool writesNeeded (Connection cxn)
-{
-  return (cxn->checkHead != NULL || cxn->takeHead != NULL ? true : false) ;
-}
-
-
-
-
-\f
-/*
- * do some simple tests to make sure it's OK.
- */
-static void validateConnection (Connection cxn)
-{
-  unsigned int i ;
-  unsigned int old ;
-  ArtHolder p ;
-
-  i = 0 ;
-
-  /* count up the articles the Connection has and make sure that matches. */
-  for (p = cxn->takeHead ; p != NULL ; p = p->next)
-    i++ ;
-  d_printf (4,"TAKE queue: %d\n",i) ;
-  old = i ;
-
-  for (p = cxn->takeRespHead ; p != NULL ; p = p->next)
-    i++ ;
-  d_printf (4,"TAKE response queue: %d\n",i - old) ;
-  old = i ;
-
-  for (p = cxn->checkHead ; p != NULL ; p = p->next)
-    i++ ;
-  d_printf (4,"CHECK queue: %d\n",i - old) ;
-  old = i ;
-
-  for (p = cxn->checkRespHead ; p != NULL ; p = p->next)
-    i++ ;
-  d_printf (4,"CHECK response queue: %d\n",i - old) ;
-
-  ASSERT (i == cxn->articleQTotal) ;
-
-  switch (cxn->state)
-    {
-      case cxnConnectingS:
-        ASSERT (cxn->doesStreaming == false) ;
-        ASSERT (cxn->articleQTotal <= 1) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        /* ASSERT (cxn->timeCon == 0) ; */
-        break ;
-
-      case cxnWaitingS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        ASSERT (cxn->myEp == NULL) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->readBlockedTimerId == 0) ;
-        ASSERT (cxn->writeBlockedTimerId == 0) ;
-        ASSERT (cxn->flushTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon == 0) ;
-        break ;
-
-      case cxnFlushingS:
-      case cxnClosingS:
-        if (!cxn->doesStreaming)
-          ASSERT (cxn->articleQTotal <= 1) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->flushTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon != 0) ;
-        ASSERT (cxn->doesStreaming || cxn->maxCheck == 1) ;
-        break ;
-
-      case cxnFeedingS:
-        if (cxn->doesStreaming)
-          /* Some(?) hosts return the 439 response even before we're done
-             sending, so don't go idle until here */
-          ASSERT (cxn->articleQTotal > 0 || writeIsPending (cxn->myEp)) ;
-        else
-          ASSERT (cxn->articleQTotal == 1) ;
-        if (cxn->readTimeout > 0 && !writeIsPending (cxn->myEp) &&
-           cxn->checkRespHead != NULL && cxn->takeRespHead != NULL)
-          ASSERT (cxn->readBlockedTimerId != 0) ;
-        if (cxn->writeTimeout > 0 && writeIsPending (cxn->myEp))
-          ASSERT (cxn->writeBlockedTimerId != 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon != 0) ;
-        ASSERT (cxn->doesStreaming || cxn->maxCheck == 1) ;
-        break;
-
-      case cxnIdleS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        if (cxn->articleReceiptTimeout > 0)
-          ASSERT (cxn->artReceiptTimerId != 0) ;
-        ASSERT (cxn->readBlockedTimerId == 0) ;
-        ASSERT (cxn->writeBlockedTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon != 0) ;
-        ASSERT (!writeIsPending (cxn->myEp)) ;
-        break ;
-
-      case cxnIdleTimeoutS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->writeBlockedTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon != 0) ;
-        ASSERT (!writeIsPending (cxn->myEp)) ;
-        break ;
-
-      case cxnSleepingS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        ASSERT (cxn->myEp == NULL) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->readBlockedTimerId == 0) ;
-        ASSERT (cxn->writeBlockedTimerId == 0) ;
-        ASSERT (cxn->flushTimerId == 0) ;
-        ASSERT (cxn->timeCon == 0) ;
-        break ;
-
-      case cxnStartingS:
-        ASSERT (cxn->articleQTotal == 0) ;
-        ASSERT (cxn->myEp == NULL) ;
-        ASSERT (cxn->artReceiptTimerId == 0) ;
-        ASSERT (cxn->readBlockedTimerId == 0) ;
-        ASSERT (cxn->writeBlockedTimerId == 0) ;
-        ASSERT (cxn->flushTimerId == 0) ;
-        ASSERT (cxn->sleepTimerId == 0) ;
-        ASSERT (cxn->timeCon == 0) ;
-        break ;
-
-      case cxnDeadS:
-        break ;
-    }
-}
-
-
-
-
-\f
-/*
- * Generate a printable string of the parameter.
- */
-static const char *stateToString (CxnState state)
-{
-  static char rval [64] ;
-
-  switch (state)
-    {
-      case cxnStartingS:
-        strlcpy (rval,"cxnStartingS", sizeof(rval)) ;
-        break ;
-
-      case cxnWaitingS:
-        strlcpy (rval,"cxnWaitingS", sizeof(rval)) ;
-        break ;
-
-      case cxnConnectingS:
-        strlcpy (rval,"cxnConnectingS", sizeof(rval)) ;
-        break ;
-
-      case cxnIdleS:
-        strlcpy (rval,"cxnIdleS", sizeof(rval)) ;
-        break ;
-
-      case cxnIdleTimeoutS:
-        strlcpy (rval,"cxnIdleTimeoutS", sizeof(rval)) ;
-        break ;
-
-      case cxnFeedingS:
-        strlcpy (rval,"cxnFeedingS", sizeof(rval)) ;
-        break ;
-
-      case cxnSleepingS:
-        strlcpy (rval,"cxnSleepingS", sizeof(rval)) ;
-        break ;
-
-      case cxnFlushingS:
-        strlcpy (rval,"cxnFlushingS", sizeof(rval)) ;
-        break ;
-
-      case cxnClosingS:
-        strlcpy (rval,"cxnClosingS", sizeof(rval)) ;
-        break ;
-
-      case cxnDeadS:
-        strlcpy (rval,"cxnDeadS", sizeof(rval)) ;
-        break ;
-
-      default:
-        snprintf (rval,sizeof(rval),"UNKNOWN STATE: %d",state) ;
-        break ;
-    }
-
-  return rval ;
-}
-
-
-
-
-\f
-/****************************************************************************
- *
- * Functions for managing the internal queue of Articles on each Connection.
- *
- ****************************************************************************/
-
-static ArtHolder newArtHolder (Article article)
-{
-  ArtHolder a = xmalloc (sizeof(struct art_holder_s)) ;
-
-  a->article = article ;
-  a->next = NULL ;
-
-  return a ;
-}
-
-
-
-
-\f
-/*
- * Deletes the article holder
- */
-static void delArtHolder (ArtHolder artH)
-{
-  if (artH != NULL)
-    free (artH) ;
-}
-
-
-
-
-\f
-/*
- * remove the article holder from the queue. Adjust the count and if nxtPtr
- * points at the element then adjust that too.
- */
-static bool remArtHolder (ArtHolder artH, ArtHolder *head, unsigned int *count)
-{
-  ArtHolder h, i ;
-
-  ASSERT (head != NULL) ;
-  ASSERT (count != NULL) ;
-
-  h = *head ;
-  i = NULL ;
-  while (h != NULL && h != artH)
-    {
-      i = h ;
-      h = h->next ;
-    }
-
-  if (h == NULL)
-    return false ;
-
-  if (i == NULL)
-    *head = (*head)->next ;
-  else
-    i->next = artH->next ;
-
-  (*count)-- ;
-
-  return true ;
-}
-
-
-
-
-\f
-/*
- * append the ArticleHolder to the queue
- */
-static void appendArtHolder (ArtHolder artH, ArtHolder *head, unsigned int *count)
-{
-  ArtHolder p ;
-
-  ASSERT (head != NULL) ;
-  ASSERT (count != NULL) ;
-
-  for (p = *head ; p != NULL && p->next != NULL ; p = p->next)
-    /* nada */ ;
-
-  if (p == NULL)
-    *head = artH ;
-  else
-    p->next = artH ;
-
-  artH->next = NULL ;
-  (*count)++ ;
-}
-
-
-
-
-\f
-/*
- * find the article holder on the queue by comparing the message-id.
- */
-static ArtHolder artHolderByMsgId (const char *msgid, ArtHolder head)
-{
-  while (head != NULL)
-    {
-      if (strcmp (msgid, artMsgId (head->article)) == 0)
-        return head ;
-
-      head = head->next ;
-    }
-
-  return NULL ;
-}
-
-
-
-/*
- * Randomize a numeber by the given percentage
- */
-
-static int fudgeFactor (int initVal)
-{
-  int newValue ;
-  static bool seeded ;
-
-  if ( !seeded )
-    {
-      time_t t = theTime () ;
-
-      /* this may have been done already in endpoint.c. Is that a problem??? */
-      srand (t) ;               
-      seeded = true ;
-    }
-  
-  newValue = initVal + (initVal / 10 - (rand() % (initVal / 5)));
-
-  return newValue ;
-}
diff --git a/innfeed/connection.h b/innfeed/connection.h
deleted file mode 100644 (file)
index f75a60e..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*  $Id: connection.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  The public interface to the Connection class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The Connection class encapulates an NNTP protocol endpoint (either regular
-**  or extended with the streaming protocol).  Each Connection is owned by a
-**  single Host object.
-**
-**  It manages the network connection (via an EndPoint) the the pumping of
-**  articles to the remote host.  It gets these articles from its Host object.
-**  If the remote doesn't handle the streaming extension, then the Connection
-**  will only manage one article at a time.  If the remote handles the
-**  extension, then the connection will queue up articles while sending the
-**  CHECK and TAKETHIS commands.
-**
-**  If the network connection drops while the Connection object has articles
-**  queued up, then it will hand them back to its Host object.
-*/
-
-#if ! defined ( connection_h__ )
-#define connection_h__
-
-
-#include <time.h>
-#include <stdio.h>
-
-#include "misc.h"
-
-
-  /*
-   * Create a new Connection.
-   * 
-   * HOST is the host object we're owned by.
-   * IDENT is an identifier to be added to syslog entries so we can tell
-   *    what's happening on different connections to the same peer.
-   * IPNAME is the name (or ip address) of the remote)
-   * MAXTOUT is the maximum amount of time to wait for a response before
-   *    considering the remote host dead.
-   * PORTNUM is the portnum to contact on the remote end.
-   * RESPTIMEOUT is the amount of time to wait for a response from a remote
-   *    before considering the connection dead.
-   * CLOSEPERIOD is the number of seconds after connecting that the
-   *     connections should be closed down and reinitialized (due to problems
-   *     with old NNTP servers that hold history files open. Value of 0 means
-   *     no close down.
-   */
-Connection newConnection (Host host,
-                          unsigned int ident,
-                          const char *ipname,
-                          unsigned int artTout,
-                          unsigned int portNum,
-                          unsigned int respTimeout,
-                          unsigned int closePeriod,
-                          double lowPassLow,
-                          double lowPassHigh,
-                         double lowPassFilter) ;
-
-  /* Causes the Connection to build the network connection. */
-bool cxnConnect (Connection cxn) ;
-
-  /* puts the connection into the wait state (i.e. waits for an article
-     before initiating a connect). Can only be called right after
-     newConnection returns, or while the Connection is in the (internal)
-     Sleeping state. */
-void cxnWait (Connection cxn) ;
-
-  /* The Connection will disconnect as if cxnDisconnect were called and then
-     it automatically reconnects to the remote. */
-void cxnFlush (Connection cxn) ;
-
-  /* The Connection sends remaining articles, then issues a QUIT and then
-     deletes itself */
-void cxnClose (Connection cxn) ;
-
-  /* The Connection drops all queueed articles, then issues a QUIT and then
-     deletes itself */
-void cxnTerminate (Connection cxn) ;
-
-  /* Blow away the connection gracelessly and immedately clean up */
-void cxnNuke (Connection cxn) ;
-
-  /* Tells the Connection to take the article and handle its
-     transmission. If it can't (due to queue size or whatever), then the
-     function returns false. The connection assumes ownership of the
-     article if it accepts it (returns true). */
-bool cxnTakeArticle (Connection cxn, Article art) ;
-
-  /* Tell the Connection to take the article (if it can) for later
-     processing. Assumes ownership of it if it takes it. */
-bool cxnQueueArticle (Connection cxn, Article art) ;
-
-  /* generate a syslog message for the connections activity. Called by Host. */
-void cxnLogStats (Connection cxn, bool final) ;
-
-  /* return the number of articles the connection can be given. This lets
-     the host shovel in as many as possible. May be zero. */
-size_t cxnQueueSpace (Connection cxn) ;
-
-  /* adjust the mode no-CHECK filter values */
-void cxnSetCheckThresholds (Connection cxn,
-                           double lowFilter, double highFilter,
-                           double lowPassFilter) ;
-
-  /* print some debugging info. */
-void gPrintCxnInfo (FILE *fp, unsigned int indentAmt) ;
-void printCxnInfo (Connection cxn, FILE *fp, unsigned int indentAmt) ;
-
-/* config file load callback */
-int cxnConfigLoadCbk (void *data) ;
-
-/* check connection state is in cxnWaitingS, cxnConnectingS or cxnIdleS */
-bool cxnCheckstate (Connection cxn) ;
-
-#endif /* connection_h__ */
diff --git a/innfeed/endpoint.c b/innfeed/endpoint.c
deleted file mode 100644 (file)
index d03254a..0000000
+++ /dev/null
@@ -1,1803 +0,0 @@
-/*  $Id: endpoint.c 7738 2008-04-06 09:33:33Z iulius $
-**
-**  The implementation of the innfeed EndPoint object class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The EndPoint class is what gives the illusion (sort of, kind of) of
-**  threading.  Basically it controls a select loop and a set of EndPoint
-**  objects.  Each EndPoint has a file descriptor it is interested in.  The
-**  users of the EndPoint tell the EndPoints to notify them when a read or
-**  write has been completed (or simple if the file descriptor is read or
-**  write ready).
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <syslog.h>
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "buffer.h"
-#include "configfile.h"
-#include "endpoint.h"
-#include "host.h"
-
-static const char *const timer_name[] = {
-  "idle", "blstats", "stsfile", "newart", "readart", "prepart", "read",
-  "write", "cb"
-};
-
-#if ! defined (NSIG)
-#define NSIG 32
-#endif
-
-
-  /* This is the structure that is the EndPoint */
-struct endpoint_s 
-{
-      /* fields for managing multiple reads into the inBuffer. */
-    Buffer *inBuffer ;          /* list of buffers to read into */
-    unsigned int inBufferIdx ;         /* where is list we're at. */
-    size_t inIndex ;            /* where in current read we're at */
-    size_t inMinLen ;           /* minimum amount to read */
-    size_t inAmtRead ;          /* amount read so far */
-    EndpRWCB inCbk ;            /* callback for when read complete */
-    void *inClientData ;        /* callback data */
-    
-      /* fields for managing multiple writes from the outBuffer */
-    Buffer *outBuffer ;         /* list of buffers to write */
-    unsigned int outBufferIdx ;        /* index into buffer list to start write */
-    size_t outIndex ;           /* where in current buffer we write from */
-    size_t outSize ;            /* total of all the buffers */
-    size_t outAmtWritten ;      /* amount written so far */
-    EndpRWCB outProgressCbk ;   /* callback when done */
-    EndpRWCB outDoneCbk ;       /* callback when done */
-    void *outClientData ;       /* callback data */
-
-    EndpWorkCbk workCbk ;       /* callback to run if no I/O to do */
-    void *workData ;            /* data for callback */
-
-    int myFd ;                  /* the file descriptor we're handling */
-    int myErrno ;               /* the errno when I/O fails */
-    
-    double selectHits ;                /* indicates how often it's ready */
-};
-
-
-
-  /* A private structure. These hold the information on the timer callbacks. */
-typedef struct timerqelem_s
-{
-    TimeoutId id ;              /* the id we gave out */
-    time_t when ;               /* The time the timer should go off */
-    EndpTCB func ;              /* the function to call */
-    void *data ;                /* the client callback data */
-    struct timerqelem_s *next ; /* next in the queue */
-} *TimerElem, TimerElemStruct ;
-
-
-
-  /* set to 1 elsewhere if you want stderr to get what's also being written
-     in doWrite. */
-int debugWrites ;
-
-extern const char *InputFile ;
-
-static EndPoint mainEndPoint ;
-static bool mainEpIsReg = false ;
-static unsigned int stdioFdMax = MAX_STDIO_FD ;
-
-time_t  PrivateTime;
-
-
-typedef void (*sigfn) (int) ;
-static sigfn *sigHandlers ;
-
-static volatile sig_atomic_t *sigFlags ;
-
-
-
-  /* private functions */
-static IoStatus doRead (EndPoint endp) ;
-static IoStatus doWrite (EndPoint endp) ;
-static IoStatus doExcept (EndPoint endp) ;
-static void pipeHandler (int s) ;
-static void signalHandler (int s) ;
-static int hitCompare (const void *v1, const void *v2) ;
-static void reorderPriorityList (void) ;
-static TimerElem newTimerElem (TimeoutId i, time_t w, EndpTCB f, void *d) ;
-static TimeoutId timerElemAdd (time_t when, EndpTCB func, void *data) ;
-static struct timeval *getTimeout (struct timeval *tout) ;
-static void doTimeout (void) ;
-static void handleSignals (void) ;
-
-#if 0
-static int ff_set (fd_set *set, unsigned int start) ;
-static int ff_free (fd_set *set, unsigned int start) ;
-#endif
-static void endpointCleanup (void) ;
-
-
-  /* Private data */
-static size_t maxEndPoints ;
-
-static EndPoint *endPoints ;    /* endpoints indexed on fd */
-static EndPoint *priorityList ; /* endpoints indexed on priority */
-
-static int absHighestFd = 0 ;       /* never goes down */
-static int highestFd = -1 ;
-static unsigned int endPointCount = 0 ;
-static unsigned int priorityCount = 0 ;
-
-static fd_set rdSet ;
-static fd_set wrSet ;
-static fd_set exSet ;
-
-static int keepSelecting ;
-
-static TimerElem timeoutQueue ;
-static TimerElem timeoutPool ;
-static TimeoutId nextId ;
-static int timeoutQueueLength ;
-
-
-
-
-  /* Create a new EndPoint and hook it to the give file descriptor. All
-     fields are initialized to appropriate values.  On the first time this
-     function is called the global data structs that manages lists of
-     endpoints are intialized. */
-static bool inited = false ;
-
-EndPoint newEndPoint (int fd) 
-{
-  EndPoint ep ;
-
-  if (!inited)
-    {
-      inited = true ;
-      atexit (endpointCleanup) ;
-    }
-  
-  if (fd < 0)
-    return NULL ;
-
-  /* try to dup the fd to a larger number to leave lower values free for
-     broken stdio implementations. */
-  if (stdioFdMax > 0 && ((unsigned int) fd) <= stdioFdMax)
-    {
-      int newfd = fcntl(fd, F_DUPFD, stdioFdMax + 1);
-      if (newfd >= 0)
-        {
-          d_printf (1,"Dupped fd %d to %d\n",fd,newfd) ;
-          if (close (fd) != 0)
-            syswarn ("ME oserr close (%d)", fd) ;
-        }
-      else
-        {
-          d_printf (1,"Couldn't dup fd %d to above %d\n",fd,stdioFdMax) ;
-          newfd = fd ;
-        }
-
-      fd = newfd ;
-    }
-
-  if ((unsigned int) fd >= maxEndPoints)
-    {
-      unsigned int i = maxEndPoints ;
-      
-      maxEndPoints = (((fd + 256) / 256) * 256); /* round up to nearest 256 */ 
-      if (endPoints == NULL)
-        {
-          endPoints = xmalloc (sizeof(EndPoint) * maxEndPoints) ;
-          priorityList = xmalloc (sizeof(EndPoint) * maxEndPoints) ;
-        }
-      else
-        {
-          endPoints = xrealloc (endPoints,sizeof(EndPoint) * maxEndPoints) ;
-          priorityList = xrealloc (priorityList,
-                                   sizeof(EndPoint) * maxEndPoints) ;
-        }
-
-      for ( ; i < maxEndPoints ; i++)
-        endPoints [i] = priorityList [i] = NULL ;
-    }
-  
-  ASSERT (endPoints [fd] == NULL) ;
-
-  if (fd > absHighestFd)
-    {
-      static bool sizelogged = false ;
-          
-#if defined (FD_SETSIZE)
-      if (fd >= FD_SETSIZE)
-        {
-          sizelogged = true ;
-          warn ("ME fd (%d) looks too big (%d -- FD_SETSIZE)", fd,
-                FD_SETSIZE) ;
-          return NULL ;
-        }
-#else
-      if (fd > (sizeof (fd_set) * CHAR_BIT))
-        {
-          sizelogged = true ;
-          warn ("ME fd (%d) looks too big (%d -- sizeof (fd_set) * CHAR_BIT)",
-                fd, (sizeof (fd_set) * CHAR_BIT)) ;
-          return NULL ;
-        }
-#endif
-
-      absHighestFd = fd ;
-    }
-      
-  ep = xcalloc (1, sizeof(struct endpoint_s)) ;
-
-  ep->inBuffer = NULL ;
-  ep->inBufferIdx = 0 ;
-  ep->inIndex = 0 ;
-  ep->inMinLen = 0 ;
-  ep->inAmtRead = 0 ;
-  ep->inCbk = NULL ;
-  ep->inClientData = NULL ;
-
-  ep->outBuffer = 0 ;
-  ep->outBufferIdx = 0 ;
-  ep->outIndex = 0 ;
-  ep->outSize = 0 ;
-  ep->outProgressCbk = NULL ;
-  ep->outDoneCbk = NULL ;
-  ep->outClientData = NULL ;
-  ep->outAmtWritten = 0 ;
-
-  ep->workCbk = NULL ;
-  ep->workData = NULL ;
-  
-  ep->myFd = fd ;
-  ep->myErrno = 0 ;
-
-  ep->selectHits = 0.0 ;
-
-  endPoints [fd] = ep ;
-  priorityList [priorityCount++] = ep ;
-  endPointCount++ ;
-
-  highestFd = (fd > highestFd ? fd : highestFd) ;
-
-  return ep ;
-}
-
-
-
-/* Delete the given endpoint. The files descriptor is closed and the two
-   Buffer arrays are released. */
-
-void delEndPoint (EndPoint ep) 
-{
-  unsigned int idx ;
-
-  if (ep == NULL)
-    return ;
-
-  ASSERT (endPoints [ep->myFd] == ep) ;
-
-  if (mainEndPoint == ep)
-    mainEndPoint = NULL ;
-  
-  if (ep->inBuffer != NULL)
-    freeBufferArray (ep->inBuffer) ;
-  
-  if (ep->outBuffer != NULL)
-    freeBufferArray (ep->outBuffer) ;
-
-  close (ep->myFd) ;
-
-  /* remove from selectable bits */
-  FD_CLR (ep->myFd,&rdSet) ;
-  FD_CLR (ep->myFd,&wrSet) ;
-  FD_CLR (ep->myFd,&exSet) ;
-
-  /* Adjust the global arrays to account for deleted endpoint. */
-  endPoints [ep->myFd] = NULL ;
-  if (ep->myFd == highestFd)
-    while (endPoints [highestFd] == NULL && highestFd >= 0)
-      highestFd-- ;
-
-  for (idx = 0 ; idx < priorityCount ; idx++)
-    if (priorityList [idx] == ep)
-      break ;
-
-  ASSERT (idx < priorityCount) ; /* i.e. was found */
-  ASSERT (priorityList [idx] == ep) ; /* redundant */
-
-  /* this hole will removed in the reorder routine */
-  priorityList [idx] = NULL ;
-
-  endPointCount-- ;
-
-  free (ep) ;
-}
-
-int endPointFd (EndPoint endp)
-{
-  ASSERT (endp != NULL) ;
-
-  return endp->myFd ;
-}
-
-
-
-
-/* Request a read to be done next time there's data. The endpoint
- * ENDP is what will do the read. BUFF is the Buffer the data should
- * go into. FUNC is the callback function to call when the read is
- * complete. CLIENTDATA is the client data to pass back into the
- * callback function. MINLEN is the minimum amount of data to
- * read. If MINLEN is 0 then then BUFF must be filled, otherwise at
- * least MINLEN bytes must be read.
- *
- * BUFF can be null, in which case no read is actually done, but the
- * callback function will be called still. This is useful for
- * listening sockets.
- *
- * Returns 0 if the read couln't be prepared (for example if a read
- * is already outstanding).
- */
-
-int prepareRead (EndPoint endp,
-                 Buffer *buffers,
-                 EndpRWCB func,
-                 void *clientData,
-                 int minlen) 
-{
-  int bufferSizeTotal = 0 ;
-  int idx ;
-  
-  ASSERT (endp != NULL) ;
-  
-  if (endp->inBuffer != NULL || FD_ISSET (endp->myFd,&rdSet)) 
-    return 0 ;                  /* something already there */
-
-  for (idx = 0 ; buffers != NULL && buffers [idx] != NULL ; idx++)
-    {
-      size_t bs = bufferSize (buffers [idx]) ;
-      size_t bds = bufferDataSize (buffers [idx]) ;
-      
-      bufferSizeTotal += (bs - bds) ;
-    }
-  
-  endp->inBuffer = buffers ;
-  endp->inBufferIdx = 0 ;
-  endp->inIndex = 0 ;
-  endp->inMinLen = (minlen > 0 ? minlen : bufferSizeTotal) ;
-  endp->inCbk = func ;
-  endp->inAmtRead = 0 ;
-  endp->inClientData = clientData ;
-
-  FD_SET (endp->myFd, &rdSet) ;
-  if ( InputFile == NULL )
-    FD_SET (endp->myFd, &exSet) ;
-
-  return 1 ;
-}
-
-
-
-/* Request a write to be done at a later point. ENDP is the EndPoint
- * to do the write. BUFF is the Buffer to write from. FUNC is the
- * function to call when the write is complete. CLIENTDATA is some
- * data to hand back to the callback function.
- *
- * If BUFF is null, then no write will actually by done, but the
- * callback function will still be called. This is useful for
- * connecting sockets.
- *
- * Returns 0 if the write couldn't be prepared (like if a write is
- * still in process.
- */
-int prepareWrite (EndPoint endp,
-                  Buffer *buffers,
-                  EndpRWCB progress,
-                  EndpRWCB done,
-                  void *clientData) 
-{
-  int bufferSizeTotal = 0 ;
-  int idx ;
-
-  ASSERT (endp != NULL) ;
-  
-  if (endp->outBuffer != NULL || FD_ISSET (endp->myFd,&wrSet))
-    return 0 ;                  /* something already there */
-
-  for (idx = 0 ; buffers != NULL && buffers [idx] != NULL ; idx++)
-    bufferSizeTotal += bufferDataSize (buffers [idx]) ;
-  
-  endp->outBuffer = buffers ;
-  endp->outBufferIdx = 0 ;
-  endp->outIndex = 0 ;
-  endp->outProgressCbk = progress ;
-  endp->outDoneCbk = done ;
-  endp->outClientData = clientData ;
-  endp->outSize = bufferSizeTotal ;
-  endp->outAmtWritten = 0 ;
-
-  FD_SET (endp->myFd, &wrSet) ;
-  FD_SET (endp->myFd, &exSet) ;
-
-  return 1 ;
-}
-
-
-/* Cancel the pending read. */
-void cancelRead (EndPoint endp)
-{
-  FD_CLR (endp->myFd,&rdSet) ;
-  if (!FD_ISSET (endp->myFd, &wrSet))
-    FD_CLR (endp->myFd,&exSet) ;
-
-  freeBufferArray (endp->inBuffer) ;
-  
-  endp->inBuffer = NULL ;
-  endp->inBufferIdx = 0 ;
-  endp->inIndex = 0 ;
-  endp->inMinLen = 0 ;
-  endp->inAmtRead = 0 ;
-  endp->inCbk = NULL ;
-  endp->inClientData = NULL ;
-}
-
-
-/* cancel all pending writes. The first len bytes of the queued write are
-  copied to buffer. The number of bytes copied (if it is less than *len) is
-  copied to len. If no write was outstanding then len will have 0 stored in
-  it. */
-void cancelWrite (EndPoint endp, char *buffer UNUSED, size_t *len UNUSED)
-{
-  FD_CLR (endp->myFd, &wrSet) ;
-  if (!FD_ISSET (endp->myFd, &rdSet))
-    FD_CLR (endp->myFd, &exSet) ;
-
-#if 0
-#error XXX need to copy data to buffer and *len
-#endif
-  
-  freeBufferArray (endp->outBuffer) ;
-  
-  endp->outBuffer = NULL ;
-  endp->outBufferIdx = 0 ;
-  endp->outIndex = 0 ;
-  endp->outProgressCbk = NULL ;
-  endp->outDoneCbk = NULL ;
-  endp->outClientData = NULL ;
-  endp->outSize = 0 ;
-  endp->outAmtWritten = 0 ;
-}
-
-/* queue up a new timeout request. to go off at a specific time. */
-TimeoutId prepareWake (EndpTCB func, time_t timeToWake, void *clientData) 
-{
-  TimeoutId id ;
-  time_t now = theTime() ;
-
-  if (now > timeToWake)
-    return 0 ;
-  
-  id = timerElemAdd (timeToWake,func,clientData) ;
-
-#if 0
-  d_printf (1,"Preparing wake %d at date %ld for %d seconds\n",
-           (int) id, (long) now, timeToWake - now) ;
-#endif
-
-  return id ;
-}
-
-
-/* queue up a new timeout request to off TIMETOSLEEP seconds from now */
-TimeoutId prepareSleep (EndpTCB func, int timeToSleep, void *clientData) 
-{
-  time_t now = theTime() ;
-  TimeoutId id ;
-  
-  id = timerElemAdd (now + timeToSleep,func,clientData) ;
-
-#if 0
-  d_printf (1,"Preparing sleep %d at date %ld for %d seconds\n",
-           (int) id, (long) now, timeToSleep) ;
-#endif
-
-  return id ;
-}
-
-
-/* Updates a an existing timeout request to go off TIMETOSLEEP seconds from
-   now, or queues a new request.  Always returns a new ID. */
-TimeoutId updateSleep (TimeoutId tid, EndpTCB func, int timeToSleep,
-                       void *clientData) 
-{
-  if (tid == 0)
-    return prepareSleep (func, timeToSleep, clientData) ;
-  else
-    {
-      /* XXX - quick and dirty but CPU wasteful implementation */
-      removeTimeout (tid) ;
-      return prepareSleep (func, timeToSleep, clientData) ;
-    }
-}
-
-
-/* Remove a timeout that was previously prepared. 0 is a legal value that
-   is just ignored. */
-bool removeTimeout (TimeoutId tid)
-{
-  TimerElem n = timeoutQueue ;
-  TimerElem p = NULL ;
-
-  if (tid == 0)
-    return true ;
-  
-  while (n != NULL && n->id != tid)
-    {
-      p = n ;
-      n = n->next ;
-    }
-
-  if (n == NULL)
-    return false ;
-
-  if (p == NULL)                /* at the head. */
-    timeoutQueue = n->next ;
-  else
-    p->next = n->next ;
-
-  n->next = timeoutPool ;
-  timeoutPool = n ;
-
-  timeoutQueueLength-- ;
-  
-  return true ;
-}
-
-
-/* The main routine. This is a near-infinite loop that drives the whole
-   program. */
-void Run (void) 
-{
-  fd_set rSet ;
-  fd_set wSet ;
-  fd_set eSet ;
-  unsigned long last_summary = 0 ;
-
-  keepSelecting = 1 ;
-  xsignal (SIGPIPE, pipeHandler) ;
-
-  while (keepSelecting)
-    {
-      struct timeval timeout ;
-      struct timeval *twait ;
-      int sval ;
-      unsigned int idx ;
-      bool modifiedTime = false ;
-      
-      twait = getTimeout (&timeout) ;
-
-      memcpy (&rSet,&rdSet,sizeof (rdSet)) ;
-      memcpy (&wSet,&wrSet,sizeof (wrSet)) ;
-      memcpy (&eSet,&exSet,sizeof (exSet)) ;
-
-      if (highestFd < 0 && twait == NULL) /* no fds and no timeout */
-        break ;
-      else if (twait != NULL && (twait->tv_sec != 0 || twait->tv_usec != 0))
-        {
-            /* if we have any workprocs registered we poll rather than
-               block on the fds */
-          for (idx = 0 ; idx < priorityCount ; idx++)
-            if (priorityList [idx] != NULL &&
-                priorityList [idx]->workCbk != NULL)
-              {
-                modifiedTime = true ;
-                twait->tv_sec = 0 ;
-                twait->tv_usec = 0 ;
-
-                break ;
-              }
-        }
-
-      /* calculate host backlog statistics */
-      TMRstart(TMR_BACKLOGSTATS);
-      gCalcHostBlStat ();
-      TMRstop(TMR_BACKLOGSTATS);
-
-      TMRstart(TMR_IDLE);
-      sval = select (highestFd + 1, &rSet, &wSet, &eSet, twait) ;
-      TMRstop(TMR_IDLE);
-
-      timePasses () ;
-      if (innconf->timer)
-        {
-         unsigned long now = TMRnow () ;
-         if (last_summary == 0 
-             || (long) (now - last_summary) > (innconf->timer * 1000))
-           {
-             TMRsummary ("ME", timer_name) ;
-             last_summary = now;
-           }
-       }
-      
-      if (sval == 0 && twait == NULL)
-        die ("No fd's ready and no timeouts") ;
-      else if (sval < 0 && errno == EINTR)
-        {
-         handleSignals () ;
-        }
-      else if (sval < 0) 
-        {
-          syswarn ("ME exception: select failed: %d", sval) ;
-          stopRun () ;
-        }
-      else if (sval > 0)
-        {
-          IoStatus rval ;
-          int readyCount = sval ;
-          int endpointsServiced = 1 ;
-          
-          handleSignals() ;
-          
-          for (idx = 0 ; idx < priorityCount ; idx++)
-            {
-              EndPoint ep = priorityList [idx] ;
-              bool specialCheck = false ;
-
-              if (readyCount > 0 && ep != NULL) 
-                {
-                  int fd = ep->myFd ;
-                  int selectHit = 0, readMiss = 0, writeMiss = 0 ;
-
-                  /* Every SELECT_RATIO times we service an endpoint in this
-                     loop we check to see if the mainEndPoint fd is ready to
-                     read or write. If so we process it and do the current
-                     endpoint next time around. */
-                  if (((endpointsServiced % (SELECT_RATIO + 1)) == 0) &&
-                      ep != mainEndPoint && mainEndPoint != NULL &&
-                      !mainEpIsReg)
-                    {
-                      fd_set trSet, twSet ;
-                      struct timeval tw ;
-                      int checkRead = FD_ISSET (mainEndPoint->myFd,&rdSet) ;
-                      int checkWrite = FD_ISSET (mainEndPoint->myFd,&wrSet) ;
-
-                      endpointsServiced++;
-
-                      if (checkRead || checkWrite) 
-                        {
-                          fd = mainEndPoint->myFd ;
-
-                          tw.tv_sec = tw.tv_usec = 0 ;
-                          memset (&trSet,0,sizeof (trSet)) ;
-                          memset (&twSet,0,sizeof (twSet)) ;
-                      
-                          if (checkRead)
-                            FD_SET (fd,&trSet) ;
-                          if (checkWrite)
-                            FD_SET (fd,&twSet) ;
-
-                          sval = select (fd + 1,&trSet,&twSet,0,&tw) ;
-
-                          if (sval > 0)
-                            {
-                              idx-- ;
-                              ep = mainEndPoint ;
-                              specialCheck = true ;
-                              if (checkRead && FD_ISSET (fd,&trSet))
-                                {
-                                  FD_SET (fd,&rSet) ;
-                                  readyCount++ ;
-                                }
-                              if (checkWrite && FD_ISSET (fd,&twSet))
-                                {
-                                  FD_SET (fd,&wSet) ;
-                                  readyCount++ ;
-                                }
-                            }
-                          else if (sval < 0)
-                            {
-                              syswarn ("ME exception: select failed: %d",
-                                       sval) ;
-                              stopRun () ;
-                              return ;
-                            }
-                          else
-                            fd = ep->myFd ; /* back to original fd. */
-                        }
-                    }
-
-                  FD_CLR (fd, &exSet) ;
-
-                  if (FD_ISSET (fd,&rSet))
-                    {
-                      readyCount-- ;
-                      endpointsServiced++ ;
-                      selectHit = 1 ;
-                      
-                      if ((rval = doRead (ep)) != IoIncomplete)
-                        {
-                          Buffer *buff = ep->inBuffer ;
-
-                          FD_CLR (fd, &rdSet) ;
-
-                          /* incase callback wants to issue read */
-                          ep->inBuffer = NULL ; 
-                          
-                          if (ep->inCbk != NULL)
-                            (*ep->inCbk) (ep,rval,buff,ep->inClientData) ;
-                          else
-                            freeBufferArray (buff) ;
-                        }
-                      else
-                        {
-                          if ( InputFile == NULL )
-                            FD_SET (ep->myFd, &exSet) ;
-                        }
-                    }
-                  else if (FD_ISSET(fd,&rdSet))
-                    readMiss = 1;
-
-                  /* get it again as the read callback may have deleted the */
-                  /* endpoint */
-                  if (specialCheck)
-                    ep = mainEndPoint ;
-                  else
-                    ep = priorityList [idx] ;
-                  
-                  if (readyCount > 0 && ep != NULL && FD_ISSET (fd,&wSet))
-                    {
-                      readyCount-- ;
-                      endpointsServiced++ ;
-                      selectHit = 1 ;
-                      
-                      if ((rval = doWrite (ep)) != IoIncomplete &&
-                         rval != IoProgress)
-                        {
-                          Buffer *buff = ep->outBuffer ;
-
-                          FD_CLR (fd, &wrSet) ;
-
-                          /* incase callback wants to issue a write */
-                          ep->outBuffer = NULL ;        
-                          
-                          if (ep->outDoneCbk != NULL)
-                            (*ep->outDoneCbk) (ep,rval,buff,ep->outClientData) ;
-                          else
-                            freeBufferArray (buff) ;
-                        }
-                      else if (rval == IoProgress)
-                        {
-                          Buffer *buff = ep->outBuffer ;
-
-                          if (ep->outProgressCbk != NULL)
-                            (*ep->outProgressCbk) (ep,rval,buff,ep->outClientData) ;
-                        }
-                      else
-                        {
-                          FD_SET (ep->myFd, &exSet) ;
-                        }
-                    }
-                  else if (FD_ISSET(fd,&wrSet))
-                    writeMiss = 1;
-
-                  /* get it again as the write callback may have deleted the */
-                  /* endpoint */
-                  if (specialCheck)
-                    ep = mainEndPoint ;
-                  else
-                    ep = priorityList [idx] ;
-
-                  if (ep != NULL)
-                    {
-                      ep->selectHits *= 0.9 ;
-                      if (selectHit)
-                        ep->selectHits += 1.0 ;
-                      else if (readMiss && writeMiss)
-                        ep->selectHits -= 1.0 ;
-                    }
-                    
-                  if (readyCount > 0 && ep != NULL && FD_ISSET (fd,&eSet))
-                    doExcept (ep) ;
-                }
-            }
-          
-          reorderPriorityList () ;
-        }
-      else if (sval == 0 && !modifiedTime)
-        doTimeout () ;
-
-        /* now we're done processing all read fds and/or the
-           timeout(s). Next we do the work callbacks for all the endpoints
-           whose fds weren't ready. */
-      for (idx = 0 ; idx < priorityCount ; idx++)
-        {
-          EndPoint ep = priorityList [idx] ;
-
-          if (ep != NULL)
-            {
-              int fd = ep->myFd ;
-              
-              if ( !FD_ISSET (fd,&rSet) && !FD_ISSET (fd,&wSet) )
-                if (ep->workCbk != NULL)
-                  {
-                    EndpWorkCbk func = ep->workCbk ;
-                    void *data = ep->workData ;
-
-                    ep->workCbk = NULL ;
-                    ep->workData = NULL ;
-                    TMRstart(TMR_CALLBACK);
-                    func (ep,data) ;
-                    TMRstop(TMR_CALLBACK);
-                  }
-              
-            }
-        }
-    }
-}
-
-void *addWorkCallback (EndPoint endp, EndpWorkCbk cbk, void *data)
-{
-  void *oldBk = endp->workData ;
-  
-  endp->workCbk = cbk ;
-  endp->workData = data ;
-
-  return oldBk ;
-}
-
-/* Tell the Run routine to stop next time around. */
-void stopRun (void) 
-{
-  keepSelecting = 0 ;
-}
-
-
-int endPointErrno (EndPoint endp)
-{
-  return endp->myErrno ;
-}
-
-bool readIsPending (EndPoint endp) 
-{
-  return (endp->inBuffer != NULL ? true : false) ;
-}
-
-bool writeIsPending (EndPoint endp)
-{
-  return (endp->outBuffer != NULL ? true : false) ;
-}
-
-void setMainEndPoint (EndPoint endp)
-{
-  struct stat buf ;
-
-  mainEndPoint = endp ;
-  if (endp->myFd >= 0 && fstat (endp->myFd,&buf) < 0)
-    syslog (LOG_ERR,"Can't fstat mainEndPoint fd (%d): %m", endp->myFd) ;
-  else if (endp->myFd < 0)
-    syslog (LOG_ERR,"Negative fd for mainEndPoint???") ;
-  else
-    mainEpIsReg = (S_ISREG(buf.st_mode) ? true : false) ;
-}
-
-int getMainEndPointFd (void)
-{
-  return(mainEndPoint->myFd) ;
-}
-
-void freeTimeoutQueue (void)
-{
-  TimerElem p, n ;
-
-  p = timeoutQueue ;
-  while (p)
-    {
-      n = p->next ;
-      p->next = timeoutPool ;
-      timeoutPool = p;
-      p = n ;
-      timeoutQueueLength-- ;
-    }
-}
-
-
-/***********************************************************************/
-/*                      STATIC FUNCTIONS BELOW HERE                    */
-/***********************************************************************/
-
-
-/*
- * called when the file descriptor on this endpoint is read ready.
- */
-static IoStatus doRead (EndPoint endp) 
-{
-  int i = 0 ;
-  unsigned int idx ;
-  unsigned int bCount = 0 ;
-  struct iovec *vp = NULL ;
-  Buffer *buffers = endp->inBuffer ;
-  unsigned int currIdx = endp->inBufferIdx ;
-  size_t amt = 0 ;
-  IoStatus rval = IoIncomplete ;
-
-  TMRstart(TMR_READ);
-  for (i = currIdx ; buffers && buffers [i] != NULL ; i++)
-    bCount++ ;
-
-  bCount = (bCount > IOV_MAX ? IOV_MAX : bCount) ;
-
-  i = 0 ;
-
-  /* now set up the iovecs for the readv */
-  if (bCount > 0)
-    {
-      char *bbase ;
-      size_t bds, bs ;
-
-      vp = xcalloc (bCount, sizeof(struct iovec)) ;
-
-      bbase = bufferBase (buffers[currIdx]) ;
-      bds = bufferDataSize (buffers[currIdx]) ;
-      bs = bufferSize (buffers [currIdx]) ;
-
-      /* inIndex is an index in the virtual array of the read, not directly
-         into the buffer. */
-      vp[0].iov_base = bbase + bds + endp->inIndex ;
-      vp[0].iov_len = bs - bds - endp->inIndex ;
-
-      amt = vp[0].iov_len ;
-      
-      for (idx = currIdx + 1 ; idx < bCount ; idx++)
-        {
-          bbase = bufferBase (buffers[idx]) ;
-          bds = bufferDataSize (buffers[idx]) ;
-          bs = bufferSize (buffers [idx]) ;
-      
-          vp [idx].iov_base = bbase ;
-          vp [idx].iov_len = bs - bds ;
-          amt += (bs - bds) ;
-        }
-
-      i = readv (endp->myFd,vp,(int) bCount) ;
-
-      if (i > 0)
-        {
-          size_t readAmt = (size_t) i ;
-            
-          endp->inAmtRead += readAmt ;
-          
-          /* check if we filled the first buffer */
-          if (readAmt >= (size_t) vp[0].iov_len)
-            {                   /* we did */
-              bufferIncrDataSize (buffers[currIdx], vp[0].iov_len) ;
-              readAmt -= vp [0].iov_len ;
-              endp->inBufferIdx++ ;
-            }
-          else
-            {
-              endp->inIndex += readAmt ;
-              bufferIncrDataSize (buffers[currIdx], readAmt) ;
-              readAmt = 0 ;
-            }
-          
-          /* now check the rest of the buffers */
-          for (idx = 1 ; readAmt > 0 ; idx++)
-            {
-              ASSERT (idx < bCount) ;
-
-              bs = bufferSize (buffers [currIdx + idx]) ;
-              bbase = bufferBase (buffers [currIdx + idx]) ;
-              bds = bufferDataSize (buffers [currIdx + idx]) ;
-              
-              if (readAmt >= (bs - bds))
-                {
-                  bufferSetDataSize (buffers [currIdx + idx],bs) ;
-                  readAmt -= bs ;
-                  endp->inBufferIdx++ ;
-                }
-              else
-                {
-                  endp->inIndex = readAmt ;
-                  bufferIncrDataSize (buffers [currIdx + idx], readAmt) ;
-                  memset (bbase + bds + readAmt, 0, bs - bds - readAmt) ;
-                  readAmt = 0 ;
-                }
-            }
-
-          if (endp->inAmtRead >= endp->inMinLen)
-            {
-              endp->inIndex = 0 ;
-              rval = IoDone ;
-            }
-        }
-      else if (i < 0 && errno != EINTR && errno != EAGAIN)
-        {
-          endp->myErrno = errno ;
-          rval = IoFailed ;
-        }
-      else if (i < 0 && errno == EINTR)
-        {
-         handleSignals () ;
-        }
-      else if (i == 0)
-        rval = IoEOF ;
-      else                   /* i < 0 && errno == EAGAIN */
-        rval = IoIncomplete ;
-      
-      free (vp) ;
-    }
-  else
-    rval = IoDone ;
-  TMRstop(TMR_READ);
-  return rval ;
-}
-
-/* called when the file descriptor on the endpoint is write ready. */
-static IoStatus doWrite (EndPoint endp)
-{
-  unsigned int idx ;
-  int i = 0 ;
-  size_t amt = 0 ;
-  unsigned int bCount = 0 ;
-  struct iovec *vp = NULL ;
-  Buffer *buffers = endp->outBuffer ;
-  unsigned int currIdx = endp->outBufferIdx ;
-  IoStatus rval = IoIncomplete ;
-  
-  TMRstart(TMR_WRITE);
-  for (i = currIdx ; buffers && buffers [i] != NULL ; i++)
-    bCount++ ;
-
-  bCount = (bCount > IOV_MAX ? IOV_MAX : bCount) ;
-
-  i = 0 ;
-  
-  if (bCount > 0)
-    {
-      vp = xcalloc (bCount, sizeof(struct iovec)) ;
-
-      vp[0].iov_base = bufferBase (buffers [currIdx]) ;
-      vp[0].iov_base = (char *) vp[0].iov_base + endp->outIndex ;
-      vp[0].iov_len = bufferDataSize (buffers [currIdx]) - endp->outIndex ;
-
-      amt = vp[0].iov_len ;
-      
-      for (idx = 1 ; idx < bCount ; idx++)
-        {
-          vp [idx].iov_base = bufferBase (buffers [idx + currIdx]) ;
-          vp [idx].iov_len = bufferDataSize (buffers [idx + currIdx]) ;
-          amt += vp[idx].iov_len ;
-        }
-
-#if 1
-      if (debugWrites) 
-        {
-          /* nasty mixing, but stderr is unbuffered usually. It's debugging only */
-          d_printf (5,"About to write this:================================\n") ;
-          writev (2,vp,bCount) ;
-          d_printf (5,"end=================================================\n") ;
-        }
-      
-#endif
-
-      ASSERT (endp->myFd >= 0) ;
-      ASSERT (vp != 0) ;
-      ASSERT (bCount > 0) ;
-      
-      i = writev (endp->myFd,vp,(int) bCount) ;
-
-      if (i > 0)
-        {
-          size_t writeAmt = (size_t) i ;
-          
-          endp->outAmtWritten += writeAmt ;
-
-          /* now figure out which buffers got completely written */
-          for (idx = 0 ; writeAmt > 0 ; idx++)
-            {
-              if (writeAmt >= (size_t) vp[idx].iov_len)
-                {
-                  endp->outBufferIdx++ ;
-                  endp->outIndex = 0 ;
-                  writeAmt -= vp [idx].iov_len ;
-                }
-              else
-                {
-                  /* this buffer was not completly written */
-                  endp->outIndex += writeAmt ;
-                  writeAmt = 0 ;
-                }
-            }
-
-          if (endp->outAmtWritten == endp->outSize)
-            rval = IoDone ;
-         else
-            rval = IoProgress ;
-        }
-      else if (i < 0 && errno == EINTR)
-        {
-         handleSignals () ;
-        }
-      else if (i < 0 && errno == EAGAIN)
-        {
-          rval = IoIncomplete ;
-        }
-      else if (i < 0)
-        {
-          endp->myErrno = errno ;
-          rval = IoFailed ;
-        }
-      else
-        d_printf (1,"Wrote 0 bytes in doWrite()?\n") ;
-
-      free (vp) ;
-    }
-  else
-    rval = IoDone ;
-
-  TMRstop(TMR_WRITE);
-  return rval ;
-}
-
-
-static IoStatus doExcept (EndPoint endp)
-{
-  int optval;
-  socklen_t size ;
-  int fd = endPointFd (endp) ;
-
-  if (getsockopt (fd, SOL_SOCKET, SO_ERROR,
-                  (char *) &optval, &size) != 0)
-    syswarn ("ME exception: getsockopt (%d)", fd) ;
-  else if (optval != 0)
-    {
-      errno = optval ;
-      syswarn ("ME exception: fd %d", fd) ;
-    }
-  else
-    syswarn ("ME exception: fd %d: Unknown error", fd) ;
-
-#if 0
-  sleep (5) ;
-  abort () ;
-#endif
-
-  /* Not reached */
-  return IoFailed ;
-}
-
-#if 0
-static void endPointPrint (EndPoint ep, FILE *fp)
-{
-  fprintf (fp,"EndPoint [%p]: fd [%d]\n",(void *) ep, ep->myFd) ;
-}
-#endif
-
-static void signalHandler (int s)
-{
-  sigFlags[s] = 1 ;
-#ifndef HAVE_SIGACTION
-  xsignal (s, signalHandler) ;
-#endif
-}
-
-
-static void pipeHandler (int s)
-{
-  xsignal (s, pipeHandler) ;
-}
-
-
-/* compare the hit ratio of two endpoint for qsort. We're sorting the
-   endpoints on their relative activity */
-static int hitCompare (const void *v1, const void *v2)
-{
-  const struct endpoint_s *e1 = *((const struct endpoint_s * const *) v1) ;
-  const struct endpoint_s *e2 = *((const struct endpoint_s * const *) v2) ;
-  double e1Hit = e1->selectHits ;
-  double e2Hit = e2->selectHits ;
-
-  if (e1 == mainEndPoint)
-    return -1 ;
-  else if (e2 == mainEndPoint)
-    return 1 ;
-  else if (e1Hit < e2Hit)
-    return 1 ;
-  else if (e1Hit > e2Hit)
-    return -1 ;
-
-  return 0 ;
-}
-
-
-
-/* We maintain the endpoints in order of the percent times they're ready
-   for read/write when they've been selected. This helps us favour the more
-   active endpoints. */
-static void reorderPriorityList (void)
-{
-  unsigned int i, j ;
-  static int thisTime = 4;
-
-  /* only sort every 4th time since it's so expensive */
-  if (--thisTime > 0)
-    return ;
-
-  thisTime = 4;
-
-  for (i = j = 0; i < priorityCount; i++)
-    if (priorityList [i] != NULL)
-      {
-        if (i != j)
-          priorityList [j] = priorityList [i] ;
-        j++ ;
-      }
-
-  for (i = j; i < priorityCount; i++)
-    priorityList [ i ] = NULL;
-
-  priorityCount = j;
-
-  qsort (priorityList, (size_t)priorityCount, sizeof (EndPoint), &hitCompare);
-}
-
-
-#define TIMEOUT_POOL_SIZE ((4096 - 2 * (sizeof (void *))) / (sizeof (TimerElemStruct)))
-
-/* create a new timeout data structure properly initialized. */
-static TimerElem newTimerElem (TimeoutId i, time_t w, EndpTCB f, void *d)
-{
-  TimerElem p ;
-
-  if (timeoutPool == NULL)
-    {
-      unsigned int j ;
-
-      timeoutPool = xmalloc (sizeof(TimerElemStruct) * TIMEOUT_POOL_SIZE) ;
-
-      for (j = 0; j < TIMEOUT_POOL_SIZE - 1; j++)
-        timeoutPool[j] . next = &(timeoutPool [j + 1]) ;
-      timeoutPool [TIMEOUT_POOL_SIZE-1] . next = NULL ;
-    }
-
-  p = timeoutPool ;
-  timeoutPool = timeoutPool->next ;
-
-  ASSERT (p != NULL) ;
-  
-  p->id = i ;
-  p->when = w ;
-  p->func = f ;
-  p->data = d ;
-  p->next = NULL ;
-
-  return p ;
-}
-
-
-
-/* add a new timeout structure to the global list. */
-static TimeoutId timerElemAdd (time_t when, EndpTCB func, void *data)
-{
-  TimerElem p = newTimerElem (++nextId ? nextId : ++nextId,when,func,data) ;
-  TimerElem n = timeoutQueue ;
-  TimerElem q = NULL ;
-  
-  while (n != NULL && n->when <= when)
-    {
-      q = n ;
-      n = n->next ;
-    }
-
-  if (n == NULL && q == NULL)   /* empty list so put at head */
-    timeoutQueue = p ;
-  else if (q == NULL)           /* put at head of list */
-    {
-      p->next = timeoutQueue ;
-      timeoutQueue = p ;
-    }
-  else if (n == NULL)           /* put at end of list */
-    q->next = p ;
-  else                          /* in middle of list */
-    {
-      p->next = q->next ;
-      q->next = p ;
-    }
-
-  timeoutQueueLength++ ;
-  
-  return p->id ;
-}
-
-
-/* Fills in TOUT with the timeout to use on the next call to
- * select. Returns TOUT. If there is no timeout, then returns NULL.  If the
- * timeout has already passed, then it calls the timeout handling routine
- * first.
- */
-static struct timeval *getTimeout (struct timeval *tout)
-{
-  struct timeval *rval = NULL ;
-  
-  if (timeoutQueue != NULL)
-    {
-      time_t now = theTime() ;
-
-      while (timeoutQueue && now > timeoutQueue->when)
-        doTimeout () ;
-          
-      if (timeoutQueue != NULL && now == timeoutQueue->when)
-        {
-          tout->tv_sec = 0 ;
-          tout->tv_usec = 0 ;
-          rval = tout ;
-        }
-      else if (timeoutQueue != NULL)
-        {
-          tout->tv_sec = timeoutQueue->when - now ;
-          tout->tv_usec = 0 ;
-          rval = tout ;
-        }
-    }
-
-  return rval ;
-}
-
-      
-  
-
-
-  
-static void doTimeout (void)
-{
-  EndpTCB cbk = timeoutQueue->func ;
-  void *data = timeoutQueue->data ;
-  TimerElem p = timeoutQueue ;
-  TimeoutId tid = timeoutQueue->id ;
-
-  timeoutQueue = timeoutQueue->next ;
-
-  p->next = timeoutPool ;
-  timeoutPool = p ;
-
-  timeoutQueueLength-- ;
-  
-  if (cbk)
-    (*cbk) (tid, data) ;        /* call the callback function */
-}
-
-
-
-
-
-#if defined (WANT_MAIN)
-
-
-#define BUFF_SIZE 100
-
-
-void timerCallback (void *cd) ;
-void timerCallback (void *cd)
-{
-  d_printf (1,"Callback \n") ;
-}
-
-  
-void lineIsWritten (EndPoint ep, IoStatus status, Buffer *buffer, void *data);
-void lineIsWritten (EndPoint ep, IoStatus status, Buffer *buffer, void *data)
-{
-  int i ;
-  
-  if (status == IoDone)
-    d_printf (1,"LINE was written\n") ;
-  else
-    {
-      int oldErrno = errno ;
-      
-      errno = endPointErrno (ep) ;
-      perror ("write failed") ;
-      errno = oldErrno ;
-    }
-
-  for (i = 0 ; buffer && buffer [i] ; i++)
-    delBuffer (buffer [i]) ;
-}
-
-void lineIsRead (EndPoint myEp, IoStatus status, Buffer *buffer, void *data);
-void lineIsRead (EndPoint myEp, IoStatus status, Buffer *buffer, void *d)
-{
-  Buffer *writeBuffers, *readBuffers ;
-  Buffer newBuff1, newBuff2 ;
-  Buffer newInputBuffer ;
-  char *data, *p ;
-  size_t len ;
-
-  if (status == IoFailed)
-    {
-      int oldErrno = errno ;
-
-      errno = endPointErrno (myEp) ;
-      perror ("read failed") ;
-      errno = oldErrno ;
-
-      return ;
-    }
-  else if (status == IoEOF)
-    {
-      d_printf (1,"EOF on endpoint.\n") ;
-      delEndPoint (myEp) ;
-
-      return ;
-    }
-  
-  
-  data = bufferBase (buffer[0]) ;
-  len = bufferDataSize (buffer[0]) ;
-  
-  if (data [len - 1] == '\r' || data [len - 1] == '\n')
-    bufferDecrDataSize (buffer [0],1) ;
-  if (data [len - 1] == '\r' || data [len - 1] == '\n')
-    bufferDecrDataSize (buffer [0],1) ;
-
-  data [len] = '\0' ;
-  
-  d_printf (1,"Got a line: %s\n", data) ;
-
-  newBuff1 = newBuffer (len + 50) ;
-  newBuff2 = newBuffer (len + 50) ;
-  newInputBuffer = newBuffer (BUFF_SIZE) ;
-  
-  p = bufferBase (newBuff1) ; 
-  strcpy (p, "Thanks for that \"") ;
-  bufferSetDataSize (newBuff1,strlen (p)) ;
-  
-  p = bufferBase (newBuff2) ;
-  strcpy (p,"\" very tasty\n") ;
-  bufferSetDataSize (newBuff2,strlen (p)) ;
-
-  writeBuffers = makeBufferArray (newBuff1,buffer[0],newBuff2,NULL) ;
-  readBuffers = makeBufferArray (newInputBuffer,NULL) ;
-  
-  prepareWrite (myEp,writeBuffers,lineIsWritten,NULL) ;
-  prepareRead (myEp,readBuffers,lineIsRead,NULL,1) ;
-
-#if 0
-  myEp->registerWake (&timerCallback,theTime() + 7,0) ;
-#endif
-}
-
-
-static void printDate (TimeoutId tid, void *data) ;
-static void printDate (TimeoutId tid, void *data)
-{
-  time_t t ;
-
-  t = theTime() ;
-  
-  d_printf (1,"Timeout (%d) time now is %ld %s",
-           (int) tid,(long) t,ctime(&t)) ;
-
-  if (timeoutQueue == NULL) 
-    {
-      int ti = (rand () % 10) + 1 ;
-
-      prepareSleep (printDate,ti,data) ;
-    }
-}
-
-TimeoutId rm ;
-
-static void Timeout (TimeoutId tid, void *data) ;
-static void Timeout (TimeoutId tid, void *data)
-{
-  static int seeded ;
-  static int howMany ;
-  static int i ;
-  time_t t = theTime() ;
-
-  if ( !seeded )
-    {
-      srand (t) ;
-      seeded = 1 ;
-    }
-
-  d_printf (1,"Timeout (%d) time now is %ld %s",
-           (int) tid, (long) t,ctime(&t)) ;
-  
-  if (timeoutQueue != NULL && timeoutQueue->next != NULL)
-    d_printf (1,"%s timeout id %d\n",
-             (removeTimeout (rm) ? "REMOVED" : "FAILED TO REMOVE"), rm) ;
-  rm = 0 ;
-  
-  howMany = (rand() % 10) + (timeoutQueue == NULL ? 1 : 0) ;
-
-  for (i = 0 ; i < howMany ; i++ )
-    {
-      TimeoutId id ;
-      int count = (rand () % 30) + 1 ;
-
-      id = (i % 2 == 0 ? prepareSleep (Timeout,count,data)
-            : prepareWake (Timeout,t + count,data)) ;
-
-      if (rm == 0)
-        rm = id ;
-    }
-}
-
-
-void newConn (EndPoint ep, IoStatus status, Buffer *buffer, void *d) ;
-void newConn (EndPoint ep, IoStatus status, Buffer *buffer, void *d)
-{
-  EndPoint newEp ;
-  struct sockaddr_in in ;
-  Buffer *readBuffers ;
-  Buffer newBuff = newBuffer (BUFF_SIZE) ;
-  int len = sizeof (in) ;
-  int fd ;
-
-  memset (&in, 0, sizeof (in)) ;
-  
-  fd = accept (ep->myFd, (struct sockaddr *) &in, &len) ;
-
-  if (fd < 0)
-    {
-      perror ("::accept") ;
-      return ;
-    }
-  
-  newEp = newEndPoint (fd) ;
-
-  prepareRead (ep, NULL, newConn,NULL,0) ;
-
-  readBuffers = makeBufferArray (newBuff,NULL) ;
-
-  prepareRead (newEp, readBuffers, lineIsRead, NULL, 1) ;
-
-  d_printf (1,"Set up a new connection\n");
-}
-
-
-int main (int argc, char **argv)
-{
-  EndPoint accConn ;
-  struct sockaddr_in accNet ;
-  int accFd = socket (AF_INET,SOCK_STREAM,0) ;
-  unsigned short port = atoi (argc > 1 ? argv[1] : "10000") ;
-  time_t t = theTime() ;
-
-
-  program = strrchr (argv[0],'/') ;
-
-  if (!program)
-    program = argv [0] ;
-  else
-    program++ ;
-
-  ASSERT (accFd >= 0) ;
-
-  memset (&accNet,0,sizeof (accNet)) ;
-  accNet.sin_family = AF_INET ;
-  accNet.sin_addr.s_addr = htonl (INADDR_ANY) ;
-  accNet.sin_port = htons (port) ;
-
-#ifdef LOG_PERROR
-  openlog (program, LOG_PERROR | LOG_PID, LOG_NEWS) ;
-#else
-  openlog (program, LOG_PID, LOG_NEWS) ;
-#endif
-  
-  if (bind (accFd, (struct sockaddr *) &accNet, sizeof (accNet)) < 0)
-    {
-      perror ("bind: %m") ;
-      exit (1) ;
-    }
-
-  listen (accFd,5) ;
-  
-  accConn = newEndPoint (accFd) ;
-
-  prepareRead (accConn,NULL,newConn,NULL,0) ;
-
-  prepareSleep (Timeout,5,(void *) 0x10) ;
-
-  t = theTime() ;
-  d_printf (1,"Time now is %s",ctime(&t)) ;
-  
-  prepareWake (printDate,t + 16,NULL) ;
-
-  Run () ;
-
-  return 0;
-}
-#endif /* WANT_MAIN */
-
-/* Probably doesn't do the right thing for SIGCHLD */
-void setSigHandler (int signum, void (*ptr)(int))
-{
-  unsigned int i ;
-
-  if (sigHandlers == NULL)
-    {
-      sigHandlers = xmalloc (sizeof(sigfn) * NSIG) ;
-      sigFlags = xmalloc (sizeof(sig_atomic_t) * NSIG) ;
-      for (i = 0 ; i < NSIG ; i++)
-        {
-          sigHandlers [i] = NULL ;
-          sigFlags [i] = 0 ;
-        }
-    }
-
-  if (signum >= NSIG)
-    {
-      syslog (LOG_ERR,"ME signal number bigger than NSIG: %d vs %d",
-              signum,NSIG) ;
-      return ;
-    }
-
-  if (xsignal (signum, signalHandler) == SIG_ERR)
-    die ("signal failed: %s", strerror(errno)) ;
-
-  sigHandlers[signum] = ptr ;
-}
-
-static void handleSignals (void)
-{
-  int i ;
-#if defined(USE_SIGVEC)
-  int mask ;
-#endif
-
-  for (i = 1; i < NSIG; i++)
-    {
-      if (sigFlags[i])
-        {
-#if defined(USE_SIGACTION)
-          sigset_t set, oset ;
-      
-          if (sigemptyset (&set) != 0 || sigaddset (&set, i) != 0)
-            die ("sigemptyset or sigaddset failed") ;
-          if (sigprocmask (SIG_BLOCK, &set, &oset) != 0)
-            die ("sigprocmask failed: %s", strerror(errno)) ;
-#elif defined(USE_SIGVEC)
-# ifndef sigmask
-#  define sigmask(s)    (1 << ((s) - 1))
-# endif
-          int mask ;
-          
-          mask = sigblock (sigmask(i)) ;
-#elif defined(USE_SIGSET)
-          if (sighold (i) != 0)
-            die ("sighold failed: %s", strerror(errno)) ;
-#else
-      /* hope for the best */
-#endif
-
-          sigFlags[i] = 0;
-
-          if (sigHandlers[i] != NULL &&
-              sigHandlers[i] != SIG_IGN &&
-              sigHandlers[i] != SIG_DFL)
-            (sigHandlers[i])(i) ;
-            
-#if defined(USE_SIGACTION)
-          if (sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL) != 0)
-            die ("sigprocmask failed: %s", strerror(errno)) ;
-#elif defined(USE_SIGVEC)
-          sigsetmask (mask) ;
-#elif defined(USE_SIGSET)
-          if (sigrelse (i) != 0)
-            die ("sigrelse failed: %s", strerror(errno)) ;
-#else
-          /* hope for the best */
-#endif
-        }
-    }
-}
-
-
-int endpointConfigLoadCbk (void *data)
-{
-  FILE *fp = (FILE *) data ;
-  long ival ;
-  int rval = 1 ;
-
-  if (getInteger (topScope,"stdio-fdmax",&ival,NO_INHERIT))
-    {
-      stdioFdMax = ival ;
-
-#if ! defined (FD_SETSIZE)
-
-      if (stdioFdMax > 0)
-        {
-          logOrPrint (LOG_ERR,fp,NO_STDIO_FDMAX) ;
-          stdioFdMax = 0 ;
-          rval = 0 ;
-        }
-
-#else
-
-      if (stdioFdMax > FD_SETSIZE)
-        {
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s is higher"
-                      " than maximum of %ld. Using %ld","stdio-fdmax",
-                      ival,"global scope",
-                      (long) FD_SETSIZE, (long) FD_SETSIZE) ;
-          stdioFdMax = FD_SETSIZE ;
-          rval = 0 ;
-        }
-      
-#endif
-      
-    }
-  else
-    stdioFdMax = 0 ;
-
-  return rval ;
-}
-
-
-
-#if 0
-/* definitely not the fastest, but the most portable way to find the first
-  set bit in a mask  */
-static int ff_set (fd_set *set,unsigned int start)
-{
-  unsigned int i ;
-
-  for (i = start ; i < FD_SETSIZE ; i++)
-    if (FD_ISSET (i,set))
-      return (int) i ;
-
-  return -1 ;
-}
-
-
-static int ff_free (fd_set *set, unsigned int start)
-{
-  unsigned int i ;
-
-  for (i = start ; i < FD_SETSIZE ; i++)
-    if (!FD_ISSET (i,set))
-      return i ;
-
-
-  return -1 ;
-}
-#endif
-
-
-static void endpointCleanup (void)
-{
-  free (endPoints) ;
-  free (priorityList) ;
-  free (sigHandlers) ;
-  endPoints = NULL ;
-  priorityList = NULL ;
-  sigHandlers = NULL ;
-}
diff --git a/innfeed/endpoint.h b/innfeed/endpoint.h
deleted file mode 100644 (file)
index 9690183..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*  $Id: endpoint.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  The public interface to the Endpoint class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The EndPoint objects are encapsulations of file descriptors that normally
-**  do blocking i/o (i.e. NOT fd's hooked to a disk file).  The EndPoint class
-**  provides methods for reqesting read/writes to happen when next possible
-**  and for the requestor to be notified when the i/o is complete (or failed
-**  for some reason).  Facilities for timeout notifications are provided too.
-**
-**  We should add a way to cancel prepared read/write.
-*/
-
-#if ! defined ( endpoint_h__ )
-#define endpoint_h__
-
-#include "misc.h"
-
-
-#define clearTimer(timerId) \
-       do {\
-               if((timerId)!=0) { \
-                       removeTimeout(timerId); \
-                       timerId=0; \
-               } \
-       }while(0)
-
-
-
-/* These typedefs really lives in misc.h
- *
- *****************************************
- *             
- * The basic (opqaue to the outside world) type.
- *              
- *      typedef struct endpoint_s *EndPoint ;
- *
- *****************************************
- *
- * The returns status of an IO request
- *
- *      typedef enum {
- *          IoDone,                     i/o completed successfully 
- *          IoIncomplete,               i/o still got more to read/write
- *          IoProgress,                 i/o still got more to read/write
- *          IoFailed                    i/o failed
- *      } IoStatus ;
- *
- * The completion callbacks are never called with the status IoIncomplete or
- * IoProgress.
- *
- *****************************************
- *
- * typedef for function callback when IO is complete (or failed).
- *      E is the EndPoint
- *      I is the status of the IO
- *      B is the buffer the IO was to read to or write from.
- *      D is the client data originally given to prepare{Write,Read}
- *
- * typedef void (*EndpRWCB) (EndPoint e, IoStatus i, Buffer b, void *d) ;
- *
- *****************************************
- *
- * typedef for function callback when a timer has gone off. D is the client
- * data given to prepare{Sleep,Wake}
- *
- * typedef void (*EndpTCB) (void *d) ;
- *
- */
-
-/* create a new EndPoint hooked up to the given file descriptor */
-EndPoint newEndPoint (int fd) ;
-
-/* shutdown the file descriptor and delete the endpoint. */
-void delEndPoint (EndPoint endp) ;
-
-/* return the file descriptor the endpoint is managing */
-int endPointFd (EndPoint endp) ;
-
-/* Request a read when available. Reads MINLEN bytes into the
- * buffers in BUFFS. BUFFS is an array of Buffers, the last of which
- * must be NULL. Note that ownership of BUFFS is never asserted, but
- * the ownership of the Buffers in it is. So if an EndPoint is
- * deleted while a read is pending the Buffers will be released, but
- * the array won't be. If MINLEN is 0 then the buffers must be
- * filled. The FUNC function gets called when the read is
- * complete. CLIENTDATA is simply passed back to the
- * callback. Returns non-zero if can be scheduled for processing.
- */
-int prepareRead (EndPoint endp,
-                 Buffer *buffs,
-                 EndpRWCB func,
-                 void *clientData,
-                 int minlen) ;
-
-/* Request a write when possible. All the data in the buffers in
- * BUFFS will be written out the endpoint. BUFFS is a NULL
- * terminated array of Buffers. See prepareWrite for a discussion on
- * the ownership of BUFFS and the Buffers inside BUFFS. The PROGRESS
- * callback function will be called and the CLIENTDATA value will be
- * passed through to it whenever any data is written except for the
- * final write.  The DONE callback function will be called and the
- * CLIENTDATA value will be passed through to it after the final write.
- * Returns non-zero if scheduled succesfully.
- */
-int prepareWrite (EndPoint endp,
-                  Buffer *buffs,
-                  EndpRWCB progress,
-                  EndpRWCB done,
-                  void *clientData) ;
-
-/* cancel any outstanding reads. */
-void cancelRead (EndPoint endp) ;
-
-/* cancel any outstanding writes. */
-void cancelWrite (EndPoint endp, char *buffer, size_t *len) ;
-
-/* return true if prepareRead has been called, but not serviced yet */
-bool readIsPending (EndPoint endp) ;
-
-/* Request a wakeup at a given time. */
-TimeoutId prepareWake (EndpTCB func,
-                       time_t timeToWake,
-                       void *clientData) ;
-
-/* return true if prepareWrite has been called, but not serviced yet */
-bool writeIsPending (EndPoint endp) ;
-
-/* Requests a wakeup TIMETOSLEEP seconds from now. */
-TimeoutId prepareSleep (EndpTCB func,
-                        int timeToSleep,
-                        void *clientData) ;
-
-/* Updates tid to wakeup TIMETOSLEEP seconds from now. */
-TimeoutId updateSleep (TimeoutId tid,
-                       EndpTCB func,
-                       int timeToSleep,
-                       void *clientData) ;
-
-  /* Set up a function to be called whenever the endpoint's file descriptor
-     is NOT ready. This is called after all other fd-ready endpoints have
-     been serviced. */
-void *addWorkCallback (EndPoint endp, EndpWorkCbk cbk, void *data) ;
-
-void setSigHandler (int sig, void (*)(int)) ;
-
-/* remove the timeout that was previously requested. Retuesn true if
-   succesfully removed, false otherwise. 0 is a legal parameter value, in
-   which case the function simply returns. */
-bool removeTimeout (TimeoutId tid) ;
-
-/* start the select loop. An initial prepare(Read|Write) or a timeout
-   better have been setup. Doesn't return unless stopRun called */
-void Run (void) ;
-
-/* stops the Run loop and makes Run() return */
-void stopRun (void) ;
-
-/* returns the errno the endpoint got. */
-int endPointErrno (EndPoint endp) ;
-
-/* Tell the EndPoint class that the given EndPoint should always be
-   considered first for servicing (i.e. the EndPoint connectied to innd) */
-void setMainEndPoint (EndPoint endp) ;
-
-/* returns the fd of the main endpoint */
-int getMainEndPointFd (void) ;
-
-void freeTimeoutQueue (void) ;
-
-int endpointConfigLoadCbk (void *data) ;
-
-
-/*
- * kre's cool idea for reducing the number of times time() is called.
- */
-extern time_t  PrivateTime;
-
-#define theTime()       (PrivateTime ? PrivateTime : time(&PrivateTime))
-#define timePasses()    (PrivateTime = 0)
-
-#endif /* endpoint_h__ */
diff --git a/innfeed/host.c b/innfeed/host.c
deleted file mode 100644 (file)
index aa4259c..0000000
+++ /dev/null
@@ -1,4046 +0,0 @@
-/*  $Id: host.c 7833 2008-05-18 20:04:35Z iulius $
-**
-**  The implementation of the innfeed Host class.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <float.h>
-#include <math.h>
-#include <netdb.h>
-#include <syslog.h>
-#include <sys/param.h>
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "article.h"
-#include "buffer.h"
-#include "configfile.h"
-#include "connection.h"
-#include "endpoint.h"
-#include "host.h"
-#include "innlistener.h"
-#include "tape.h"
-
-#define REQ 1
-#define NOTREQ 0
-#define NOTREQNOADD 2
-
-#define VALUE_OK 0
-#define VALUE_TOO_HIGH 1
-#define VALUE_TOO_LOW 2
-#define VALUE_MISSING 3
-#define VALUE_WRONG_TYPE 4
-
-#define METHOD_STATIC 0
-#define METHOD_APS 1
-#define METHOD_QUEUE 2
-#define METHOD_COMBINED 3
-
-/* the limit of number of connections open when a host is
-   set to 0 to mean "infinite" */
-#define MAXCON 500
-#define MAXCONLIMIT(xx) ((xx==0)?MAXCON:xx)
-
-#define BACKLOGFILTER 0.7
-#define BACKLOGLWM 20.0
-#define BACKLOGHWM 50.0
-
-/* time between retrying blocked hosts in seconds */
-#define TRYBLOCKEDHOSTPERIOD 120
-
-extern char *configFile ;
-#if defined(hpux) || defined(__hpux) || defined(_SCO_DS)
-extern int h_errno;
-#endif
-
-/* the host keeps a couple lists of these */
-typedef struct proc_q_elem 
-{
-    Article article ;
-    struct proc_q_elem *next ;
-    struct proc_q_elem *prev ;
-    time_t whenToRequeue ;
-} *ProcQElem ;
-
-typedef struct host_param_s
-{
-  char *peerName;
-  char *ipName;
-  struct sockaddr_in *bindAddr;
-#ifdef HAVE_INET6
-  struct sockaddr_in6 *bindAddr6;
-#endif
-  int family;
-  unsigned int articleTimeout;
-  unsigned int responseTimeout;
-  unsigned int initialConnections;
-  unsigned int absMaxConnections;
-  unsigned int maxChecks;
-  unsigned short portNum;
-  bool forceIPv4;
-  unsigned int closePeriod;
-  unsigned int dynamicMethod;
-  bool wantStreaming;
-  bool dropDeferred;
-  bool minQueueCxn;
-  double lowPassLow; /* as percentages */
-  double lowPassHigh;
-  double lowPassFilter;
-  unsigned int backlogLimit ;
-  unsigned int backlogLimitHigh ;
-  double backlogFactor ;
-  double dynBacklogFilter ;
-  double dynBacklogLowWaterMark ;
-  double dynBacklogHighWaterMark ;
-  bool backlogFeedFirst ;
-  char *username;
-  char *password;
-} *HostParams ;
-
-struct host_s 
-{
-    InnListener listener ;      /* who created me. */
-    struct sockaddr **ipAddrs ;        /* the ip addresses of the remote */
-    int nextIpAddr ;           /* the next ip address to hand out */
-
-    Connection *connections ;   /* NULL-terminated list of all connections */
-    bool *cxnActive ;           /* true if the corresponding cxn is active */
-    bool *cxnSleeping ;         /* true if the connection is sleeping */
-    unsigned int maxConnections;       /* maximum no of cxns controlled by method */
-    unsigned int activeCxns ;          /* number of connections currently active */
-    unsigned int sleepingCxns ;        /* number of connections currently sleeping */
-    Connection blockedCxn ;     /* the first connection to get the 400 banner*/
-    Connection notThisCxn ;    /* don't offer articles to this connection */
-
-    HostParams params;          /* Parameters from config file */
-
-    bool remoteStreams ;        /* true if remote supports streaming */
-    
-    ProcQElem queued ;          /* articles done nothing with yet. */
-    ProcQElem queuedTail ;
-
-    ProcQElem processed ;       /* articles given to a Connection */
-    ProcQElem processedTail ;
-
-    ProcQElem deferred ;       /* articles which have been deferred by */
-    ProcQElem deferredTail ;   /* a connection */
-    
-    TimeoutId statsId ;         /* timeout id for stats logging. */
-    TimeoutId ChkCxnsId ;      /* timeout id for dynamic connections */
-    TimeoutId deferredId ;     /* timeout id for deferred articles */
-
-    Tape myTape ;
-    
-    bool backedUp ;             /* set to true when all cxns are full */
-    unsigned int backlog ;             /* number of arts in `queued' queue */
-    unsigned int deferLen ;            /* number of arts in `deferred' queue */
-
-    bool loggedModeOn ;         /* true if we logged going into no-CHECK mode */
-    bool loggedModeOff ;        /* true if we logged going out of no-CHECK mode */
-
-    bool loggedBacklog ;        /* true if we already logged the fact */
-    bool notifiedChangedRemBlckd ; /* true if we logged a new response 400 */
-    bool removeOnReload ;      /* true if host should be removed at end of
-                                * config reload
-                                */
-    bool isDynamic;             /* true if host created dynamically */
-
-    /* these numbers get reset periodically (after a 'final' logging). */
-    unsigned int artsOffered ;         /* # of articles we offered to remote. */
-    unsigned int artsAccepted ;        /* # of articles succesfully transferred */
-    unsigned int artsNotWanted ;       /* # of articles remote already had */
-    unsigned int artsRejected ;        /* # of articles remote rejected */
-    unsigned int artsDeferred ;        /* # of articles remote asked us to retry */
-    unsigned int artsMissing ;         /* # of articles whose file was missing. */
-    unsigned int artsToTape ;          /* # of articles given to tape */
-    unsigned int artsQueueOverflow ;   /* # of articles that overflowed `queued' */
-    unsigned int artsCxnDrop ;         /* # of articles caught in dead cxn */
-    unsigned int artsHostSleep ;       /* # of articles spooled by sleeping host */
-    unsigned int artsHostClose ;       /* # of articles caught by closing host */
-    unsigned int artsFromTape ;        /* # of articles we pulled off tape */
-    double artsSizeAccepted ;  /* size of articles succesfully transferred */
-    double artsSizeRejected ;  /* size of articles remote rejected */
-
-    /* Dynamic Peerage - MGF */
-    unsigned int artsProcLastPeriod ;  /* # of articles processed in last period */
-    unsigned int secsInLastPeriod ;    /* Number of seconds in last period */
-    unsigned int lastCheckPoint ;      /* total articles at end of last period */
-    unsigned int lastSentCheckPoint ;  /* total articles sent end of last period */
-    unsigned int lastTotalCheckPoint ; /* total articles total end of last period */
-    bool maxCxnChk ;            /* check for maxConnections */
-    time_t lastMaxCxnTime ;     /* last time a maxConnections increased */
-    time_t lastChkTime;         /* last time a check was made for maxConnect */
-    unsigned int nextCxnTimeChk ;      /* next check for maxConnect */
-
-    double backlogFilter;        /* IIR filter for size of backlog */
-
-    /* These numbers are as above, but for the life of the process. */
-    unsigned int gArtsOffered ;        
-    unsigned int gArtsAccepted ;
-    unsigned int gArtsNotWanted ;
-    unsigned int gArtsRejected ;
-    unsigned int gArtsDeferred ;
-    unsigned int gArtsMissing ;
-    unsigned int gArtsToTape ;
-    unsigned int gArtsQueueOverflow ;
-    unsigned int gArtsCxnDrop ;
-    unsigned int gArtsHostSleep ;
-    unsigned int gArtsHostClose ;
-    unsigned int gArtsFromTape ;
-    double gArtsSizeAccepted ;
-    double gArtsSizeRejected ;
-    unsigned int gCxnQueue ;
-    unsigned int gNoQueue ;
-
-    time_t firstConnectTime ;   /* time of first connect. */
-    time_t connectTime ;        /* the time the first connection was fully
-                                   set up (MODE STREAM and everything
-                                   else). */
-    time_t spoolTime ;          /* the time the Host had to revert to
-                                   spooling articles to tape. */
-    time_t lastSpoolTime ;      /* the time the last time the Host had to
-                                   revert to spooling articles to tape. */
-    time_t nextIpLookup ;      /* time of last IP name resolution */
-
-    char *blockedReason ;       /* what the 400 from the remote says. */
-    
-    Host next ;                 /* for global list of hosts. */
-
-    unsigned long dlAccum ;            /* cumulative deferLen */
-    unsigned int blNone ;              /* number of times the backlog was 0 */
-    unsigned int blFull ;              /* number of times the backlog was full */
-    unsigned int blQuartile[4] ;       /* number of times in each quartile */
-    unsigned long blAccum ;            /* cumulative backlog for computing mean */
-    unsigned int blCount ;             /* the sample count */
-};
-
-/* A holder for the info we got out of the config file, but couldn't create
-   the Host object for (normally due to lock-file problems).*/
-
-typedef struct host_holder_s
-{
-  HostParams params;
-  struct host_holder_s *next ;
-} *HostHolder ;
-
-
-/* These numbers are as above, but for all hosts over
-   the life of the process. */
-long procArtsOffered ;        
-long procArtsAccepted ;
-long procArtsNotWanted ;
-long procArtsRejected ;
-long procArtsDeferred ;
-long procArtsMissing ;
-double procArtsSizeAccepted ;
-double procArtsSizeRejected ;
-long procArtsToTape ;
-long procArtsFromTape ;
-
-static HostParams defaultParams=NULL;
-
-static HostHolder blockedHosts ; /* lists of hosts we can't lock */
-static TimeoutId tryBlockedHostsId = 0 ;
-static time_t lastStatusLog ;
-
-  /*
-   * Host object private methods.
-   */
-static void articleGone (Host host, Connection cxn, Article article) ;
-static void hostStopSpooling (Host host) ;
-static void hostStartSpooling (Host host) ;
-static void hostLogStats (Host host, bool final) ;
-static void hostStatsTimeoutCbk (TimeoutId tid, void *data) ;
-static void hostDeferredArtCbk (TimeoutId tid, void *data) ;
-static void backlogToTape (Host host) ;
-static void queuesToTape (Host host) ;
-static bool amClosing (Host host) ;
-static void hostLogStatus (void) ;
-static void hostPrintStatus (Host host, FILE *fp) ;
-static int validateBool (FILE *fp, const char *name,
-                         int required, bool setval,
-                        scope * sc, unsigned int inh);
-static int validateReal (FILE *fp, const char *name, double low,
-                        double high, int required, double setval,
-                        scope * sc, unsigned int inh);
-static int validateInteger (FILE *fp, const char *name,
-                           long low, long high, int required, long setval,
-                           scope * sc, unsigned int inh);
-
-static HostParams newHostParams(HostParams p);
-static void freeHostParams(HostParams params);
-
-static HostHolder FindBlockedHost(const char *name);
-static void addBlockedHost(HostParams params);
-static void tryBlockedHosts(TimeoutId tid, void *data);
-static Host newHost (InnListener listener, HostParams p);
-
-static HostParams getHostInfo (void);
-static HostParams hostDetails (scope *s,
-                              char *name,
-                              bool isDefault,
-                              FILE *fp);
-
-static Host findHostByName (char *name) ;
-static void hostCleanup (void) ;
-static void hostAlterMaxConnections(Host host,
-                                   unsigned int absMaxCxns, unsigned int maxCxns,
-                                   bool makeConnect);
-
-/* article queue management functions */
-static Article remHead (ProcQElem *head, ProcQElem *tail) ;
-static void queueArticle (Article article, ProcQElem *head, ProcQElem *tail,
-                         time_t when) ;
-static bool remArticle (Article article, ProcQElem *head, ProcQElem *tail) ;
-
-
-
-
-
-/*
- * Host class data
- */
-
-/* if true then when a Host logs its stats, it has all its connections
-   log theirs too. */
-static bool logConnectionStats = (bool) LOG_CONNECTION_STATS ;
-
-/* The frequency in seconds with which a Host will log its stats. */
-static time_t statsPeriod = STATS_PERIOD ;
-static time_t statsResetPeriod = STATS_RESET_PERIOD ;
-
-static Host gHostList = NULL ;
-
-static unsigned int gHostCount = 0 ;
-
-static unsigned int maxIpNameLen = 0 ;
-static unsigned int maxPeerNameLen = 0 ;
-
-static unsigned int hostHighwater = HOST_HIGHWATER ;
-static time_t start ;
-static char startTime [30] ;    /* for ctime(3) */
-static pid_t myPid ;
-
-static char *statusFile = NULL ;
-static unsigned int dnsRetPeriod ;
-static unsigned int dnsExpPeriod ;
-
-bool genHtml = false ;
-
-/*******************************************************************/
-/*                  PUBLIC FUNCTIONS                               */
-/*******************************************************************/
-
-
-/* function called when the config file is loaded */
-int hostConfigLoadCbk (void *data)
-{
-  int rval = 1, bval ;
-  long iv ;
-  FILE *fp = (FILE *) data ;
-  char *p ;
-
-
-  d_printf(1,"hostConfigLoadCbk\n");
-
-  if (defaultParams)
-    {
-      freeHostParams(defaultParams);
-      defaultParams=NULL;
-    }
-   
-  /* get optional global defaults */
-  if (getInteger (topScope,"dns-retry",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld","dns-retry",
-                      iv,"global scope",(long)DNS_RETRY_PERIOD) ;
-          iv = DNS_RETRY_PERIOD ;
-        }
-    }
-  else
-    iv = DNS_RETRY_PERIOD ;
-  dnsRetPeriod = (unsigned int) iv ;
-  
-  
-  if (getInteger (topScope,"dns-expire",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld","dns-expire",iv,
-                      "global scope",(long)DNS_EXPIRE_PERIOD) ;
-          iv = DNS_EXPIRE_PERIOD ;
-        }
-    }
-  else
-    iv = DNS_EXPIRE_PERIOD ;
-  dnsExpPeriod = (unsigned int) iv ;
-
-  if (getBool (topScope,"gen-html",&bval,NO_INHERIT))
-    genHtml = (bval ? true : false) ;
-  else
-    genHtml = GEN_HTML ;
-  
-  if (getString (topScope,"status-file",&p,NO_INHERIT))
-    {
-      hostSetStatusFile (p) ;
-      free (p) ;
-    }
-  else
-    hostSetStatusFile (INNFEED_STATUS) ;
-  
-  
-  if (getBool (topScope,"connection-stats",&bval,NO_INHERIT))
-    logConnectionStats = (bval ? true : false) ;
-  else
-    logConnectionStats = (LOG_CONNECTION_STATS ? true : false) ;
-
-
-  if (getInteger (topScope,"host-queue-highwater", &iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld","host-queue-highwater",
-                      iv,"global scope",(long) HOST_HIGHWATER) ;
-          iv = HOST_HIGHWATER ;
-        }
-    }
-  else
-    iv = HOST_HIGHWATER ;
-  hostHighwater = (unsigned int) iv ;
-
-  if (getInteger (topScope,"stats-period",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld","stats-period",
-                      iv,"global scope",(long)STATS_PERIOD) ;
-          iv = STATS_PERIOD ;
-        }
-    }
-  else
-    iv = STATS_PERIOD ;
-  statsPeriod = (unsigned int) iv ;
-
-
-  if (getInteger (topScope,"stats-reset",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld","stats-reset",iv,
-                      "global scope",(long)STATS_RESET_PERIOD) ;
-          iv = STATS_RESET_PERIOD ;
-        }
-    }
-  else
-    iv = STATS_RESET_PERIOD ;
-  statsResetPeriod = (unsigned int) iv ;
-  
-  defaultParams=hostDetails(topScope, NULL, true, fp);
-  ASSERT(defaultParams!=NULL);
-
-  return rval ;
-}
-
-/*
- * make a new HostParams structure copying an existing one
- * or from compiled defaults
- */
-
-HostParams newHostParams(HostParams p)
-{
-  HostParams params;
-
-  params = xmalloc (sizeof(struct host_param_s)) ;
-
-  if (p != NULL)
-    {
-      /* Copy old stuff in */
-      memcpy ((char *) params, (char *) p, sizeof(struct host_param_s));
-      if (params->peerName)
-       params->peerName = xstrdup(params->peerName);
-      if (params->ipName)
-       params->ipName = xstrdup(params->ipName);
-      if (params->bindAddr)
-        {
-          struct sockaddr_in *s = params->bindAddr;
-          params->bindAddr = xmalloc(sizeof(*s));
-          memcpy(params->bindAddr, s, sizeof(*s));
-        }
-#ifdef HAVE_INET6
-      if (params->bindAddr6)
-        {
-          struct sockaddr_in6 *s = params->bindAddr6;
-          params->bindAddr6 = xmalloc(sizeof(*s));
-          memcpy(params->bindAddr6, s, sizeof(*s));
-        }
-#endif
-    }
-  else
-    {
-      /* Fill in defaults */
-      params->peerName=NULL;
-      params->ipName=NULL;
-      params->bindAddr=NULL;
-#ifdef HAVE_INET6
-      params->bindAddr6=NULL;
-#endif
-      params->family = 0;
-      params->articleTimeout=ARTTOUT;
-      params->responseTimeout=RESPTOUT;
-      params->initialConnections=INIT_CXNS;
-      params->absMaxConnections=MAX_CXNS;
-      params->maxChecks=MAX_Q_SIZE;
-      params->portNum=PORTNUM;
-      params->forceIPv4=FORCE_IPv4;
-      params->closePeriod=CLOSE_PERIOD;
-      params->dynamicMethod=METHOD_STATIC;
-      params->wantStreaming=STREAM;
-      params->dropDeferred=false;
-      params->minQueueCxn=false;
-      params->lowPassLow=NOCHECKLOW;
-      params->lowPassHigh=NOCHECKHIGH;
-      params->lowPassFilter=FILTERVALUE;
-      params->backlogLimit=BLOGLIMIT;
-      params->backlogLimitHigh=BLOGLIMIT_HIGH ;
-      params->backlogFactor=LIMIT_FUDGE ;
-      params->dynBacklogFilter = BACKLOGFILTER ;
-      params->dynBacklogLowWaterMark = BACKLOGLWM;
-      params->dynBacklogHighWaterMark = BACKLOGHWM;
-      params->backlogFeedFirst=false;
-      params->username=NULL;
-      params->password=NULL;
-    }
-  return (params);
-}
-            
-/*
- * Free up a param structure
- */
-
-void freeHostParams(HostParams params)
-{
-  ASSERT(params != NULL);
-  if (params->peerName)
-    free (params->peerName) ;
-  if (params->ipName)
-    free (params->ipName) ;
-  if (params->bindAddr)
-    free (params->bindAddr) ;
-#ifdef HAVE_INET6
-  if (params->bindAddr6)
-    free (params->bindAddr6) ;
-#endif
-  free (params) ;
-}  
-
-static void hostReconfigure(Host h, HostParams params)
-{
-  unsigned int i, absMaxCxns ;
-  double oldBacklogFilter ;
-  
-  if (strcmp(h->params->ipName, params->ipName) != 0)
-    {
-      free (h->params->ipName) ;
-      h->params->ipName = xstrdup (params->ipName) ;
-      h->nextIpLookup = theTime () ;
-    }
-  
-  /* Put in new parameters
-     Unfortunately we can't blat on top of absMaxConnections
-     as we need to do some resizing here
-     */
-  
-  ASSERT (h->params != NULL);
-  
-  oldBacklogFilter = h->params->dynBacklogFilter;
-  i = h->params->absMaxConnections; /* keep old value */
-  absMaxCxns = params->absMaxConnections;
-  /* Use this set of params and allocate, and free
-   * up the old
-   */
-  freeHostParams(h->params);
-  h->params = params;
-  h->params->absMaxConnections = i; /* restore old value */
-  
-  /* If the backlog filter value has changed, reset the
-   * filter as the value therein will be screwy
-   */
-  if (h->params->dynBacklogFilter != oldBacklogFilter)
-    h->backlogFilter = ((h->params->dynBacklogLowWaterMark
-                        + h->params->dynBacklogHighWaterMark)
-                       /200.0 /(1.0-h->params->dynBacklogFilter));
-  
-  /* We call this anyway - it does nothing if the values
-   * haven't changed. This is because doing things like
-   * just changing "dynamic-method" requires this call
-   * to be made
-   */
-  hostAlterMaxConnections(h, absMaxCxns, h->maxConnections, false);
-  
-  for ( i = 0 ; i < MAXCONLIMIT(h->params->absMaxConnections) ; i++ )
-    if (h->connections[i] != NULL)
-      cxnSetCheckThresholds (h->connections[i],
-                            h->params->lowPassLow,
-                            h->params->lowPassHigh,
-                            h->params->lowPassFilter) ;
-  
-  /* XXX how to handle initCxns change? */
-}
-
-
-void configHosts (bool talkSelf)
-{
-  Host nHost, h, q ;
-  HostHolder hh, hi ;
-  HostParams params;
-
-  /* Remove the current blocked host list */
-  for (hh = blockedHosts, hi = NULL ; hh != NULL ; hh = hi)
-    {
-      freeHostParams(hh->params);
-      hi = hh->next ;
-      free (hh) ;
-    }
-  blockedHosts = NULL ;
-
-  closeDroppedArticleFile () ;
-  openDroppedArticleFile () ;
-  
-  while ((params = getHostInfo ()) !=NULL )
-    {
-      h = findHostByName (params->peerName) ;
-      /* We know the host isn't blocked as we cleared the blocked list */
-      /* Have we already got this host up and running ?*/
-      if ( h != NULL )
-       {
-         hostReconfigure(h, params);
-         h->removeOnReload = false ; /* Don't remove at the end */
-       }
-      else
-        {
-           
-         /* It's a host we haven't seen from the config file before */
-         nHost = newHost (mainListener, params);
-
-         if (nHost == NULL)
-           {
-             addBlockedHost(params);
-
-              warn ("ME locked cannot setup peer %s", params->peerName) ;
-           }
-         else 
-           {
-             if (params->initialConnections == 0 && talkSelf)
-                notice ("%s config ignored batch mode with initial"
-                        " connection count of 0", params->peerName) ;
-
-             if ( !listenerAddPeer (mainListener,nHost) )
-               die ("failed to add a new peer\n") ;
-           }
-       }
-
-    }
-  
-
-  for (h = gHostList; h != NULL; h = q) 
-    {
-      q = h->next ;
-      if (h->removeOnReload)
-       {
-         if (h->isDynamic)
-           {
-             /* change to the new default parameters */
-             params = newHostParams(defaultParams);
-             ASSERT(params->peerName == NULL);
-             ASSERT(params->ipName == NULL);
-             ASSERT(h->params->peerName != NULL);
-             ASSERT(h->params->ipName != NULL);
-             params->peerName = xstrdup(h->params->peerName);
-             params->ipName = xstrdup(h->params->ipName);
-             hostReconfigure(h, params);
-             h->removeOnReload = true;
-           }
-         else
-           hostClose (h) ;         /* h may be deleted in here. */
-       }
-      else
-        /* prime it for the next config file read */
-        h->removeOnReload = true ;
-    }
-
-  hostLogStatus () ;
-}
-
-
-void hostAlterMaxConnections(Host host,
-                            unsigned int absMaxCxns, unsigned int maxCxns,
-                            bool makeConnect)
-{
-  unsigned int lAbsMaxCxns;
-  unsigned int i;
-  
-  /* Fix 0 unlimited case */
-  lAbsMaxCxns = MAXCONLIMIT(absMaxCxns);
-  
-  /* Don't accept 0 for maxCxns */
-  maxCxns=MAXCONLIMIT(maxCxns);
-  
-  if ( host->params->dynamicMethod == METHOD_STATIC)
-    {
-      /* If running static, ignore the maxCxns passed in, we'll
-        just use absMaxCxns
-        */
-      maxCxns = lAbsMaxCxns;
-    }
-  
-  if ( maxCxns > lAbsMaxCxns)
-    {
-      /* ensure maxCxns is of the correct form */
-      maxCxns = lAbsMaxCxns;
-    }
-
-  if ((maxCxns < host->maxConnections) && (host->connections != NULL))
-    {
-      /* We are going to have to nuke some connections, as the current
-         max is now greater than the new max
-        */
-      for ( i = host->maxConnections ; i > maxCxns ; i-- )
-       {
-         /* XXX this is harsh, and arguably there could be a
-            cleaner way of doing it.  the problem being addressed
-            by doing it this way is that eventually a connection
-            closed cleanly via cxnClose can end up ultimately
-            calling hostCxnDead after h->maxConnections has
-            been lowered and the relevant arrays downsized.
-            If trashing the old, unallocated space in
-            hostCxnDead doesn't kill the process, the
-            ASSERT against h->maxConnections surely will.
-            */
-         if (host->connections[i - 1] != NULL)
-           {
-             cxnLogStats (host->connections [i-1], true) ;
-             cxnNuke (host->connections[i-1]) ;
-             host->connections[i-1] = NULL;
-           }
-       }
-      host->maxConnections = maxCxns ;
-    }
-  
-  if (host->connections)
-    for (i = host->maxConnections ; i <= MAXCONLIMIT(host->params->absMaxConnections) ; i++)
-      {
-       /* Ensure we've got an empty values only beyond the maxConnection
-          water mark.
-          */
-       ASSERT (host->connections[i] == NULL);
-      }
-  
-  if ((lAbsMaxCxns != MAXCONLIMIT(host->params->absMaxConnections)) ||
-      (host->connections == NULL))
-    {
-      /* we need to change the size of the connection array */
-      if (host->connections == NULL)
-       {
-         /* not yet allocated */
-         
-         host->connections = xcalloc (lAbsMaxCxns + 1, sizeof(Connection)) ;
-         
-         ASSERT (host->cxnActive == NULL);
-         host->cxnActive = xcalloc (lAbsMaxCxns, sizeof(bool)) ;
-         
-         ASSERT (host->cxnSleeping == NULL) ;
-         host->cxnSleeping = xcalloc (lAbsMaxCxns, sizeof(bool)) ;
-         
-         for (i = 0 ; i < lAbsMaxCxns ; i++)
-           {
-             host->connections [i] = NULL ;
-             host->cxnActive[i] = false ;
-             host->cxnSleeping[i] = false ;
-           }
-         host->connections[lAbsMaxCxns] = NULL;
-       }
-      else
-       {
-         host->connections =
-            xrealloc (host->connections,
-                      sizeof(Connection) * (lAbsMaxCxns + 1));
-         host->cxnActive = xrealloc (host->cxnActive,
-                                      sizeof(bool) * lAbsMaxCxns) ;
-         host->cxnSleeping = xrealloc (host->cxnSleeping,
-                                        sizeof(bool) * lAbsMaxCxns) ;
-
-         if (lAbsMaxCxns > MAXCONLIMIT(host->params->absMaxConnections))
-           {
-             for (i = MAXCONLIMIT(host->params->absMaxConnections) ;
-                  i < lAbsMaxCxns ; i++)
-               {
-                 host->connections[i+1] = NULL; /* array always 1 larger */
-                 host->cxnActive[i] = false ;
-                 host->cxnSleeping[i] = false ;
-               }
-           }
-       }
-      host->params->absMaxConnections = absMaxCxns;
-    }    
-  /* if maximum was raised, establish the new connexions
-     (but don't start using them).
-     */
-  if ( maxCxns > host->maxConnections)
-    {
-      i = host->maxConnections ;
-      /* need to set host->maxConnections before cxnWait() */
-      host->maxConnections = maxCxns;
-
-      while ( i < maxCxns )
-       {
-         host->cxnActive [i] = false ;
-         host->cxnSleeping [i] = false ;
-         /* create a new connection */
-         host->connections [i] =
-           newConnection (host, i,
-                          host->params->ipName,
-                          host->params->articleTimeout,
-                          host->params->portNum,
-                          host->params->responseTimeout,
-                          host->params->closePeriod,
-                          host->params->lowPassLow,
-                          host->params->lowPassHigh,
-                          host->params->lowPassFilter) ;
-
-         /* connect if low enough numbered, or we were forced to */
-         if ((i < host->params->initialConnections) || makeConnect)
-           cxnConnect (host->connections [i]) ;
-         else
-           cxnWait (host->connections [i]) ;
-         i++ ;
-       }
-    }
-
-}
-
-/*
- * Find a host on the blocked host list
- */
-
-static HostHolder FindBlockedHost(const char *name)
-{
-  HostHolder hh = blockedHosts;
-  while (hh != NULL)
-    if ((hh->params) && (hh->params->peerName) &&
-       (strcmp(name,hh->params->peerName) == 0))
-      return hh;
-    else
-      hh=hh->next;
-  return NULL;
-}
-
-static void addBlockedHost(HostParams params)
-{
-  HostHolder hh;
-
-  hh = xmalloc (sizeof(struct host_holder_s)) ;
-  /* Use this set of params */
-         
-  hh->params = params;
-  
-  hh->next = blockedHosts ;
-  blockedHosts = hh ;
-}
-
-/*
- * We iterate through the blocked host list and try and reconnect ones
- * where we couldn't get a lock
- */
-static void tryBlockedHosts(TimeoutId tid UNUSED , void *data UNUSED )
-{
-  HostHolder hh,hi;
-  HostParams params;
-  
-  hh = blockedHosts; /* Get start of our queue */
-  blockedHosts = NULL ; /* remove them all from the queue of hosts */
-
-  while (hh != NULL)
-    {
-      params = hh->params;
-      hi= hh->next;
-      free(hh);
-      hh = hi;
-
-      if (params && params->peerName)
-       {
-         if (findHostByName(params->peerName)!=NULL)
-           {
-             /* Wierd, someone's managed to start it when it's on
-              * the blocked list. Just silently discard.
-              */
-             freeHostParams(params);
-           }
-         else
-           {
-             Host nHost;
-             nHost = newHost (mainListener, params);
-
-             if (nHost == NULL)
-               {
-                 addBlockedHost(params);
-
-                  warn ("ME locked cannot setup peer %s", params->peerName) ;
-               }
-             else 
-               {
-                 d_printf(1,"Unblocked host %s\n",params->peerName);
-
-                 if (params->initialConnections == 0 &&
-                     listenerIsDummy(mainListener) /*talk to self*/)
-                    notice ("%s config ignored batch mode with initial"
-                            " connection count of 0", params->peerName) ;
-
-                 if ( !listenerAddPeer (mainListener,nHost) )
-                   die ("failed to add a new peer\n") ;
-               }
-           }
-       }
-    }
-  tryBlockedHostsId = prepareSleep(tryBlockedHosts,
-                                  TRYBLOCKEDHOSTPERIOD, NULL);
-}
-
-
-/*
- * Create a new Host object with default parameters. Called by the
- * InnListener.
- */
-
-Host newDefaultHost (InnListener listener,
-                    const char *name) 
-{
-  HostParams p;
-  Host h = NULL;
-
-  if (FindBlockedHost(name)==NULL)
-    {
-
-      p=newHostParams(defaultParams);
-      ASSERT(p!=NULL);
-
-      /* relies on fact listener and names are null in default*/
-      p->peerName=xstrdup(name);
-      p->ipName=xstrdup(name);
-      
-      h=newHost (listener,p);
-      if (h==NULL)
-       {
-         /* Couldn't get a lock - add to list of blocked peers */
-         addBlockedHost(p);
-
-          warn ("ME locked cannot setup peer %s", p->peerName);
-
-         return NULL;
-       }
-
-      h->isDynamic = true;
-      h->removeOnReload = true;
-
-      notice ("ME unconfigured peer %s added", p->peerName) ;
-    }
-  return h;
-}
-
-/*
- * Create a new host and attach the supplied param structure
- */
-
-static bool inited = false ;
-Host newHost (InnListener listener, HostParams p)
-{
-  Host nh ; 
-
-  ASSERT (p->maxChecks > 0) ;
-
-  if (!inited)
-    {
-      inited = true ;
-      atexit (hostCleanup) ;
-    }
-
-  /*
-   * Once only, init the first blocked host check
-   */
-  if (tryBlockedHostsId==0)
-    tryBlockedHostsId = prepareSleep(tryBlockedHosts,
-                                    TRYBLOCKEDHOSTPERIOD, NULL);
-
-  nh =  xcalloc (1, sizeof(struct host_s)) ;
-
-  nh->params = p;
-  nh->listener = listener;
-
-  nh->connections = NULL; /* We'll get these allocated later */
-  nh->cxnActive = NULL;
-  nh->cxnSleeping = NULL;
-
-  nh->activeCxns = 0 ;
-  nh->sleepingCxns = 0 ;
-
-  nh->blockedCxn = NULL ;
-  nh->notThisCxn = NULL ;
-
-  nh->queued = NULL ;
-  nh->queuedTail = NULL ;
-
-  nh->processed = NULL ;
-  nh->processedTail = NULL ;
-
-  nh->deferred = NULL ;
-  nh->deferredTail = NULL ;
-  
-  nh->statsId = 0 ;
-  nh->ChkCxnsId = 0 ;
-  nh->deferredId = 0;
-
-  nh->myTape = newTape (nh->params->peerName,
-                       listenerIsDummy (nh->listener)) ;
-  if (nh->myTape == NULL)
-    {                           /* tape couldn't be locked, probably */
-      free (nh->connections) ;
-      free (nh->cxnActive) ;
-      free (nh->cxnSleeping) ;
-      
-      free (nh) ;
-      return NULL ; /* note we don't free up p */
-    }
-
-  nh->backedUp = false ;
-  nh->backlog = 0 ;
-  nh->deferLen = 0 ;
-
-  nh->loggedBacklog = false ;
-  nh->loggedModeOn = false ;
-  nh->loggedModeOff = false ;
-  nh->notifiedChangedRemBlckd = false ;
-  nh->removeOnReload = false ; /* ready for config file reload */
-  nh->isDynamic = false ;
-
-  nh->artsOffered = 0 ;
-  nh->artsAccepted = 0 ;
-  nh->artsNotWanted = 0 ;
-  nh->artsRejected = 0 ;
-  nh->artsDeferred = 0 ;
-  nh->artsMissing = 0 ;
-  nh->artsToTape = 0 ;
-  nh->artsQueueOverflow = 0 ;
-  nh->artsCxnDrop = 0 ;
-  nh->artsHostSleep = 0 ;
-  nh->artsHostClose = 0 ;
-  nh->artsFromTape = 0 ;
-  nh->artsSizeAccepted = 0 ;
-  nh->artsSizeRejected = 0 ;
-
-  nh->artsProcLastPeriod = 0;
-  nh->secsInLastPeriod = 0;
-  nh->lastCheckPoint = 0;
-  nh->lastSentCheckPoint = 0;
-  nh->lastTotalCheckPoint = 0;
-  nh->maxCxnChk = true;
-  nh->lastMaxCxnTime = time(0);
-  nh->lastChkTime = time(0);
-  nh->nextCxnTimeChk = 30;
-  nh->backlogFilter = ((nh->params->dynBacklogLowWaterMark
-                       + nh->params->dynBacklogHighWaterMark)
-                      /200.0 /(1.0-nh->params->dynBacklogFilter));
-
-  nh->gArtsOffered = 0 ;
-  nh->gArtsAccepted = 0 ;
-  nh->gArtsNotWanted = 0 ;
-  nh->gArtsRejected = 0 ;
-  nh->gArtsDeferred = 0 ;
-  nh->gArtsMissing = 0 ;
-  nh->gArtsToTape = 0 ;
-  nh->gArtsQueueOverflow = 0 ;
-  nh->gArtsCxnDrop = 0 ;
-  nh->gArtsHostSleep = 0 ;
-  nh->gArtsHostClose = 0 ;
-  nh->gArtsFromTape = 0 ;
-  nh->gArtsSizeAccepted = 0 ;
-  nh->gArtsSizeRejected = 0 ;
-  nh->gCxnQueue = 0 ;
-  nh->gNoQueue = 0 ;
-  
-  nh->firstConnectTime = 0 ;
-  nh->connectTime = 0 ;
-  
-  nh->spoolTime = 0 ;
-
-  nh->blNone = 0 ;
-  nh->blFull = 0 ;
-  nh->blQuartile[0] = nh->blQuartile[1] = nh->blQuartile[2] =
-                     nh->blQuartile[3] = 0 ;
-  nh->dlAccum = 0;
-  nh->blAccum = 0;
-  nh->blCount = 0;
-
-
-  nh->maxConnections = 0; /* we currently have no connections allocated */
-
-  /* Note that the following will override the initialCxns specified as
-     maxCxns if we are on non-dyamic feed
-   */
-  hostAlterMaxConnections(nh, nh->params->absMaxConnections,
-                         nh->params->initialConnections, false);
-
-  nh->next = gHostList ;
-  gHostList = nh ;
-  gHostCount++ ;
-
-  if (maxIpNameLen == 0)
-    {
-      start = theTime() ;
-      strlcpy (startTime,ctime (&start),sizeof (startTime)) ;
-      myPid = getpid() ;
-    }
-  
-  if (strlen (nh->params->ipName) > maxIpNameLen)
-    maxIpNameLen = strlen (nh->params->ipName) ;
-  if (strlen (nh->params->peerName) > maxPeerNameLen)
-    maxPeerNameLen = strlen (nh->params->peerName) ;
-  
-  return nh ;
-}
-
-struct sockaddr *hostIpAddr (Host host, int family)
-{
-  int i ;
-  struct sockaddr **newIpAddrPtrs = NULL;
-  struct sockaddr_storage *newIpAddrs = NULL;
-  struct sockaddr *returnAddr;
-
-  ASSERT(host->params != NULL);
-
-  /* check to see if need to look up the host name */
-  if (host->nextIpLookup <= theTime())
-    {
-#ifdef HAVE_INET6
-      int gai_ret;
-      struct addrinfo *res, *p;
-      struct addrinfo hints;
-
-      memset(&hints, 0, sizeof(hints));
-      hints.ai_family = family ? family : AF_UNSPEC;
-      hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
-      hints.ai_flags = AI_ADDRCONFIG;
-#endif
-      if((gai_ret = getaddrinfo(host->params->ipName, NULL, &hints, &res)) != 0
-        || res == NULL)
-       {
-          warn ("%s can't resolve hostname %s: %s", host->params->peerName,
-               host->params->ipName, gai_ret == 0 ? "no addresses returned"
-               : gai_strerror(gai_ret)) ;
-       }
-      else
-       {
-         /* figure number of pointers that need space */
-         i = 0;
-         for ( p = res ; p ; p = p->ai_next ) ++i;
-
-         newIpAddrPtrs = (struct sockaddr **)
-           xmalloc ( (i + 1) * sizeof(struct sockaddr *) );
-
-         newIpAddrs = (struct sockaddr_storage *)
-           xmalloc ( i * sizeof(struct sockaddr_storage) );
-
-         i = 0;
-         /* copy the addresses from the getaddrinfo linked list */
-         for( p = res ; p ; p = p->ai_next )
-           {
-             memcpy( &newIpAddrs[i], p->ai_addr, p->ai_addrlen );
-             newIpAddrPtrs[i] = (struct sockaddr *)(&newIpAddrs[i]);
-             ++i;
-           }
-         newIpAddrPtrs[i] = NULL ;
-         freeaddrinfo( res );
-       }
-#else
-      struct hostent *hostEnt ;
-      struct in_addr ipAddr;
-
-      /* see if the ipName we're given is a dotted quad */
-      if ( !inet_aton (host->params->ipName,&ipAddr) )
-       {
-         if ((hostEnt = gethostbyname (host->params->ipName)) == NULL)
-           {
-              warn ("%s can't resolve hostname %s: %s", host->params->peerName,
-                   host->params->ipName, hstrerror(h_errno)) ;
-           }
-         else
-           {
-             /* figure number of pointers that need space */
-             for (i = 0 ; hostEnt->h_addr_list[i] ; i++)
-               ;
-
-             newIpAddrPtrs = xmalloc ((i + 1) * sizeof(struct sockaddr *));
-             newIpAddrs = xmalloc (i * sizeof(struct sockaddr_storage));
-
-             /* copy the addresses from gethostbyname() static space */
-             i = 0;
-             for (i = 0 ; hostEnt->h_addr_list[i] ; i++)
-               {
-                 make_sin( (struct sockaddr_in *)(&newIpAddrs[i]),
-                       (struct in_addr *)(hostEnt->h_addr_list[i]) );
-                 newIpAddrPtrs[i] = (struct sockaddr *)(&newIpAddrs[i]);
-               }
-             newIpAddrPtrs[i] = NULL ;
-           }
-       }
-      else
-       {
-         newIpAddrPtrs = (struct sockaddr **)
-                 xmalloc ( 2 * sizeof( struct sockaddr * ) );
-         newIpAddrs = (struct sockaddr_storage *)
-                 xmalloc ( sizeof( struct sockaddr_storage ) );
-
-         make_sin( (struct sockaddr_in *)newIpAddrs, &ipAddr );
-         newIpAddrPtrs[0] = (struct sockaddr *)newIpAddrs;
-         newIpAddrPtrs[1] = NULL;
-       }
-#endif
-
-      if (newIpAddrs)
-       {
-         if (host->ipAddrs)
-         {
-           if(host->ipAddrs[0])
-             free (host->ipAddrs[0]);
-           free (host->ipAddrs) ;
-         }
-         host->ipAddrs = newIpAddrPtrs ;
-         host->nextIpAddr = 0 ;
-         host->nextIpLookup = theTime () + dnsExpPeriod ;
-       }
-      else
-       {
-         /* failed to setup new addresses */
-         host->nextIpLookup = theTime () + dnsRetPeriod ;
-       }
-    }
-
-  if (host->ipAddrs)
-    returnAddr = host->ipAddrs[host->nextIpAddr] ;
-  else
-    returnAddr = NULL ;
-
-  return returnAddr ;
-}
-
-
-#ifdef HAVE_INET6
-/*
- * Delete IPv4 addresses from the address list.
- */
-void hostDeleteIpv4Addr (Host host)
-{
-  int i, j;
-
-  if (!host->ipAddrs)
-    return;
-  for (i = 0, j = 0; host->ipAddrs[i]; i++) {
-    if (host->ipAddrs[i]->sa_family != AF_INET)
-      host->ipAddrs[j++] = host->ipAddrs[i];
-  }
-  host->ipAddrs[j] = 0;
-  if (host->nextIpAddr >= j)
-      host->nextIpAddr = 0;
-}
-#endif
-
-
-void hostIpFailed (Host host)
-{
-  if (host->ipAddrs)
-      if (host->ipAddrs[++host->nextIpAddr] == NULL)
-       host->nextIpAddr = 0 ;
-}
-
-
-void gPrintHostInfo (FILE *fp, unsigned int indentAmt)
-{
-  Host h ;
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-  
-  fprintf (fp,"%sGlobal Host list : (count %d) {\n",indent,gHostCount) ;
-  
-  for (h = gHostList ; h != NULL ; h = h->next)
-    printHostInfo (h,fp,indentAmt + INDENT_INCR) ;
-  
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-void printHostInfo (Host host, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  ProcQElem qe ;
-  double cnt = (host->blCount) ? (host->blCount) : 1.0;
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sHost : %p {\n",indent,(void *) host) ;
-
-  if (host == NULL)
-    {
-      fprintf (fp,"%s}\n",indent) ;
-      return ;
-    }
-  
-  fprintf (fp,"%s    peer-name : %s\n",indent,host->params->peerName) ;
-  fprintf (fp,"%s    ip-name : %s\n",indent,host->params->ipName) ;
-#ifdef HAVE_INET6
-  if (host->params->family == AF_INET6)
-    {
-      fprintf (fp,"%s    bindaddress : none\n",indent);
-    }
-  else
-#endif
-    {
-      fprintf (fp,"%s    bindaddress : %s\n",indent,
-      host->params->bindAddr == NULL ||
-      host->params->bindAddr->sin_addr.s_addr == 0 ? "any" :
-        inet_ntoa(host->params->bindAddr->sin_addr));
-    }
-#ifdef HAVE_INET6
-  if (host->params->family == AF_INET)
-    {
-      fprintf (fp,"%s    bindaddress6 : none\n",indent);
-    }
-  else
-    {
-      char buf[128];
-      fprintf (fp,"%s    bindaddress6 : %s\n",indent,
-        host->params->bindAddr6 == NULL ? "any" :
-          inet_ntop(AF_INET6, &host->params->bindAddr6->sin6_addr,
-            buf, sizeof(buf)));
-    }
-#endif
-  fprintf (fp,"%s    abs-max-connections : %d\n",indent,
-          host->params->absMaxConnections) ;
-  fprintf (fp,"%s    active-connections : %d\n",indent,host->activeCxns) ;
-  fprintf (fp,"%s    sleeping-connections : %d\n",indent,host->sleepingCxns) ;
-  fprintf (fp,"%s    initial-connections : %d\n",indent,
-          host->params->initialConnections) ;
-  fprintf (fp,"%s    want-streaming : %s\n",indent,
-           boolToString (host->params->wantStreaming)) ;
-  fprintf (fp,"%s    drop-deferred : %s\n",indent,
-           boolToString (host->params->dropDeferred)) ;
-  fprintf (fp,"%s    min-queue-connection : %s\n",indent,
-           boolToString (host->params->minQueueCxn)) ;
-  fprintf (fp,"%s    remote-streams : %s\n",indent,
-           boolToString (host->remoteStreams)) ;
-  fprintf (fp,"%s    max-checks : %d\n",indent,host->params->maxChecks) ;
-  fprintf (fp,"%s    article-timeout : %d\n",indent,
-          host->params->articleTimeout) ;
-  fprintf (fp,"%s    response-timeout : %d\n",indent,
-          host->params->responseTimeout) ;
-  fprintf (fp,"%s    close-period : %d\n",indent,
-          host->params->closePeriod) ;
-  fprintf (fp,"%s    port : %d\n",indent,host->params->portNum) ;
-  fprintf (fp,"%s    dynamic-method : %d\n",indent,
-          host->params->dynamicMethod) ;
-  fprintf (fp,"%s    dynamic-backlog-filter : %2.1f\n",indent,
-          host->params->dynBacklogFilter) ;
-  fprintf (fp,"%s    dynamic-backlog-lwm : %2.1f\n",indent,
-          host->params->dynBacklogLowWaterMark) ;
-  fprintf (fp,"%s    dynamic-backlog-hwm : %2.1f\n",indent,
-          host->params->dynBacklogHighWaterMark) ;
-  fprintf (fp,"%s    no-check on : %2.1f\n",indent,
-          host->params->lowPassHigh) ;
-  fprintf (fp,"%s    no-check off : %2.1f\n",indent,
-          host->params->lowPassLow) ;
-  fprintf (fp,"%s    no-check filter : %2.1f\n",indent,
-          host->params->lowPassFilter) ;
-  fprintf (fp,"%s    backlog-limit : %d\n",indent,
-          host->params->backlogLimit) ;
-  fprintf (fp,"%s    backlog-limit-high : %d\n",indent,
-          host->params->backlogLimitHigh) ;
-  fprintf (fp,"%s    backlog-factor : %2.1f\n",indent,
-          host->params->backlogFactor) ;
-  fprintf (fp,"%s    max-connections : %d\n",indent,
-          host->maxConnections) ;
-  fprintf (fp,"%s    backlog-feed-first : %s\n",indent,
-           boolToString (host->params->backlogFeedFirst)) ;
-
-
-  fprintf (fp,"%s    statistics-id : %d\n",indent,host->statsId) ;
-  fprintf (fp,"%s    ChkCxns-id : %d\n",indent,host->ChkCxnsId) ;
-  fprintf (fp,"%s    deferred-id : %d\n",indent,host->deferredId) ;
-  fprintf (fp,"%s    backed-up : %s\n",indent,boolToString (host->backedUp));
-  fprintf (fp,"%s    backlog : %d\n",indent,host->backlog) ;
-  fprintf (fp,"%s    deferLen : %d\n",indent,host->deferLen) ;
-  fprintf (fp,"%s    loggedModeOn : %s\n",indent,
-           boolToString (host->loggedModeOn)) ;
-  fprintf (fp,"%s    loggedModeOff : %s\n",indent,
-           boolToString (host->loggedModeOff)) ;
-  fprintf (fp,"%s    logged-backlog : %s\n",indent,
-           boolToString (host->loggedBacklog)) ;
-  fprintf (fp,"%s    streaming-type changed : %s\n",indent,
-           boolToString (host->notifiedChangedRemBlckd)) ;
-  fprintf (fp,"%s    articles offered : %d\n",indent,host->artsOffered) ;
-  fprintf (fp,"%s    articles accepted : %d\n",indent,host->artsAccepted) ;
-  fprintf (fp,"%s    articles not wanted : %d\n",indent,
-           host->artsNotWanted) ;
-  fprintf (fp,"%s    articles rejected : %d\n",indent,host->artsRejected);
-  fprintf (fp,"%s    articles deferred : %d\n",indent,host->artsDeferred) ;
-  fprintf (fp,"%s    articles missing : %d\n",indent,host->artsMissing) ;
-  fprintf (fp,"%s    articles spooled : %d\n",indent,host->artsToTape) ;
-  fprintf (fp,"%s      because of queue overflow : %d\n",indent,
-           host->artsQueueOverflow) ;
-  fprintf (fp,"%s      when the we closed the host : %d\n",indent,
-           host->artsHostClose) ;
-  fprintf (fp,"%s      because the host was asleep : %d\n",indent,
-           host->artsHostSleep) ;
-  fprintf (fp,"%s    articles unspooled : %d\n",indent,host->artsFromTape) ;
-  fprintf (fp,"%s    articles requeued from dropped connections : %d\n",indent,
-           host->artsCxnDrop) ;
-
-  fprintf (fp,"%s    process articles offered : %d\n",indent,
-           host->gArtsOffered) ;
-  fprintf (fp,"%s    process articles accepted : %d\n",indent,
-           host->gArtsAccepted) ;
-  fprintf (fp,"%s    process articles not wanted : %d\n",indent,
-           host->gArtsNotWanted) ;
-  fprintf (fp,"%s    process articles rejected : %d\n",indent,
-           host->gArtsRejected);
-  fprintf (fp,"%s    process articles deferred : %d\n",indent,
-           host->gArtsDeferred) ;
-  fprintf (fp,"%s    process articles missing : %d\n",indent,
-           host->gArtsMissing) ;
-  fprintf (fp,"%s    process articles spooled : %d\n",indent,
-           host->gArtsToTape) ;
-  fprintf (fp,"%s      because of queue overflow : %d\n",indent,
-           host->gArtsQueueOverflow) ;
-  fprintf (fp,"%s      when the we closed the host : %d\n",indent,
-           host->gArtsHostClose) ;
-  fprintf (fp,"%s      because the host was asleep : %d\n",indent,
-           host->gArtsHostSleep) ;
-  fprintf (fp,"%s    process articles unspooled : %d\n",indent,
-           host->gArtsFromTape) ;
-  fprintf (fp,"%s    process articles requeued from dropped connections : %d\n",
-           indent, host->gArtsCxnDrop) ;
-
-  fprintf (fp,"%s    average (mean) defer length : %.1f\n", indent,
-          (double) host->dlAccum / cnt) ;
-  fprintf (fp,"%s    average (mean) queue length : %.1f\n", indent,
-           (double) host->blAccum / cnt) ;
-  fprintf (fp,"%s      percentage of the time empty : %.1f\n", indent,
-           100.0 * host->blNone / cnt) ;
-  fprintf (fp,"%s      percentage of the time >0%%-25%% : %.1f\n", indent,
-           100.0 * host->blQuartile[0] / cnt) ;
-  fprintf (fp,"%s      percentage of the time 25%%-50%% : %.1f\n", indent,
-           100.0 * host->blQuartile[1] / cnt) ;
-  fprintf (fp,"%s      percentage of the time 50%%-75%% : %.1f\n", indent,
-           100.0 * host->blQuartile[2] / cnt) ;
-  fprintf (fp,"%s      percentage of the time 75%%-<100%% : %.1f\n", indent,
-           100.0 * host->blQuartile[3] / cnt) ;
-  fprintf (fp,"%s      percentage of the time full : %.1f\n", indent,
-           100.0 * host->blFull / cnt) ;
-  fprintf (fp,"%s      number of samples : %u\n", indent, host->blCount) ;
-
-  fprintf (fp,"%s    firstConnectTime : %s",indent,
-           ctime (&host->firstConnectTime));
-  fprintf (fp,"%s    connectTime : %s",indent,ctime (&host->connectTime));
-  fprintf (fp,"%s    spoolTime : %s",indent,ctime (&host->spoolTime)) ;
-  fprintf (fp,"%s    last-spool-time : %s",indent,
-           ctime (&host->lastSpoolTime)) ;
-  
-#if 0
-  fprintf (fp,"%s    tape {\n",indent) ;
-  printTapeInfo (host->myTape,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-#else
-  fprintf (fp,"%s    tape : %p\n",indent,(void *) host->myTape) ;
-#endif
-  
-  fprintf (fp,"%s    QUEUED articles {\n",indent) ;
-  for (qe = host->queued ; qe != NULL ; qe = qe->next)
-    {
-#if 0
-      printArticleInfo (qe->article,fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s    %p\n",indent,(void *) qe->article) ;
-#endif
-    }
-  
-  fprintf (fp,"%s    }\n",indent) ;
-  
-  fprintf (fp,"%s    IN PROCESS articles {\n",indent) ;
-  for (qe = host->processed ; qe != NULL ; qe = qe->next)
-    {
-#if 0
-      printArticleInfo (qe->article,fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s    %p\n",indent,(void *) qe->article) ;
-#endif
-    }
-  
-  fprintf (fp,"%s    }\n",indent) ;
-  fprintf (fp,"%s    DEFERRED articles {\n",indent) ;
-  for (qe = host->deferred ; qe != NULL ; qe = qe->next)
-    {
-#if 0
-       printArticleInfo (qe->article,fp,indentAmt + INDENT_INCR) ;
-#else
-       fprintf (fp,"%s    %p\n",indent,(void *) qe->article) ;
-#endif
-    }
-
-  fprintf (fp,"%s    }\n",indent) ;
-  fprintf (fp,"%s    DEFERRED articles {\n",indent) ;
-  for (qe = host->deferred ; qe != NULL ; qe = qe->next)
-    {
-#if 0
-      printArticleInfo (qe->article,fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s    %p\n",indent,(void *) qe->article) ;
-#endif
-    }
-  
-  fprintf (fp,"%s    }\n",indent) ;
-
-  
-  
-  fprintf (fp,"%s    Connections {\n",indent) ;
-  for (i = 0 ; i < host->maxConnections ; i++)
-    {
-#if 0
-      if (host->connections[i] != NULL)
-        printCxnInfo (*cxn,fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s        %p\n",indent,(void *) host->connections[i]) ;
-#endif
-    }
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    Active Connections {\n%s        ",indent,indent) ;
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->cxnActive[i])
-      fprintf (fp," [%d:%p]",i,(void *) host->connections[i]) ;
-  fprintf (fp,"\n%s    }\n",indent) ;
-
-  fprintf (fp,"%s    Sleeping Connections {\n%s        ",indent,indent) ;
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->cxnSleeping[i])
-      fprintf (fp," [%d:%p]",i,(void *) host->connections[i]) ;
-  fprintf (fp,"\n%s    }\n",indent) ;
-
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-
-
-
-
-\f
-/* close down all the connections of the Host. All articles that are in
- * processes are still pushed out and then a QUIT is issued. The Host will
- * also spool all inprocess articles to tape incase the process is about to
- * be killed (they'll be refused next time around). When all Connections
- * report that they're gone, then the Host will delete itself.
- */
-void hostClose (Host host)
-{
-  unsigned int i ;
-  unsigned int cxnCount ;
-
-  d_printf (1,"Closing host %s\n",host->params->peerName) ;
-  
-  queuesToTape (host) ;
-  delTape (host->myTape) ;
-  host->myTape = NULL ;
-  
-  hostLogStats (host,true) ;
-
-  clearTimer (host->statsId) ;
-  clearTimer (host->ChkCxnsId) ;
-  clearTimer (host->deferredId) ;
-  
-  host->connectTime = 0 ;
-
-  /* when we call cxnTerminate() on the last Connection, the Host objects
-     will end up getting deleted out from under us (via hostCxnGone()). If
-     we are running with a malloc that scribbles over memory after freeing
-     it, then we'd fail in the second for loop test. Trying to access
-     host->maxConnections. */
-  for (i = 0, cxnCount = 0 ; i < host->maxConnections ; i++) 
-    cxnCount += (host->connections [i] != NULL ? 1 : 0) ;
-  for (i = 0 ; i < cxnCount ; i++)
-    if (host->connections[i] != NULL)
-      cxnTerminate (host->connections [i]) ;
-}
-
-\f
-/*
- * check if host should get more connections opened, or some closed...
- */
-void hostChkCxns(TimeoutId tid UNUSED, void *data) {
-  Host host = (Host) data;
-  unsigned int currArticles, currSentArticles, currTotalArticles, newMaxCxns ;
-  double lastAPS, currAPS, percentTaken, ratio ;
-  double backlogRatio, backlogMult;
-
-  if(!host->maxCxnChk)
-    return;
-
-  ASSERT(host->params != NULL);
-
-  if(host->secsInLastPeriod > 0) 
-    lastAPS = host->artsProcLastPeriod / (host->secsInLastPeriod * 1.0);
-  else
-    lastAPS = host->artsProcLastPeriod * 1.0;
-
-  newMaxCxns = host->maxConnections;
-
-  currArticles =        (host->gArtsAccepted + host->gArtsRejected +
-                        (host->gArtsNotWanted / 4)) - host->lastCheckPoint ;
-
-  host->lastCheckPoint = (host->gArtsAccepted + host->gArtsRejected +
-                        (host->gArtsNotWanted / 4));
-
-  currSentArticles = host->gArtsAccepted + host->gArtsRejected
-                      - host->lastSentCheckPoint ;
-
-  host->lastSentCheckPoint = host->gArtsAccepted + host->gArtsRejected;
-
-  currTotalArticles = host->gArtsAccepted + host->gArtsRejected
-                      + host->gArtsRejected + host->gArtsQueueOverflow
-                     - host->lastTotalCheckPoint ;
-
-  host->lastTotalCheckPoint = host->gArtsAccepted + host->gArtsRejected
-                      + host->gArtsRejected + host->gArtsQueueOverflow ;
-
-  currAPS = currArticles / (host->nextCxnTimeChk * 1.0) ;
-
-  percentTaken = currSentArticles * 1.0 /
-    ((currTotalArticles==0)?1:currTotalArticles);
-
-  /* Get how full the queue is currently */
-  backlogRatio = (host->backlog * 1.0 / hostHighwater);
-  backlogMult = 1.0/(1.0-host->params->dynBacklogFilter);
-
-  d_printf(1,"%s hostChkCxns - entry filter=%3.3f blmult=%3.3f blratio=%3.3f\n",host->params->peerName,host->backlogFilter, backlogMult, backlogRatio);
-
-  ratio = 0.0; /* ignore APS by default */
-
-  switch (host->params->dynamicMethod)
-    {
-      case METHOD_COMBINED:
-        /* When a high % of articles is being taken, take notice of the
-        * APS values. However for smaller %s, quickly start to ignore this
-        * and concentrate on queue sizes
-        */
-        ratio = percentTaken * percentTaken;
-       /* nobreak; */
-      case METHOD_QUEUE:
-        /* backlogFilter is an IIR filtered version of the backlogRatio.
-        */
-        host->backlogFilter *= host->params->dynBacklogFilter;
-       /* Penalise anything over the backlog HWM twice as severely
-        * (otherwise we end up feeding some sites constantly
-        * just below the HWM. This way random noise makes
-        * such sites jump to one more connection
-        *
-        * Use factor (1-ratio) so if ratio is near 1 we ignore this
-        */
-       if (backlogRatio>host->params->dynBacklogLowWaterMark/100.0)
-         host->backlogFilter += (backlogRatio+1.0)/2.0 * (1.0-ratio);
-       else
-         host->backlogFilter += backlogRatio * (1.0-ratio);
-
-       /*
-        * Now bump it around for APS too
-        */
-       if ((currAPS - lastAPS) >= 0.1)
-         host->backlogFilter += ratio*((currAPS - lastAPS) + 1.0);
-       else if ((currAPS - lastAPS) < -.2)
-         host->backlogFilter -= ratio;
-       
-       d_printf(1,"%s hostChkCxns - entry hwm=%3.3f lwm=%3.3f new=%3.3f [%3.3f,%3.3f]\n",
-              host->params->peerName,host->params->dynBacklogHighWaterMark,
-              host->params->dynBacklogLowWaterMark,host->backlogFilter, 
-              (host->params->dynBacklogLowWaterMark * backlogMult / 100.0),
-              (host->params->dynBacklogHighWaterMark * backlogMult / 100.0));
-
-        if (host->backlogFilter <
-           (host->params->dynBacklogLowWaterMark * backlogMult / 100.0))
-         newMaxCxns--;
-       else if (host->backlogFilter >
-                (host->params->dynBacklogHighWaterMark * backlogMult / 100.0))
-         newMaxCxns++;
-       break;
-      case METHOD_STATIC:
-       /* well not much to do, just check maxConnection = absMaxConnections */
-       ASSERT (host->maxConnections == MAXCONLIMIT(host->params->absMaxConnections));
-       break;
-      case METHOD_APS:
-       if ((currAPS - lastAPS) >= 0.1)
-         newMaxCxns += (int)(currAPS - lastAPS) + 1 ;
-       else if ((currAPS - lastAPS) < -.2)
-         newMaxCxns--;
-       break;
-    }
-
-  d_printf(1, "hostChkCxns: Chngs %f\n", currAPS - lastAPS);
-
-  if (newMaxCxns < 1) newMaxCxns=1;
-  if (newMaxCxns > MAXCONLIMIT(host->params->absMaxConnections))
-    newMaxCxns = MAXCONLIMIT(host->params->absMaxConnections);
-
-  if (newMaxCxns != host->maxConnections)
-    {
-      notice ("%s hostChkCxns - maxConnections was %d now %d",
-              host->params->peerName, host->maxConnections,newMaxCxns);
-      host->backlogFilter= ((host->params->dynBacklogLowWaterMark
-                            + host->params->dynBacklogHighWaterMark)
-                           /200.0 * backlogMult);
-      host->artsProcLastPeriod = currArticles ;
-      host->secsInLastPeriod = host->nextCxnTimeChk ;
-
-      /* Alter MaxConnections and in doing so ensure we connect new
-        cxns immediately if we are adding stuff
-       */
-      hostAlterMaxConnections(host, host->params->absMaxConnections,
-                             newMaxCxns, true);
-  }
-
-  if(host->nextCxnTimeChk <= 240) host->nextCxnTimeChk *= 2;
-  else host->nextCxnTimeChk = 300;
-  d_printf(1, "prepareSleep hostChkCxns, %d\n", host->nextCxnTimeChk);
-  host->ChkCxnsId = prepareSleep(hostChkCxns, host->nextCxnTimeChk, host);
-}
-
-\f
-/*
- * have the Host transmit the Article if possible.
- */
-void hostSendArticle (Host host, Article article)
-{
-  ASSERT(host->params != NULL);
-  if (host->spoolTime > 0)
-    {                           /* all connections are asleep */
-      host->artsHostSleep++ ;
-      host->gArtsHostSleep++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape, article) ;
-      return ;
-    }
-
-  /* at least one connection is feeding or waiting and there's no backlog */
-  if (host->queued == NULL)
-    {
-      unsigned int idx ;
-      Article extraRef ;
-      Connection cxn = NULL ;
-      
-      extraRef = artTakeRef (article) ; /* the referrence we give away */
-      
-      /* stick on the queue of articles we've handed off--we're hopeful. */
-      queueArticle (article,&host->processed,&host->processedTail, 0) ;
-
-      if (host->params->minQueueCxn) {
-        Connection x_cxn = NULL ;
-        unsigned int x_queue = host->params->maxChecks + 1 ;
-
-        for (idx = 0 ; x_queue > 0 && idx < host->maxConnections ; idx++)
-          if ((cxn = host->connections[idx]) != host->notThisCxn) {
-            if (!host->cxnActive [idx]) {
-              if (!host->cxnSleeping [idx]) {
-                if (cxnTakeArticle (cxn, extraRef)) {
-                  host->gNoQueue++ ;
-                  return ;
-                } else
-                  d_printf (1,"%s Inactive connection %d refused an article\n",
-                           host->params->peerName,idx) ;
-              }
-            } else {
-              unsigned int queue = host->params->maxChecks - cxnQueueSpace (cxn) ;
-              if (queue < x_queue) {
-                x_queue = queue ;
-                x_cxn = cxn ;
-              }
-            }
-          }
-
-        if (x_cxn != NULL && cxnTakeArticle (x_cxn, extraRef)) {
-          if (x_queue == 0) host->gNoQueue++ ;
-          else              host->gCxnQueue += x_queue ;
-          return ;
-        }
-
-      } else {
-
-        /* first we try to give it to one of our active connections. We
-           simply start at the bottom and work our way up. This way
-           connections near the end of the list will get closed sooner from
-           idleness. */
-        for (idx = 0 ; idx < host->maxConnections ; idx++)
-          {
-            if (host->cxnActive [idx] &&
-                (cxn = host->connections[idx]) != host->notThisCxn &&
-                cxnTakeArticle (cxn, extraRef)) {
-              unsigned int queue = host->params->maxChecks - cxnQueueSpace (cxn) - 1;
-              if (queue == 0) host->gNoQueue++ ;
-              else            host->gCxnQueue += queue ;
-             return ;
-            }
-          }
-
-        /* Wasn't taken so try to give it to one of the waiting connections. */
-        for (idx = 0 ; idx < host->maxConnections ; idx++)
-          if (!host->cxnActive [idx] && !host->cxnSleeping [idx] &&
-              (cxn = host->connections[idx]) != host->notThisCxn)
-            {
-              if (cxnTakeArticle (cxn, extraRef)) {
-                unsigned int queue = host->params->maxChecks - cxnQueueSpace (cxn) - 1;
-                if (queue == 0) host->gNoQueue++ ;
-                else            host->gCxnQueue += queue ;
-                return ;
-              } else
-                d_printf (1,"%s Inactive connection %d refused an article\n",
-                         host->params->peerName,idx) ;
-            }
-      }
-
-      /* this'll happen if all connections are feeding and all
-         their queues are full, or if those not feeding are asleep. */
-      d_printf (1, "Couldn't give the article to a connection\n") ;
-      
-      delArticle (extraRef) ;
-          
-      remArticle (article,&host->processed,&host->processedTail) ;
-      if (!cxnCheckstate (cxn))
-        {
-          host->artsToTape++ ;
-          host->gArtsToTape++ ;
-          procArtsToTape++ ;
-          tapeTakeArticle (host->myTape,article) ;
-          return ;
-        }
-    }
-
-  /* either all the per connection queues were full or we already had
-     a backlog, so there was no sense in checking. */
-  queueArticle (article,&host->queued,&host->queuedTail, 0) ;
-    
-  host->backlog++ ;
-  backlogToTape (host) ;
-}
-
-
-
-
-
-
-\f
-/*
- * called by the Host's connection when the remote is refusing postings
- * from us becasue we're not allowed (banner code 400).
- */
-void hostCxnBlocked (Host host, Connection cxn, char *reason)
-{
-  ASSERT(host->params != NULL);
-#ifndef NDEBUG
-  {
-    unsigned int i ;
-    
-    for (i = 0 ; i < host->maxConnections ; i++)
-      if (host->connections [i] == cxn)
-        ASSERT (host->cxnActive [i] == false) ;
-  }
-#endif
-
-  if (host->blockedReason == NULL)
-    host->blockedReason = xstrdup (reason) ;
-  
-  if (host->activeCxns == 0 && host->spoolTime == 0)
-    {
-      host->blockedCxn = cxn ;  /* to limit log notices */
-      notice ("%s remote cannot accept articles initial: %s",
-              host->params->peerName, reason) ;
-    }
-  else if (host->activeCxns > 0 && !host->notifiedChangedRemBlckd)
-    {
-      notice ("%s remote cannot accept articles change: %s",
-              host->params->peerName, reason) ;
-      host->notifiedChangedRemBlckd = true ;
-    }
-  else if (host->spoolTime != 0 && host->blockedCxn == cxn)
-    {
-      notice ("%s remote cannot accept articles still: %s",
-              host->params->peerName, reason) ;
-    }
-  
-}
-
-
-
-
-
-
-\f
-/*
- * Called by the Connection when it gets a response back to the MODE
- * STREAM command. It's now that we consider the connection usable.
- */
-void hostRemoteStreams (Host host, Connection cxn, bool doesStreaming)
-{
-  unsigned int i ;
-
-  host->blockedCxn = NULL ;
-  if (host->blockedReason != NULL)
-    free (host->blockedReason) ;
-  host->blockedReason = NULL ;
-  
-  /* we may have told the connection to quit while it was in the middle
-     of connecting */
-  if (amClosing (host))
-    return ;
-  
-  if (host->connectTime == 0)   /* first connection for this cycle. */
-    {
-      if (doesStreaming && host->params->wantStreaming)
-        notice ("%s remote MODE STREAM", host->params->peerName) ;
-      else if (doesStreaming)
-        notice ("%s remote MODE STREAM disabled", host->params->peerName) ;
-      else
-        notice ("%s remote MODE STREAM failed", host->params->peerName) ;
-
-      if (host->spoolTime > 0)
-        hostStopSpooling (host) ;
-
-      /* set up the callback for statistics logging. */
-      if (host->statsId != 0)
-        clearTimer (host->statsId) ;
-      host->statsId = prepareSleep (hostStatsTimeoutCbk, statsPeriod, host) ;
-
-      if (host->ChkCxnsId != 0)
-      clearTimer (host->ChkCxnsId);
-      host->ChkCxnsId = prepareSleep (hostChkCxns, 30, host) ;
-
-      host->remoteStreams = (host->params->wantStreaming ? doesStreaming : false) ;
-
-      host->connectTime = theTime() ;
-      if (host->firstConnectTime == 0)
-        host->firstConnectTime = host->connectTime ;
-    }
-  else if (host->remoteStreams != doesStreaming && host->params->wantStreaming)
-    notice ("%s remote MODE STREAM change", host->params->peerName) ;
-
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->connections [i] == cxn)
-      {
-        host->cxnActive [i] = true ;
-        if (host->cxnSleeping [i])
-          host->sleepingCxns-- ;
-        host->cxnSleeping [i] = false ;
-        break ;
-      }
-
-  ASSERT (i != host->maxConnections) ;
-
-  host->activeCxns++ ;
-
-  hostLogStatus () ;
-}
-
-
-
-
-
-
-\f
-/*
- * Called by the connection when it is no longer connected to the
- * remote. Perhaps due to getting a code 400 to an IHAVE, or due to a
- * periodic close.
- */
-void hostCxnDead (Host host, Connection cxn)
-{
-  unsigned int i ;
-    
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->connections [i] == cxn)
-      {
-        if (host->cxnActive [i]) /* won't be active if got 400 on banner */
-          {
-            host->cxnActive [i] = false ;
-            host->activeCxns-- ;
-
-            if (!amClosing (host) && host->activeCxns == 0)
-              {
-                clearTimer (host->statsId) ;
-                clearTimer (host->ChkCxnsId) ;
-                hostLogStats (host,true) ;
-                host->connectTime = 0 ;
-              }
-          }
-        else if (host->cxnSleeping [i]) /* cxnNuke can be called on sleepers  */
-          {
-            host->cxnSleeping [i] = false ;
-            host->sleepingCxns-- ;
-          }
-
-        break ;
-      }
-
-  ASSERT (i < host->maxConnections) ;
-  hostLogStatus () ;
-}
-
-
-
-
-
-
-\f
-/*
- * Called by the Connection when it is going to sleep so the Host won't
- * bother trying to give it Articles
- */
-void hostCxnSleeping (Host host, Connection cxn)
-{
-  unsigned int i ;
-
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->connections [i] == cxn)
-      {
-        if (!host->cxnSleeping [i]) 
-          {
-            host->cxnSleeping [i] = true ;
-            host->sleepingCxns++ ;
-          }
-
-        if (host->spoolTime == 0 && host->sleepingCxns >= host->maxConnections)
-          hostStartSpooling (host) ;
-
-        break ;
-      }
-
-  ASSERT (i < host->maxConnections) ;
-
-  hostLogStatus () ;
-}
-
-
-
-
-
-
-\f
-/*
- * Called by the Connection when it goes into the waiting state.
- */
-void hostCxnWaiting (Host host, Connection cxn)
-{
-  unsigned int i ;
-
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->connections [i] == cxn)
-      {
-        if (host->cxnSleeping [i])
-          host->sleepingCxns-- ;
-        host->cxnSleeping [i] = false ;
-        break ;
-      }
-
-  ASSERT (i < host->maxConnections) ;
-
-  if (host->spoolTime > 0)
-    hostStopSpooling (host) ;
-
-  hostLogStatus () ;
-}
-
-
-
-
-
-
-\f
-/*
- * Called by the Connection when it is about to delete itself.
- */
-bool hostCxnGone (Host host, Connection cxn)
-{
-  unsigned int i;
-  bool oneThere = false ;
-  char msgstr[SMBUF] ;
-
-  /* forget about the Connection and see if we are still holding any live
-     connections still. */
-  for (i = 0 ; i < host->maxConnections ; i++)
-    if (host->connections [i] == cxn)
-      {
-        if (!amClosing (host))
-          {
-            warn ("%s:%d connection vanishing", host->params->peerName, i) ;
-          }
-        host->connections [i] = NULL ;
-        if (host->cxnActive [i])
-          {
-            host->cxnActive [i] = false ;
-            host->activeCxns-- ;
-          }
-        else if (host->cxnSleeping [i])
-          {
-            host->cxnSleeping [i] = false ;
-            host->sleepingCxns-- ;
-          }
-      }
-    else if (host->connections [i] != NULL)
-      oneThere = true ;
-
-  /* remove the host if it has no connexions */
-  if ( !oneThere )
-    {
-      time_t now = theTime() ;
-      unsigned int hostsLeft ;
-
-      if (host->firstConnectTime > 0) {
-        snprintf(msgstr, sizeof(msgstr), "accsize %.0f rejsize %.0f",
-                 host->gArtsSizeAccepted, host->gArtsSizeRejected);
-        notice ("%s global seconds %ld offered %d accepted %d refused %d"
-                " rejected %d missing %d %s spooled %d unspooled %d",
-                host->params->peerName, (long) (now - host->firstConnectTime),
-                host->gArtsOffered, host->gArtsAccepted,
-                host->gArtsNotWanted, host->gArtsRejected,
-                host->gArtsMissing, msgstr,
-                host->gArtsToTape, host->gArtsFromTape) ;
-      }
-
-      hostsLeft = listenerHostGone (host->listener, host) ;
-      delHost (host) ;
-
-      if (hostsLeft == 0) {
-        snprintf(msgstr, sizeof(msgstr), "accsize %.0f rejsize %.0f",
-                 procArtsSizeAccepted, procArtsSizeRejected);
-        notice ("ME global seconds %ld offered %ld accepted %ld refused %ld"
-                " rejected %ld missing %ld %s spooled %ld unspooled %ld",
-                (long) (now - start),
-                procArtsOffered, procArtsAccepted,
-                procArtsNotWanted,procArtsRejected,
-                procArtsMissing, msgstr,
-                procArtsToTape, procArtsFromTape) ;
-      }
-      
-      /* return true if that was the last host */
-      return (hostsLeft == 0 ? true : false) ;
-    }
-
-  /* return false because there is still at least one host (this one) */
-  return false ;
-}
-
-
-
-
-
-
-\f
-/*
- * The connections has offered an article to the remote.
- */
-void hostArticleOffered (Host host, Connection cxn UNUSED)
-{
-  host->artsOffered++ ;
-  host->gArtsOffered++ ;
-  procArtsOffered++ ;
-}
-
-
-
-
-
-
-\f
-/*
- * Article was succesfully transferred.
- */
-void hostArticleAccepted (Host host, Connection cxn, Article article)
-{
-  const char *filename = artFileName (article) ;
-  const char *msgid = artMsgId (article) ;
-  double len = artSize (article);
-
-  d_printf (5,"Article %s (%s) was transferred\n", msgid, filename) ;
-  
-  host->artsAccepted++ ;
-  host->gArtsAccepted++ ;
-  procArtsAccepted++ ;
-  host->artsSizeAccepted += len ;
-  host->gArtsSizeAccepted += len ;
-  procArtsSizeAccepted += len ;
-
-  /* host has two references to the article here... the parameter `article'
-     and the queue */
-
-  delArticle (article) ;        /* drop the parameter reference */
-
-  if (!amClosing (host))
-    articleGone (host,cxn,article) ; /* and the one in the queue */
-}
-
-
-
-
-
-
-\f
-/*
- * remote said no thanks to an article.
- */
-void hostArticleNotWanted (Host host, Connection cxn, Article article)
-{
-  const char *filename = artFileName (article) ;
-  const char *msgid = artMsgId (article) ;
-
-  d_printf (5,"Article %s (%s) was not wanted\n", msgid, filename) ;
-  
-  host->artsNotWanted++ ;
-  host->gArtsNotWanted++ ;
-  procArtsNotWanted++ ;
-  
-  
-  /* host has two references to the article here... `article' and the
-     queue */
-
-  delArticle (article) ;        /* drop the `article' reference */
-  
-  if (!amClosing (host)) 
-    articleGone (host,cxn,article) ; /* and the one in the queue */
-}
-
-
-
-
-
-
-\f
-/*
- * remote rejected the article after it was was transferred
- */
-void hostArticleRejected (Host host, Connection cxn, Article article) 
-{
-  const char *filename = artFileName (article) ;
-  const char *msgid = artMsgId (article) ;
-  double len = artSize (article);
-
-  d_printf (5,"Article %s (%s) was rejected\n", msgid, filename) ;
-  
-  host->artsRejected++ ;
-  host->gArtsRejected++ ;
-  procArtsRejected++ ;
-  host->artsSizeRejected += len ;
-  host->gArtsSizeRejected += len ;
-  procArtsSizeRejected += len ;
-
-  /* host has two references to the article here... `article' and the queue */
-
-  delArticle (article) ;        /* drop the `article' reference */
-
-  if (!amClosing (host))
-    articleGone (host,cxn,article) ;
-}
-
-
-
-
-
-
-\f
-/*
- * The remote wants us to retry the article later.
- */
-void hostArticleDeferred (Host host, Connection cxn, Article article) 
-{
-  host->artsDeferred++ ;
-  host->gArtsDeferred++ ;
-  procArtsDeferred++ ;
-
-
-  if (!amClosing (host))
-    {
-      Article extraRef ;
-      int deferTimeout = 5 ; /* XXX - should be tunable */
-      time_t now = theTime() ;
-
-      extraRef = artTakeRef (article) ; /* hold a reference until requeued */
-      articleGone (host,cxn,article) ; /* drop from the queue */
-
-      if (host->deferred == NULL)
-       {
-           if (host->deferredId != 0)
-             clearTimer (host->deferredId) ;
-           host->deferredId = prepareSleep (hostDeferredArtCbk, deferTimeout,
-                                            host) ;
-        }
-
-      queueArticle (article,&host->deferred,&host->deferredTail,
-                   now + deferTimeout) ;
-      host->deferLen++ ;
-      backlogToTape (host) ;
-      delArticle (extraRef) ;
-    }
-  else
-    delArticle(article); /*drop parameter reference if not sent to tape*/
-}
-
-
-
-
-
-
-\f
-/*
- * The Connection is giving the article back to the Host, but it doesn't
- * want a new one in return.
- */
-void hostTakeBackArticle (Host host, Connection cxn UNUSED, Article article) 
-{
-  if (!amClosing (host)) 
-    {
-      Article extraRef ;
-
-      host->artsCxnDrop++ ;
-      host->gArtsCxnDrop++ ;
-      extraRef = artTakeRef (article) ; /* hold a reference until requeued */
-      articleGone (host,NULL,article) ; /* drop from the queue */
-      host->notThisCxn = cxn;
-      hostSendArticle (host, article) ; /* requeue it */
-      host->notThisCxn = NULL;
-      delArticle (extraRef) ;
-    }
-  else
-    delArticle(article); /*drop parameter reference if not sent to tape*/
-
-}
-
-
-
-
-
-
-\f
-/*
- * The disk file for the article is no longer valid
- */
-void hostArticleIsMissing (Host host, Connection cxn, Article article)
-{
-  const char *filename = artFileName (article) ;
-  const char *msgid = artMsgId (article) ;
-
-  d_printf (5, "%s article is missing %s %s\n", host->params->peerName, msgid, filename) ;
-    
-  host->artsMissing++ ;
-  host->gArtsMissing++ ;
-  procArtsMissing++ ;
-
-  /* host has two references to the article here... `article' and the
-     queue */
-
-  delArticle (article) ;        /* drop the `article' reference */
-
-  if (!amClosing (host))
-    articleGone (host,cxn,article) ; /* and the one in the queue */
-}
-
-
-
-
-
-
-\f
-/* The Connection wants something to do. This is called by the Connection
- * after it has transferred an article. This is what keeps the pipes full
- * of data off the tapes if the input from inn is idle.
- */
-bool hostGimmeArticle (Host host, Connection cxn)
-{
-  Article article = NULL ;
-  bool gaveSomething = false ;
-  size_t amtToGive = cxnQueueSpace (cxn) ; /* may be more than one */
-  int feed = 0 ;
-
-  if (amClosing (host))
-    {
-      d_printf (5,"%s no article to give due to closing\n",host->params->peerName) ;
-
-      return false ;
-    }
-
-  if (amtToGive == 0)
-    d_printf (5,"%s Queue space is zero....\n",host->params->peerName) ;
-  
-  while (amtToGive > 0)
-    {
-      bool tookIt ;
-      unsigned int queue = host->params->maxChecks - amtToGive ;
-
-      if (host->params->backlogFeedFirst) {
-       if ((article = getArticle (host->myTape)) != NULL)
-         feed = 2;
-       else if ((article = remHead (&host->queued,&host->queuedTail)) != NULL)
-         feed = 1;
-       else
-         feed = 3;
-      }
-      else {
-       if ((article = remHead (&host->queued,&host->queuedTail)) != NULL)
-         feed = 1;
-       else if ((article = getArticle (host->myTape)) != NULL)
-         feed = 2;
-       else
-         feed = 3;
-      }
-
-      switch (feed) {
-      case 1:
-          host->backlog-- ;
-          tookIt = cxnQueueArticle (cxn,artTakeRef (article)) ;
-
-          ASSERT (tookIt == true) ;
-
-          if (queue == 0) host->gNoQueue++ ;
-          else            host->gCxnQueue += queue ;
-
-          queueArticle (article,&host->processed,&host->processedTail, 0) ;
-          amtToGive-- ;
-
-          gaveSomething = true ;
-          break ;
-
-      case 2:
-          /* go to the tapes */
-          tookIt = cxnQueueArticle (cxn,artTakeRef (article)) ;
-
-          ASSERT (tookIt == true) ;
-
-          if (queue == 0) host->gNoQueue++ ;
-          else            host->gCxnQueue += queue ;
-
-          host->artsFromTape++ ;
-          host->gArtsFromTape++ ;
-          procArtsFromTape++ ;
-          queueArticle (article,&host->processed,&host->processedTail, 0) ;
-          amtToGive-- ;
-
-          gaveSomething = true ;
-
-          break ;
-
-      case 3:
-          /* we had nothing left to give... */
-          
-          if (host->processed == NULL) /* and if nothing outstanding... */
-            listenerHostIsIdle (host->listener,host) ; /* tell our owner */
-  
-          amtToGive = 0 ;
-
-          break ;
-      }
-    }
-
-  return gaveSomething ;
-}
-
-
-
-
-
-
-\f
-/*
- * get the name that INN uses for this host
- */
-const char *hostPeerName (Host host)
-{
-  ASSERT (host != NULL) ;
-    
-  return host->params->peerName ;
-}
-
-/*
- * get the IPv4 bindaddress
- */
-const struct sockaddr_in *hostBindAddr (Host host)
-{
-  ASSERT (host != NULL) ;
-    
-  return host->params->bindAddr ;
-}
-
-#ifdef HAVE_INET6
-/*
- * get the IPv6 bindaddress
- */
-const struct sockaddr_in6 *hostBindAddr6 (Host host)
-{
-  ASSERT (host != NULL) ;
-    
-  return host->params->bindAddr6 ;
-}
-
-/*
- * get the address family
- */
-int hostAddrFamily (Host host)
-{
-  ASSERT (host != NULL) ;
-
-  return host->params->family ;
-}
-#endif
-
-/*
- * get the username and password for authentication
- */
-const char *hostUsername (Host host)
-{
-  ASSERT (host != NULL) ;
-
-  return host->params->username ;
-}
-const char *hostPassword (Host host)
-{
-  ASSERT (host != NULL) ;
-
-  return host->params->password ;
-}
-
-
-/* return true if the Connections for this host should attempt to do
-   streaming. */
-bool hostWantsStreaming (Host host)
-{
-  return host->params->wantStreaming ;
-}
-
-unsigned int hostMaxChecks (Host host)
-{
-  return host->params->maxChecks ;
-}
-
-bool hostDropDeferred (Host host)
-{
-  return host->params->dropDeferred ;
-}
-
-
-
-
-
-
-\f
-/**********************************************************************/
-/**                       CLASS FUNCTIONS                            **/
-/**********************************************************************/
-
-/*
- * Set the state of whether each Connection is told to log its stats when
- * its controlling Host logs its stats.
- */
-void hostLogConnectionStats (bool val)
-{
-  logConnectionStats = val ;
-}
-
-
-bool hostLogConnectionStatsP (void)
-{
-  return logConnectionStats ;
-}
-
-
-
-/*
- * Called by one of the Host's Connection's when it (the Connection)
- * switches into or out of no-CHECK mode.
- */
-void hostLogNoCheckMode (Host host, bool on, double low, double cur, double high)
-{
-  if (on && host->loggedModeOn == false)
-    {
-      notice ("%s mode no-CHECK entered [%.2f,%.2f,%.2f]",
-              host->params->peerName, low, cur, high) ;
-      host->loggedModeOn = true ;
-    }
-  else if (!on && host->loggedModeOff == false) 
-    {
-      notice ("%s mode no-CHECK exited [%.2f,%.2f,%.2f]",
-              host->params->peerName, low, cur, high) ;
-      host->loggedModeOff = true ;
-    }
-}
-
-
-
-void hostSetStatusFile (const char *filename)
-{
-  FILE *fp ;
-  
-  if (filename == NULL)
-    die ("Can't set status file name with a NULL filename\n") ;
-  else if (*filename == '\0')
-    die ("Can't set status file name with a empty string\n") ;
-
-  if (*filename == '/')
-    statusFile = xstrdup (filename) ;
-  else
-    statusFile = concatpath (innconf->pathlog,filename) ;
-
-  if ((fp = fopen (statusFile,"w")) == NULL)
-    {
-      syslog (LOG_ERR,"Status file is not a valid pathname: %s",
-              statusFile) ;
-      free (statusFile) ;
-      statusFile = NULL ;
-    }
-  else
-    fclose (fp) ;
-}
-
-void gHostStats (void)
-{
-  Host h ;
-  time_t now = theTime() ;
-  char msgstr[SMBUF] ;
-
-  for (h = gHostList ; h != NULL ; h = h->next)
-      if (h->firstConnectTime > 0) {
-        snprintf(msgstr, sizeof(msgstr), "accsize %.0f rejsize %.0f",
-                 h->gArtsSizeAccepted, h->gArtsSizeRejected);
-        notice ("%s global seconds %ld offered %d accepted %d refused %d"
-                " rejected %d missing %d %s spooled %d unspooled %d",
-                h->params->peerName,
-                (long) (now - h->firstConnectTime),
-                h->gArtsOffered, h->gArtsAccepted,
-                h->gArtsNotWanted, h->gArtsRejected,
-                h->gArtsMissing, msgstr,
-                h->gArtsToTape, h->gArtsFromTape) ;
-      }
-}
-
-
-
-/**********************************************************************/
-/**                      PRIVATE FUNCTIONS                           **/
-/**********************************************************************/
-
-
-
-
-#define INHERIT        1
-#define NO_INHERIT 0
-
-\f
-static HostParams hostDetails (scope *s,
-                              char *name,
-                              bool isDefault,
-                              FILE *fp)
-{
-  long iv ;
-  int bv, vival, inherit ;
-  HostParams p;
-  char * q;
-  double rv, l, h ;
-  value * v;
-
-  p=newHostParams(isDefault?NULL:defaultParams);
-
-  if (isDefault)
-    {
-      ASSERT (name==NULL);
-    }
-  else
-    {
-      if (name)
-       {
-         p->peerName=xstrdup(name);
-       }
-  
-      if (s != NULL)
-        {
-         if (getString (s,IP_NAME,&q,NO_INHERIT))
-           p->ipName = q ;
-         else
-           p->ipName = xstrdup (name) ;
-        }
-
-      if (getString (s,"username",&q,NO_INHERIT))
-       p->username = q;
-      if (getString (s,"password",&q,NO_INHERIT))
-       p->password = q;
-
-      if (p->username != NULL && p->password == NULL)
-       logOrPrint (LOG_ERR,fp,"cannot find password for %s",p->peerName);
-      if (p->username == NULL && p->password != NULL)
-       logOrPrint (LOG_ERR,fp,"cannot find username for %s",p->peerName);
-
-    }
-
-#ifdef HAVE_INET6
-  if (getString(s,"bindaddress6",&q,isDefault?NO_INHERIT:INHERIT))
-    {
-      struct addrinfo *res, hints;
-
-      if (strcmp(q, "none") == 0)
-        p->family = AF_INET;
-      else if (p->family == AF_INET)
-        p->family = 0;
-
-      if (strcmp(q, "any") != 0 && strcmp(q, "all") != 0 &&
-        strcmp(q, "none") != 0)
-        {
-          memset( &hints, 0, sizeof( hints ) );
-          hints.ai_flags = AI_NUMERICHOST;
-          if( getaddrinfo( q, NULL, &hints, &res ) )
-     {
-       logOrPrint (LOG_ERR, fp, 
-                      "unable to determine IPv6 bind address for %s",
-                      p->peerName) ;
-            }
-          else
-            {
-              p->bindAddr6 = (struct sockaddr_in6 *) xmalloc (res->ai_addrlen);
-              memcpy( p->bindAddr6, res->ai_addr, res->ai_addrlen );
-            }
- }
-    }
-#endif
-
-    if (getString(s,"bindaddress",&q,isDefault?NO_INHERIT:INHERIT))
-    {
-      struct in_addr addr ;
-
-#ifdef HAVE_INET6
-      if (strcmp(q, "none") == 0) {
-        if (p->family) {
-          logOrPrint (LOG_ERR,fp,"cannot set both bindaddress and bindaddress6"
-                      " to \"none\" -- ignoring them for %s",p->peerName);
-          p->family = 0;
-        } else {
-          p->family = AF_INET6;
-        }
-      } else if (p->family == AF_INET6)
-        p->family = 0;
-#endif
-
-      if (strcmp(q, "any") != 0 && strcmp(q, "all") != 0 &&
-           strcmp(q, "none") != 0)
-        {
-          if (!inet_aton(q,&addr))
-            {
-              logOrPrint (LOG_ERR, fp,
-                      "unable to determine IPv4 bind address for %s",
-                      p->peerName) ;
-            }
-          else
-            {
-              p->bindAddr = (struct sockaddr_in *)
-                              xmalloc (sizeof(struct sockaddr_in));
-              make_sin( (struct sockaddr_in *)p->bindAddr, &addr );
-            }
-        }
-    }
-
-  /* check required global defaults are there and have good values */
-  
-
-#define GETINT(sc,f,n,min,max,req,val,inh)              \
-  vival = validateInteger(f,n,min,max,req,val,sc,inh);  \
-  if (isDefault) do{                                    \
-    if(vival==VALUE_WRONG_TYPE)                         \
-      {                                                 \
-        logOrPrint(LOG_CRIT,fp,"cannot continue");      \
-        exit(1);                                        \
-      }                                                 \
-    else if(vival != VALUE_OK)                          \
-      val = 0;                                          \
-  } while(0);                                           \
-  iv = 0 ;                                              \
-  getInteger (sc,n,&iv,inh) ;                           \
-  val = (unsigned int) iv ;
-
-#define GETREAL(sc,f,n,min,max,req,val,inh)             \
-  vival = validateReal(f,n,min,max,req,val,sc,inh);     \
-  if (isDefault) do{                                    \
-    if(vival==VALUE_WRONG_TYPE)                         \
-      {                                                 \
-        logOrPrint(LOG_CRIT,fp,"cannot continue");      \
-        exit(1);                                        \
-      }                                                 \
-    else if(vival != VALUE_OK)                          \
-      rv = 0;                                           \
-  } while(0);                                           \
-  rv = 0 ;                                              \
-  getReal (sc,n,&rv,inh) ;                              \
-  val = rv ;
-
-#define GETBOOL(sc,f,n,req,val,inh)                     \
-  vival = validateBool(f,n,req,val,sc,inh);             \
-  if (isDefault) do{                                    \
-    if(vival==VALUE_WRONG_TYPE)                         \
-      {                                                 \
-        logOrPrint(LOG_CRIT,fp,"cannot continue");      \
-        exit(1);                                        \
-      }                                                 \
-    else if(vival != VALUE_OK)                          \
-      bv = 0;                                           \
-  } while(0);                                           \
-  bv = 0 ;                                              \
-  getBool (sc,n,&bv,inh)  ;                             \
-  val = (bv ? true : false);
-
-  inherit = isDefault?NO_INHERIT:INHERIT;
-  GETINT(s,fp,"article-timeout",0,LONG_MAX,REQ,p->articleTimeout, inherit);
-  GETINT(s,fp,"response-timeout",0,LONG_MAX,REQ,p->responseTimeout, inherit);
-  GETINT(s,fp,"close-period",0,LONG_MAX,REQ,p->closePeriod, inherit);
-  GETINT(s,fp,"initial-connections",0,LONG_MAX,REQ,p->initialConnections, inherit);
-  GETINT(s,fp,"max-connections",0,LONG_MAX,REQ,p->absMaxConnections, inherit);
-  GETINT(s,fp,"max-queue-size",1,LONG_MAX,REQ,p->maxChecks, inherit);
-  GETBOOL(s,fp,"streaming",REQ,p->wantStreaming, inherit);
-  GETBOOL(s,fp,"drop-deferred",REQ,p->dropDeferred, inherit);
-  GETBOOL(s,fp,"min-queue-connection",REQ,p->minQueueCxn, inherit);
-  GETREAL(s,fp,"no-check-high",0.0,100.0,REQ,p->lowPassHigh, inherit);
-  GETREAL(s,fp,"no-check-low",0.0,100.0,REQ,p->lowPassLow, inherit);
-  GETREAL(s,fp,"no-check-filter",0.1,DBL_MAX,REQ,p->lowPassFilter, inherit);
-  GETINT(s,fp,"port-number",0,LONG_MAX,REQ,p->portNum, inherit);
-  GETINT(s,fp,"backlog-limit",0,LONG_MAX,REQ,p->backlogLimit, inherit);
-
-#ifdef HAVE_INET6
-  GETBOOL(s,fp,"force-ipv4",NOTREQ,p->forceIPv4,inherit);
-  if (p->forceIPv4)
-    p->family = AF_INET;
-#endif
-
-  if (findValue (s,"backlog-factor",inherit) == NULL &&
-      findValue (s,"backlog-limit-high",inherit) == NULL)
-    {
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: must define at least one of backlog-factor"
-                  " and backlog-limit-high. Adding %s: %f", "backlog-factor",
-                  LIMIT_FUDGE) ;
-      addReal (s,"backlog-factor",LIMIT_FUDGE) ;
-      rv = 0 ;
-    }
-
-  GETBOOL(s,fp,"backlog-feed-first",NOTREQ,p->backlogFeedFirst, inherit);
-
-  /* Innfeed should emit a warning if backlog-feed-first is set
-     to "true" for any peer that doesn't have max-connections and
-     initial-connections both set to "1" */
-  if ((p->backlogFeedFirst)
-      && ((p->initialConnections <= 1) || (p->absMaxConnections != 1)))
-    {
-      if (p->peerName != NULL)
-       logOrPrint (LOG_WARNING,fp,
-                   "ME config: innfeed will make more than one connection"
-                   " to peer %s, but backlog-feed-first is set", p->peerName);
-      else
-       logOrPrint (LOG_WARNING,fp,
-                   "ME config: innfeed will make more than one connection"
-                   " to peer, but backlog-feed-first is set");
-    }
-
-  GETINT(s,fp,"backlog-limit-high",0,LONG_MAX,NOTREQNOADD,p->backlogLimitHigh, inherit);
-  GETREAL(s,fp,"backlog-factor",1.0,DBL_MAX,NOTREQNOADD,p->backlogFactor, inherit);
-
-  GETINT(s,fp,"dynamic-method",0,3,REQ,p->dynamicMethod, inherit);
-  GETREAL(s,fp,"dynamic-backlog-filter",0.0,DBL_MAX,REQ,p->dynBacklogFilter, inherit);
-  GETREAL(s,fp,"dynamic-backlog-low",0.0,100.0,REQ,p->dynBacklogLowWaterMark, inherit);
-  GETREAL(s,fp,"dynamic-backlog-high",0.0,100.0,REQ,p->dynBacklogHighWaterMark, inherit);
-
-  l=p->lowPassLow;
-  h=p->lowPassHigh;
-  if (l > h)
-    {
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: no-check-low value greater than no-check-high"
-                  " (%f vs %f). Setting to %f and %f", l, h, NOCHECKLOW,
-                  NOCHECKHIGH) ;
-      rv = 0 ;
-      v = findValue (s,"no-check-low",NO_INHERIT) ;
-      v->v.real_val = p->lowPassLow = NOCHECKLOW ;
-      v = findValue (s,"no-check-high",NO_INHERIT) ;
-      v->v.real_val = p->lowPassHigh = NOCHECKHIGH ;
-    }
-  else if (h - l < 5.0)
-    logOrPrint (LOG_WARNING,fp,
-                "ME config: no-check-low and no-check-high are close"
-                " together (%f vs %f)",l,h) ;
-
-  return p;
-}
-
-
-
-
-static HostParams getHostInfo (void)
-{
-  static int idx = 0 ;
-  value *v ;
-  scope *s ;
-  HostParams p=NULL;
-
-  bool isGood = false ;
-
-  if (topScope == NULL)
-    return p;
-  
-  while ((v = getNextPeer (&idx)) != NULL) 
-    {
-      if (!ISPEER (v))
-        continue ;
-
-      s = v->v.scope_val ;
-
-      p=hostDetails(s,v->name,false,NULL);
-
-      isGood = true ;
-      
-      break ;
-    }
-
-  if (v == NULL)
-    idx = 0 ;                   /* start over next time around */
-
-  return p;
-}
-
-
-/*
- * fully delete and clean up the Host object.
- */
-void delHost (Host host)
-{
-  Host h,q ;
-
-  for (h = gHostList, q = NULL ; h != NULL ; q = h, h = h->next)
-    if (h == host)
-      {
-        if (gHostList == h)
-          gHostList = gHostList->next ;
-        else
-          q->next = h->next ;
-        break ;
-      }
-
-  ASSERT (h != NULL) ;
-        
-  delTape (host->myTape) ;
-  
-  free (host->connections) ;
-  free (host->cxnActive) ;
-  free (host->cxnSleeping) ;
-  free (host->params->peerName) ;
-  free (host->params->ipName) ;
-
-  if (host->ipAddrs)
-  {
-    if(host->ipAddrs[0])
-      free (host->ipAddrs[0]);
-    free (host->ipAddrs) ;
-  }
-
-  free (host) ;
-  gHostCount-- ;
-}
-
-
-\f
-static Host findHostByName (char *name) 
-{
-  Host h;
-
-  for (h = gHostList; h != NULL; h = h->next)
-    if ( strcmp(h->params->peerName, name) == 0 )
-      return h;
-
-  return NULL;
-}
-
-
-\f
-/* 
- * the article can be dropped from the process queue and the connection can
- * take a new article if there are any to be had.
- */
-static void articleGone (Host host, Connection cxn, Article article)
-{
-  if ( !remArticle (article,&host->processed,&host->processedTail) )
-    die ("remArticle in articleGone failed") ;
-
-  delArticle (article) ;
-
-  if (cxn != NULL)
-    hostGimmeArticle (host,cxn) ; /* may not give anything over */
-}
-
-
-
-
-
-
-\f
-/*
- * One of the Connections for this Host has reestablished itself, so stop
- * spooling article info to disk.
- */
-static void hostStopSpooling (Host host)
-{
-  ASSERT (host->spoolTime != 0) ;
-  
-  clearTimer (host->statsId) ;
-  hostLogStats (host,true) ;
-  host->spoolTime = 0 ;
-}
-
-
-
-
-
-
-\f
-/*
- * No connections are active and we're getting response 201 or 400 (or some
- * such) so that we need to start spooling article info to disk.
- */
-static void hostStartSpooling (Host host)
-{
-  ASSERT (host->spoolTime == 0) ;
-
-  queuesToTape (host) ;
-
-  hostLogStats (host,true) ;
-  
-  host->spoolTime = theTime() ;
-  if (host->firstConnectTime == 0)
-    host->firstConnectTime = host->spoolTime ;
-
-  /* don't want to log too frequently */
-  if (SPOOL_LOG_PERIOD > 0 &&
-      (host->spoolTime - host->lastSpoolTime) > SPOOL_LOG_PERIOD)
-    {
-      notice ("%s spooling no active connections", host->params->peerName) ;
-      host->lastSpoolTime = host->spoolTime ;
-    }
-  
-  host->connectTime = 0 ;
-
-  host->notifiedChangedRemBlckd = false ;
-
-  clearTimer (host->statsId) ;
-  host->statsId = prepareSleep (hostStatsTimeoutCbk, statsPeriod, host) ;
-}
-
-
-
-
-
-
-\f
-/*
- * Time to log the statistics for the Host. If FINAL is true then the
- * counters will be reset.
- */
-static void hostLogStats (Host host, bool final)
-{
-  time_t now = theTime() ;
-  time_t *startPeriod ;
-  double cnt = (host->blCount) ? (host->blCount) : 1.0;
-  char msgstr[SMBUF] ;
-
-  if (host->spoolTime == 0 && host->connectTime == 0)
-    return ;        /* host has never connected and never started spooling*/
-
-  startPeriod = (host->spoolTime != 0 ? &host->spoolTime : &host->connectTime);
-
-  if (now - *startPeriod >= statsResetPeriod)
-    final = true ;
-  
-  if (host->spoolTime != 0)
-    notice ("%s %s seconds %ld spooled %d on_close %d sleeping %d",
-            host->params->peerName, (final ? "final" : "checkpoint"),
-            (long) (now - host->spoolTime), host->artsToTape,
-            host->artsHostClose, host->artsHostSleep) ;
-  else {
-    snprintf(msgstr, sizeof(msgstr), "accsize %.0f rejsize %.0f",
-             host->artsSizeAccepted, host->artsSizeRejected);
-    notice ("%s %s seconds %ld offered %d accepted %d refused %d rejected %d"
-            " missing %d %s spooled %d on_close %d unspooled %d"
-            " deferred %d/%.1f requeued %d"
-            " queue %.1f/%d:%.0f,%.0f,%.0f,%.0f,%.0f,%.0f",
-            host->params->peerName, (final ? "final" : "checkpoint"),
-            (long) (now - host->connectTime),
-            host->artsOffered, host->artsAccepted,
-            host->artsNotWanted, host->artsRejected,
-            host->artsMissing, msgstr,
-            host->artsToTape,
-            host->artsHostClose, host->artsFromTape,
-            host->artsDeferred, (double)host->dlAccum/cnt,
-            host->artsCxnDrop,
-            (double)host->blAccum/cnt, hostHighwater,
-            (100.0*host->blNone)/cnt,
-            (100.0*host->blQuartile[0])/cnt, (100.0*host->blQuartile[1])/cnt,
-            (100.0*host->blQuartile[2])/cnt, (100.0*host->blQuartile[3])/cnt,
-            (100.0*host->blFull)/cnt) ;
-  }
-
-  if (logConnectionStats) 
-    {
-      unsigned int i ;
-      
-      for (i = 0 ; i < host->maxConnections ; i++)
-        if (host->connections [i] != NULL && host->cxnActive [i])
-          cxnLogStats (host->connections [i],final) ;
-    }
-
-  /* one 'spooling backlog' message per stats logging period */
-  host->loggedBacklog = false ;
-  host->loggedModeOn = host->loggedModeOff = false ;
-
-  if (final)
-    {
-      host->artsOffered = 0 ;
-      host->artsAccepted = 0 ;
-      host->artsNotWanted = 0 ;
-      host->artsRejected = 0 ;
-      host->artsDeferred = 0 ;
-      host->artsMissing = 0 ;
-      host->artsToTape = 0 ;
-      host->artsQueueOverflow = 0 ;
-      host->artsCxnDrop = 0 ;
-      host->artsHostSleep = 0 ;
-      host->artsHostClose = 0 ;
-      host->artsFromTape = 0 ;
-      host->artsSizeAccepted = 0 ;
-      host->artsSizeRejected = 0 ;
-      
-      *startPeriod = theTime () ; /* in of case STATS_RESET_PERIOD */
-    }
-
-    /* reset these each log period */
-    host->blNone = 0 ;
-    host->blFull = 0 ;
-    host->blQuartile[0] = host->blQuartile[1] = host->blQuartile[2] =
-                          host->blQuartile[3] = 0;
-    host->dlAccum = 0;
-    host->blAccum = 0;
-    host->blCount = 0;
-
-#if 0
-  /* XXX turn this section on to get a snapshot at each log period. */
-  if (gPrintInfo != NULL)
-    gPrintInfo () ;
-#endif
-}
-
-
-
-
-
-
-\f
-
-static double
-convsize(double size, char **tsize)
-{
-    double dsize;
-    static char tTB[]="TB";
-    static char tGB[]="GB";
-    static char tMB[]="MB";
-    static char tKB[]="KB";
-    static char tB []="B";
-
-    if (size/((double)1024*1024*1024*1000)>=1.) {
-       dsize=size/((double)1024*1024*1024*1024);
-       *tsize=tTB;
-    } else if (size/(1024*1024*1000)>=1.) {
-       dsize=size/(1024*1024*1024);
-       *tsize=tGB;
-    } else if (size/(1024*1000)>=1.) {
-       dsize=size/(1024*1024);
-       *tsize=tMB;
-    } else if (size/1000>=1.) {
-       dsize=size/1024;
-       *tsize=tKB;
-    } else {
-       dsize=size;
-       *tsize=tB;
-    }
-    return dsize;
-}
-
-
-/*
- * Log the status of the Hosts.
- */
-extern char *versionInfo ;
-static void hostLogStatus (void)
-{
-  FILE *fp = NULL ;
-  Host h ;
-  bool anyToLog = false ;
-  unsigned int peerNum = 0, actConn = 0, slpConn = 0, maxcon = 0 ;
-  static bool logged = false ;
-  static bool flogged = false ;
-
-  if (statusFile == NULL && !logged)
-    {
-      syslog (LOG_ERR,"No status file to write to") ;
-      logged = true ;
-      return ;
-    }
-
-  logged = false ;
-    
-  for (h = gHostList ; h != NULL ; h = h->next)
-    if (h->myTape != NULL)   /* the host deletes its tape when it's closing */
-      {
-        anyToLog = true ;
-        peerNum++ ;
-        actConn += h->activeCxns ;
-        slpConn += h->sleepingCxns ;
-        maxcon += h->maxConnections ;
-      }
-
-  if (!anyToLog)
-    return ;
-
-  lastStatusLog = theTime() ;
-  
-  TMRstart(TMR_STATUSFILE);
-  if ((fp = fopen (statusFile,"w")) == NULL)
-    {
-      if ( !flogged )
-        syswarn ("ME oserr status file open: %s", statusFile) ;
-      flogged = true ;
-    }
-  else
-    {
-      char timeString [30] ;
-      time_t now ;
-      long sec ;
-      long offered ;        
-      double size, totalsize;
-      char *tsize;
-
-      flogged = false ;
-      
-      now = time (NULL) ;
-      sec = (long) (now - start) ;
-      strlcpy (timeString,ctime (&now),sizeof (timeString)) ;
-
-      if (genHtml)
-        {
-          fprintf (fp, "<HTML>\n"
-                      "<HEAD>\n"
-                      "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"300;\">\n"
-                      "</HEAD>\n"
-                      "<BODY>\n") ;
-         fprintf (fp, "\n");
-         fprintf (fp, "<PRE>\n");
-       }
-
-      fprintf (fp,"%s\npid %d started %s\nUpdated: %s",
-               versionInfo,(int) myPid,startTime,timeString) ;
-      fprintf (fp,"(peers: %d active-cxns: %d sleeping-cxns: %d idle-cxns: %d)\n\n",
-               peerNum, actConn, slpConn,(maxcon - (actConn + slpConn))) ;
-
-      fprintf (fp,"Configuration file: %s\n\n",configFile) ;
-      
-      if (genHtml)
-      {
-        fprintf (fp, "</PRE>\n");
-        fprintf (fp,"<UL>\n");
-        for (h = gHostList ; h != NULL ; h = h->next)
-          fprintf (fp,"<LI><A href=\"#%s\">%s</A></LI>\n",
-                   h->params->peerName, h->params->peerName);
-        fprintf (fp,"</UL>\n\n");
-        fprintf (fp,"<PRE>\n");
-      }
-
-      mainLogStatus (fp) ;
-      listenerLogStatus (fp) ;
-
-/*
-Default peer configuration parameters:
-    article timeout: 600       initial connections: 1
-   response timeout: 300           max connections: 5
-       close period: 6000               max checks: 25
-     want streaming: true           dynamic method: 1
-        no-check on: 95.0%     dynamic backlog low: 25%
-       no-check off: 90.0%    dynamic backlog high: 50%
-    no-check filter: 50.0   dynamic backlog filter: 0.7
-  backlog low limit: 1024                 port num: 119
- backlog high limit: 1280       backlog feed first: false
-     backlog factor: 1.1
-*/
-      fprintf(fp,"%sDefault peer configuration parameters:%s\n",
-              genHtml ? "<B>" : "", genHtml ? "</B>" : "") ;
-      fprintf(fp,"    article timeout: %-5d     initial connections: %d\n",
-           defaultParams->articleTimeout,
-           defaultParams->initialConnections) ;
-      fprintf(fp,"   response timeout: %-5d         max connections: %d\n",
-           defaultParams->responseTimeout,
-           defaultParams->absMaxConnections) ;
-      fprintf(fp,"       close period: %-5d              max checks: %d\n",
-           defaultParams->closePeriod,
-           defaultParams->maxChecks) ;
-      fprintf(fp,"     want streaming: %-5s          dynamic method: %d\n",
-           defaultParams->wantStreaming ? "true " : "false",
-           defaultParams->dynamicMethod) ;
-      fprintf(fp,"        no-check on: %-2.1f%%     dynamic backlog low: %-2.1f%%\n",
-           defaultParams->lowPassHigh,
-           defaultParams->dynBacklogLowWaterMark) ;
-      fprintf(fp,"       no-check off: %-2.1f%%    dynamic backlog high: %-2.1f%%\n",
-           defaultParams->lowPassLow,
-           defaultParams->dynBacklogHighWaterMark) ;
-      fprintf(fp,"    no-check filter: %-2.1f   dynamic backlog filter: %-2.1f\n",
-           defaultParams->lowPassFilter,
-           defaultParams->dynBacklogFilter) ;
-      fprintf(fp,"  backlog limit low: %-7d         drop-deferred: %s\n",
-           defaultParams->backlogLimit,
-           defaultParams->dropDeferred ? "true " : "false");
-      fprintf(fp," backlog limit high: %-7d         min-queue-cxn: %s\n",
-           defaultParams->backlogLimitHigh,
-           defaultParams->minQueueCxn ? "true " : "false");
-      fprintf(fp,"  backlog feed first: %s\n",
-           defaultParams->backlogFeedFirst ? "true " : "false");
-      fprintf(fp,"     backlog factor: %1.1f\n\n",
-           defaultParams->backlogFactor);
-
-      tapeLogGlobalStatus (fp) ;
-
-      fprintf (fp,"\n") ;
-      fprintf(fp,"%sglobal (process)%s\n",
-              genHtml ? "<B>" : "", genHtml ? "</B>" : "") ;
-      
-      fprintf (fp, "   seconds: %ld\n", sec) ;
-      if (sec == 0) sec = 1 ;
-      offered = procArtsOffered ? procArtsOffered : 1 ;
-      totalsize = procArtsSizeAccepted+procArtsSizeRejected ;
-      if (totalsize == 0) totalsize = 1. ;
-
-      fprintf (fp, "   offered: %-5ld\t%6.2f art/s\n",
-               procArtsOffered,
-               (double)procArtsOffered/sec) ;
-      fprintf (fp, "  accepted: %-5ld\t%6.2f art/s\t%5.1f%%\n",
-               procArtsAccepted,
-               (double)procArtsAccepted/sec,
-               (double)procArtsAccepted*100./offered) ;
-      fprintf (fp, "   refused: %-5ld\t%6.2f art/s\t%5.1f%%\n",
-               procArtsNotWanted,
-               (double)procArtsNotWanted/sec,
-               (double)procArtsNotWanted*100./offered) ;
-      fprintf (fp, "  rejected: %-5ld\t%6.2f art/s\t%5.1f%%\n",
-               procArtsRejected,
-               (double)procArtsRejected/sec,
-               (double)procArtsRejected*100./offered) ;
-      fprintf (fp, "   missing: %-5ld\t%6.2f art/s\t%5.1f%%\n",
-               procArtsMissing,
-               (double)procArtsMissing/sec,
-               (double)procArtsMissing*100./offered) ;
-      fprintf (fp, "  deferred: %-5ld\t%6.2f art/s\t%5.1f%%\n",
-               procArtsDeferred,
-               (double)procArtsDeferred/sec,
-               (double)procArtsDeferred*100./offered) ;
-
-      size=convsize(procArtsSizeAccepted, &tsize);
-      fprintf (fp, "accpt size: %.3g %s", size, tsize) ;
-      size=convsize(procArtsSizeAccepted/sec, &tsize);
-      fprintf (fp, " \t%6.3g %s/s\t%5.1f%%\n",
-               size, tsize,
-               procArtsSizeAccepted*100./totalsize) ;
-
-      size=convsize(procArtsSizeRejected, &tsize);
-      fprintf (fp, "rejct size: %.3g %s", size, tsize) ;
-      size=convsize(procArtsSizeRejected/sec, &tsize);
-      fprintf (fp, " \t%6.3g %s/s\t%5.1f%%\n",
-               size, tsize,
-               procArtsSizeRejected*100./totalsize) ;
-
-      fprintf (fp, "\n");
-
-      for (h = gHostList ; h != NULL ; h = h->next)
-        hostPrintStatus (h,fp) ;
-
-      if (genHtml) 
-       {
-          fprintf (fp,"</PRE>\n") ;
-          fprintf (fp,"</BODY>\n") ;
-          fprintf (fp,"</HTML>\n") ;
-       }
-      
-      fclose (fp) ;
-    }
-    TMRstop(TMR_STATUSFILE);
-}
-
-/*
- * This prints status information for each host.  An example of the
- * format of the output is:
- *
- * sitename
- *   seconds: 351       art. timeout: 400          ip name: foo.bar
- *   offered: 1194     resp. timeout: 240             port: 119
- *  accepted: 178     want streaming: yes      active cxns: 6
- *   refused: 948       is streaming: yes    sleeping cxns: 0
- *  rejected: 31          max checks: 25      initial cxns: 5
- *   missing: 0          no-check on: 95.0%      idle cxns: 4
- *  deferred: 0         no-check off: 95.0%       max cxns: 8/10
- *  requeued: 0        no-check fltr: 50.0    queue length: 0.0/200
- *   spooled: 0       dynamic method: 0              empty: 100.0%
- *[overflow]: 0        dyn b'log low: 25%          >0%-25%: 0.0%
- *[on_close]: 0       dyn b'log high: 50%          25%-50%: 0.0%
- *[sleeping]: 0       dyn b'log stat: 37%          50%-75%: 0.0%
- * unspooled: 0       dyn b'log fltr: 0.7        75%-<100%: 0.0%
- *  no queue: 1234    avr.cxns queue: 0.0             full: 0.0%
- *accpt size: 121.1 MB drop-deferred: false   defer length: 0
- *rejct size: 27.1 MB  min-queue-cxn: false
- *                 backlog low limit: 1000000
- *                backlog high limit: 2000000     (factor 2.0)
- *                 backlog shrinkage: 0 bytes (from current file)
- *   offered:  1.13 art/s   accepted:  0.69 art/s (101.71 KB/s)
- *   refused:  0.01 art/s   rejected:  0.42 art/s (145.11 KB/s)
- *   missing 0 spooled 0
- *
- */
-static void hostPrintStatus (Host host, FILE *fp)
-{
-  time_t now = theTime() ;
-  double cnt = (host->blCount) ? (host->blCount) : 1.0;
-  double size;
-  char *tsize;
-  char buf[]="1234.1 MB";
-
-  ASSERT (host != NULL) ;
-  ASSERT (fp != NULL) ;
-
-  if (genHtml)
-    fprintf (fp,"<A name=\"%s\"><B>%s</B></A>",host->params->peerName,
-             host->params->peerName);
-  else
-    fprintf (fp,"%s",host->params->peerName);
-
-  if (host->blockedReason != NULL)
-    fprintf (fp,"  (remote status: ``%s'')",host->blockedReason) ;
-
-  fputc ('\n',fp) ;
-
-  fprintf (fp, "   seconds: %-7ld   art. timeout: %-5d        ip name: %s\n",
-          host->firstConnectTime > 0 ? (long)(now - host->firstConnectTime) : 0,
-          host->params->articleTimeout, host->params->ipName) ;
-           
-  fprintf (fp, "   offered: %-7ld  resp. timeout: %-5d           port: %d\n",
-          (long) host->gArtsOffered, host->params->responseTimeout,
-          host->params->portNum);
-
-  fprintf (fp, "  accepted: %-7ld want streaming: %s      active cxns: %d\n",
-          (long) host->gArtsAccepted, 
-           (host->params->wantStreaming ? "yes" : "no "),
-          host->activeCxns) ;
-
-  fprintf (fp, "   refused: %-7ld   is streaming: %s    sleeping cxns: %d\n",
-          (long) host->gArtsNotWanted,
-           (host->remoteStreams ? "yes" : "no "),
-          host->sleepingCxns) ;
-
-  fprintf (fp, "  rejected: %-7ld     max checks: %-5d   initial cxns: %d\n",
-          (long) host->gArtsRejected, host->params->maxChecks,
-          host->params->initialConnections) ;
-
-  fprintf (fp, "   missing: %-7ld    no-check on: %-3.1f%%      idle cxns: %d\n",
-          (long) host->gArtsMissing, host->params->lowPassHigh,
-           host->maxConnections - (host->activeCxns + host->sleepingCxns)) ;
-
-  fprintf (fp, "  deferred: %-7ld   no-check off: %-3.1f%%       max cxns: %d/%d\n",
-          (long) host->gArtsDeferred, host->params->lowPassLow,
-          host->maxConnections, host->params->absMaxConnections) ;
-
-  fprintf (fp, "  requeued: %-7ld  no-check fltr: %-3.1f    queue length: %-3.1f/%d\n",
-          (long) host->gArtsCxnDrop, host->params->lowPassFilter,
-          (double)host->blAccum / cnt, hostHighwater) ;
-
-  fprintf (fp, "   spooled: %-7ld dynamic method: %-5d          empty: %-3.1f%%\n",
-          (long) host->gArtsToTape,
-          host->params->dynamicMethod,
-          100.0 * host->blNone / cnt) ;
-
-  fprintf (fp, "[overflow]: %-7ld  dyn b'log low: %-3.1f%%        >0%%-25%%: %-3.1f%%\n",
-          (long) host->gArtsQueueOverflow, 
-          host->params->dynBacklogLowWaterMark,
-          100.0 * host->blQuartile[0] / cnt) ;
-
-  fprintf (fp, "[on_close]: %-7ld dyn b'log high: %-3.1f%%        25%%-50%%: %-3.1f%%\n",
-          (long) host->gArtsHostClose,
-          host->params->dynBacklogHighWaterMark,
-          100.0 * host->blQuartile[1] / cnt) ;
-
-  fprintf (fp, "[sleeping]: %-7ld dyn b'log stat: %-3.1f%%        50%%-75%%: %-3.1f%%\n",
-          (long) host->gArtsHostSleep,
-          host->backlogFilter*100.0*(1.0-host->params->dynBacklogFilter),
-          100.0 * host->blQuartile[2] / cnt) ;
-
-  fprintf (fp, " unspooled: %-7ld dyn b'log fltr: %-3.1f       75%%-<100%%: %-3.1f%%\n",
-          (long) host->gArtsFromTape,
-          host->params->dynBacklogLowWaterMark,
-          100.0 * host->blQuartile[3] / cnt) ;
-
-  fprintf (fp, "  no queue: %-7ld avr.cxns queue: %-3.1f             full: %-3.1f%%\n",
-          (long) host->gNoQueue,
-          (double) host->gCxnQueue / (host->gArtsOffered ? host->gArtsOffered :1) ,
-          100.0 * host->blFull / cnt) ;
-  size=convsize(host->gArtsSizeAccepted, &tsize);
-  snprintf(buf,sizeof(buf),"%.3g %s", size, tsize);
-  fprintf (fp, "accpt size: %-8s drop-deferred: %-5s   defer length: %-3.1f\n",
-          buf, host->params->dropDeferred ? "true " : "false",
-           (double)host->dlAccum / cnt) ;
-  size=convsize(host->gArtsSizeRejected, &tsize);
-  snprintf(buf,sizeof(buf),"%.3g %s", size, tsize);
-  fprintf (fp, "rejct size: %-8s min-queue-cxn: %s\n",
-          buf, host->params->minQueueCxn ? "true " : "false");
-
-  tapeLogStatus (host->myTape,fp) ;
-
-  {
-  time_t      sec = (time_t) (now - host->connectTime);
-  double      or, ar, rr, jr;
-  double      ars, jrs;
-  char       *tars, *tjrs;
-  if (sec != 0) {
-      or = (double) host->artsOffered / (double) sec;
-      ar = (double) host->artsAccepted / (double) sec;
-      rr = (double) host->artsNotWanted / (double) sec;
-      jr = (double) host->artsRejected / (double) sec;
-      ars = convsize (host->artsSizeAccepted/sec, &tars);
-      jrs = convsize (host->artsSizeRejected/sec, &tjrs);
-      fprintf(fp, "   offered: %5.2f art/s   accepted: %5.2f art/s, %.3g %s/s\n",
-             or, ar, ars, tars);
-      fprintf(fp, "   refused: %5.2f art/s   rejected: %5.2f art/s, %.3g %s/s\n",
-             rr, jr, jrs, tjrs);
-  }
-  fprintf(fp, "   missing %d spooled %d\n",
-         host->artsMissing, host->artsToTape);
-  }
-
-#ifdef        XXX_STATSHACK
-  {
-  time_t      now = time(NULL), sec = (long) (now - host->connectTime);
-  float               or, ar, rr, jr;
-
-  if (sec != 0) {
-      or = (float) host->artsOffered / (float) sec;
-      ar = (float) host->artsAccepted / (float) sec;
-      rr = (float) host->artsNotWanted / (float) sec;
-      jr = (float) host->artsRejected / (float) sec;
-      fprintf(fp, "\t\tor %02.2f ar %02.2f rr %02.2f jr %02.2f\n",
-              or, ar, rr, jr);
-  }
-  fprintf(fp, "\tmissing %d spooled %d\n",
-      host->artsMissing,host->backlogSpooled);
-  }
-#endif        /* XXX_STATSHACK */
-  
-  fprintf (fp, "\n\n");
-}
-
-
-
-
-
-
-\f
-/*
- * The callback function for the statistics timer to call.
- */
-static void hostStatsTimeoutCbk (TimeoutId tid UNUSED, void *data)
-{
-  Host host = (Host) data ;
-  time_t now = theTime () ;
-
-  ASSERT (tid == host->statsId) ;
-  
-  if (!amClosing (host))
-    hostLogStats (host, false) ;
-
-  if (now - lastStatusLog >= statsPeriod)
-    hostLogStatus () ;
-  
-  host->statsId = prepareSleep (hostStatsTimeoutCbk, statsPeriod, host) ;
-}
-
-
-/*
- * The callback function for the deferred article timer to call.
- */
-static void hostDeferredArtCbk (TimeoutId tid UNUSED, void *data)
-{
-  Host host = (Host) data ;
-  time_t now = theTime () ;
-  Article article ;
-
-  ASSERT (tid == host->deferredId) ;
-
-  while (host->deferred && host->deferred->whenToRequeue <= now)
-    {
-      article = remHead (&host->deferred,&host->deferredTail) ;
-      host->deferLen-- ;
-      hostSendArticle (host, article) ; /* requeue it */
-    }
-
-  if (host->deferred)
-    host->deferredId = prepareSleep (hostDeferredArtCbk,
-                                    host->deferred->whenToRequeue - now,
-                                    host) ;
-  else
-    host->deferredId = 0;
-}
-
-
-/* if the host has too many unprocessed articles so we send some to the tape. */
-static void backlogToTape (Host host)
-{
-  Article article ;
-
-  while ((host->backlog + host->deferLen) > hostHighwater)
-    {
-      if (!host->loggedBacklog)
-       {
-         host->loggedBacklog = true ;
-       }
-  
-      if (host->deferred != NULL)
-       {
-         article = remHead (&host->deferred,&host->deferredTail) ;
-          host->deferLen--;
-       }
-      else
-       {
-         article = remHead (&host->queued,&host->queuedTail) ;
-          host->backlog--;
-       }
-
-      ASSERT(article != NULL);
-
-      host->artsQueueOverflow++ ;
-      host->gArtsQueueOverflow++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape,article) ;
-    }
-}
-
-
-
-
-
-
-\f
-/*
- * Returns true of the Host is in the middle of closing down.
- */
-static bool amClosing (Host host)
-{
-  return (host->myTape == NULL ? true : false) ;
-}
-
-
-
-
-
-
-\f
-/*
- * flush all queued articles all the way out to disk.
- */
-static void queuesToTape (Host host)
-{
-  Article art ;
-  
-  while ((art = remHead (&host->processed,&host->processedTail)) != NULL)
-    {
-      host->artsHostClose++ ;
-      host->gArtsHostClose++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape,art) ;
-    }
-  
-  while ((art = remHead (&host->queued,&host->queuedTail)) != NULL)
-    {
-      host->backlog-- ;
-      host->artsHostClose++ ;
-      host->gArtsHostClose++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape,art) ;
-    }
-
-  while ((art = remHead (&host->deferred,&host->deferredTail)) != NULL)
-    {
-      host->deferLen-- ;
-      host->artsHostClose++ ;
-      host->gArtsHostClose++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape,art) ;
-    }
-
-  while ((art = remHead (&host->deferred,&host->deferredTail)) != NULL)
-    {
-      host->deferLen-- ;
-      host->artsHostClose++ ;
-      host->gArtsHostClose++ ;
-      host->artsToTape++ ;
-      host->gArtsToTape++ ;
-      procArtsToTape++ ;
-      tapeTakeArticle (host->myTape,art) ;
-    }
-}
-
-
-
-
-
-
-\f
-#define QUEUE_ELEM_POOL_SIZE ((4096 - 2 * (sizeof (void *))) / (sizeof (struct proc_q_elem)))
-
-static ProcQElem queueElemPool ;
-
-/*
- * Add an article to the given queue.
- */
-static void queueArticle (Article article, ProcQElem *head, ProcQElem *tail,
-                         time_t when)
-{
-  ProcQElem elem ;
-
-  if (queueElemPool == NULL)
-    {
-      unsigned int i ;
-
-      queueElemPool =
-        xmalloc (sizeof(struct proc_q_elem) * QUEUE_ELEM_POOL_SIZE) ;
-
-      for (i = 0; i < QUEUE_ELEM_POOL_SIZE - 1; i++)
-        queueElemPool[i] . next = &(queueElemPool [i + 1]) ;
-      queueElemPool [QUEUE_ELEM_POOL_SIZE-1] . next = NULL ;
-    }
-
-  elem = queueElemPool ;
-  ASSERT (elem != NULL) ;
-  queueElemPool = queueElemPool->next ;
-
-  elem->article = article ;
-  elem->next = NULL ;
-  elem->prev = *tail ;
-  elem->whenToRequeue = when ;
-  if (*tail != NULL)
-    (*tail)->next = elem ;
-  else
-    *head = elem ;
-  *tail = elem ;  
-}
-
-
-
-
-
-
-\f
-/*
- * remove the article from the queue
- */
-static bool remArticle (Article article, ProcQElem *head, ProcQElem *tail)
-{
-  ProcQElem elem ;
-
-  ASSERT (head != NULL) ;
-  ASSERT (tail != NULL) ;
-
-  /* we go backwards down the list--probably faster */
-  elem = *tail ;
-  while (elem != NULL && elem->article != article)
-    elem = elem->prev ;
-
-  if (elem != NULL)
-    {
-      if (elem->prev != NULL)
-        elem->prev->next = elem->next ;
-      if (elem->next != NULL)
-        elem->next->prev = elem->prev ;
-      if (*head == elem)
-        *head = elem->next ;
-      if (*tail == elem)
-        *tail = elem->prev ;
-
-      elem->next = queueElemPool ;
-      queueElemPool = elem ;
-      
-      return true ;
-    }
-  else
-    return false ;
-}
-
-
-
-
-
-
-\f
-/*
- * remove the article that's at the head of the queue and return
- * it. Returns NULL if the queue is empty.
- */
-static Article remHead (ProcQElem *head, ProcQElem *tail)
-{
-  ProcQElem elem ;
-  Article art ;
-
-  ASSERT (head != NULL) ;
-  ASSERT (tail != NULL) ;
-  ASSERT ((*head == NULL && *tail == NULL) ||
-          (*head != NULL && *tail != NULL)) ;
-
-  if (*head == NULL)
-    return NULL ;
-
-  elem = *head ;
-  art = elem->article ;
-  *head = elem->next ;
-  if (elem->next != NULL)
-    elem->next->prev = NULL ;
-
-  if (*tail == elem)
-    *tail = NULL ;
-
-  elem->next = queueElemPool ;
-  queueElemPool = elem ;
-
-  return art ;
-}
-
-
-
-static int validateInteger (FILE *fp, const char *name,
-                     long low, long high, int required, long setval,
-                    scope * sc, unsigned int inh)
-{
-  int rval = VALUE_OK ;
-  value *v ;
-  scope *s ;
-  char *p = strrchr (name,':') ;
-  
-  v = findValue (sc,name,inh) ;
-  if (v == NULL && required != NOTREQNOADD)
-    {
-      s = findScope (sc,name,0) ;
-      addInteger (s,p ? p + 1 : name,setval) ;
-      if (required == REQ)
-        {
-          rval = VALUE_MISSING ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: no definition for required key %s",name) ;
-        }
-      else if (required)
-        logOrPrint (LOG_INFO,fp,
-                    "ME config: adding missing key/value %s: %ld",name
-                    ,setval) ;
-    }
-  else if (v != NULL && v->type != intval)
-    {
-      rval = VALUE_WRONG_TYPE ;
-      logOrPrint (LOG_ERR,fp,"ME config: value of %s is not an integer",name) ;
-    }
-  else if (v != NULL && low != LONG_MIN && v->v.int_val < low)
-    {
-      rval = VALUE_TOO_LOW ;
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: value of %s (%ld) in %s is lower than minimum"
-                  " of %ld. Using %ld",name,v->v.int_val,
-                  "global scope",low,low) ;
-      v->v.int_val = low ;
-    }
-  else if (v != NULL && high != LONG_MAX && v->v.int_val > high)
-    {
-      rval = VALUE_TOO_HIGH ;
-      logOrPrint(LOG_ERR,fp,
-                 "ME config: value of %s (%ld) in %s is higher than maximum"
-                 " of %ld. Using %ld",name,v->v.int_val,
-                 "global scope",high,high);
-      v->v.int_val = high ;
-    }
-  
-  return rval ;
-}
-
-
-
-static int validateReal (FILE *fp, const char *name, double low,
-                         double high, int required, double setval,
-                        scope * sc, unsigned int inh)
-{
-  int rval = VALUE_OK ;
-  value *v ;
-  scope *s ;
-  char *p = strrchr (name,':') ;
-  
-  v = findValue (sc,name,inh) ;
-  if (v == NULL && required != NOTREQNOADD)
-    {
-      s = findScope (sc,name,0) ;
-      addReal (s,p ? p + 1 : name,setval) ;
-      if (required == REQ)
-        {
-          rval = VALUE_MISSING ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: no definition for required key %s",name) ;
-        }
-      else
-        logOrPrint (LOG_INFO,fp,
-                    "ME config: adding missing key/value %s: %f",name,
-                    setval) ;
-    }
-  else if (v != NULL && v->type != realval)
-    {
-      rval = VALUE_WRONG_TYPE ;
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: value of %s is not a floating point number",
-                  name) ;
-    }
-  else if (v != NULL && low != -DBL_MAX && v->v.real_val < low)
-    {
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: value of %s (%f) is lower than minimum of %f",
-                  name,v->v.real_val,low) ;
-      v->v.real_val = setval ;
-    }
-  else if (v != NULL && high != DBL_MAX && v->v.real_val > high)
-    {
-      logOrPrint (LOG_ERR,fp,
-                  "ME config: value of %s (%f) is higher than maximum of %f",
-                  name,v->v.real_val,high) ;
-      v->v.real_val = setval ;
-    }
-    
-  return rval ;
-}
-
-
-
-static int validateBool (FILE *fp, const char *name, int required, bool setval,
-                        scope * sc, unsigned int inh)
-{
-  int rval = VALUE_OK ;
-  value *v ;
-  scope *s ;
-  char *p = strrchr (name,':') ;
-  
-  v = findValue (sc,name,inh) ;
-  if (v == NULL && required != NOTREQNOADD)
-    {
-      s = findScope (sc,name,0) ;
-      addBoolean (s,p ? p + 1 : name, setval ? 1 : 0)  ;
-      if (required == REQ)
-        {
-          rval = VALUE_MISSING ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: no definition for required key %s",name) ;
-        }
-      else
-        logOrPrint (LOG_INFO,fp,
-                    "ME config: adding missing key/value %s: %s",name,
-                    (setval ? "true" : "false")) ;
-    }
-  else if (v != NULL && v->type != boolval)
-    {
-      rval = VALUE_WRONG_TYPE ;
-      logOrPrint (LOG_ERR,fp,"ME config: value of %s is not a boolean",name) ;
-    }
-  
-  return rval ;
-}
-
-
-void gCalcHostBlStat (void)
-{
-  Host h ;
-  
-  for (h = gHostList ; h != NULL ; h = h->next)
-    {
-      h->dlAccum += h->deferLen ;
-      h->blAccum += h->backlog ;
-      if (h->backlog == 0)
-          h->blNone++ ;
-      else if (h->backlog >= (hostHighwater - h->deferLen))
-          h->blFull++ ;
-      else
-          h->blQuartile[(4*h->backlog) / (hostHighwater - h->deferLen)]++ ;
-      h->blCount++ ;
-    }
-}
-static void hostCleanup (void)
-{
-  if (statusFile != NULL)
-    free (statusFile) ;
-  statusFile = NULL ;
-}
diff --git a/innfeed/host.h b/innfeed/host.h
deleted file mode 100644 (file)
index d773895..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*  $Id: host.h 7778 2008-04-17 21:27:22Z iulius $
-**
-**  The public interface to the Host class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The Host class represents the remote news system that we're feeding.  A
-**  Host object has possibly multiple connections to the remote system which
-**  it sends articles down.  It is given the articles by other objects
-**  (typically the InnListener), and once taken it assumes all responsibility
-**  for transmission or temporary storage on network failures etc.
-*/
-
-#if ! defined ( host_h__ )
-#define host_h__
-
-
-#include <stdio.h>
-
-#include "misc.h"
-
-/*
- * Functions from elsewhere used by host.c
- */
-
-extern void mainLogStatus (FILE *fp) ;
-
-
-/*
- * Functions used by the InnListener
- */
-
-
-/*
- * Create a new Host object.
- *
- * NAME is the name that INN uses.
- * IPNAME is the name the networking code uses (or the ascii dotted quad
- *    IP address).
- * ARTTIMEOUT is the max amount of time we'll wait for a new article
- *    from INN before considering the connection unused and we'll close
- *    down.
- * RESPTIMEOUT is the max amount of time we'll wait for any reponse
- *    from a remote. Past this we'll close down the network connection.
- * INITIALCXNS is the number of Connections to create at Host creation time.
- * MAXCXNS is the maximum number of parallel connections to the
- *    remote host we can run at any one time.
- * MAXCHECK is the maximum number of nntp CHECK commands to be outstanding
- *    on a connection before opening up a new connection (or refusing
- *    new articles if we get to MAXCXNS).
- * PORTNUM is the port number on the remote host we should talk to.
- * CLOSEPERIOD is the number of seconds after connecting that the
- *     connections should be closed down and reinitialized (due to problems
- *     with old NNTP servers that hold history files open. Value of 0 means
- *     dont close down.
- * STREAMING is a boolean flag to tell if the Host wants its Connections to
- *     do streaming or not.
- * LOWPASSHIGH is the high value for the low-pass filter.
- * LOWPASSLOW is the low value for the low-pass filter.
- */
-
-void configHosts (bool talkSelf) ;
-
-/* print some debugging info. */
-void gPrintHostInfo (FILE *fp, unsigned int indentAmt) ;
-void printHostInfo (Host host, FILE *fp, unsigned int indentAmt) ;
-
-/* Delete the host object. Drops all the active connections immediately
-   (i.e. no QUIT) . */
-void delHost (Host host) ;
-
-/* Get a new default host object */
-Host newDefaultHost (InnListener listener,
-                    const char *name); 
-
-/* gently close down all the host's connections (issue QUITs). */
-void hostClose (Host host) ;
-
-/* gently close down all active connections (issue QUITs) and recreate
-   them immediately */
-void hostFlush (Host host) ;
-
-/* have the HOST transmit the ARTICLE, or, failing that, store article
-   information for later attempts. */
-void hostSendArticle (Host host, Article article) ;
-
-/* return an IP address for the host */
-struct sockaddr *hostIpAddr (Host host, int family) ;
-
-/* Delete all IPv4 addresses from the address list */
-void hostDeleteIpv4Addr (Host host);
-
-/* mark the current IP address as failed and rotate to the next one */
-void hostIpFailed (Host host) ;
-
-/*
- * Functions used by the Connection to indicate Connection state.
- */
-
-/* called by the Host's connection when the remote is refusing
-   postings. Code 400 in the banner */
-void hostCxnBlocked (Host host, Connection cxn, char *reason) ;
-
-/* called by the Connection when it has determined if the remote supports
-   the streaming extension or not. */
-void hostRemoteStreams (Host host, Connection cxn, bool doesStream) ;
-
-/* Called by the connection when it is no longer connected to the
-   remote. Perhaps due to getting a code 400 to an IHAVE. */
-void hostCxnDead (Host host, Connection cxn) ;
-
-/* Called when the Connection deletes itself */
-bool hostCxnGone (Host host, Connection cxn) ;
-
-/* Called when the Connection goes to sleep. */
-void hostCxnSleeping (Host host, Connection cxn) ;
-
-/* Called when the Connection starts waiting for articles. */
-void hostCxnWaiting (Host host, Connection cxn) ;
-
-
-
-/* Called when the connection has sent an IHAVE or a CHECK, or a TAKETHIS
-   when in no-check mode.*/
-void hostArticleOffered (Host host, Connection cxn) ;
-
-/* called by the Connection when the article was transferred. */
-void hostArticleAccepted (Host host, Connection cxn, Article article) ;
-
-/* Called by the connection when the remote answered 435 or 438 */
-void hostArticleNotWanted (Host host, Connection cxn, Article article) ;
-
-/* Called by the connection when the remote answered 437 or 439 */
-void hostArticleRejected (Host host, Connection cxn, Article article) ;
-
-/* Called when the connection when the remote answered 400 or 431 or 436 */
-void hostArticleDeferred (Host host, Connection cxn, Article article) ;
-
-/* Called by the connection if it discovers the file is gone. */
-void hostArticleIsMissing (Host host, Connection cxn, Article article) ;
-
-
-/* Called by the connection when it wants to defer articles, but it
-   doesn't want the Host to queue any news on it. */
-void hostTakeBackArticle (Host host, Connection cxn, Article article) ;
-
-
-/* called by the Connection when it is idle and wants to get things
-   moving. Returns true if there was something to do and the Host called
-   cxnQueueArticle() . */
-bool hostGimmeArticle (Host host, Connection cxn) ;
-
-/* get the name that INN uses for this host */
-const char *hostPeerName (Host host) ;
-
-/* get the bindaddress */
-const struct sockaddr_in *hostBindAddr(Host host) ;
-#ifdef HAVE_INET6
-const struct sockaddr_in6 *hostBindAddr6(Host host) ;
-int hostAddrFamily (Host host);
-#endif
-
-/* get the username and password for authentication */
-const char *hostUsername (Host host) ;
-const char *hostPassword (Host host) ;
-
-/* if VAL is true then each time the host logs its stats all its
-   connections will too. */
-void hostLogConnectionStats (bool val) ;
-bool hostLogConnectionStatsP (void) ;
-
-#if 0
-/* Set the frequency (in seconds) with which we log statistics */
-void hostSetStatsPeriod (unsigned int period) ;
-#endif
-
-/* return whether or not the Connections should attempt to stream. */
-bool hostWantsStreaming (Host host) ;
-
-/* return maxChecks */
-unsigned int hostmaxChecks (Host host);
-
-/* return if we should drop deferred articles */
-bool hostDropDeferred (Host host);
-
-/* return the maximum number of CHECKs that can be outstanding */
-unsigned int hostMaxChecks (Host host) ;
-
-/* Called by the Host's connections when they go into (true) or out of
-   (false) no-CHECK mode. */
-void hostLogNoCheckMode (Host host, bool on, double low, double cur, double high) ;
-
-/* calculate host backlog statistics */
-void gCalcHostBlStat (void) ;
-
-/* calculate host global statistics */
-void gHostStats (void) ;
-
-/* set the pathname of the file to use instead of innfeed.status */
-void hostSetStatusFile (const char *filename) ;
-
-/* function called when config file is loaded. */
-int hostConfigLoadCbk (void *data) ;
-
-void hostChkCxns(TimeoutId tid, void *data);
-
-#endif /* host_h__ */
diff --git a/innfeed/imap_connection.c b/innfeed/imap_connection.c
deleted file mode 100644 (file)
index f575686..0000000
+++ /dev/null
@@ -1,4681 +0,0 @@
-/*  $Id: imap_connection.c 7103 2004-12-23 22:36:27Z rra $
-**
-**  Feed articles to an IMAP server via LMTP and IMAP.
-**
-**  Written by Tim Martin.
-**
-**  Instead of feeding articles via nntp to another host this feeds the
-**  messages via lmtp to a host and the control messages (cancel's etc..) it
-**  performs via IMAP.  This means it has 2 active connections at any given
-**  time and 2 queues.
-**
-**  When an article comes in it is immediatly placed in the lmtp queue. When
-**  an article is picked off the lmtp queue for processing first check if it's
-**  a control message.  If so, place it in the IMAP queue.  If not, attempt to
-**  deliver via LMTP.
-**
-**  This attempts to follow the exact same api as connection.c.
-**  
-**  TODO:
-**  
-**  feed to smtp 
-**  security layers?  <--punt on for now
-**  authname/password per connection object
-**  untagged IMAP messages
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#include <netdb.h>
-#include <time.h>
-#include <syslog.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "buffer.h"
-#include "connection.h"
-#include "endpoint.h"
-#include "host.h"
-#include "innfeed.h"
-#include "article.h"
-#include "configfile.h"
-
-#ifdef HAVE_SASL
-# include <sasl/sasl.h>
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 1024
-#endif
-
-#define IMAP_PORT 143
-
-#ifdef SMTPMODE
-# define LMTP_PORT 25
-#else
-# define LMTP_PORT 2003
-#endif
-
-#define IMAP_TAGLENGTH 6
-
-#define QUEUE_MAX_SIZE 250
-
-#define DOSOMETHING_TIMEOUT 60
-
-
-
-/* external */
-extern char *deliver_username;
-extern char *deliver_authname;
-extern char *deliver_password;
-extern char *deliver_realm;
-extern char *deliver_rcpt_to;
-extern char *deliver_to_header;
-
-
-char hostname[MAXHOSTNAMELEN];
-char *mailfrom_name = NULL; /* default to no return path */
-
-#ifdef HAVE_SASL
-static int initialized_sasl = 0; /* weather sasl_client_init() has been called */
-#endif
-
-/* states the imap connection may be in */
-typedef enum {
-
-    IMAP_DISCONNECTED = 1,
-    IMAP_WAITING,
-    
-    IMAP_CONNECTED_NOTAUTH,
-
-    IMAP_READING_INTRO,
-
-    IMAP_WRITING_CAPABILITY,
-    IMAP_READING_CAPABILITY,
-
-    IMAP_WRITING_STARTAUTH,
-    IMAP_READING_STEPAUTH,
-    IMAP_WRITING_STEPAUTH,
-
-    IMAP_IDLE_AUTHED,
-    IMAP_WRITING_NOOP,
-    IMAP_READING_NOOP,
-
-    IMAP_WRITING_CREATE,
-    IMAP_READING_CREATE,
-
-    IMAP_WRITING_DELETE,
-    IMAP_READING_DELETE,
-
-    IMAP_WRITING_SELECT,
-    IMAP_READING_SELECT,
-
-    IMAP_WRITING_SEARCH,
-    IMAP_READING_SEARCH,
-
-    IMAP_WRITING_STORE,
-    IMAP_READING_STORE,
-    
-    IMAP_WRITING_CLOSE,
-    IMAP_READING_CLOSE,
-
-    IMAP_WRITING_QUIT,
-    IMAP_READING_QUIT
-   
-} imap_state_t;
-
-typedef enum {
-    LMTP_DISCONNECTED = 1,
-    LMTP_WAITING,
-
-    LMTP_CONNECTED_NOTAUTH,
-
-    LMTP_READING_INTRO,
-
-    LMTP_WRITING_LHLO,
-    LMTP_READING_LHLO,
-
-    LMTP_WRITING_STARTAUTH,
-    LMTP_READING_STEPAUTH,
-    LMTP_WRITING_STEPAUTH,
-
-    LMTP_AUTHED_IDLE,
-    LMTP_WRITING_NOOP,
-    LMTP_READING_NOOP,
-   
-    LMTP_READING_RSET,
-    LMTP_READING_MAILFROM,
-    LMTP_READING_RCPTTO,
-    LMTP_READING_DATA,
-    LMTP_READING_CONTENTS,
-
-    LMTP_WRITING_UPTODATA,
-    LMTP_WRITING_CONTENTS,
-
-    LMTP_WRITING_QUIT,
-    LMTP_READING_QUIT
-
-} lmtp_state_t;
-
-typedef struct imap_capabilities_s {
-
-    int imap4;         /* does server support imap4bis? */
-    int logindisabled; /* does the server allow the login command? */
-
-    char *saslmechs;   /* supported SASL mechanisms */
-
-} imap_capabilities_t;
-
-typedef struct lmtp_capabilities_s {
-
-    int Eightbitmime;
-    int EnhancedStatusCodes;
-    int pipelining;
-
-    char *saslmechs;
-
-} lmtp_capabilities_t;
-
-typedef enum {
-    STAT_CONT = 0,
-    STAT_NO = 1,
-    STAT_OK = 2,
-    STAT_FAIL = 3
-} imt_stat;
-
-/* Message types */
-typedef enum {
-    DELIVER,
-    CREATE_FOLDER,
-    CANCEL_MSG,
-    DELETE_FOLDER
-} control_type_t;
-
-typedef struct control_item_s {
-
-    Article article;
-    char *folder;
-    char *msgid;                 /* only for cancel's */
-    unsigned long  uid;          /* only for cancel's */
-
-} control_item_t;
-
-typedef struct article_queue_s {
-
-    control_type_t type;
-
-    time_t arrived;
-    time_t nextsend; /* time we should next try to send article */
-
-    int trys;
-
-    int counts_toward_size;
-
-    union {
-       Article article;
-       control_item_t *control;
-       void *generic;
-    } data;
-
-    struct article_queue_s *next;
-
-} article_queue_t;
-
-typedef struct Q_s {
-
-    article_queue_t *head;
-
-    article_queue_t *tail;
-
-    int size;
-
-} Q_t;
-
-typedef struct connection_s {
-
-    /* common stuff */
-    char *ServerName;
-
-    char *lmtp_respBuffer;         /* buffer all responses are read into */
-    Buffer lmtp_rBuffer;           /* buffer all responses are read into */
-
-    Host myHost ;                   /* the host who owns the connection */
-    
-    time_t timeCon ;                /* the time the connect happened 
-                                      (last auth succeeded) */
-
-    int issue_quit;                 /* Three states:
-                                    *   0 - don't do anything
-                                    *   1 - after issue quit enter wait state
-                                    *   2 - after issue quit reconnect
-                                    *   3 - after issue quit delete connection
-                                    *   4 - nuke cxn
-                                    */
-
-    /* Statistics */    
-    int lmtp_succeeded;
-    int lmtp_failed;
-
-    int cancel_succeeded;
-    int cancel_failed;
-    
-    int create_succeeded;
-    int create_failed;
-    
-    int remove_succeeded;
-    int remove_failed;
-
-    
-    /* LMTP stuff */
-    int lmtp_port;
-    lmtp_state_t lmtp_state;
-#ifdef HAVE_SASL
-    sasl_conn_t *saslconn_lmtp;
-#endif /* HAVE_SASL */
-    int sockfd_lmtp;
-
-    time_t lmtp_timeCon ;
-
-    EndPoint lmtp_endpoint;
-    unsigned int ident ;               /* an identifier for syslogging. */
-
-    lmtp_capabilities_t *lmtp_capabilities;
-
-    int lmtp_disconnects;
-    char *lmtp_tofree_str;
-
-    article_queue_t *current_article;
-    Buffer *current_bufs;
-    int     current_rcpts_issued;
-    int     current_rcpts_okayed;
-
-    /* Timer for the max amount of time to wait for a response from the
-       remote */
-    unsigned int lmtp_readTimeout ;
-    TimeoutId lmtp_readBlockedTimerId ;
-
-    /* Timer for the max amount of time to wait for a any amount of data
-       to be written to the remote */
-    unsigned int lmtp_writeTimeout ;
-    TimeoutId lmtp_writeBlockedTimerId ;
-
-    /* Timer for the number of seconds to sleep before attempting a
-       reconnect. */
-    unsigned int lmtp_sleepTimeout ;
-    TimeoutId lmtp_sleepTimerId ;
-
-    /* Timer for max amount between queueing some articles and trying to send them */
-    unsigned int dosomethingTimeout ;
-    TimeoutId dosomethingTimerId ;
-
-    Q_t lmtp_todeliver_q;
-
-
-
-    /* IMAP stuff */
-    int imap_port;
-#ifdef HAVE_SASL
-    sasl_conn_t *imap_saslconn;
-#endif /* HAVE_SASL */
-
-    char *imap_respBuffer;
-    Buffer imap_rBuffer;
-    EndPoint imap_endpoint;
-
-    imap_capabilities_t *imap_capabilities;
-    
-    int imap_sockfd;
-
-    time_t imap_timeCon ;
-
-    imap_state_t imap_state;
-    int imap_disconnects;
-    char *imap_tofree_str;
-
-    char imap_currentTag[IMAP_TAGLENGTH];
-    int  imap_tag_num;
-
-    /* Timer for the max amount of time to wait for a response from the
-       remote */
-    unsigned int imap_readTimeout ;
-    TimeoutId imap_readBlockedTimerId ;
-
-    /* Timer for the max amount of time to wait for a any amount of data
-       to be written to the remote */
-    unsigned int imap_writeTimeout ;
-    TimeoutId imap_writeBlockedTimerId ;
-
-    /* Timer for the number of seconds to sleep before attempting a
-       reconnect. */
-    unsigned int imap_sleepTimeout ;
-    TimeoutId imap_sleepTimerId ;
-
-    Q_t imap_controlMsg_q;
-
-    article_queue_t *current_control;
-
-    struct connection_s *next;
-
-} connection_t;
-
-static Connection gCxnList = NULL ;
-static unsigned int gCxnCount= 0 ;
-static unsigned int max_reconnect_period = MAX_RECON_PER ;
-static unsigned int init_reconnect_period = INIT_RECON_PER;
-
-typedef enum {
-    RET_OK = 0,
-    RET_FAIL = 1,
-    RET_QUEUE_EMPTY,
-    RET_EXCEEDS_SIZE,
-    RET_NO_FULLLINE,
-    RET_NO,
-    RET_ARTICLE_BAD
-} conn_ret;
-
-
-/********** Private Function Declarations *************/
-
-static void lmtp_readCB (EndPoint e, IoStatus i, Buffer *b, void *d);
-static void imap_readCB (EndPoint e, IoStatus i, Buffer *b, void *d);
-static void imap_writeCB (EndPoint e, IoStatus i, Buffer *b, void *d);
-static void lmtp_writeCB (EndPoint e, IoStatus i, Buffer *b, void *d);
-
-static conn_ret lmtp_Connect(connection_t *cxn);
-static conn_ret imap_Connect(connection_t *cxn);
-
-static void prepareReopenCbk (Connection cxn, int type);
-
-static void lmtp_readTimeoutCbk (TimeoutId id, void *data);
-static void imap_readTimeoutCbk (TimeoutId id, void *data);
-
-static void dosomethingTimeoutCbk (TimeoutId id, void *data);
-
-static conn_ret WriteToWire_imapstr(connection_t *cxn, char *str, int slen);
-static conn_ret WriteToWire_lmtpstr(connection_t *cxn, char *str, int slen);
-
-static conn_ret WriteToWire(connection_t *cxn, EndpRWCB callback, 
-                           EndPoint endp, Buffer *array);
-static void lmtp_sendmessage(connection_t *cxn, Article justadded);
-static void imap_ProcessQueue(connection_t *cxn);
-
-static conn_ret FindHeader(Buffer *bufs, const char *header, char **start, char **end);
-static conn_ret PopFromQueue(Q_t *q, article_queue_t **item);
-
-enum failure_type {
-    MSG_SUCCESS = 0,
-    MSG_FAIL_DELIVER = 1,
-    MSG_GIVE_BACK = 2,
-    MSG_MISSING = 3
-};
-
-static void QueueForgetAbout(connection_t *cxn, article_queue_t *item, 
-                            enum failure_type failed);
-
-static void delConnection (Connection cxn);
-static void DeleteIfDisconnected(Connection cxn);
-static void DeferAllArticles(connection_t *cxn, Q_t *q);
-
-static void lmtp_Disconnect(connection_t *cxn);
-static void imap_Disconnect(connection_t *cxn);
-static conn_ret imap_listenintro(connection_t *cxn);
-
-static void imap_writeTimeoutCbk (TimeoutId id, void *data);
-static void lmtp_writeTimeoutCbk (TimeoutId id, void *data);
-
-/******************** PRIVATE FUNCTIONS ***************************/
-
-static const char *imap_stateToString(int state)
-{
-    switch (state)
-       {
-       case IMAP_DISCONNECTED: return "disconnected";   
-       case IMAP_WAITING: return "waiting";
-       case IMAP_CONNECTED_NOTAUTH: return "connected (unauthenticated)";
-       case IMAP_READING_INTRO: return "reading intro";
-       case IMAP_WRITING_CAPABILITY: return "writing CAPABILITY";
-       case IMAP_READING_CAPABILITY: return "reading CAPABILITY";
-       case IMAP_WRITING_STARTAUTH: return "writing AUTHENTICATE";
-       case IMAP_READING_STEPAUTH: return "reading stepauth";
-       case IMAP_WRITING_STEPAUTH: return "writing stepauth";
-       case IMAP_IDLE_AUTHED: return "idle (authenticated)";
-       case IMAP_WRITING_NOOP: return "writing NOOP";
-       case IMAP_READING_NOOP: return "reading NOOP response";
-       case IMAP_WRITING_CREATE: return "writing CREATE";
-       case IMAP_READING_CREATE: return "reading CREATE response";
-       case IMAP_WRITING_DELETE: return "writing DELETE command";
-       case IMAP_READING_DELETE: return "reading DELETE response";            
-       case IMAP_WRITING_SELECT: return "writing SELECT";
-       case IMAP_READING_SELECT: return "reading SELECT response";
-       case IMAP_WRITING_SEARCH: return "writing SEARCH";
-       case IMAP_READING_SEARCH: return "reading SEARCH response";
-       case IMAP_WRITING_STORE: return "writing STORE";
-       case IMAP_READING_STORE: return "reading STORE response";           
-       case IMAP_WRITING_CLOSE: return "writing CLOSE";
-       case IMAP_READING_CLOSE: return "reading CLOSE response";
-       case IMAP_WRITING_QUIT: return "writing LOGOUT";
-       case IMAP_READING_QUIT: return "reading LOGOUT response";
-       default: return "Unknown state";
-       }
-}
-
-static const char *lmtp_stateToString(int state)
-{
-    switch(state)
-       {
-       case LMTP_DISCONNECTED: return "disconnected";
-       case LMTP_WAITING: return "waiting";
-       case LMTP_CONNECTED_NOTAUTH: return "connected (unauthenticated)";
-       case LMTP_READING_INTRO: return "reading intro";
-       case LMTP_WRITING_LHLO: return "writing LHLO";
-       case LMTP_READING_LHLO: return "reading LHLO response";
-       case LMTP_WRITING_STARTAUTH: return "writing AUTH";
-       case LMTP_READING_STEPAUTH: return "reading stepauth";
-       case LMTP_WRITING_STEPAUTH: return "writing stepauth";
-       case LMTP_AUTHED_IDLE: return "idle (authenticated)";
-       case LMTP_WRITING_NOOP: return "writing NOOP";
-       case LMTP_READING_NOOP: return "reading NOOP response";
-       case LMTP_READING_RSET: return "reading RSET response";
-       case LMTP_READING_MAILFROM: return "reading MAIL FROM response";
-       case LMTP_READING_RCPTTO: return "reading RCPT TO response";
-       case LMTP_READING_DATA: return "reading DATA response";
-       case LMTP_READING_CONTENTS: return "reading contents response";
-       case LMTP_WRITING_UPTODATA: 
-           return "writing RSET, MAIL FROM, RCPT TO, DATA commands";
-       case LMTP_WRITING_CONTENTS: return "writing contents of message";
-       case LMTP_WRITING_QUIT: return "writing QUIT";
-       case LMTP_READING_QUIT: return "reading QUIT";
-       default: return "unknown state";
-       }
-}
-
-/******************************* Queue functions ***********************************/
-
-/*
- * Add a message to a generic queue
- *
- *  q       - the queue adding to
- *  item    - the data to add to the queue
- *  type    - the type of item it is (i.e. cancel,lmtp,etc..)
- *  addsmsg - weather this should be counted toward the queue size
- *            this is for control msg's that create multiple queue items.
- *            For example a cancel message canceling a message in multiple
- *            newsgroups will create >1 queue item but we only want it to count
- *            once towards the queue
- *  must    - wheather we must take it even though it may put us over our max size
- */
-
-static conn_ret AddToQueue(Q_t *q, void *item, 
-                          control_type_t type, int addsmsg, bool must)
-{
-    article_queue_t *newentry;
-
-    if (must == false)
-    {
-       if (q->size >= QUEUE_MAX_SIZE)
-        {
-           return RET_EXCEEDS_SIZE;
-       }
-    } else {
-       if (q->size >= QUEUE_MAX_SIZE * 10)
-        {
-           d_printf(0, "Queue has grown way too much. Dropping article\n");
-           return RET_FAIL;
-       }
-    }
-
-    /* add to the end of our queue */
-    newentry = xmalloc(sizeof(article_queue_t));
-
-    newentry->type = type;
-
-    /* send as soon as possible */
-    newentry->nextsend = newentry->arrived = time(NULL);
-
-    newentry->trys = 0;
-
-    newentry->data.generic = item;
-    newentry->next = NULL;
-    newentry->counts_toward_size = addsmsg;
-
-    /* add to end of queue */
-    if (q->tail == NULL)
-    {
-       q->head = newentry;
-       q->tail = newentry;
-    } else {
-
-       q->tail->next = newentry;
-       q->tail = newentry;
-    }
-
-    q->size+=addsmsg;
-
-    return RET_OK;
-}
-
-/*
- * Pop an item from the queue
- *
- * q    - the queue to pop from
- * item - where the item shall be placed upon sucess
- *
- */
-
-static conn_ret PopFromQueue(Q_t *q, article_queue_t **item)
-{
-    /* if queue empty return error */
-    if ( q->head == NULL)
-    {
-       return RET_QUEUE_EMPTY;
-    }
-    
-    /* set what we return */
-    *item = q->head;
-
-    q->head = q->head->next;
-    if (q->head == NULL) q->tail = NULL;
-
-    q->size-=(*item)->counts_toward_size;
-    
-    return RET_OK;
-}
-
-/*
- * ReQueue an item. Will either put it back in the queue for another try
- * or forget about it
- *
- *  cxn     - our connection object (needed so forget about things)
- *  q       - the queue to requeue to 
- *  entry   - the item to put back
- */
-
-static void ReQueue(connection_t *cxn, Q_t *q, article_queue_t *entry)
-{
-    /* look at the time it's been here */
-    entry->nextsend = time(NULL) + (entry->trys *30); /* xxx better formula? */
-
-    entry->trys++;
-    
-    /* give up after 5 tries xxx configurable??? */
-    if (entry->trys >= 5)
-    {
-       QueueForgetAbout(cxn, entry, MSG_FAIL_DELIVER);
-       return;
-    }
-
-
-    /* ok let's add back to the end of the queue */
-    entry->next = NULL;
-
-    /* add to end of queue */
-    if (q->tail == NULL)
-    {
-       q->head = entry;
-       q->tail = entry;
-    } else {
-       q->tail->next = entry;
-       q->tail = entry;
-    }
-
-    q->size+=entry->counts_toward_size;
-}
-
-
-
-/*
- * Forget about an item. Tells host object if we succeeded/failed/etc with the message
- *
- * cxn    - connection object
- * item   - item
- * failed - type of failure (see below)
- *
- * failed:
- *   0 - succeeded delivering message
- *   1 - failed delivering message
- *   2 - Try to give back to host
- *   3 - Article missing (i.e. can't find on disk)
- */
-static void QueueForgetAbout(connection_t *cxn, article_queue_t *item, 
-                            enum failure_type failed)
-{
-    Article art = NULL;
-    
-    switch (item->type)
-       {
-       case DELIVER:
-           if (failed>0)
-               cxn->lmtp_failed++;
-           art = item->data.article;
-           break;
-
-       case CANCEL_MSG:
-           if (failed>0)
-               cxn->cancel_failed++;
-           free(item->data.control->msgid);
-           free(item->data.control->folder);
-
-           if (item->counts_toward_size == 1)
-               art = item->data.control->article;
-
-           free(item->data.control );
-           break;
-
-       case CREATE_FOLDER: 
-           if (failed>0)
-               cxn->create_failed++;
-           free(item->data.control->folder);
-
-           art = item->data.control->article;
-
-           free(item->data.control );
-           break;
-       case DELETE_FOLDER:
-           if (failed>0)
-               cxn->remove_failed++;
-           free(item->data.control->folder);
-
-           art = item->data.control->article;
-
-           free(item->data.control );
-           break;
-
-       default:
-           d_printf(0, "%s:%d QueueForgetAbout(): "
-                    "Unknown type to forget about\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           break;
-       }
-
-    if (art!=NULL) {
-       switch (failed) {
-       case MSG_SUCCESS:
-           hostArticleAccepted (cxn->myHost, cxn, art);
-           break;
-
-       case MSG_FAIL_DELIVER:
-           hostArticleRejected (cxn->myHost, cxn, art);
-           break;
-
-       case MSG_GIVE_BACK:
-           hostTakeBackArticle (cxn->myHost, cxn, art);
-           break;
-
-       case MSG_MISSING:
-           hostArticleIsMissing(cxn->myHost, cxn, art);
-           break;
-       default:
-           d_printf(0,"%s:%d QueueForgetAbout(): failure type unknown\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           break;
-       }
-    }
-
-    free(item);
-}
-
-/*
- * How much space is available in the queue
- */
-
-static int QueueSpace(Q_t *q)
-{
-    int ret = QUEUE_MAX_SIZE - q->size;
-    if (ret < 0) ret = 0;
-    return ret;
-}
-
-/*
- * How many items are in the queue
- */
-
-static int QueueItems(Q_t *q)
-{
-    return q->size;
-}
-
-
-/***************************** END Queue functions ***********************************/
-
-/***************************** Generic Parse Functions *******************************/
-
-/* returns the end of the header */
-
-static char *GetUntil(char *str)
-{
-    while (((*str) != '\0') && ( (*str) != '\r') && ( (*str) != '\n'))
-    {
-       str++;
-    }
-
-    return str;
-}
-
-static char *GotoNextLine(char *str)
-{
-    while (((*str) != '\0') && ( (*str) != '\r') && ( (*str) != '\n'))
-    {
-       str++;
-    }
-
-    if (*str == '\r') str++;
-    if (*str == '\n') str++;
-
-    return str;
-}
-
-/*
- * Finds the given header in the message
- *  Returns NULL if not found
- */
-static conn_ret FindHeader(Buffer *bufs, const char *header, char **start,
-       char **end)
-{
-    Buffer b;
-    int size;
-    char *str_base;
-    char *str;
-    int headerlen = strlen(header);
-    
-    if (bufs==NULL)
-    {
-       if (start)
-           *start=NULL; 
-       return RET_ARTICLE_BAD; 
-    }
-    
-    b = bufs[0];
-    size = bufferSize(b);
-    str_base = bufferBase(b);
-    str = str_base;
-    
-    while ((str - str_base) < size - headerlen)
-    {
-       if (*str == header[0])
-       {
-           if ((strncasecmp(header, str, headerlen)==0) && ( *(str + headerlen)==':'))
-           {
-
-               if (start)
-               {
-                   *start = str+headerlen+1;
-
-                   /* get rid of leading whitespace */
-                   while ( isspace((int) **start))                     
-                       (*start)++;
-               }
-               
-               if (end)
-                   *end = GetUntil(str+headerlen+1);
-               
-               return RET_OK;
-           }
-       } else if (*str == '\n') { 
-           /* end of headers */
-           return RET_NO;
-       }
-       str = GotoNextLine(str);
-    }
-
-    return RET_NO;
-}
-
-static conn_ret GetLine(char *buf, char *ret, int retmaxsize)
-{
-    char *str_base;
-    char *str;
-
-    int size = strlen(buf);
-    str_base = buf;
-    str = str_base;
-
-    while ( (*str) != '\0')
-    {
-       if ((*str) == '\n')
-        {
-           if (str-str_base > retmaxsize)
-           {
-               d_printf(0, "Max size exceeded! %s\n",str_base);
-               return RET_FAIL;
-           }
-
-           /* fill in the return string */
-           memcpy(ret, str_base, str-str_base);
-           ret[ str - str_base -1] = '\0';
-
-           memcpy( str_base, str_base + (str-str_base)+1, size - (str-str_base));
-           str_base[size - (str-str_base)]='\0';
-
-           return RET_OK;
-       }
-
-       str++;
-    }
-
-    /* couldn't find a full line */
-    return RET_NO_FULLLINE;
-}
-
-
-
-/************************** END Generic Parse Functions *******************************/
-
-/************************ Writing to Network functions *****************/
-
-static conn_ret WriteToWire(connection_t *cxn, EndpRWCB callback, 
-                           EndPoint endp, Buffer *array)
-{
-
-    if (array == NULL) return RET_FAIL;
-
-    prepareWrite (endp,
-                  array,
-                  NULL,
-                 callback,
-                  cxn);
-
-    return RET_OK;
-}
-
-static conn_ret WriteToWire_str(connection_t *cxn, EndpRWCB callback,
-                               EndPoint endp, char *str, int slen)
-{
-    conn_ret result;
-    Buffer buff;
-    Buffer *writeArr;
-
-    if (slen==-1) slen = strlen(str);
-
-    buff = newBufferByCharP(str, slen+1, slen);
-    ASSERT (buff != NULL);   
-
-    writeArr = makeBufferArray (buff, NULL) ;
-
-    result = WriteToWire(cxn, callback, endp, writeArr);
-
-    return result;
-}
-
-static conn_ret WriteToWire_imapstr(connection_t *cxn, char *str, int slen)
-{
-    /* prepare the timeouts */
-    clearTimer (cxn->imap_readBlockedTimerId) ;
-    
-    /* set up the write timer. */
-    clearTimer (cxn->imap_writeBlockedTimerId) ;
-
-    if (cxn->imap_writeTimeout > 0)
-       cxn->imap_writeBlockedTimerId = prepareSleep (imap_writeTimeoutCbk, cxn->imap_writeTimeout,
-                                                cxn);
-    cxn->imap_tofree_str = str;
-    return WriteToWire_str(cxn, imap_writeCB, cxn->imap_endpoint, str, slen);
-}
-
-static conn_ret WriteToWire_lmtpstr(connection_t *cxn, char *str, int slen)
-{
-    /* prepare the timeouts */
-    clearTimer (cxn->lmtp_readBlockedTimerId) ;
-    
-    /* set up the write timer. */
-    clearTimer (cxn->lmtp_writeBlockedTimerId) ;
-
-    if (cxn->lmtp_writeTimeout > 0)
-       cxn->lmtp_writeBlockedTimerId = prepareSleep (lmtp_writeTimeoutCbk, cxn->lmtp_writeTimeout,
-                                                cxn) ;
-
-
-
-    cxn->lmtp_tofree_str = str;
-    return WriteToWire_str(cxn, lmtp_writeCB, cxn->lmtp_endpoint, str, slen);
-}
-
-static conn_ret WriteArticle(connection_t *cxn, Buffer *array)
-{
-    int array_len = bufferArrayLen (array);
-    int lup=0;
-    int result;
-
-    for (lup=0;lup<array_len;lup++)
-    {
-       int current_size;
-       Buffer current_buf;
-       char *current_start;
-
-       current_buf = array[lup];
-               
-       current_size = bufferDataSize( current_buf );
-       
-       current_start = bufferBase( current_buf );
-
-    }
-
-    /* just call writetowire since it's easy */
-    result = WriteToWire(cxn, lmtp_writeCB, cxn->lmtp_endpoint, array);
-
-    if (result!=RET_OK)
-    {
-       return result;
-    }
-
-    cxn->lmtp_state = LMTP_WRITING_CONTENTS;
-
-    return RET_OK;
-}
-
-/************************ END Writing to Network functions *****************/
-
-
-
-/*
- * Adds a cancel item to the control queue
- * Cancel item to delete message with <msgid> in <folder>
- *
- * cxn       - connection object
- * folder    - pointer to start of folder string (this is a pointer into the actual message buffer)
- * folderlen - length of folder string 
- * msgid     - pointer to start of msgid string (this is a pointer into the actual message buffer)
- * msgidlen  - length of msgid string 
- * art       - the article for this control message (NULL if this cancel object lacks one)
- * must      - if must be accepted into queue
- */
-
-static conn_ret addCancelItem(connection_t *cxn, 
-                             char *folder, int folderlen,
-                             char *msgid, int msgidlen,
-                             Article art, int must)
-{
-    control_item_t *item;
-    conn_ret result;
-    int i;
-
-    ASSERT(folder); ASSERT(msgid); ASSERT(cxn);
-
-    /* sanity check folder, msgid */
-    for (i = 0; i < folderlen; i++) ASSERT(!isspace((int) folder[i]));
-    for (i = 0; i < msgidlen; i++) ASSERT(!isspace((int) msgid[i]));
-
-    /* create the object */
-    item = xcalloc (1, sizeof(control_item_t));
-
-    item->folder = xcalloc(folderlen+1, 1);
-    memcpy(item->folder, folder, folderlen);
-    item->folder[folderlen] = '\0';
-    
-    item->msgid = xcalloc (msgidlen+1, 1);
-    memcpy(item->msgid, msgid, msgidlen);
-    item->msgid[msgidlen] = '\0';
-
-    item->article = art;
-    
-    /* try to add to the queue (counts if art isn't null) */
-    result = AddToQueue(&(cxn->imap_controlMsg_q), item, CANCEL_MSG, (art != NULL), must);
-    if (result != RET_OK) {
-       d_printf(1,"%s:%d addCancelItem(): "
-                "I thought we had in space in [imap] queue "
-                "but apparently not\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-
-       /* cleanup */
-       free(item->folder);
-       free(item->msgid);
-       free(item);
-
-       return result;
-    }
-               
-    return RET_OK;
-}
-
-static conn_ret AddControlMsg(connection_t *cxn, 
-                             Article art, 
-                             Buffer *bufs, 
-                             char *control_header, 
-                             char *control_header_end, 
-                             bool must)
-{
-    char *rcpt_list = NULL, *rcpt_list_end;
-    control_item_t *item;
-    conn_ret res = RET_OK;
-    int t;
-
-    /* make sure contents ok; this also should load it into memory */
-    if (!artContentsOk (art)) {
-       d_printf(0, "%s:%d AddControlMsg(): "
-                "artContentsOk() said article was bad\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       hostArticleIsMissing (cxn->myHost, cxn, art);
-       return RET_FAIL;
-    }
-
-    res = RET_OK;
-    /* now let's look at the control to see what it is */
-    if (!strncasecmp(control_header,"newgroup",8)) {
-       control_header += 8;
-       t = CREATE_FOLDER;
-    } else if (!strncasecmp(control_header,"rmgroup",7)) {
-       /* jump past "rmgroup" */
-       control_header += 7;
-       t = DELETE_FOLDER;
-    } else if (!strncasecmp(control_header,"cancel",6)) {
-       t = CANCEL_MSG;
-       control_header += 6;
-    } else {
-       /* unrecognized type */
-       char tmp[100];
-       char *endstr;
-       size_t clen;
-
-       endstr = strchr(control_header,'\n');
-       clen = endstr - control_header;
-
-       if (clen > sizeof(tmp)-1) clen = sizeof(tmp)-1;
-
-       memcpy(tmp,control_header, clen);
-       tmp[clen]='\0';
-       
-       d_printf(0,"%s:%d Don't understand control header [%s]\n",
-                hostPeerName (cxn->myHost), cxn->ident,tmp);
-       return RET_FAIL;
-    }
-
-    switch (t) {
-    case CREATE_FOLDER:
-    case DELETE_FOLDER:
-    {
-       int folderlen;
-
-       /* go past all white space */
-       while ((*control_header == ' ') && 
-              (control_header != control_header_end)) {
-           control_header++;
-       }
-
-       /* trim trailing whitespace */
-       while (control_header_end[-1] == ' ') {
-           control_header_end--;
-       }
-
-       if (control_header >= control_header_end) {
-           d_printf(0,"%s:%d addControlMsg(): "
-                    "newgroup/rmgroup header has no group specified\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           return RET_FAIL;
-       }
-
-       folderlen = control_header_end - control_header;
-
-       item = xcalloc(1, sizeof(control_item_t));
-
-       item->folder = xcalloc(folderlen + 1, 1);
-       memcpy(item->folder, control_header, folderlen);
-       item->folder[folderlen] = '\0';
-
-       item->article = art;
-
-       if (AddToQueue(&(cxn->imap_controlMsg_q), item, t, 1, must) != RET_OK) {
-           d_printf(1,"%s:%d addCancelItem(): "
-                    "I thought we had in space in [imap] queue"
-                    " but apparently not\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           free(item->folder);
-           free(item);
-           return RET_FAIL;
-       }
-
-       break;
-    }
-
-    case CANCEL_MSG:
-    {
-       char *str, *laststart;
-
-       while (((*control_header) == ' ') && 
-              (control_header != control_header_end))
-       {
-           control_header++;
-       }
-
-       if (control_header == control_header_end)
-       {
-           d_printf(0, "%s:%d Control header contains cancel "
-                       "with no msgid specified\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           return RET_FAIL;
-       }
-
-       if (FindHeader(bufs, "Newsgroups", &rcpt_list, &rcpt_list_end)!=RET_OK)
-       {
-           d_printf(0,"%s:%d Cancel msg contains no newsgroups header\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           return RET_FAIL;
-       }
-
-       str = rcpt_list;
-       laststart = rcpt_list;
-
-       while (str != rcpt_list_end)
-       {
-           if (*str == ',') {
-               /* eliminate leading whitespace */
-               while (((*laststart) ==' ') || ((*laststart)=='\t'))
-               {
-                   laststart++;
-               }
-
-               res = addCancelItem(cxn, laststart, 
-                                   str - laststart, 
-                                   control_header, 
-                                   control_header_end - control_header,
-                                   NULL, must);
-               if (res!=RET_OK) return res;
-               
-               laststart = str+1;
-           }
-
-           str++;
-       }
-       
-       if (laststart<str)
-       {
-
-           res = addCancelItem(cxn, laststart, str - laststart, 
-                               control_header,
-                               control_header_end - control_header, 
-                               art, must);
-           if (res!=RET_OK) return res;
-       }
-       break;
-    }
-    default:
-       /* huh?!? */
-       d_printf(0, "%s:%d internal error in addControlMsg()\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-    }
-    return RET_FAIL;
-}
-
-/*
- * Show msg handling statistics
- */
-
-static void show_stats(connection_t *cxn)
-{   
-    d_printf(0, "%s:%d\n",hostPeerName (cxn->myHost), cxn->ident);
-    d_printf(0, "  imap queue = %d lmtp queue = %d\n",
-            QueueItems(&(cxn->imap_controlMsg_q)),
-            QueueItems(&(cxn->lmtp_todeliver_q)));
-    d_printf(0,"  imap state = %s\n", imap_stateToString(cxn->imap_state));
-    d_printf(0,"  lmtp state = %s\n", lmtp_stateToString(cxn->lmtp_state));
-    d_printf(0,"  delivered:  yes: %d no: %d\n",
-            cxn->lmtp_succeeded, 
-            cxn->lmtp_failed);
-    d_printf(0,"  cancel:     yes: %d no: %d\n",
-            cxn->cancel_succeeded, cxn->cancel_failed);
-    d_printf(0,"  create:     yes: %d no: %d\n",
-            cxn->create_succeeded, cxn->create_failed);
-    d_printf(0,"  remove:     yes: %d no: %d\n",
-            cxn->remove_succeeded, cxn->remove_failed);
-}
-
-/**************************** SASL helper functions ******************************/
-
-#ifdef HAVE_SASL
-/* callback to get userid or authid */
-static int getsimple(void *context __attribute__((unused)),
-                    int id,
-                    const char **result,
-                    unsigned *len)
-{
-  char *username;
-  char *authid;
-
-  if (! result)
-    return SASL_BADPARAM;
-
-
-  switch (id) {
-  case SASL_CB_GETREALM:
-      *result = deliver_realm;
-      if (len)
-         *len = deliver_realm ? strlen(deliver_realm) : 0;
-      break;
-
-  case SASL_CB_USER:
-      *result = deliver_username;
-      if (len)
-         *len = deliver_username ? strlen(deliver_username) : 0;
-    break;
-  case SASL_CB_AUTHNAME:
-    authid=deliver_authname;
-    *result = authid;
-    if (len)
-      *len = authid ? strlen(authid) : 0;
-      break;
-  case SASL_CB_LANGUAGE:
-    *result = NULL;
-    if (len)
-      *len = 0;
-    break;
-  default:
-    return SASL_BADPARAM;
-  }
-  return SASL_OK;
-}
-
-/* callback to get password */
-static int
-getsecret(sasl_conn_t *conn,
-         void *context __attribute__((unused)),
-         int id,
-         sasl_secret_t **psecret)
-{
-  size_t passlen;
-
-  if (! conn || ! psecret || id != SASL_CB_PASS)
-    return SASL_BADPARAM;
-
-  if (deliver_password==NULL)
-  {
-      d_printf(0,"SASL requested a password but I don't have one\n");
-      return SASL_FAIL;
-  }
-
-  passlen = strlen(deliver_password);
-  *psecret = xmalloc(sizeof(sasl_secret_t) + passlen + 1);
-  if (! *psecret)
-    return SASL_FAIL;
-
-  strlcpy((*psecret)->data, deliver_password, passlen + 1);
-  (*psecret)->len = passlen;
-
-  return SASL_OK;
-}
-
-
-/* callbacks we support */
-static sasl_callback_t saslcallbacks[] = {
-  {
-    SASL_CB_GETREALM, &getsimple, NULL
-  }, {
-    SASL_CB_USER, &getsimple, NULL
-  }, {
-    SASL_CB_AUTHNAME, &getsimple, NULL
-  }, {
-    SASL_CB_PASS, &getsecret, NULL    
-  }, {
-    SASL_CB_LIST_END, NULL, NULL
-  }
-};
-
-static sasl_security_properties_t *make_secprops(int min,int max)
-{
-  sasl_security_properties_t *ret=
-    xmalloc(sizeof(sasl_security_properties_t));
-
-  ret->maxbufsize=1024;
-  ret->min_ssf=min;
-  ret->max_ssf=max;
-
-  ret->security_flags=0;
-  ret->property_names=NULL;
-  ret->property_values=NULL;
-
-  return ret;
-}
-
-#ifndef NI_WITHSCOPEID
-#define NI_WITHSCOPEID 0
-#endif
-#ifndef NI_MAXHOST
-#define NI_MAXHOST     1025
-#endif
-#ifndef NI_MAXSERV
-#define NI_MAXSERV     32
-#endif
-
-static int iptostring(const struct sockaddr *addr, socklen_t addrlen,
-                    char *out, unsigned outlen) {
-    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
-    
-    if(!addr || !out) return SASL_BADPARAM;
-
-    getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
-               NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
-
-    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
-       return SASL_BUFOVER;
-
-    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
-
-    return SASL_OK;
-}
-
-static conn_ret SetSASLProperties(sasl_conn_t *conn, int sock, int minssf, int maxssf)
-{
-  int saslresult;
-  sasl_security_properties_t *secprops=NULL;
-  int addrsize=sizeof(struct sockaddr_in);
-  char localip[60], remoteip[60];
-  struct sockaddr_in saddr_l;
-  struct sockaddr_in saddr_r;
-
-  /* create a security structure and give it to sasl */
-  secprops = make_secprops(minssf, maxssf);
-  if (secprops != NULL)
-  {
-    sasl_setprop(conn, SASL_SEC_PROPS, secprops);
-    free(secprops);
-  }
-
-  if (getpeername(sock,(struct sockaddr *)&saddr_r,&addrsize)!=0)
-    return RET_FAIL;
-
-  if (iptostring((struct sockaddr *)&saddr_r, sizeof(struct sockaddr_in),
-               remoteip, sizeof(remoteip)))
-    return RET_FAIL;
-
-  if (sasl_setprop(conn, SASL_IPREMOTEPORT, remoteip)!=SASL_OK)
-    return RET_FAIL;
-  
-  addrsize=sizeof(struct sockaddr_in);
-  if (getsockname(sock,(struct sockaddr *) &saddr_l,&addrsize)!=0)
-    return RET_FAIL;
-
-  if (iptostring((struct sockaddr *)&saddr_l, sizeof(struct sockaddr_in),
-                localip, sizeof(localip)))
-    return RET_FAIL;
-    
-  if (sasl_setprop(conn, SASL_IPLOCALPORT, localip)!=SASL_OK)
-    return RET_FAIL;
-  
-  return RET_OK;
-}
-#endif /* HAVE_SASL */
-
-/************************** END SASL helper functions ******************************/
-
-/************************* Startup functions **********************************/
-
-static conn_ret Initialize(connection_t *cxn, int respTimeout)
-{
-#ifdef HAVE_SASL
-    conn_ret saslresult;
-#endif /* HAVE_SASL */
-
-    d_printf(1,"%s:%d initializing....\n",
-            hostPeerName (cxn->myHost), cxn->ident);
-
-#ifdef HAVE_SASL
-    /* only call sasl_client_init() once */
-    if (initialized_sasl == 0)
-    {
-       /* Initialize SASL */
-       saslresult=sasl_client_init(saslcallbacks);
-       
-       if (saslresult!=SASL_OK)
-       {
-           d_printf(0,
-                    "%s:%d Error initializing SASL (sasl_client_init) (%s)\n",
-                    hostPeerName (cxn->myHost), cxn->ident,
-                    sasl_errstring(saslresult, NULL, NULL));
-           return RET_FAIL;
-       } else {
-           initialized_sasl = 1;
-       }
-    }
-#endif /* HAVE_SASL */
-
-    cxn->lmtp_rBuffer = newBuffer(4096);
-    if (cxn->lmtp_rBuffer == NULL)
-    {
-       d_printf(0, "%s:%d Failure allocating buffer for lmtp_rBuffer\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-    bufferAddNullByte(cxn->lmtp_rBuffer);
-
-
-    cxn->imap_rBuffer = newBuffer(4096);
-    if (cxn->imap_rBuffer == NULL)
-    {
-       d_printf(0, "%s:%d Failure allocating buffer for imap_rBuffer \n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-    bufferAddNullByte(cxn->imap_rBuffer);
-
-    /* Initialize timeouts */
-    cxn->lmtp_writeTimeout = respTimeout;
-    cxn->lmtp_readTimeout = respTimeout;
-    cxn->imap_writeTimeout = respTimeout;
-    cxn->imap_readTimeout = respTimeout;
-    cxn->lmtp_sleepTimerId = 0 ;
-    cxn->lmtp_sleepTimeout = init_reconnect_period ;
-    cxn->imap_sleepTimerId = 0 ;
-    cxn->imap_sleepTimeout = init_reconnect_period ;
-
-    cxn->dosomethingTimeout = DOSOMETHING_TIMEOUT;
-
-    /* set up the write timer. */
-    clearTimer (cxn->dosomethingTimerId) ;
-
-    if (cxn->dosomethingTimeout > 0)
-       cxn->dosomethingTimerId = prepareSleep (dosomethingTimeoutCbk, 
-                                               cxn->dosomethingTimeout, cxn);
-
-
-
-    return RET_OK;
-}
-
-
-/* initialize the network */
-static conn_ret init_net(char *serverFQDN, 
-                        int port,
-                        int *sock)
-{
-  struct sockaddr_in addr;
-  struct hostent *hp;
-
-  if ((hp = gethostbyname(serverFQDN)) == NULL) {
-      d_printf(0, "gethostbyname(): %s\n", strerror(errno));
-    return RET_FAIL;
-  }
-
-  if (( (*sock) = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-      d_printf(0, "socket(): %s\n", strerror(errno));
-      return RET_FAIL; 
-  }
-
-  addr.sin_family = AF_INET;
-  memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
-  addr.sin_port = htons(port);
-
-  if (connect( (*sock), (struct sockaddr *) &addr, sizeof (addr)) < 0) {
-      d_printf(0,"connect(): %s\n",
-              strerror(errno));
-      return RET_FAIL;
-  }
-
-  return RET_OK;
-}
-
-
-
-static conn_ret SetupLMTPConnection(connection_t *cxn,
-                                   char *serverName,
-                                   int port)
-{
-#ifdef HAVE_SASL
-    int saslresult;
-#endif /* HAVE_SASL */
-    conn_ret result;
-
-    cxn->lmtp_port = port;
-
-    if (serverName==NULL)
-    {
-       d_printf(0, "%s:%d serverName is null\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;        
-    }
-
-#ifdef HAVE_SASL
-    /* Free the SASL connection if we already had one */
-    if (cxn->saslconn_lmtp!=NULL)
-    {
-       sasl_dispose(&cxn->saslconn_lmtp);
-    }
-
-    /* Start SASL */
-    saslresult=sasl_client_new("lmtp",
-                              serverName,
-                              NULL,
-                              NULL,
-                              NULL,
-                              0,
-                              &cxn->saslconn_lmtp);
-
-    if (saslresult != SASL_OK)
-    {
-
-       d_printf(0, "%s:%d:LMTP Error creating a new SASL connection (%s)\n",
-                hostPeerName (cxn->myHost), cxn->ident,
-                sasl_errstring(saslresult,NULL,NULL));
-       return RET_FAIL;
-    }
-#endif /* HAVE_SASL */
-
-    /* Connect the Socket */
-    result = init_net(serverName,
-                     LMTP_PORT, /*port,*/
-                     &(cxn->sockfd_lmtp));
-   
-    if (result != RET_OK)
-    {
-       d_printf(0, "%s:%d unable to connect to lmtp host\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-
-    if (cxn->lmtp_respBuffer) free(cxn->lmtp_respBuffer);
-    cxn->lmtp_respBuffer = xmalloc (4096);
-    cxn->lmtp_respBuffer[0]='\0';
-
-    /* Free if we had an existing one */
-    if (cxn->lmtp_endpoint != NULL)
-    {
-       delEndPoint(cxn->lmtp_endpoint);
-       cxn->lmtp_endpoint = NULL;
-    }
-
-    cxn->lmtp_endpoint = newEndPoint(cxn->sockfd_lmtp);
-    if (cxn->lmtp_endpoint == NULL)
-    {
-       d_printf(0, "%s:%d:LMTP failure creating endpoint\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-
-#ifdef HAVE_SASL
-    /* Set the SASL properties */
-    result = SetSASLProperties(cxn->saslconn_lmtp, cxn->sockfd_lmtp, 
-                              0, 0);
-    
-    if (result != RET_OK)
-    {
-       d_printf(0,"%s:%d:LMTP error setting SASL properties\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-#endif /* HAVE_SASL */
-
-
-    return RET_OK;
-}
-
-static conn_ret SetupIMAPConnection(connection_t *cxn,
-                                   char *serverName,
-                                   int port)
-{
-#ifdef HAVE_SASL
-    int saslresult;
-#endif /* HAVE_SASL */
-    conn_ret result;
-
-    cxn->imap_port = port;
-
-    if (serverName==NULL)
-    {
-       d_printf(0,"%s:%d:IMAP Servername is null",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;        
-    }
-
-#ifdef HAVE_SASL
-    /* Free the SASL connection if we already had one */
-    if (cxn->imap_saslconn!=NULL)
-    {
-       sasl_dispose(&cxn->imap_saslconn);
-    }
-
-    /* Start SASL */
-    saslresult=sasl_client_new("imap",
-                              serverName,
-                              NULL,
-                              NULL,
-                              NULL,
-                              0,
-                              &cxn->imap_saslconn);
-
-    if (saslresult != SASL_OK)
-    {
-       d_printf(0,"%s:%d:IMAP Error creating a new SASL connection (%s)",
-                hostPeerName (cxn->myHost), cxn->ident,
-                sasl_errstring(saslresult,NULL,NULL));
-       return RET_FAIL;
-    }
-#endif /* HAVE_SASL */
-
-    /* Connect the Socket */
-    result = init_net(serverName,
-                     port,
-                     &(cxn->imap_sockfd));
-   
-    if (result != RET_OK)
-    {
-       d_printf(0,"%s:%d:IMAP Unable to start network connection for IMAP",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-
-    if (cxn->imap_respBuffer) free(cxn->imap_respBuffer);
-    cxn->imap_respBuffer = xmalloc (4096);
-    cxn->imap_respBuffer[0]='\0';
-
-    /* Free if we had an existing one */
-    if (cxn->imap_endpoint != NULL)
-    {
-       delEndPoint(cxn->imap_endpoint);
-       cxn->imap_endpoint = NULL;
-    }
-
-    cxn->imap_endpoint = newEndPoint(cxn->imap_sockfd);
-    if (cxn->imap_endpoint == NULL)
-    {
-       d_printf(0,"%s:%d:IMAP Failure creating imap endpoint\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return RET_FAIL;
-    }
-
-#ifdef HAVE_SASL
-    /* Set the SASL properties */
-    result = SetSASLProperties(cxn->imap_saslconn, cxn->imap_sockfd, 
-                              0, 0);    
-    if (result != RET_OK)
-    {
-       d_printf(0,"%s:%d:IMAP Error setting sasl properties",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return result;
-    }
-#endif /* HAVE_SASL */
-
-
-    return RET_OK;
-}
-
-/************************* END Startup functions **********************************/
-
-/* Return the response code for this line
-   -1 if it doesn't seem to have one
-*/
-static int ask_code(char *str)
-{
-    int ret = 0;
-    
-    if (str==NULL) return -1;
-
-    if (strlen(str) < 3) return -1;
-
-    /* check to make sure 0-2 are digits */
-    if ((isdigit((int) str[0])==0) ||
-       (isdigit((int) str[1])==0) ||
-       (isdigit((int) str[2])==0))
-    {
-       d_printf(0,
-                "Parse error: response does not begin with a code [%s]\n",
-                str);
-       return -1;
-    }
-
-
-    ret = ((str[0]-'0')*100)+
-         ((str[1]-'0')*10)+
-         (str[2]-'0');
-    
-    return ret;
-}
-
-/* is this a continuation or not?
-   220-fdfsd is        (1)
-   220 fdsfs is not    (0)
- */
-
-static int ask_keepgoing(char *str)
-{
-    if (str==NULL) return 0;
-    if (strlen(str) < 4) return 0;
-
-    if (str[3]=='-') return 1;
-
-    return 0;
-}
-
-
-static conn_ret lmtp_listenintro(connection_t *cxn)
-{
-    Buffer *readBuffers;
-
-    /* set up to receive */
-    readBuffers = makeBufferArray (bufferTakeRef (cxn->lmtp_rBuffer), NULL) ;
-    prepareRead(cxn->lmtp_endpoint, readBuffers, lmtp_readCB, cxn, 5);    
-
-    cxn->lmtp_state = LMTP_READING_INTRO;
-
-    return RET_OK;
-}
-
-
-
-/************************** IMAP functions ***********************/
-
-static conn_ret imap_Connect(connection_t *cxn)
-{
-    conn_ret result;
-
-    ASSERT(cxn->imap_sleepTimerId == 0);
-
-    /* make the IMAP connection */
-    result = SetupIMAPConnection(cxn,
-                                cxn->ServerName,
-                                IMAP_PORT); 
-
-    /* Listen to the intro and start the authenticating process */
-    result = imap_listenintro(cxn);
-
-    return result;
-}
-
-/*
- * This is called when the data write timeout for the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void imap_writeTimeoutCbk (TimeoutId id UNUSED, void *data)
-{
-  connection_t *cxn = (Connection) data ;
-  const char *peerName ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  syslog (LOG_WARNING, "timeout for %s", peerName);
-  d_printf(0, "%s: shutting down non-responsive IMAP connection (%s)\n",
-          hostPeerName (cxn->myHost), 
-          imap_stateToString(cxn->imap_state));
-
-  cxnLogStats (cxn,true) ;
-
-  imap_Disconnect(cxn);
-}
-
-/*
- * This is called when the timeout for the reponse from the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void imap_readTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-  const char *peerName ;
-
-  ASSERT (id == cxn->imap_readBlockedTimerId) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  warn ("%s:%d cxnsleep non-responsive connection", peerName, cxn->ident) ;
-  d_printf(0, "%s:%d shutting down non-responsive IMAP connection (%s)\n",
-          hostPeerName (cxn->myHost), cxn->ident,
-          imap_stateToString(cxn->imap_state));
-
-  cxnLogStats (cxn,true);
-
-  if (cxn->imap_state == IMAP_DISCONNECTED)
-    {
-      imap_Disconnect(cxn);
-      lmtp_Disconnect(cxn);
-      delConnection (cxn) ;
-    }
-  else {
-      imap_Disconnect(cxn);
-  }      
-}
-
-/*
- * Called by the EndPoint class when the timer goes off
- */
-static void imap_reopenTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  ASSERT (id == cxn->imap_sleepTimerId) ;
-
-  cxn->imap_sleepTimerId = 0 ;
-
-  d_printf(1,"%s:%d:IMAP Reopen timer rang. Try to make new connection now\n",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-  
-  if (cxn->imap_state != IMAP_DISCONNECTED)
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            imap_stateToString (cxn->imap_state)) ;
-    }
-  else {
-      if (imap_Connect(cxn) != RET_OK)
-         prepareReopenCbk(cxn, 0);
-  }
-}
-
-static void imap_Disconnect(connection_t *cxn)
-{
-    clearTimer (cxn->imap_sleepTimerId) ;
-    cxn->imap_sleepTimerId = 0;
-    clearTimer (cxn->imap_readBlockedTimerId) ;
-    clearTimer (cxn->imap_writeBlockedTimerId) ;
-
-    DeferAllArticles(cxn, &(cxn->imap_controlMsg_q)) ;      /* give any articles back to Host */
-
-    cxn->imap_state = IMAP_DISCONNECTED;
-
-    cxn->imap_disconnects++;
-
-    cxn->imap_respBuffer[0]='\0';
-
-    if (cxn->issue_quit == 0)
-       prepareReopenCbk(cxn,0);
-
-    DeleteIfDisconnected(cxn);
-}
-
-/************************** END IMAP functions ***********************/
-
-/************************ LMTP functions **************************/
-
-/*
- * Create a network lmtp connection
- * and start listening for the intro string
- *
- */
-
-static conn_ret lmtp_Connect(connection_t *cxn)
-{
-    conn_ret result;
-
-    ASSERT(cxn->lmtp_sleepTimerId == 0);
-
-    /* make the LMTP connection */
-    result = SetupLMTPConnection(cxn,
-                                cxn->ServerName,
-                                LMTP_PORT);
-
-    if (result!=RET_OK) return result;
-
-    /* Listen to the intro */
-    result = lmtp_listenintro(cxn);
-
-    return result;
-}
-
-
-
-static void lmtp_Disconnect(connection_t *cxn)
-{
-    clearTimer (cxn->lmtp_sleepTimerId) ;
-    cxn->lmtp_sleepTimerId = 0;
-    clearTimer (cxn->lmtp_readBlockedTimerId) ;
-    clearTimer (cxn->lmtp_writeBlockedTimerId) ;
-
-    /* give any articles back to Host */
-    DeferAllArticles(cxn, &(cxn->lmtp_todeliver_q)) ;      
-
-    cxn->lmtp_state = LMTP_DISCONNECTED;
-
-    cxn->lmtp_disconnects++;
-
-    cxn->lmtp_respBuffer[0]='\0';
-
-    if (cxn->issue_quit == 0)
-       prepareReopenCbk(cxn,1);
-
-    DeleteIfDisconnected(cxn);
-}
-
-
-
-/*
- * Called by the EndPoint class when the timer goes off
- */
-static void lmtp_reopenTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  ASSERT (id == cxn->lmtp_sleepTimerId) ;
-
-  cxn->lmtp_sleepTimerId = 0 ;
-
-  d_printf(1,"%s:%d:LMTP Reopen timer rang. Try to make new connection now\n",
-           hostPeerName (cxn->myHost), cxn->ident) ;
-        
-  if (cxn->lmtp_state != LMTP_DISCONNECTED)
-    {
-      warn ("%s:%d cxnsleep connection in bad state: %s",
-            hostPeerName (cxn->myHost), cxn->ident,
-            lmtp_stateToString (cxn->lmtp_state)) ;
-    }
-  else {
-      if (lmtp_Connect(cxn) != RET_OK)
-         prepareReopenCbk(cxn, 1);
-  }
-}
-
-/*
- * Set up the callback used when the Connection is sleeping (i.e. will try
- * to reopen the connection).
- *
- * type (0 = imap, 1 = lmtp)
- */
-static void prepareReopenCbk (Connection cxn, int type)
-{
-    /* xxx check state */
-
-
-
-    if (type == 0) {
-
-       cxn->imap_sleepTimerId = prepareSleep (imap_reopenTimeoutCbk, 
-                                              cxn->imap_sleepTimeout, cxn) ;
-       d_printf (1,"%s:%d IMAP connection error\n"
-                 "  will try to reconnect in %d seconds\n",
-                 hostPeerName (cxn->myHost), cxn->ident, 
-                 cxn->imap_sleepTimeout) ;
-    } else {
-       cxn->lmtp_sleepTimerId = prepareSleep (lmtp_reopenTimeoutCbk, 
-                                              cxn->lmtp_sleepTimeout, cxn) ;
-       d_printf (1,"%s:%d:LMTP connection error\n"
-                 "will try to reconnect in %d seconds\n",
-                 hostPeerName (cxn->myHost), cxn->ident, 
-                 cxn->lmtp_sleepTimeout) ;
-    }
-
-    /* bump the sleep timer amount each time to wait longer and longer. Gets
-       reset in resetConnection() */
-    if (type == 0) {
-       cxn->imap_sleepTimeout *= 2 ;
-       if (cxn->imap_sleepTimeout > max_reconnect_period)
-           cxn->imap_sleepTimeout = max_reconnect_period ;
-    } else {
-       cxn->lmtp_sleepTimeout *= 2 ;
-       if (cxn->lmtp_sleepTimeout > max_reconnect_period)
-           cxn->lmtp_sleepTimeout = max_reconnect_period ;
-    }
-}
-
-/*
- * This is called when the timeout for the reponse from the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void lmtp_readTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-  const char *peerName ;
-
-  ASSERT (id == cxn->lmtp_readBlockedTimerId) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  warn ("%s:%d cxnsleep non-responsive connection", peerName, cxn->ident) ;
-  d_printf(0,"%s:%d shutting down non-responsive LMTP connection (%s)\n",
-           hostPeerName (cxn->myHost), cxn->ident,
-          lmtp_stateToString(cxn->lmtp_state));
-
-  cxnLogStats (cxn,true) ;
-
-  if (cxn->lmtp_state == LMTP_DISCONNECTED) {
-      imap_Disconnect(cxn);
-      lmtp_Disconnect(cxn);
-      delConnection (cxn) ;
-  } else {
-      lmtp_Disconnect(cxn);
-  }      
-}
-
-
-
-/*
- * This is called when the data write timeout for the remote
- * goes off. We tear down the connection and notify our host.
- */
-static void lmtp_writeTimeoutCbk (TimeoutId id UNUSED, void *data)
-{
-    connection_t *cxn = (Connection) data ;
-    const char *peerName ;
-
-    peerName = hostPeerName (cxn->myHost) ;
-
-    syslog (LOG_WARNING, "timeout for %s", peerName);
-    d_printf(0, "%s:%d shutting down non-responsive LMTP connection (%s)\n",
-            hostPeerName (cxn->myHost), cxn->ident,
-            lmtp_stateToString(cxn->lmtp_state)) ;
-
-    cxnLogStats (cxn,true);
-
-    lmtp_Disconnect(cxn);
-}
-
-/************************ END LMTP functions **************************/
-
-/************************** LMTP write functions ********************/
-
-static conn_ret lmtp_noop(connection_t *cxn)
-{
-    int result;
-    char *p;
-
-    p = xstrdup("NOOP\r\n");
-    result = WriteToWire_lmtpstr(cxn, p, strlen(p));
-    if (result!=RET_OK) return result;
-
-    cxn->lmtp_state = LMTP_WRITING_NOOP;
-
-    return RET_OK;
-}
-
-static conn_ret lmtp_IssueQuit(connection_t *cxn)
-{
-    int result;
-    char *p;
-
-    p = xstrdup("QUIT\r\n");
-    result = WriteToWire_lmtpstr(cxn, p, strlen(p));
-    if (result!=RET_OK) return result;
-
-    cxn->lmtp_state = LMTP_WRITING_QUIT;
-
-    return RET_OK;
-}
-
-static conn_ret lmtp_getcapabilities(connection_t *cxn)
-{
-    int result;
-    char *p;
-
-    if (cxn->lmtp_capabilities != NULL)
-    {
-       if (cxn->lmtp_capabilities->saslmechs) {
-           free( cxn->lmtp_capabilities->saslmechs);
-       }
-       free( cxn->lmtp_capabilities );
-       cxn->lmtp_capabilities = NULL;
-    }
-
-    cxn->lmtp_capabilities = xcalloc (1, sizeof(lmtp_capabilities_t));
-    cxn->lmtp_capabilities->saslmechs = NULL;
-
-#ifdef SMTPMODE
-    p = concat("EHLO ", hostname, "\r\n", (char *) 0);
-#else
-    p = concat("LHLO ", hostname, "\r\n", (char *) 0);
-#endif /* SMTPMODE */
-
-    result = WriteToWire_lmtpstr(cxn, p, strlen(p));
-    if (result!=RET_OK) return result;
-
-    cxn->lmtp_state = LMTP_WRITING_LHLO;
-
-    return RET_OK;    
-}
-
-#ifdef HAVE_SASL
-static conn_ret lmtp_authenticate(connection_t *cxn)
-{
-    int saslresult;
-    
-    const char *mechusing;
-    const char *out;
-    unsigned int outlen;
-    char *inbase64;
-    int inbase64len;
-    int status;
-    int result;
-
-    char *p;
-
-    sasl_interact_t *client_interact=NULL;
-
-
-    saslresult=sasl_client_start(cxn->saslconn_lmtp, 
-                                cxn->lmtp_capabilities->saslmechs,
-                                &client_interact,
-                                &out, &outlen,
-                                &mechusing);
-
-
-
-    if ((saslresult != SASL_OK) && 
-       (saslresult != SASL_CONTINUE)) {
-
-       d_printf(0,"%s:%d:LMTP Error calling sasl_client_start (%s)\n",
-                hostPeerName (cxn->myHost), cxn->ident,
-                sasl_errstring(saslresult, NULL, NULL));
-       return RET_FAIL;
-    }
-
-    d_printf(1,"%s:%d:LMTP Decided to try to authenticate with SASL mechanism=%s\n",           
-            hostPeerName (cxn->myHost), cxn->ident,mechusing);
-
-    if (!out)
-    {
-       /* no initial client response */
-        p = concat("AUTH ", mechusing, "\r\n", (char *) 0);
-    } else if (!outlen) {
-       /* empty initial client response */
-        p = concat("AUTH ", mechusing, " =\r\n", (char *) 0);
-    } else {
-       /* initial client response - convert to base64 */
-       inbase64 = xmalloc(outlen*2+10);
-
-       saslresult = sasl_encode64(out, outlen,
-                                  inbase64, outlen*2+10,
-                                   (unsigned *) &inbase64len);
-       if (saslresult != SASL_OK) return RET_FAIL;
-        p = concat("AUTH ", mechusing, " ", inbase64, "\r\n", (char *) 0);
-        free(inbase64);
-    }
-
-    result = WriteToWire_lmtpstr(cxn, p, strlen(p));
-
-    cxn->lmtp_state = LMTP_WRITING_STARTAUTH;
-
-    return RET_OK;
-}
-
-static imt_stat lmtp_getauthline(char *str, char **line, int *linelen)
-{
-  char buf[4096];
-  int saslresult;
-  int response_code = -1;
-  
-  response_code = ask_code(str);
-
-  if (response_code == 334) {
-      
-      /* continue */
-
-  } else if (response_code == 235) {
-
-      /* woohoo! authentication complete */
-      return STAT_OK;
-
-  } else {
-      /* failure of some sort */
-      d_printf(0,"?:?:LMTP Authentication failure (%d) [%s]\n",
-              response_code,str);
-      return STAT_NO;
-  }
-
-  str += 4; /* jump past the "334 " */
-
-  *line = xmalloc(strlen(str)+30);
-  if ((*line)==NULL) {
-      return STAT_NO;
-  }
-
-  /* decode this line */      
-  saslresult = sasl_decode64(str, strlen(str), 
-                            *line, strlen(str)+1, (unsigned *) linelen);
-  if (saslresult != SASL_OK) {
-      d_printf(0,"?:?:LMTP base64 decoding error\n");
-      return STAT_NO;
-  }
-
-  return STAT_CONT;
-}
-#endif /* HAVE_SASL */
-
-static void lmtp_writeCB (EndPoint e UNUSED, IoStatus i UNUSED, Buffer *b,
-       void *d)
-{
-    connection_t *cxn = (connection_t *) d;
-    Buffer *readBuffers;
-
-    clearTimer (cxn->lmtp_writeBlockedTimerId) ;
-
-    /* Free the string that was written */
-    freeBufferArray (b);
-    if (cxn->lmtp_tofree_str!=NULL)
-    {
-       free(cxn->lmtp_tofree_str);
-       cxn->lmtp_tofree_str=NULL;
-    }
-
-    /* set up to receive */
-    readBuffers = makeBufferArray (bufferTakeRef (cxn->lmtp_rBuffer), NULL) ;
-    prepareRead(cxn->lmtp_endpoint, readBuffers, lmtp_readCB, cxn, 5);
-
-   /* set up the response timer. */
-    clearTimer (cxn->lmtp_readBlockedTimerId) ;
-
-    if (cxn->lmtp_readTimeout > 0)
-       cxn->lmtp_readBlockedTimerId = prepareSleep (lmtp_readTimeoutCbk, 
-                                                    cxn->lmtp_readTimeout, cxn) ;
-
-
-    switch (cxn->lmtp_state)
-       {
-           
-       case LMTP_WRITING_LHLO:
-           cxn->lmtp_state = LMTP_READING_LHLO;
-           break;
-
-       case LMTP_WRITING_STARTAUTH:
-       case LMTP_WRITING_STEPAUTH:
-
-           cxn->lmtp_state = LMTP_READING_STEPAUTH;
-
-           break;
-
-       case LMTP_WRITING_UPTODATA:
-           /* expect result to rset */
-           cxn->lmtp_state = LMTP_READING_RSET;
-           break;
-
-       case LMTP_WRITING_CONTENTS:
-           /* so we sent the whole DATA command
-              let's see what the server responded */
-
-           cxn->lmtp_state = LMTP_READING_CONTENTS;
-
-           break;
-
-       case LMTP_WRITING_NOOP:
-           cxn->lmtp_state = LMTP_READING_NOOP;
-           break;
-
-       case LMTP_WRITING_QUIT:
-           cxn->lmtp_state = LMTP_READING_QUIT;
-           break;
-
-       default:
-
-           d_printf(0,"%s:%d:LMTP Unknown state. Internal error\n",
-                    hostPeerName (cxn->myHost), cxn->ident) ;
-
-           break;
-       }
-}
-
-/************************** END LMTP write functions ********************/
-
-/************************** IMAP sending functions ************************/
-
-
-static void imap_writeCB (EndPoint e UNUSED, IoStatus i UNUSED, Buffer *b,
-       void *d)
-{
-    connection_t *cxn = (connection_t *) d;
-    Buffer *readBuffers;
-
-    clearTimer (cxn->imap_writeBlockedTimerId) ;
-
-    /* free the string we just wrote out */
-    freeBufferArray (b);
-    if (cxn->imap_tofree_str!=NULL)
-    {
-       free(cxn->imap_tofree_str);
-       cxn->imap_tofree_str=NULL;
-    }
-
-    /* set up to receive */
-    readBuffers = makeBufferArray (bufferTakeRef (cxn->imap_rBuffer), NULL) ;
-    prepareRead(cxn->imap_endpoint, readBuffers, imap_readCB, cxn, 5);
-
-    /* set up the response timer. */
-    clearTimer (cxn->imap_readBlockedTimerId) ;
-
-    if (cxn->imap_readTimeout > 0)
-       cxn->imap_readBlockedTimerId = prepareSleep(imap_readTimeoutCbk, 
-                                                   cxn->imap_readTimeout, 
-                                                   cxn);
-
-    switch (cxn->imap_state) {
-    case IMAP_WRITING_CAPABILITY:
-       cxn->imap_state = IMAP_READING_CAPABILITY;
-       break;
-
-    case IMAP_WRITING_STEPAUTH:
-    case IMAP_WRITING_STARTAUTH:
-       cxn->imap_state = IMAP_READING_STEPAUTH;
-       break;
-
-    case IMAP_WRITING_CREATE:
-       cxn->imap_state = IMAP_READING_CREATE;
-       break;
-
-    case IMAP_WRITING_DELETE:
-       cxn->imap_state = IMAP_READING_DELETE;
-       break;
-
-    case IMAP_WRITING_SELECT:
-       cxn->imap_state = IMAP_READING_SELECT;
-       break;
-
-    case IMAP_WRITING_SEARCH:
-       cxn->imap_state = IMAP_READING_SEARCH;
-       break;
-
-    case IMAP_WRITING_STORE:
-       cxn->imap_state = IMAP_READING_STORE;
-       break;
-
-    case IMAP_WRITING_CLOSE:
-       cxn->imap_state = IMAP_READING_CLOSE;
-       break;
-
-    case IMAP_WRITING_NOOP:
-       cxn->imap_state = IMAP_READING_NOOP;
-       break;
-
-    case IMAP_WRITING_QUIT:
-       cxn->imap_state = IMAP_READING_QUIT;
-       break;
-
-    default:
-       d_printf(0,"%s:%d:IMAP invalid connection state\n",
-                hostPeerName (cxn->myHost), cxn->ident) ;
-       imap_Disconnect(cxn);
-       break;
-    }
-}
-
-/*
- * Tag is already allocated
- */
-
-static void imap_GetTag(connection_t *cxn)
-{
-    sprintf(cxn->imap_currentTag,"%06d",cxn->imap_tag_num);
-    cxn->imap_tag_num++;
-    if (cxn->imap_tag_num >= 999999)
-    {
-       cxn->imap_tag_num = 0;
-    }
-}
-
-#ifdef HAVE_SASL
-static conn_ret imap_sendAuthStep(connection_t *cxn, char *str)
-{
-    conn_ret result;
-    int saslresult;
-    char in[4096];
-    unsigned int inlen;
-    const char *out;
-    unsigned int outlen;
-    char *inbase64;
-    unsigned int inbase64len;
-
-    /* base64 decode it */
-
-    saslresult = sasl_decode64(str, strlen(str), 
-                              in, strlen(str)+1, &inlen);
-    if (saslresult != SASL_OK) {
-       d_printf(0,"%s:%d:IMAP base64 decoding error\n",
-                hostPeerName (cxn->myHost), cxn->ident) ;
-       return RET_FAIL;
-    }
-
-    saslresult=sasl_client_step(cxn->imap_saslconn,
-                               in,
-                               inlen,
-                               NULL,
-                               &out,
-                               &outlen);
-
-    /* check if sasl succeeded */
-    if (saslresult != SASL_OK && saslresult != SASL_CONTINUE) {
-
-       d_printf(0,"%s:%d:IMAP sasl_client_step failed with %s\n",
-                hostPeerName (cxn->myHost), cxn->ident,
-                sasl_errstring(saslresult,NULL,NULL));
-       cxn->imap_state = IMAP_CONNECTED_NOTAUTH;
-       return RET_FAIL;
-    }
-
-    inbase64 = xmalloc(outlen * 2 + 10);
-
-    /* convert to base64 */
-    saslresult = sasl_encode64(out, outlen,
-                              inbase64, outlen*2, (unsigned *) &inbase64len);
-
-    if (saslresult != SASL_OK) return RET_FAIL;
-
-    /* append endline */
-    strlcpy(inbase64 + inbase64len, "\r\n", outlen * 2 + 10 - inbase64len);
-    inbase64len+=2;
-    
-    /* send to server */
-    result = WriteToWire_imapstr(cxn,inbase64, inbase64len);
-    
-    cxn->imap_state = IMAP_WRITING_STEPAUTH;
-
-    return result;
-}
-#endif /* HAVE_SASL */
-
-static conn_ret imap_sendAuthenticate(connection_t *cxn)
-{
-    int result;
-
-    char *p;
-
-#ifdef HAVE_SASL
-    const char *mechusing;
-    char *inbase64;
-    int inbase64len;
-    int saslresult=SASL_NOMECH;
-
-    sasl_interact_t *client_interact=NULL;
-
-    if (cxn->imap_capabilities->saslmechs) {
-       saslresult=sasl_client_start(cxn->imap_saslconn, 
-                                    cxn->imap_capabilities->saslmechs,
-                                    &client_interact,
-                                    NULL, NULL,
-                                    &mechusing);
-    }
-
-
-
-    /* If no mechs try "login" */
-    if (saslresult == SASL_NOMECH)
-    {
-
-#else /* HAVE_SASL */
-
-     { /* always do login */
-
-#endif /* HAVE_SASL */
-       d_printf(1,"%s:%d:IMAP No mechanism found. Trying login method\n",
-                hostPeerName (cxn->myHost), cxn->ident) ;
-
-       if (cxn->imap_capabilities->logindisabled==1)
-       {
-           d_printf(0,"%s:%d:IMAP Login command w/o security layer not allowed on this server\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           return RET_FAIL;
-       }
-
-       if (deliver_authname==NULL)
-       {
-           d_printf(0,"%s:%d:IMAP Unable to log in because can't find a authname\n",
-                    hostPeerName (cxn->myHost), cxn->ident) ;
-           return RET_FAIL;
-       }
-
-       if (deliver_password==NULL)
-       {
-           d_printf(0,"%s:%d:IMAP Unable to log in because can't find a password\n",
-                    hostPeerName (cxn->myHost), cxn->ident) ;
-           return RET_FAIL;
-       }
-
-       imap_GetTag(cxn);
-
-        p = concat(cxn->imap_currentTag, " LOGIN ", deliver_authname, " \"",
-                   deliver_password, "\"\r\n", (char *) 0);
-       
-       result = WriteToWire_imapstr(cxn, p, strlen(p));
-       
-       cxn->imap_state = IMAP_WRITING_STARTAUTH;
-       
-       return RET_OK;       
-    }
-
-#ifdef HAVE_SASL
-    if ((saslresult != SASL_OK) && 
-       (saslresult != SASL_CONTINUE)) {
-
-       d_printf(0,"%s:%d:IMAP Error calling sasl_client_start (%s) mechusing = %s\n",
-                hostPeerName (cxn->myHost), cxn->ident,
-                sasl_errstring(saslresult, NULL, NULL), mechusing);
-       return RET_FAIL;
-    }
-
-    d_printf(1,"%s:%d:IMAP Trying to authenticate to imap with %s mechanism\n",
-            hostPeerName (cxn->myHost), cxn->ident,
-            mechusing);
-
-    imap_GetTag(cxn);
-
-    p = concat(cxn->imap_currentTag, " AUTHENTICATE ", mechusing, "\r\n",
-               (char *) 0);
-    result = WriteToWire_imapstr(cxn, p, strlen(p));
-
-    cxn->imap_state = IMAP_WRITING_STARTAUTH;
-
-    return RET_OK;
-#endif /* HAVE_SASL */
-}
-
-static conn_ret imap_CreateGroup(connection_t *cxn, char *bboard)
-{
-    conn_ret result;
-    char *tosend;
-
-    d_printf(1,"%s:%d:IMAP Ok creating group [%s]\n",
-            hostPeerName (cxn->myHost), cxn->ident,
-            bboard);
-
-    imap_GetTag(cxn);
-
-    tosend = concat(cxn->imap_currentTag, " CREATE ", bboard, "\r\n",
-                    (char *) 0);
-
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result!=RET_OK) return result;
-    
-    cxn->imap_state = IMAP_WRITING_CREATE;
-    
-    return RET_OK;
-}
-
-static conn_ret imap_DeleteGroup(connection_t *cxn, char *bboard)
-{
-    conn_ret result;
-    char *tosend;
-
-    d_printf(1,"%s:%d:IMAP Ok removing bboard [%s]\n",
-                hostPeerName (cxn->myHost), cxn->ident, bboard);
-
-    imap_GetTag(cxn);
-
-    tosend = concat(cxn->imap_currentTag, " DELETE ", bboard, "\r\n",
-                    (char *) 0);
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result!=RET_OK) return result;
-
-    cxn->imap_state = IMAP_WRITING_DELETE;
-    
-    return RET_OK;
-}
-
-static conn_ret imap_CancelMsg(connection_t *cxn, char *newsgroup)
-{
-    conn_ret result;
-    char *tosend;
-
-    ASSERT(newsgroup);
-
-    imap_GetTag(cxn);
-
-    /* select mbox */
-    tosend = concat(cxn->imap_currentTag, " SELECT ", newsgroup, "\r\n",
-                    (char *) 0);
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result != RET_OK) return result;
-
-    cxn->imap_state = IMAP_WRITING_SELECT;
-
-    hostArticleOffered (cxn->myHost, cxn);
-
-    return RET_OK;
-}
-
-static conn_ret imap_sendSearch(connection_t *cxn, char *msgid)
-{
-    conn_ret result;
-    char *tosend;
-
-    ASSERT(msgid);
-
-    imap_GetTag(cxn);
-
-    /* preform search */
-    tosend = concat(cxn->imap_currentTag,
-                    " UID SEARCH header \"Message-ID\" \"", msgid, "\"\r\n",
-                    (char *) 0);
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result != RET_OK) return result;
-
-    cxn->imap_state = IMAP_WRITING_SEARCH;
-
-    return RET_OK;
-}
-
-static conn_ret imap_sendKill(connection_t *cxn, unsigned uid)
-{
-    conn_ret result;
-    char *tosend;
-    size_t length;
-
-    imap_GetTag(cxn);
-
-    length = 7 + 50 + 20;
-    tosend = xmalloc(length);
-    snprintf(tosend,length,"%s UID STORE %d +FLAGS.SILENT (\\Deleted)\r\n",
-             cxn->imap_currentTag, uid);
-
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result != RET_OK) return result;
-
-    cxn->imap_state = IMAP_WRITING_STORE;
-
-    return RET_OK;
-}
-
-static conn_ret imap_sendSimple(connection_t *cxn, const char *atom, int st)
-{
-    char *tosend;
-    conn_ret result;
-
-    imap_GetTag(cxn);
-    tosend = concat(cxn->imap_currentTag, " ", atom, "\r\n", (char *) 0);
-
-    result = WriteToWire_imapstr(cxn, tosend, -1);
-    if (result != RET_OK) return result;
-
-    cxn->imap_state = st;
-
-    return RET_OK;
-}
-
-static conn_ret imap_sendClose(connection_t *cxn)
-{
-    return imap_sendSimple(cxn, "CLOSE", IMAP_WRITING_CLOSE);
-}
-
-static conn_ret imap_sendQuit(connection_t *cxn)
-{
-    return imap_sendSimple(cxn, "LOGOUT", IMAP_WRITING_QUIT);
-}
-
-static conn_ret imap_noop(connection_t *cxn)
-{
-    return imap_sendSimple(cxn, "NOOP", IMAP_WRITING_NOOP);
-}
-       
-
-static conn_ret imap_sendCapability(connection_t *cxn)
-{
-    return imap_sendSimple(cxn, "CAPABILITY", IMAP_WRITING_CAPABILITY);
-}
-
-/************************** END IMAP sending functions ************************/
-
-/************************** IMAP reading functions ***************************/
-
-static conn_ret imap_listenintro(connection_t *cxn)
-{
-    Buffer *readBuffers;
-
-    /* set up to receive */
-    readBuffers = makeBufferArray (bufferTakeRef (cxn->imap_rBuffer), NULL) ;
-    prepareRead(cxn->imap_endpoint, readBuffers, imap_readCB, cxn, 5);    
-
-    cxn->imap_state = IMAP_READING_INTRO;
-
-    return RET_OK;
-}
-
-static conn_ret imap_ParseCapability(char *string, imap_capabilities_t **caps)
-{
-    char *str = string;
-    char *start = str;
-    size_t mechlen;
-
-    /* allocate the caps structure if it doesn't already exist */
-    if ( (*caps) == NULL)
-       (*caps) = xcalloc(1, sizeof(imap_capabilities_t));
-
-    while ( (*str) != '\0')
-    {
-
-       while (((*str) != '\0') && ((*str)!=' '))
-       {
-           str++;
-       }
-       
-       if ( (*str) != '\0')
-       {
-           *str = '\0';
-           str++;
-       }
-
-       if ( strcasecmp(start,"IMAP4")==0)
-       {
-           (*caps)->imap4 = 1;
-       } else if (strcasecmp(start,"LOGINDISABLED")==0) {
-           (*caps)->logindisabled = 1;
-       } else if ( strncmp(start, "AUTH=", 5)==0) {
-           
-           if ( (*caps)->saslmechs == NULL)
-           {
-                (*caps)->saslmechs = xstrdup (start + 5);
-           } else {
-                mechlen = strlen((*caps)->saslmechs) + 1;
-                mechlen += strlen(start + 5) + 1;
-               (*caps)->saslmechs = xrealloc((*caps)->saslmechs, mechlen);
-                strlcat((*caps)->saslmechs, " ", mechlen);
-                strlcat((*caps)->saslmechs, start + 5, mechlen);
-           }
-       }
-       
-       start = str;
-          
-    }
-
-    if ((*caps)->saslmechs) {
-       d_printf(1,"?:?:IMAP parsed capabilities: saslmechs = %s\n",
-                (*caps)->saslmechs);
-    }
-
-    return RET_OK;
-}
-
-
-static void imap_readCB (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-    connection_t *cxn = (connection_t *) d;
-    Buffer *readBuffers ;
-
-    int okno;
-    char *str;
-    char strbuf[4096];
-    char *linestart;
-    conn_ret ret;
-    char *p;
-
-    p = bufferBase(b[0]);
-
-    /* Add what we got to our internal read buffer */
-    bufferAddNullByte (b[0]) ;
-
-    if (i != IoDone) {
-       errno = endPointErrno(e);
-
-       syslog(LOG_ERR, "%s:%d IMAP i/o failed: %m",
-              hostPeerName (cxn->myHost), cxn->ident);
-       freeBufferArray (b);
-       imap_Disconnect(cxn);
-       return;
-    }
-
-    if (strchr (p, '\n') == NULL) {
-       /* partial read. expand buffer and retry */
-       
-       if (expandBuffer (b[0], BUFFER_EXPAND_AMOUNT)==false) {
-           d_printf(0,"%s:%d:IMAP expanding buffer returned false\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           
-           imap_Disconnect(cxn);
-           return;
-       }
-       readBuffers = makeBufferArray (bufferTakeRef (b[0]), NULL) ;
-       
-       if (!prepareRead (e, readBuffers, imap_readCB, cxn, 1)) {
-           imap_Disconnect(cxn);
-       }
-       
-       freeBufferArray (b);
-       return;
-    }
-
-    clearTimer (cxn->imap_readBlockedTimerId) ;
-
-    /* we got something. add to our buffer and free b */
-
-    strcat(cxn->imap_respBuffer, p);
-
-    bufferSetDataSize( b[0], 0);
-
-    freeBufferArray (b);
-
-
-
-    /* goto here to take another step */
- reset:
-
-    /* see if we have a full line */
-    ret = GetLine( cxn->imap_respBuffer , strbuf, sizeof(strbuf));
-    str = strbuf;
-    linestart = str;
-
-    /* if we don't have a full line */
-    if ( ret == RET_NO_FULLLINE)
-       {
-
-           readBuffers = makeBufferArray (bufferTakeRef (cxn->imap_rBuffer), NULL) ;
-
-           if ( !prepareRead (e, readBuffers, imap_readCB, cxn, 1) )
-               {
-                   imap_Disconnect(cxn);
-               }
-           return;
-
-       } else if (ret!=RET_OK)
-           {
-               return;
-           }
-
-    /* if untagged */
-    if ((str[0]=='*') && (str[1]==' '))
-    {
-       str+=2;
-       
-       /* now figure out what kind of untagged it is */
-       if (strncasecmp(str,"CAPABILITY ",11)==0)
-       {
-           str+=11;
-           
-           imap_ParseCapability(str,&(cxn->imap_capabilities));
-           
-       } else if (strncasecmp(str,"SEARCH",6)==0) {
-
-           str+=6;
-           
-           if ( (*str) == ' ')
-           {
-               str++;
-               
-               cxn->current_control->data.control->uid = atoi(str);
-               
-               d_printf(1,"%s:%d:IMAP i think the UID = %ld\n",
-                        hostPeerName (cxn->myHost), cxn->ident,
-                        cxn->current_control->data.control->uid);
-           } else {
-               /* it's probably a blank uid (i.e. message doesn't exist) */
-               cxn->current_control->data.control->uid = (unsigned long)-1;
-           }
-
-           
-       } else if (strncasecmp(str,"OK ",3)==0) {
-           
-           if (cxn->imap_state==IMAP_READING_INTRO)
-           {
-               imap_sendCapability(cxn); /* xxx errors */
-               return;
-               
-           } else {
-               
-           }
-           
-           
-       } else {
-           /* untagged command not understood */
-       }
-
-       /* always might be more to look at */
-       goto reset;
-
-    } else if ((str[0]=='+') && (str[1]==' ')) {
-
-       str+=2;
-
-       if (cxn->imap_state == IMAP_READING_STEPAUTH)
-       {
-#ifdef HAVE_SASL
-           if (imap_sendAuthStep(cxn, str)!=RET_OK)
-           {
-               imap_Disconnect(cxn);
-           }
-#else
-           d_printf(0,"%s:%d:IMAP got a '+ ...' without SASL. Something's wrong\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           imap_Disconnect(cxn);
-#endif /* HAVE_SASL */
-
-           return;
-       } else {
-           d_printf(0,"%s:%d:IMAP got a '+ ...' in state where not expected\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           imap_Disconnect(cxn);
-           return;
-       }
-       
-
-       
-    } else if (strncmp(str, cxn->imap_currentTag, IMAP_TAGLENGTH)==0) {        
-       /* matches our tag */
-       str += IMAP_TAGLENGTH;
-       
-       if (str[0]!=' ')
-       {
-           d_printf(0,"%s:%d:IMAP Parse error: tag with no space afterward\n",
-                    hostPeerName (cxn->myHost), cxn->ident);
-           imap_Disconnect(cxn);
-           return;         
-       }
-       str++;
-
-       /* should be OK/NO */
-       if (strncmp(str,"OK",2)==0)
-       {
-           okno = 1;
-       } else {
-           okno = 0;
-       }
-       
-       switch(cxn->imap_state)
-           {
-           case IMAP_READING_CAPABILITY:
-
-               if (okno==1) {
-                   if (imap_sendAuthenticate(cxn)!=RET_OK)
-                   {
-                       d_printf(0,"%s:%d:IMAP sendauthenticate failed\n",
-                                hostPeerName (cxn->myHost), cxn->ident);
-                       imap_Disconnect(cxn);
-                   }
-                   return;
-               } else {
-                   d_printf(0,"%s:%d:IMAP CAPABILITY gave a NO response\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-                   imap_Disconnect(cxn);
-               }
-               return;
-               
-               break;
-           case IMAP_READING_STEPAUTH:
-               
-               if (okno == 1) {
-
-                   cxn->imap_sleepTimeout = init_reconnect_period ;
-
-                   cxn->imap_timeCon = theTime () ;
-                   cxn->timeCon = theTime () ;
-                   
-                   d_printf(0,"%s:%d IMAP authentication succeeded\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-
-                   cxn->imap_disconnects=0;
-                   
-                   cxn->imap_state = IMAP_IDLE_AUTHED;
-
-                   /* try to send a message if we have one */
-                   
-                   imap_ProcessQueue(cxn);
-               } else {
-                   d_printf(0,"%s:%d:IMAP Authentication failed with [%s]\n",               
-                            hostPeerName (cxn->myHost), cxn->ident,str);
-                   imap_Disconnect(cxn);
-               }
-
-               return;
-
-               break;
-               
-           case IMAP_READING_CREATE:
-
-                   if (okno==1) {
-                       
-                       d_printf(1,"%s:%d:IMAP Create of bboard successful\n",
-                                hostPeerName (cxn->myHost), cxn->ident);
-                                
-                       cxn->create_succeeded++;
-
-                       /* we can delete article now */
-                       QueueForgetAbout(cxn, cxn->current_control, 
-                                        MSG_SUCCESS);
-                   } else {
-                       d_printf(1,"%s:%d:IMAP Create failed with [%s] for %s\n",
-                                hostPeerName (cxn->myHost), cxn->ident,str,
-                                cxn->current_control->data.control->folder);
-
-                       ReQueue(cxn, &(cxn->imap_controlMsg_q), cxn->current_control);
-                   }
-
-                   imap_ProcessQueue(cxn);
-                       
-                   break;
-                   
-           case IMAP_READING_DELETE:
-
-                   if (okno==1) {
-                       d_printf(1,"%s:%d:IMAP Delete successful\n",
-                                hostPeerName (cxn->myHost), cxn->ident);
-                       cxn->remove_succeeded++;
-
-                       /* we can delete article now */
-                       QueueForgetAbout(cxn, cxn->current_control, 
-                                        MSG_SUCCESS);
-                   } else {
-                       d_printf(1,"%s:%d:IMAP Delete mailbox failed with [%s] for %s\n",
-                                hostPeerName (cxn->myHost), cxn->ident,str,
-                                cxn->current_control->data.control->folder);
-
-                       ReQueue(cxn, &(cxn->imap_controlMsg_q), cxn->current_control);
-                       
-                   }
-
-                   imap_ProcessQueue(cxn);
-                   return;
-                       
-                   break;
-
-           case IMAP_READING_SELECT:
-
-                   if (okno==1) {
-
-                       imap_sendSearch(cxn, cxn->current_control->data.control->msgid);
-                       return;
-
-                   } else {
-                       d_printf(1,"%s:%d:IMAP Select failed with [%s] for %s\n",
-                                hostPeerName (cxn->myHost), cxn->ident,str,
-                                cxn->current_control->data.control->folder);
-
-                       ReQueue(cxn, &(cxn->imap_controlMsg_q), cxn->current_control);
-                       
-                       cxn->imap_state = IMAP_IDLE_AUTHED;
-
-                       imap_ProcessQueue(cxn);
-                       return;
-                   }
-
-                   break;
-
-           case IMAP_READING_SEARCH:
-               /* if no message let's forget about it */
-               if (cxn->current_control->data.control->uid
-                       == (unsigned long)-1) {
-                   d_printf(2, "%s:%d:IMAP Search didn't find the message\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-                   QueueForgetAbout(cxn, cxn->current_control, 
-                                    MSG_FAIL_DELIVER);
-                   if (imap_sendClose(cxn) != RET_OK)
-                       imap_Disconnect(cxn);
-                   return;
-               }
-
-               if (okno==1) {
-                   /* we got a uid. let's delete it */
-                   if (imap_sendKill(cxn, 
-                                      cxn->current_control->data.control->uid)
-                           != RET_OK)
-                       imap_Disconnect(cxn);
-                   return;
-               } else {
-                   d_printf(0, "%s:%d IMAP Received NO response to SEARCH\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-                   ReQueue(cxn, &(cxn->imap_controlMsg_q), 
-                           cxn->current_control);
-                   
-                   if (imap_sendClose(cxn) != RET_OK)
-                       imap_Disconnect(cxn);
-                   return;
-               }
-               break;
-
-           case IMAP_READING_STORE:
-
-                   if (okno==1) {
-
-                       d_printf(1,"%s:%d:IMAP Processed a Cancel fully\n",
-                                hostPeerName (cxn->myHost), cxn->ident);
-
-                       /* we can delete article now */
-                       QueueForgetAbout(cxn, cxn->current_control,
-                                        MSG_SUCCESS);
-
-                       cxn->cancel_succeeded++;
-
-                       if (imap_sendClose(cxn) != RET_OK)
-                           imap_Disconnect(cxn);
-                       return;
-
-                   } else {
-
-                       d_printf(1,"%s:%d:IMAP Store failed\n",
-                                hostPeerName (cxn->myHost), cxn->ident);
-                       ReQueue(cxn, &(cxn->imap_controlMsg_q), cxn->current_control);
-
-                       if (imap_sendClose(cxn) != RET_OK)
-                           imap_Disconnect(cxn);
-                       return;
-                   }
-
-                   break;
-
-           case IMAP_READING_NOOP:
-               cxn->imap_state = IMAP_IDLE_AUTHED;
-               return;
-               break;
-
-           case IMAP_READING_CLOSE:
-               if (!okno) {
-                   /* we can't do anything about it */
-                   d_printf(1,"%s:%d:IMAP Close failed\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-               }
-
-               cxn->imap_state = IMAP_IDLE_AUTHED;
-               
-               imap_ProcessQueue(cxn);             
-               return;
-               break;
-
-           case IMAP_READING_QUIT:
-               
-               /* we don't care if the server said OK or NO just
-                  that it said something */
-
-               d_printf(1,"%s:%d:IMAP Read quit response\n",
-                        hostPeerName (cxn->myHost), cxn->ident);
-               
-               cxn->imap_state = IMAP_DISCONNECTED;
-
-               DeleteIfDisconnected(cxn);
-               break;
-                   
-
-           default:
-               d_printf(0,"%s:%d:IMAP I don't understand state %d [%s]\n",
-                        hostPeerName (cxn->myHost), cxn->ident,
-                        cxn->imap_state,str);
-               imap_Disconnect(cxn);
-               break;
-           }
-           
-
-    } else {
-       d_printf(0,"%s:%d:IMAP tag (%s) doesn't match what we gave (%s). What's up with that??\n",
-                hostPeerName (cxn->myHost), cxn->ident, str, cxn->imap_currentTag);
-       imap_Disconnect(cxn);
-    }
-    
-}
-
-/************************** END IMAP reading functions ***************************/
-
-/*************************** LMTP reading functions ****************************/
-
-static void lmtp_readCB (EndPoint e, IoStatus i, Buffer *b, void *d)
-{
-    connection_t *cxn = (connection_t *) d;
-    char str[4096];
-    Buffer *readBuffers;
-    int result;
-    int response_code;
-    conn_ret ret;
-#ifdef HAVE_SASL
-    int inlen;
-    char *in;
-    int outlen;
-    const char *out;
-    char *inbase64;
-    int inbase64len;
-    imt_stat status;
-    int saslresult;
-    sasl_interact_t *client_interact=NULL;
-#endif /* HAVE_SASL */
-
-    char *p = bufferBase(b[0]);
-
-    bufferAddNullByte (b[0]) ;
-
-    if (i != IoDone) {
-       errno = endPointErrno(e);
-       syslog(LOG_ERR, "%s:%d LMTP i/o failed: %m",
-              hostPeerName (cxn->myHost), cxn->ident);
-
-       freeBufferArray (b);
-       lmtp_Disconnect(cxn);
-       return;
-    }
-
-    if (strchr (p, '\n') == NULL)
-    {
-       /* partial read. expand buffer and retry */
-
-       d_printf(0,"%s:%d:LMTP Partial. retry\n",
-                hostPeerName (cxn->myHost),cxn->ident);
-       expandBuffer (b[0], BUFFER_EXPAND_AMOUNT) ;
-       readBuffers = makeBufferArray (bufferTakeRef (b[0]), NULL) ;
-       
-       if ( !prepareRead (e, readBuffers, lmtp_readCB, cxn, 1) )
-       {
-           lmtp_Disconnect(cxn);
-        }
-
-       freeBufferArray (b);
-       return;
-    }
-
-    clearTimer (cxn->lmtp_readBlockedTimerId) ;
-
-    /* Add what we got to our internal read buffer */
-    strcat(cxn->lmtp_respBuffer, p);
-
-    bufferSetDataSize( b[0], 0);
-
-    freeBufferArray (b);
-
- reset:
-    /* see if we have a full line */
-    ret = GetLine( cxn->lmtp_respBuffer, str, sizeof(str));
-
-    /* get a line */
-    if (ret!=RET_OK)
-    {
-       if (ret!=RET_NO_FULLLINE)
-       {
-           /* was a more serious error */
-           d_printf(0,"%s:%d:LMTP Internal error getting line from server\n",
-                    hostPeerName (cxn->myHost),cxn->ident);
-           lmtp_Disconnect(cxn);
-           return;         
-       }
-
-       /* set up to receive some more */
-       readBuffers = makeBufferArray (bufferTakeRef (cxn->lmtp_rBuffer), NULL) ;
-       prepareRead(cxn->lmtp_endpoint, readBuffers, lmtp_readCB, cxn, 5);
-       return;
-    }
-
-    switch (cxn->lmtp_state)
-       {
-
-       case LMTP_READING_INTRO:
-           
-           if (ask_code(str)!=220)
-           {
-               d_printf(0,"%s:%d:LMTP Initial server msg does not start with 220 (began with %d)\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        ask_code(str));
-               lmtp_Disconnect(cxn);
-               return;
-           }
-
-           /* the initial intro could have many lines via
-               continuations. see if we need to read more */
-           if (ask_keepgoing(str)==1)
-           {
-               goto reset;
-           }
-
-           result = lmtp_getcapabilities(cxn);
-
-           if (result != RET_OK)
-           {
-               d_printf(0,"%s:%d:LMTP lmtp_getcapabilities() failure\n",
-                        hostPeerName (cxn->myHost),cxn->ident);
-               lmtp_Disconnect(cxn);
-               return;
-           }
-
-           break;
-
-       case LMTP_READING_LHLO:
-           /* recieve the response(s) */
-           response_code = ask_code(str);
-           
-           if (response_code != 250) /* was none */
-           {
-               d_printf(0,"%s:%d:LMTP Response code unexpected (%d)\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        response_code);
-               lmtp_Disconnect(cxn);
-               return;
-           }
-
-           /* look for one we know about; ignore all others */
-           if (strncmp(str+4,"8BITMIME",strlen("8BITMIME"))==0)
-           {
-               cxn->lmtp_capabilities->Eightbitmime = 1;
-           } else if (strncmp(str+4, "ENHANCEDSTATUSCODES",
-                              strlen("ENHANCEDSTATUSCODES"))==0) {
-               cxn->lmtp_capabilities->EnhancedStatusCodes = 1;
-           } else if (strncmp(str+4, "AUTH",4)==0) {
-               cxn->lmtp_capabilities->saslmechs = xstrdup(str + 4 + 5);
-           } else if (strncmp(str+4,"PIPELINING",strlen("PIPELINING"))==0) {
-               cxn->lmtp_capabilities->pipelining = 1;
-           } else {
-               /* don't care; ignore */
-           }
-           
-           /* see if this is the last line of the capability */
-           if (ask_keepgoing(str)==1)
-           {
-               goto reset;
-           } else {
-               /* we require a few capabilities */
-               if (!cxn->lmtp_capabilities->pipelining) {
-                   d_printf(0,"%s:%d:LMTP We require PIPELINING\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-                   
-                   lmtp_Disconnect(cxn);
-                   return;
-               }
-#ifdef HAVE_SASL
-               if (cxn->lmtp_capabilities->saslmechs) {
-                   /* start the authentication */
-                   result = lmtp_authenticate(cxn);
-                   
-                   if (result != RET_OK) {
-                       d_printf(0,"%s:%d:LMTP lmtp_authenticate() error\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-                       lmtp_Disconnect(cxn);
-                       return;
-                   }
-#else
-               if (0) {
-                   /* noop */
-#endif
-               } else {
-                   /* either we can't authenticate or the remote server
-                      doesn't support it */
-                   cxn->lmtp_state = LMTP_AUTHED_IDLE;
-                   d_printf(1,"%s:%d:LMTP Even though we can't authenticate"
-                            " we're going to try to feed anyway\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-                   /* We just assume we don't need to authenticate 
-                      (great assumption huh?) */
-                   hostRemoteStreams (cxn->myHost, cxn, true) ;
-
-                   cxn->lmtp_timeCon = theTime () ;
-                   cxn->timeCon = theTime () ;
-                   
-                   /* try to send a message if we have one */
-                   lmtp_sendmessage(cxn,NULL);
-                   return;
-               }
-           }
-           break;
-
-#ifdef HAVE_SASL
-       case LMTP_READING_STEPAUTH:
-           inlen = 0;
-           status = lmtp_getauthline(str, &in, &inlen);
-
-           switch (status)
-               {
-
-               case STAT_CONT:
-
-                   saslresult=sasl_client_step(cxn->saslconn_lmtp,
-                                               in,
-                                               inlen,
-                                               &client_interact,
-                                               &out,
-                                               &outlen);
-
-                   free(in);
-
-                   /* check if sasl succeeded */
-                   if (saslresult != SASL_OK && saslresult != SASL_CONTINUE) {
-                       d_printf(0,"%s:%d:LMTP sasl_client_step(): %s\n",
-                                hostPeerName (cxn->myHost),cxn->ident,
-                                sasl_errstring(saslresult,NULL,NULL));
-
-                       lmtp_Disconnect(cxn);
-                       return;
-                   }
-
-                   /* convert to base64 */
-                   inbase64 = xmalloc(outlen*2+10);
-
-                   saslresult = sasl_encode64(out, outlen,
-                                              inbase64, outlen*2+10, 
-                                              (unsigned *) &inbase64len);
-                   
-                   if (saslresult != SASL_OK)
-                   {
-                       d_printf(0,"%s:%d:LMTP sasl_encode64(): %s\n",
-                                hostPeerName (cxn->myHost),cxn->ident,
-                                sasl_errstring(saslresult,NULL,NULL));
-
-                       lmtp_Disconnect(cxn);
-                       return;
-                   }
-
-                   /* add an endline */
-                   strlcpy(inbase64 + inbase64len, "\r\n", outlen * 2 + 10);
-
-                   /* send to server */
-                   result = WriteToWire_lmtpstr(cxn,inbase64, inbase64len+2);
-
-                   if (result != RET_OK)
-                   {
-                       d_printf(0,"%s:%d:LMTP WriteToWire() failure\n",
-                                hostPeerName (cxn->myHost),cxn->ident);
-                       lmtp_Disconnect(cxn);
-                       return;
-                   }
-
-                   cxn->lmtp_state = LMTP_WRITING_STEPAUTH;
-                   break;
-                   
-               case STAT_OK:
-                   cxn->lmtp_sleepTimeout = init_reconnect_period ;
-      
-                   d_printf(0,"%s:%d LMTP authentication succeeded\n",
-                            hostPeerName (cxn->myHost), cxn->ident);
-
-                   cxn->lmtp_disconnects=0;
-
-                   hostRemoteStreams (cxn->myHost, cxn, true) ;
-
-                   cxn->lmtp_timeCon = theTime () ;
-                   cxn->timeCon = theTime () ;
-
-                   cxn->lmtp_state = LMTP_AUTHED_IDLE;
-
-
-                   /* try to send a message if we have one */
-                   lmtp_sendmessage(cxn,NULL);
-                   return;
-
-                   break;
-
-               default:
-                   d_printf(0,"%s:%d:LMTP failed authentication\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-                   lmtp_Disconnect(cxn);
-                   return;
-               }
-           break;
-#endif /* HAVE_SASL */
-                   
-       case LMTP_READING_RSET:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-           if (ask_code(str) != 250) {
-               d_printf(0,"%s:%d:LMTP RSET failed with (%d)\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        ask_code(str));
-               lmtp_Disconnect(cxn);
-               return;
-           }
-
-           /* we pipelined so next we recieve the mail from response */
-           cxn->lmtp_state = LMTP_READING_MAILFROM;
-           goto reset;
-
-       case LMTP_READING_MAILFROM:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-           if (ask_code(str) != 250) {
-               d_printf(0,"%s:%d:LMTP MAILFROM failed with (%d)\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        ask_code(str));
-               lmtp_Disconnect(cxn);
-               return;
-           }
-
-           /* we pipelined so next we recieve the rcpt's */
-           cxn->lmtp_state = LMTP_READING_RCPTTO;
-           goto reset;
-           break;
-
-       case LMTP_READING_RCPTTO:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-           if (ask_code(str)!=250) {
-               d_printf(1,"%s:%d:LMTP RCPT TO failed with (%d) %s\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        ask_code(str), str);
-
-               /* if got a 5xx don't try to send anymore */
-               cxn->current_article->trys=100;
-
-               cxn->current_rcpts_issued--;
-           } else {
-               cxn->current_rcpts_okayed++;
-           }
-
-           /* if issued equals number okayed then we're done */
-           if ( cxn->current_rcpts_okayed == cxn->current_rcpts_issued) {
-               cxn->lmtp_state = LMTP_READING_DATA;
-           } else {
-               /* stay in same state */
-           }
-           goto reset;
-           break;
-
-       case LMTP_READING_DATA:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-           if (cxn->current_rcpts_issued == 0) {
-               if (cxn->current_article->trys < 100) {
-                   d_printf(1, "%s:%d:LMTP None of the rcpts "
-                            "were accepted for this message. Re-queueing\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-               }
-
-               ReQueue(cxn, &(cxn->lmtp_todeliver_q), cxn->current_article);
-
-               cxn->lmtp_state = LMTP_AUTHED_IDLE;
-               lmtp_sendmessage(cxn,NULL);
-           } else {
-               if (WriteArticle(cxn, cxn->current_bufs) != RET_OK)
-               {
-                   d_printf(0, "%s:%d:LMTP Error writing article\n",
-                            hostPeerName (cxn->myHost),cxn->ident);
-                   lmtp_Disconnect(cxn);
-                   return;
-               }
-               
-               cxn->lmtp_state = LMTP_WRITING_CONTENTS;
-           }
-
-           break;
-
-       case LMTP_READING_CONTENTS:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-
-           /* need 1 response from server for every rcpt */
-           cxn->current_rcpts_issued--;
-           
-           if (ask_code(str) != 250) {
-               d_printf(1, "%s:%d:LMTP DATA failed with %d (%s)\n",
-                        hostPeerName (cxn->myHost),cxn->ident,
-                        ask_code(str), str);
-               cxn->current_rcpts_okayed--;
-           }
-
-           if (cxn->current_rcpts_issued>0) {
-               goto reset;
-           }
-
-           /*
-            * current_rcpts_okayed is number that succeeded
-            *
-            */
-           if (cxn->current_rcpts_okayed == 0) {
-               cxn->lmtp_state = LMTP_AUTHED_IDLE;
-           } else {
-               cxn->lmtp_state = LMTP_AUTHED_IDLE;
-               cxn->lmtp_succeeded++;      
-               d_printf(1, "%s:%d:LMTP Woohoo! message accepted\n",
-                        hostPeerName (cxn->myHost),cxn->ident);
-           }
-
-           /* we can delete article now */
-           QueueForgetAbout(cxn, cxn->current_article, MSG_SUCCESS);
-
-           /* try to send another if we have one and we're still idle
-            * forgetting the msg might have made us unidle
-            */
-           if (cxn->lmtp_state == LMTP_AUTHED_IDLE) {
-               lmtp_sendmessage(cxn,NULL);
-           }
-           
-           break;
-
-       case LMTP_READING_NOOP:
-           if (ask_keepgoing(str)) {
-               goto reset;
-           }
-           cxn->lmtp_state = LMTP_AUTHED_IDLE;
-           break;
-
-       case LMTP_READING_QUIT:
-           d_printf(1,"%s:%d:LMTP read quit\n",
-                    hostPeerName (cxn->myHost),cxn->ident);
-
-           cxn->lmtp_state = LMTP_DISCONNECTED;            
-
-           DeleteIfDisconnected(cxn);
-           break;
-
-       default:
-
-           d_printf(0,"%s:%d:LMTP Bad state in lmtp_readCB %d\n",
-                    hostPeerName (cxn->myHost),cxn->ident,
-                    cxn->lmtp_state);
-           lmtp_Disconnect(cxn);
-           return;
-       }
-
-
-}
-
-/*
- * Add a rcpt to:<foo> to the string
- *
- */
-
-static void addrcpt(char *newrcpt, int newrcptlen, char **out, int *outalloc)
-{
-    int size = strlen(*out);
-    int fsize = size;
-    int newsize = size + 9+strlen(deliver_rcpt_to)+newrcptlen+3;
-    char c;
-
-    /* see if we need to grow the string */
-    if (newsize > *outalloc) {
-       (*outalloc) = newsize;
-       (*out) = xrealloc(*out, *outalloc);
-    }
-
-    strlcpy((*out) + size,"RCPT TO:<", newsize - size);
-    size += 9;
-
-    c = newrcpt[newrcptlen];
-    newrcpt[newrcptlen] = '\0';
-    size += snprintf((*out) + size, newsize - size, deliver_rcpt_to, newrcpt);
-    newrcpt[newrcptlen] = c;
-
-    strlcpy((*out) + size, ">\r\n", newsize - size);
-
-    /* has embedded '\n' */
-    d_printf(2, "Attempting to send to: %s", (*out) + fsize);
-}
-
-/*
- * Takes the newsgroups header value and makes it into a list of RCPT TO:'s we can send over the wire
- *
- *  in     - newsgroups header start
- *  in_end - end of newsgroups header
- *  num    - number of rcpt's we created
- */
-
-static char *ConvertRcptList(char *in, char *in_end, int *num)
-{
-    int retalloc = 400;
-    char *ret = xmalloc(retalloc);
-    char *str = in;
-    char *laststart = in;
-
-    (*num) = 0;
-
-    /* start it off empty */     
-    strlcpy(ret, "", retalloc);
-    
-    while ( str !=  in_end)
-    {
-       if ((*str) == ',')
-       {
-           /* eliminate leading whitespace */
-           while (((*laststart) ==' ') || ((*laststart)=='\t'))
-           {
-               laststart++;
-           }
-
-#ifndef SMTPMODE
-           addrcpt(laststart, str - laststart, &ret, &retalloc);
-           (*num)++;
-#endif /* SMTPMODE */
-           laststart = str+1;
-       }
-
-       str++;
-    }
-
-    if (laststart<str)
-    {
-       addrcpt(laststart, str - laststart, &ret, &retalloc);
-       (*num)++;
-    }
-
-    return ret;
-}
-
-static void addto(char *newrcpt, int newrcptlen, const char *sep,
-                 char **out, int *outalloc)
-{
-    int size = strlen(*out);
-    int newsize = size + strlen(sep)+1+strlen(deliver_to_header)+newrcptlen+1;
-    char c;
-
-    /* see if we need to grow the string */
-    if (newsize > *outalloc) {
-       (*outalloc) = newsize;
-       (*out) = xrealloc(*out, *outalloc);
-    }
-
-    size += snprintf((*out) + size, newsize - size, "%s<", sep);
-
-    c = newrcpt[newrcptlen];
-    newrcpt[newrcptlen] = '\0';
-    size += snprintf((*out) + size, newsize - size, deliver_to_header,newrcpt);
-    newrcpt[newrcptlen] = c;
-
-    strlcpy((*out) + size, ">", newsize - size);
-}
-
-/*
- * Takes the newsgroups header value and makes it into a To: header
- *
- *  in     - newsgroups header start
- *  in_end - end of newsgroups header
- */
-
-static char *BuildToHeader(char *in, char *in_end)
-{
-    int retalloc = 400;
-    char *ret = xmalloc(retalloc);
-    char *str = in;
-    char *laststart = in;
-    const char *sep = "";
-
-    /* start it off with the header name */     
-    strlcpy(ret,"To: ", retalloc);
-    
-    while ( str !=  in_end)
-    {
-       if ((*str) == ',')
-       {
-           /* eliminate leading whitespace */
-           while (((*laststart) ==' ') || ((*laststart)=='\t'))
-           {
-               laststart++;
-           }
-
-           addto(laststart, str - laststart, sep, &ret, &retalloc);
-           laststart = str+1;
-
-           /* separate multiple addresses with a comma */
-           sep = ", ";
-       }
-
-       str++;
-    }
-
-    if (laststart<str)
-    {
-       addto(laststart, str - laststart, sep, &ret, &retalloc);
-    }
-
-    /* terminate the header */
-    strlcat(ret, "\n\r", retalloc);
-    return ret;
-}
-
-/*************************** END LMTP reading functions ****************************/
-
-
-
-/*
- * Process the control message queue. If we run out ask the host for more.
- *
- *  cxn       - connection object
- */
-
-static void imap_ProcessQueue(connection_t *cxn)
-{
-    article_queue_t *item;
-    int result;
-
- retry:
-
-    /* pull an article off the queue */
-    result = PopFromQueue(&(cxn->imap_controlMsg_q), &item);
-
-    if (result==RET_QUEUE_EMPTY)
-    {
-       if (cxn->issue_quit)
-       {
-           imap_sendQuit(cxn);
-           return;
-       }
-
-       cxn->imap_state = IMAP_IDLE_AUTHED;
-
-       /* now we wait for articles from our Host, or we have some
-          articles already. On infrequently used connections, the
-          network link is torn down and rebuilt as needed. So we may
-          be rebuilding the connection here in which case we have an
-          article to send. */
-
-       /* make sure imap has _lots_ of space too */
-       if ((QueueItems(&(cxn->lmtp_todeliver_q)) == 0) && 
-           (QueueItems(&(cxn->imap_controlMsg_q)) == 0))
-       {
-           if (hostGimmeArticle (cxn->myHost,cxn)==true)
-               goto retry;
-       }
-
-       return;
-    }
-
-    cxn->current_control = item;
-
-    switch (item->type)
-       {
-       case CREATE_FOLDER:
-           imap_CreateGroup(cxn, item->data.control->folder);
-           break;
-
-       case CANCEL_MSG:
-           imap_CancelMsg(cxn, item->data.control->folder);
-           break;
-
-       case DELETE_FOLDER:
-           imap_DeleteGroup(cxn, item->data.control->folder); 
-           break;
-       default:
-           break;
-       }
-
-    return;
-}
-
-
-
-/*
- *
- * Pulls a message off the queue and trys to start sending it. If the
- * message is a control message put it in the control queue and grab
- * another message. If the message doesn't exist on disk or something
- * is wrong with it tell the host and try again. If we run out of
- * messages to get tell the host we want more
- *
- * cxn       - connection object
- * justadded - the article that was just added to the queue
- */
-
-static void lmtp_sendmessage(connection_t *cxn, Article justadded)
-{
-    bool res;
-    conn_ret result;
-    char *p;
-    Buffer *bufs;
-    char *control_header = NULL;
-    char *control_header_end = NULL;
-
-    article_queue_t *item;
-    char *rcpt_list, *rcpt_list_end;
-
-    /* retry point */
- retry:
-
-    /* pull an article off the queue */
-    result = PopFromQueue(&(cxn->lmtp_todeliver_q), &item);
-
-    if (result==RET_QUEUE_EMPTY)
-    {
-       if (cxn->issue_quit) {
-           lmtp_IssueQuit(cxn);
-           return;
-       }
-       /* now we wait for articles from our Host, or we have some
-          articles already. On infrequently used connections, the
-          network link is torn down and rebuilt as needed. So we may
-          be rebuilding the connection here in which case we have an
-          article to send. */
-
-       /* make sure imap has space too */
-       d_printf(1,"%s:%d stalled waiting for articles\n",
-                hostPeerName (cxn->myHost),cxn->ident);
-       if ((QueueItems(&(cxn->lmtp_todeliver_q)) == 0) && 
-           (QueueItems(&(cxn->imap_controlMsg_q)) == 0)) {
-           if (hostGimmeArticle (cxn->myHost,cxn)==true)
-               goto retry;
-       }
-
-       return;
-    }
-
-    /* make sure contents ok; this also should load it into memory */
-    res = artContentsOk (item->data.article);
-    if (res==false)
-    {
-       if (justadded == item->data.article) {
-           ReQueue(cxn, &(cxn->lmtp_todeliver_q), item);
-           return;
-       } else {
-           /* tell to reject taking this message */
-           QueueForgetAbout(cxn,item, MSG_MISSING);
-       }
-
-       goto retry;
-    }
-
-    /* Check if it's a control message */
-    bufs = artGetNntpBuffers (item->data.article);
-    if (bufs == NULL)
-    {
-       /* tell to reject taking this message */
-       QueueForgetAbout(cxn,item, MSG_MISSING);
-       goto retry;
-    }
-
-    result = FindHeader(bufs, "Control", &control_header, &control_header_end);
-    if (result == RET_OK) {
-       result = AddControlMsg(cxn, item->data.article, bufs, 
-                              control_header,control_header_end, 1);
-       if (result != RET_OK) {
-           d_printf(1,"%s:%d Error adding to [imap] control queue\n",
-                    hostPeerName (cxn->myHost),cxn->ident) ;
-           ReQueue(cxn, &(cxn->lmtp_todeliver_q), item);
-           return;
-       }
-
-       switch(cxn->imap_state) {
-       case IMAP_IDLE_AUTHED:
-           /* we're idle. let's process the queue */
-           imap_ProcessQueue(cxn);
-           break;
-       case IMAP_DISCONNECTED:
-       case IMAP_WAITING:
-           /* Let's connect. Once we're connected we can 
-              worry about the message */
-           if (cxn->imap_sleepTimerId == 0) {
-               if (imap_Connect(cxn) != RET_OK) prepareReopenCbk(cxn,0);
-           }
-           break;
-       default:
-           /* we're doing something right now */
-           break;
-       }
-       
-       /* all we did was add a control message. 
-          we still want to get an lmtp message */
-       goto retry;
-    }
-
-    if (cxn->current_bufs != NULL) {
-       /*      freeBufferArray(cxn->current_bufs); */
-       cxn->current_bufs = NULL;
-    }
-    cxn->current_bufs = bufs;
-    cxn->current_article = item;
-    
-    /* we make use of pipelining here
-       send:
-         rset
-         mail from
-        rcpt to
-        data
-    */
-
-    /* find out who it's going to */
-    result = FindHeader(cxn->current_bufs, "Newsgroups", 
-                       &rcpt_list, &rcpt_list_end);
-
-    if ((result != RET_OK) || (rcpt_list == NULL)) {
-       d_printf(1,"%s:%d Didn't find Newsgroups header\n",
-                hostPeerName (cxn->myHost),cxn->ident) ;
-       QueueForgetAbout(cxn, cxn->current_article, MSG_FAIL_DELIVER);
-       goto retry;     
-    }
-
-    /* free's original rcpt_list */
-    rcpt_list = ConvertRcptList(rcpt_list, rcpt_list_end, 
-                               &cxn->current_rcpts_issued);
-    cxn->current_rcpts_okayed = 0;
-    
-    if(mailfrom_name == NULL)
-       mailfrom_name = xstrdup("");
-    p = concat("RSET\r\n"
-               "MAIL FROM:<", mailfrom_name, ">\r\n",
-               rcpt_list,
-               "DATA\r\n", (char *) 0);
-
-    cxn->lmtp_state = LMTP_WRITING_UPTODATA;
-    result = WriteToWire_lmtpstr(cxn, p, strlen(p));
-
-    if (result != RET_OK) {
-       d_printf(0,"%s:%d failed trying to write\n",
-                hostPeerName (cxn->myHost),cxn->ident) ;
-       lmtp_Disconnect(cxn);
-       return;
-    }
-
-    /* prepend To: header to article */
-    if (deliver_to_header) {
-       char *to_list, *to_list_end;
-       int i, len;
-
-       result = FindHeader(cxn->current_bufs, "Followup-To", 
-                           &to_list, &to_list_end);
-
-       if ((result != RET_OK) || (to_list == NULL)) {
-           result = FindHeader(cxn->current_bufs, "Newsgroups", 
-                               &to_list, &to_list_end);
-       }
-
-       /* free's original to_list */
-       to_list = BuildToHeader(to_list, to_list_end);
-
-       len = bufferArrayLen(cxn->current_bufs);
-       cxn->current_bufs = xrealloc(cxn->current_bufs,
-                                     sizeof(Buffer) * (len+2));
-       cxn->current_bufs[len+1] = NULL;
-
-       for (i = len; i > 0; i--) {
-           cxn->current_bufs[i] = cxn->current_bufs[i-1];
-       }
-
-       cxn->current_bufs[0] = newBufferByCharP(to_list, strlen(to_list+1),
-                                               strlen(to_list));
-    }
-
-    hostArticleOffered (cxn->myHost, cxn);
-}
-
-/*
- * Called by the EndPoint class when the timer goes off
- */
-static void dosomethingTimeoutCbk (TimeoutId id, void *data)
-{
-  Connection cxn = (Connection) data ;
-
-  ASSERT (id == cxn->dosomethingTimerId) ;
-
-  show_stats(cxn);
-
-  /* we're disconnected but there are things to send */
-  if ((cxn->lmtp_state == LMTP_DISCONNECTED) && 
-      (cxn->lmtp_sleepTimerId == 0) &&
-      QueueItems(&(cxn->lmtp_todeliver_q)) > 0)
-  {
-      if (lmtp_Connect(cxn) != RET_OK)
-         prepareReopenCbk(cxn, 1);
-  }
-
-  if ((cxn->imap_state == IMAP_DISCONNECTED) &&
-      (cxn->imap_sleepTimerId == 0) &&
-      (QueueItems(&(cxn->imap_controlMsg_q)) > 0))
-  {
-      if (imap_Connect(cxn) != RET_OK)
-         prepareReopenCbk(cxn, 0);
-  }
-
-
-  /* if we're idle and there are items to send let's send them */
-  if ((cxn->lmtp_state == LMTP_AUTHED_IDLE) && 
-      QueueItems(&(cxn->lmtp_todeliver_q)) > 0) {
-      lmtp_sendmessage(cxn,NULL);
-  } else if (cxn->lmtp_state == LMTP_AUTHED_IDLE) {
-      lmtp_noop(cxn);
-  }
-
-  if ((cxn->imap_state == IMAP_IDLE_AUTHED) &&
-      (QueueItems(&(cxn->imap_controlMsg_q)) > 0)) {
-      imap_ProcessQueue(cxn);
-  } else if (cxn->imap_state == IMAP_IDLE_AUTHED) {
-      imap_noop(cxn);
-  }
-
-  /* set up the timer. */
-  clearTimer (cxn->dosomethingTimerId) ;
-
-  cxn->dosomethingTimerId = prepareSleep (dosomethingTimeoutCbk, 
-                                         cxn->dosomethingTimeout, cxn);  
-}
-
-/* Give all articles in the queue back to the host. We're probably
- * going to exit soon.
- * */
-
-static void DeferAllArticles(connection_t *cxn, Q_t *q)
-{
-    article_queue_t *cur;
-    conn_ret ret;
-    
-    while (1)
-    {
-       ret = PopFromQueue(q, &cur);
-       if (ret == RET_QUEUE_EMPTY) return;
-
-       if (ret == RET_OK)
-        {
-           QueueForgetAbout(cxn, cur, MSG_GIVE_BACK);
-       } else {
-           d_printf(0,"%s:%d Error emptying queue (deffering all articles)\n",
-                    hostPeerName (cxn->myHost),cxn->ident);
-           return;
-       }
-    }
-}
-
-/*
- * Does the actual deletion of a connection and all its private data.
- */
-static void delConnection (Connection cxn)
-{
-  bool shutDown;
-  Connection c, q;
-
-  if (cxn == NULL)
-    return ;
-
-  d_printf (1,"Deleting connection: %s:%d\n",
-           hostPeerName (cxn->myHost),cxn->ident) ;
-
-  for (c = gCxnList, q = NULL ; c != NULL ; q = c, c = c->next)
-    if (c == cxn)
-      {
-        if (gCxnList == c)
-          gCxnList = gCxnList->next ;
-        else
-          q->next = c->next ;
-        break ;
-      }
-  
-  ASSERT (c != NULL) ;
-  if (cxn->lmtp_endpoint != NULL)
-    delEndPoint (cxn->lmtp_endpoint) ;
-  if (cxn->imap_endpoint != NULL)
-    delEndPoint (cxn->imap_endpoint) ;
-
-  delBuffer (cxn->imap_rBuffer) ;
-  delBuffer (cxn->lmtp_rBuffer) ;
-
-  /* tell the Host we're outta here. */
-  shutDown = hostCxnGone (cxn->myHost, cxn) ;
-
-  cxn->ident = 0 ;
-  cxn->timeCon = 0 ;
-
-  free (cxn->ServerName) ;
-
-  clearTimer (cxn->imap_readBlockedTimerId) ;
-  clearTimer (cxn->imap_writeBlockedTimerId) ;
-  clearTimer (cxn->lmtp_readBlockedTimerId) ;
-  clearTimer (cxn->lmtp_writeBlockedTimerId) ;
-
-  clearTimer (cxn->imap_sleepTimerId);
-  cxn->imap_sleepTimerId = 0;  
-  clearTimer (cxn->lmtp_sleepTimerId);  
-  cxn->lmtp_sleepTimerId = 0;
-
-  clearTimer (cxn->dosomethingTimerId);
-
-  free (cxn->imap_respBuffer);
-  free (cxn->lmtp_respBuffer);
-
-  free (cxn) ;
-
-  if (shutDown)
-    {
-      /* exit program if that was the last connexion for the last host */
-      /* XXX what about if there are ever multiple listeners?
-        XXX    this will be executed if all hosts on only one of the 
-        XXX    listeners have gone */
-      time_t now = theTime () ;
-      char dateString [30] ;
-
-      strlcpy (dateString,ctime (&now),sizeof (dateString)) ;
-      dateString [24] = '\0' ;
-
-      notice ("ME finishing at %s", dateString) ;
-
-      exit (0) ;
-    }
-}
-
-
-/******************** PUBLIC FUNCTIONS ****************************/
-
-
-
-  /*
-   * Create a new Connection.
-   * 
-   * HOST is the host object we're owned by.
-   * IDENT is an identifier to be added to syslog entries so we can tell
-   *    what's happening on different connections to the same peer.
-   * IPNAME is the name (or ip address) of the remote)
-   * MAXTOUT is the maximum amount of time to wait for a response before
-   *    considering the remote host dead.
-   * PORTNUM is the portnum to contact on the remote end.
-   * RESPTIMEOUT is the amount of time to wait for a response from a remote
-   *    before considering the connection dead.
-   * CLOSEPERIOD is the number of seconds after connecting that the
-   *     connections should be closed down and reinitialized (due to problems
-   *     with old NNTP servers that hold history files open. Value of 0 means
-   *     no close down.
-   */
-
-Connection newConnection (Host host,
-                          unsigned int ident,
-                          const char *ipname,
-                          unsigned int artTout UNUSED,
-                          unsigned int portNum UNUSED,
-                          unsigned int respTimeout,
-                          unsigned int closePeriod UNUSED,
-                          double lowPassLow UNUSED,
-                          double lowPassHigh UNUSED,
-                         double lowPassFilter UNUSED)
-{
-    Connection cxn;
-    /* check arguments */
-
-    /* allocate connection structure */
-    cxn = xcalloc (1, sizeof(connection_t)) ;
-
-    cxn->ident = ident ;
-    cxn->ServerName = xstrdup (ipname) ;
-    cxn->myHost = host ;
-
-    /* setup mailfrom user */
-    if (gethostname(hostname, MAXHOSTNAMELEN)!=0)
-    {
-       d_printf(0,"%s gethostname failed\n",ipname);
-       return NULL;
-    }
-
-
-    mailfrom_name = concat("news@", hostname, (char *) 0);
-
-    cxn->next = gCxnList ;
-    gCxnList = cxn ;
-    gCxnCount++ ;
-
-    /* init stuff */
-    Initialize(cxn, respTimeout);
-
-    return cxn;
-}
-
-
-/* Causes the Connection to build the network connection. */
-bool cxnConnect (Connection cxn)
-{
-    /* make the lmtp connection */
-    if (lmtp_Connect(cxn) != RET_OK) return false;
-
-    if (imap_Connect(cxn) != RET_OK) return false;
-
-    return true;
-}
-
-
-static void QuitIfIdle(Connection cxn)
-{
-    if ((cxn->lmtp_state == LMTP_AUTHED_IDLE) && 
-       (QueueItems(&(cxn->lmtp_todeliver_q))<=0)) {
-       lmtp_IssueQuit(cxn);
-    }
-    if ((cxn->imap_state == IMAP_IDLE_AUTHED) && 
-       (QueueItems(&(cxn->imap_controlMsg_q))<=0)) {
-       imap_sendQuit(cxn);
-    }
-}
-
-static void DeleteIfDisconnected(Connection cxn)
-{
-    /* we want to shut everything down. if both connections disconnected now we can */
-    if ((cxn->issue_quit >= 1) &&
-       (cxn->lmtp_state == LMTP_DISCONNECTED) &&
-       (cxn->imap_state == IMAP_DISCONNECTED))
-    {
-
-       switch (cxn->issue_quit)
-       {
-       case 1:
-           if (cxn->lmtp_state == LMTP_DISCONNECTED)
-           {
-               cxn->lmtp_state = LMTP_WAITING;
-               cxn->imap_state = IMAP_WAITING;
-               cxn->issue_quit = 0;
-               hostCxnWaiting (cxn->myHost,cxn) ;  /* tell our Host we're waiting */
-           }
-           break;
-       case 2:
-           if (cxn->lmtp_state == LMTP_DISCONNECTED)
-           {
-               cxn->issue_quit = 0;
-               
-               if (imap_Connect(cxn)!=RET_OK) prepareReopenCbk(cxn,0);
-               if (lmtp_Connect(cxn)!=RET_OK) prepareReopenCbk(cxn,1);
-           }
-           break;
-       case 3:
-           if (cxn->lmtp_state == LMTP_DISCONNECTED)
-           {
-               hostCxnDead (cxn->myHost,cxn) ;
-               delConnection(cxn);
-           }
-           break;
-           
-       }       
-    }
-}
-
-  /* puts the connection into the wait state (i.e. waits for an article
-     before initiating a connect). Can only be called right after
-     newConnection returns, or while the Connection is in the (internal)
-     Sleeping state. */
-void cxnWait (Connection cxn)
-{
-    cxn->issue_quit = 1;
-
-    QuitIfIdle(cxn);
-}
-
-  /* The Connection will disconnect as if cxnDisconnect were called and then
-     it automatically reconnects to the remote. */
-void cxnFlush (Connection cxn)
-{
-    cxn->issue_quit = 2;
-
-    QuitIfIdle(cxn);
-}
-
-
-
-  /* The Connection sends remaining articles, then issues a QUIT and then
-     deletes itself */
-void cxnClose (Connection cxn)
-{
-    d_printf(0,"%s:%d Closing cxn\n",hostPeerName (cxn->myHost), cxn->ident);
-    cxn->issue_quit = 3;
-
-    QuitIfIdle(cxn);
-
-    DeleteIfDisconnected(cxn);
-}
-
-  /* The Connection drops all queueed articles, then issues a QUIT and then
-     deletes itself */
-void cxnTerminate (Connection cxn)
-{
-    d_printf(0,"%s:%d Terminate\n",hostPeerName (cxn->myHost), cxn->ident);
-
-    cxn->issue_quit = 3;    
-
-    /* give any articles back to host in both queues */
-    DeferAllArticles(cxn, &(cxn->lmtp_todeliver_q));
-    DeferAllArticles(cxn, &(cxn->imap_controlMsg_q));
-
-    QuitIfIdle(cxn);
-}
-
-  /* Blow away the connection gracelessly and immedately clean up */
-void cxnNuke (Connection cxn)
-{
-    d_printf(0,"%s:%d Nuking connection\n",cxn->ServerName, cxn->ident);
-
-    cxn->issue_quit = 4;
-
-    /* give any articles back to host in both queues */
-    DeferAllArticles(cxn, &(cxn->lmtp_todeliver_q));
-    DeferAllArticles(cxn, &(cxn->imap_controlMsg_q));
-
-    imap_Disconnect(cxn);
-    lmtp_Disconnect(cxn);
-
-    hostCxnDead (cxn->myHost,cxn);    
-    delConnection(cxn);
-}
-
-/*
- * must
- *   true  - must queue article. Don't try sending
- *   false - queue of article may fail. Try sending
- *
- * Always adds to lmtp queue even if control message
- *
- */
-
-static bool ProcessArticle(Connection cxn, Article art, bool must)
-{
-    conn_ret result;
-
-    /* Don't accept any articles when we're closing down the connection */
-    if (cxn->issue_quit > 1) {
-       return false;
-    }
-
-    /* if it's a regular message let's add it to the queue */
-    result = AddToQueue(&(cxn->lmtp_todeliver_q), art, DELIVER,1,must);
-
-    if (result == RET_EXCEEDS_SIZE) {
-       return false;
-    }
-
-    if (result != RET_OK)
-    {
-       d_printf(0,"%s:%d Error adding to delivery queue\n",
-                hostPeerName (cxn->myHost), cxn->ident);
-       return must;
-    }
-
-    if (must == true) return true;
-
-    switch (cxn->lmtp_state)
-       {
-       case LMTP_WAITING:
-       case LMTP_DISCONNECTED:     
-           if (cxn->lmtp_sleepTimerId == 0)
-               if (lmtp_Connect(cxn) != RET_OK) prepareReopenCbk(cxn,1);
-           break;
-           
-       case LMTP_AUTHED_IDLE:
-           lmtp_sendmessage(cxn,art);
-           break;
-       default:
-           /* currently doing something */
-           break;
-       }
-    
-    return true;
-}
-
-  /* Tells the Connection to take the article and handle its
-     transmission. If it can't (due to queue size or whatever), then the
-     function returns false. The connection assumes ownership of the
-     article if it accepts it (returns true). */
-bool cxnTakeArticle (Connection cxn, Article art)
-{
-    /* if we're closing down always refuse */
-    if (cxn->issue_quit == 1) return false;
-
-    return ProcessArticle (cxn,art,false);
-}
-
-  /* Tell the Connection to take the article (if it can) for later
-     processing. Assumes ownership of it if it takes it. */
-bool cxnQueueArticle (Connection cxn, Article art)
-{
-    return ProcessArticle (cxn,art,true);
-}
-
-/* generate a syslog message for the connections activity. Called by Host. */
-void cxnLogStats (Connection cxn, bool final)
-{
-  const char *peerName ;
-  time_t now = theTime() ;
-  int total, good, bad;
-
-  ASSERT (cxn != NULL) ;
-
-  peerName = hostPeerName (cxn->myHost) ;
-
-  total = cxn->lmtp_succeeded + cxn->lmtp_failed;
-  total += cxn->cancel_succeeded + cxn->cancel_failed;
-  total += cxn->create_succeeded + cxn->create_failed;
-  total += cxn->remove_succeeded + cxn->remove_failed;
-
-  good = cxn->lmtp_succeeded;
-  good += cxn->cancel_succeeded;
-  good += cxn->create_succeeded;
-  good += cxn->remove_succeeded;
-
-  bad = cxn->lmtp_failed;
-  bad += cxn->cancel_failed;
-  bad += cxn->create_failed;
-  bad += cxn->remove_failed;
-  notice ("%s:%d %s seconds %ld accepted %d refused %d rejected %d",
-          peerName, cxn->ident, (final ? "final" : "checkpoint"),
-          (long) (now - cxn->timeCon), total, 0, bad);
-  show_stats(cxn);
-
-  if (final) {
-      cxn->lmtp_succeeded   = 0;
-      cxn->lmtp_failed     = 0;
-      cxn->cancel_succeeded = 0;
-      cxn->cancel_failed   = 0;
-      cxn->create_succeeded = 0;
-      cxn->create_failed   = 0;
-      cxn->remove_succeeded = 0;
-      cxn->remove_failed   = 0;
-
-      if (cxn->timeCon > 0)
-        cxn->timeCon = theTime() ;
-    }
-
-}
-
-  /* return the number of articles the connection can be given. This lets
-     the host shovel in as many as possible. May be zero. */
-size_t cxnQueueSpace (Connection cxn)
-{
-    int lmtpsize;
-    int imapsize;
-
-    lmtpsize = QueueSpace(&(cxn->lmtp_todeliver_q));
-    imapsize = QueueSpace(&(cxn->imap_controlMsg_q));
-
-    if (lmtpsize >=1) lmtpsize--;
-    if (imapsize >=1) imapsize--;
-
-    d_printf(1,"%s:%d Q Space lmtp size = %d state = %d\n",
-            hostPeerName (cxn->myHost), cxn->ident,
-            lmtpsize,cxn->lmtp_state);
-    d_printf(1,"%s:%d Q Space imap size = %d state = %d\n",
-            hostPeerName (cxn->myHost), cxn->ident,
-            imapsize,cxn->imap_state); 
-
-    /* return the smaller of our 2 queues */
-    if (lmtpsize < imapsize)
-       return lmtpsize;
-    else
-       return imapsize;
-}
-
-  /* adjust the mode no-CHECK filter values */
-void cxnSetCheckThresholds (Connection cxn,
-                           double lowFilter UNUSED,
-                           double highFilter UNUSED,
-                           double lowPassFilter UNUSED)
-{
-    d_printf(1,"%s:%d Threshold change. This means nothing to me\n",
-            hostPeerName (cxn->myHost), cxn->ident);
-}
-
-/* print some debugging info. */
-void gPrintCxnInfo (FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  Connection cxn ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sGlobal Connection list : (count %d) {\n",
-           indent,gCxnCount) ;
-  for (cxn = gCxnList ; cxn != NULL ; cxn = cxn->next)
-    printCxnInfo (cxn,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-void printCxnInfo (Connection cxn, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  article_queue_t *artH ;
-
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sConnection : %p {\n",indent, (void *) cxn) ;
-  fprintf (fp,"%s    host : %p\n",indent, (void *) cxn->myHost) ;
-  fprintf (fp,"%s    endpoint (imap): %p\n",indent, (void *) cxn->imap_endpoint) ;
-  fprintf (fp,"%s    endpoint (lmtp): %p\n",indent, (void *) cxn->lmtp_endpoint) ;
-  fprintf (fp,"%s    state (imap) : %s\n",indent, imap_stateToString (cxn->imap_state)) ;
-  fprintf (fp,"%s    state (lmtp) : %s\n",indent, lmtp_stateToString (cxn->lmtp_state)) ;
-  fprintf (fp,"%s    ident : %d\n",indent,cxn->ident) ;
-  fprintf (fp,"%s    ip-name (imap): %s\n", indent, cxn->ServerName) ;
-  fprintf (fp,"%s    ip-name (lmtp): %s\n", indent, cxn->ServerName) ;
-  fprintf (fp,"%s    port-number (imap) : %d\n",indent,cxn->imap_port) ;
-  fprintf (fp,"%s    port-number (lmtp) : %d\n",indent,cxn->lmtp_port) ;
-
-  fprintf (fp,"%s    Issuing Quit : %d\n",indent, cxn->issue_quit) ;
-
-  fprintf (fp,"%s    time-connected (imap) : %ld\n",indent,(long) cxn->imap_timeCon) ;
-  fprintf (fp,"%s    time-connected (lmtp) : %ld\n",indent,(long) cxn->lmtp_timeCon) ;
-  fprintf (fp,"%s    articles from INN : %d\n",indent,
-          cxn->lmtp_succeeded+
-          cxn->lmtp_failed+
-          cxn->cancel_succeeded+
-          cxn->cancel_failed+
-          cxn->create_succeeded+
-          cxn->create_failed+
-          cxn->remove_succeeded+
-          cxn->remove_failed+
-          QueueSpace(&(cxn->lmtp_todeliver_q))+
-          QueueSpace(&(cxn->imap_controlMsg_q))
-          );
-  fprintf(fp,"%s    LMTP STATS: yes: %d no: %d\n",indent, 
-         cxn->lmtp_succeeded, cxn->lmtp_failed);
-  fprintf(fp,"%s    control:    yes: %d no: %d\n",indent, 
-         cxn->cancel_succeeded, cxn->cancel_failed);
-  fprintf(fp,"%s    create:     yes: %d no: %d\n",indent, 
-         cxn->create_succeeded, cxn->create_failed);
-  fprintf(fp,"%s    remove:     yes: %d no: %d\n",indent, 
-         cxn->remove_succeeded, cxn->remove_failed);
-
-  fprintf (fp,"%s    response-timeout : %d\n",indent,cxn->imap_readTimeout) ;
-  fprintf (fp,"%s    response-callback : %d\n",indent,cxn->imap_readBlockedTimerId) ;
-
-  fprintf (fp,"%s    write-timeout : %d\n",indent,cxn->imap_writeTimeout) ;
-  fprintf (fp,"%s    write-callback : %d\n",indent,cxn->imap_writeBlockedTimerId) ;
-
-  fprintf (fp,"%s    reopen wait : %d\n",indent,cxn->imap_sleepTimeout) ;
-  fprintf (fp,"%s    reopen id : %d\n",indent,cxn->imap_sleepTimerId) ;
-
-  fprintf (fp,"%s    IMAP queue {\n",indent) ;
-  for (artH = cxn->imap_controlMsg_q.head; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->data.article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    LMTP queue {\n",indent) ;
-  for (artH = cxn->lmtp_todeliver_q.head ; artH != NULL ; artH = artH->next)
-    printArticleInfo (artH->data.control->article,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-/* config file load callback */
-int cxnConfigLoadCbk (void *data UNUSED)
-{
-  long iv ;
-  int rval = 1 ;
-  FILE *fp = (FILE *) data ;
-
-  if (getInteger (topScope,"max-reconnect-time",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld", "max-reconnect-time",
-                      iv,"global scope",(long) MAX_RECON_PER);
-          iv = MAX_RECON_PER ;
-        }
-    }
-  else
-    iv = MAX_RECON_PER ;
-  max_reconnect_period = (unsigned int) iv ;
-
-  if (getInteger (topScope,"initial-reconnect-time",&iv,NO_INHERIT))
-    {
-      if (iv < 1)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 1. Using %ld", "initial-reconnect-time",
-                      iv,"global scope",(long)INIT_RECON_PER);
-          iv = INIT_RECON_PER ;
-        }
-    }
-  else
-    iv = INIT_RECON_PER ;
-  init_reconnect_period = (unsigned int) iv ;
-
-  return rval ;
-}
-
-/* check connection state is in cxnWaitingS, cxnConnectingS or cxnIdleS */
-bool cxnCheckstate (Connection cxn)
-{
-    d_printf(5, "%s:%d Being asked to check state\n",
-            hostPeerName (cxn->myHost), cxn->ident);
-
-    /* return false if either connection is doing something */
-    if (cxn->imap_state > IMAP_IDLE_AUTHED) return false;
-    if (cxn->lmtp_state > LMTP_AUTHED_IDLE) return false;
-
-    return true;
-}
diff --git a/innfeed/innfeed-convcfg.in b/innfeed/innfeed-convcfg.in
deleted file mode 100644 (file)
index d23d18a..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-#! /usr/bin/perl
-# 
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Sun, 19 Jan 1997 21:19:24 +0100
-# Project:      INN (innfeed)
-# File:         innfeed-convcfg.in
-# RCSId:        $Id: innfeed-convcfg.in 2680 1999-11-15 06:37:43Z rra $
-# Description:  Read in a old version of innfeed.conf on the command line 
-#              or on stdin, and write a new version on stdout.
-# 
-
-require 'ctime.pl' ;
-
-
-@keyorder = (
-'pid-file',
-'debug-level',
-'use-mmap',
-'log-file',
-'stdio-fdmax',
-'backlog-directory',
-'backlog-rotate-period',
-'backlog-ckpt-period',
-'backlog-newfile-period',
-'dns-retry',
-'dns-expire',
-'close-period',
-'gen-html',
-'status-file',
-'connection-stats',
-'host-queue-highwater',
-'stats-period',
-'stats-reset',
-'max-reconnect-time',
-'initial-reconnect-time',
-'article-timeout',
-'response-timeout',
-'initial-connections',
-'max-connections',
-'max-queue-size',
-'streaming',
-'no-check-high',
-'no-check-low',
-'port-number',
-'backlog-limit',
-'backlog-factor',
-'backlog-limit-highwater'
-);
-
-%procDefaults = (
-'pid-file', 'innfeed.pid',
-'debug-level', '0',
-'use-mmap', 'false',
-'log-file', 'innfeed.log',
-'stdio-fdmax', '0',
-'backlog-directory', 'innfeed',
-'backlog-rotate-period', '60',
-'backlog-ckpt-period', '30',
-'backlog-newfile-period', '600',
-'dns-retry', '900',
-'dns-expire', '86400',
-'close-period', '3600',
-'gen-html', 'false',
-'status-file', 'innfeed.status',
-'connection-stats', 'false',
-'host-queue-highwater', '10',
-'stats-period', '600',
-'stats-reset', '43200',
-'max-reconnect-time', '3600',
-'initial-reconnect-time', '30',
-'article-timeout', '600',
-'response-timeout', '300',
-'initial-connections', '1',
-'max-connections', '5',
-'max-queue-size', '25',
-'streaming', 'true',
-'no-check-high', '195.0',
-'no-check-low', '90.0',
-'port-number', '119',
-'backlog-limit', '0',
-'backlog-factor', '1.10',
-'backlog-limit-highwater', '0',
-                );
-
-%defaultKeys = ('article-timeout', 1,
-               'response-timeout', 1,
-               'initial-connections', 1,
-               'max-connections', 1,
-               'max-queue-size', 1,
-               'streaming', 1,
-               'no-check-high', 1,
-               'no-check-low', 1,
-               'port-number', 1,
-               'backlog-limit', 1) ;
-
-@defaultOrder = ('article-timeout', 
-               'response-timeout', 
-               'initial-connections', 
-               'max-connections', 
-               'max-queue-size', 
-               'streaming', 
-               'no-check-high', 
-               'no-check-low', 
-               'port-number', 
-               'backlog-limit') ;
-
-%formats = () ;
-
-foreach $key (keys %procDefaults) {
-    $max = length ($key) if length ($key) > $max ;
-    if ($procDefaults{$key} =~ /^true$/i || $procDefaults{$key} =~ /^false$/i){
-       $formats{$key} = "%s" ;
-    } elsif ($procDefaults{$key} =~ /^\d+$/) {
-       $formats{$key} = "%d" ;
-    } elsif ($procDefaults{$key} =~ /^\d+\.\d*$/) {
-       $formats{$key} = "%.4f" ;
-    } else {
-       $formats{$key} = "%s" ;
-    }
-}
-
-
-while (<>) {
-    next if /^\s*$/ ;
-    next if /^#/ ;
-
-    chop ;
-    @F = split (':') ;
-
-    if ($F[0] eq "default") {
-       $procDefaults{'article-timeout'} = $F[2] ;
-       $procDefaults{'response-timeout'} = $F[3] ;
-       $procDefaults{'initial-connections'} = $F[4] ;
-       $procDefaults{'max-connections'} = $F[5] ;
-       $procDefaults{'max-queue-size'} = $F[6] ;
-       $procDefaults{'streaming'} = $F[7] ;
-       $procDefaults{'no-check-low'} = $F[8] * 10.0 ;
-       $procDefaults{'no-check-high'} = $F[9] * 10.0 ;
-       $procDefaults{'port-number'} = $F[10] ;
-
-       printf "## This file was automatically generated created by $0\n" ;
-       printf "## On %s##\n\n", &ctime(time) ;
-
-       foreach $key (@keyorder) {
-           next if $defaultKeys{$key} ;
-
-           die "No format for $key\n" unless $formats{$key} ;
-           $format = "%${max}s:\t" . $formats{$key} . "\n" ;
-           printf $format, $key, $procDefaults{$key} ;
-       }
-
-       printf "\n\n## Defaults merged from:\n##\t$_\n\n" ;
-       foreach $key (@defaultOrder) {
-           die "No format for $key\n" unless $formats{$key} ;
-           $format ="%${max}s:\t" . $formats{$key} . "\n" ;
-           printf $format, $key, $procDefaults{$key} ;
-       }
-       print "\n\n\n" ;
-       $gotDefault = 1 ;
-    } elsif (@F == 0) {
-       die "Badly formed line: $0\n" ;
-    } else {
-       if (!$gotDefault) {
-           $gotDefault = 1 ;   # warn only one time.
-           warn "No default line was present.\n" ;
-       }
-
-       print "## Peer created from:\n" ;
-       print "##\t$_\n\n" ;
-       printf "peer %s {\n", $F[0] ;
-
-       printf "\tip-name: $F[1]\n" if $F[1] && $F[0] ne $F[1] ;
-       printf "\tarticle-timeout: %d\n", $F[2] if $F[2] ;
-       printf "\tresponse-timeout: %d\n", $F[3] if $F[3] ;
-       printf "\tinitial-connections: %d\n", $F[4] if ($F[4] ne "") ;
-       printf "\tmax-connections: %d\n", $F[5] if ($F[5] ne "") ;
-       printf "\tmax-queue-size: %d\n", $F[6] if ($F[6] ne "") ;
-       printf "\tstreaming: %s\n", $F[7] if ($F[7] ne "") ;
-       printf "\tno-check-high: %0.2f\n", $F[9] * 10.0 if ($F[9] ne "") ;
-       printf "\tno-check-low: %0.2f\n", $F[8] * 10.0 if ($F[8] ne "") ;
-       printf "\tport-number: %d\n", $F[10] if ($F[10] ne "") ;
-
-       print "}\n\n\n" ;
-    }
-}
-       
-       
diff --git a/innfeed/innfeed.h b/innfeed/innfeed.h
deleted file mode 100644 (file)
index e743174..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*  $Id: innfeed.h 7559 2006-08-28 02:10:39Z eagle $
-**
-**  innfeed's configuration values.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The application configuration values.  This file is #include'd before any
-**  system header files, so it can't rely on any CPP symbols other that what
-**  the compiler defines.
-*/
-
-#if ! defined ( innfeed_h__ )
-#define innfeed_h__
-
-#include "inn/timer.h"
-
-/**********************************************************************/
-/*                     Application specific defines                   */
-/**********************************************************************/
-
-/* the path to the run-time config file. If relative, then relative to
-   @ETCDIR@. Overridden by ``-c'' option. */
-#define CONFIG_FILE "innfeed.conf"
-
-
-/*
- * This next section contains things than can be overriden in the config
- * file. The strings inside each comment is the key used in the
- * innfeed.conf file to override the value here. See innfeed.conf for a
- * description of each./
- */
-
-/* in tape.c */
-#define TAPE_DIRECTORY                 "innfeed"   /* [pathspool]/backlog-directory */
-#define TAPE_HIGHWATER                 5               /* backlog-highwater */
-#define TAPE_ROTATE_PERIOD     60              /* backlog-rotate-period */
-#define TAPE_CHECKPOINT_PERIOD         30              /* backlog-ckpt-period */
-#define TAPE_NEWFILE_PERIOD    600             /* backlog-newfile-period */
-#define TAPE_DISABLE           false           /* no-backlog */
-
-/* in main.c */
-#define PID_FILE               "innfeed.pid"   /* [pathrun]/pid-file */
-#define LOG_FILE               "innfeed.log"   /* [pathlog]/log-file */
-
-/* in host.c */
-#define DNS_RETRY_PERIOD       900             /* dns-retry */
-#define DNS_EXPIRE_PERIOD      86400           /* dns-expire */
-#define CLOSE_PERIOD           (60 * 60 * 24)  /* close-period */
-#define GEN_HTML               false           /* gen-html */
-#define INNFEED_STATUS                 "innfeed.status" /* status-file */
-#define LOG_CONNECTION_STATS   0               /* connection-stats */
-#define HOST_HIGHWATER                 10              /* host-highwater */
-#define STATS_PERIOD           (60 * 10)       /* stats-period */
-#define STATS_RESET_PERIOD     (60 * 60 * 12)  /* stats-reset-period */
-
-#define ARTTOUT                        600             /* article-timeout */
-#define RESPTOUT               300             /* response-timeout */
-#define INIT_CXNS              1               /* initial-connections */
-#define MAX_CXNS               2               /* max-connections */
-#define MAX_Q_SIZE             5               /* max-queue-size */
-#define STREAM                 true            /* streaming */
-#define NOCHECKHIGH            95.0            /* no-check-high */
-#define NOCHECKLOW             90.0            /* no-check-low */
-#define PORTNUM                119             /* port-number */
-#define FORCE_IPv4             false           /* force using IPv4 */
-#define BLOGLIMIT              0               /* backlog-limit */
-#define LIMIT_FUDGE            1.10            /* backlog-factor */
-#define BLOGLIMIT_HIGH         0               /* backlog-limit-high */
-
-#define INIT_RECON_PER 30      /* initial-reconnect-time */
-#define MAX_RECON_PER (60 * 60 * 1)/* max-reconnect-time */
-
-
-
-
-
-
-
-/****************************************************************************/
-/* 
- * The rest below are not run-time configurable.
- */
-
-/* If this file exists at startup then it's the same as having done
-   '-d 1' on the command line. This is a cheap way of avoiding continual
-   reloading of the newsfeeds file when debugging. */
-#define DEBUG_FILE "innfeed.debug" /* Relative to pathlog */
-
-/* if defined to a non-zero number, then a snapshot will be printed
-   whenever die() is called (e.g. on assert failure). This can use up a
-   lot of disk space. */
-#define SNAPSHOT_ON_DIE 0
-
-/* the full pathname of the file to get a printed dump of the system when
-   a SIGINT is delivered (or SNAPSHOT_ON_DIE is non-zero--see below). */
-#define SNAPSHOT_FILE "innfeed.snapshot" /* Relative to pathlog */
-
-/* Define this be an existing directory (or NULL). If innfeed deliberatly
-   dumps core it will chdir() to this directory first (if non-NULL). If
-   NULL then it will chdir to TAPE_DIRECTORY (as possibly modified by
-   the '-b' option). */
-#define CORE_DIRECTORY NULL
-
-/* strings that get added to the end of a peer name for generating
-   backlog file names.  A peername cannot end in any of these string
-   (e.g. having a peer called 'mypeer.input' will not work) */
-#define OUTPUT_TAIL ".output"
-#define INPUT_TAIL ".input"
-#define LOCK_TAIL ".lock"
-
-/* rough estimate of average article line length (including
-   headers). Smaller number means more efficient article preparation (for
-   transfer), but, if much smaller than reality, then more memory
-   wastage. */
-#define CHARS_PER_LINE 60
-
-/* How many seconds between logging statistics on article allocation.
-   For no logging set to 0 */
-#define ARTICLE_STATS_PERIOD (10 * 60) /* 10 minutes */
-
-/* max number of parallel connections to a single remote. This is just a
-   sanity check for the runtime config file. */
-#define MAX_CONNECTION_COUNT 50
-
-/* default size in bytes for buffers */
-#define BUFFER_SIZE 256
-
-/* amount we expand buffers on partial reads */
-#define BUFFER_EXPAND_AMOUNT 128 
-
-/* minimum number of seconds between log messages for starting
-   spooling. i.e. if the connection bounces up and down this will prevent
-   frequent logging of the spooling message. 0 turns off this logging. */
-#define SPOOL_LOG_PERIOD 600
-
-/* some big numbers just for sanity checking */
-#define MAX_MAXCHECKS 10000     /* no more than 10000 articles at a time */
-#define MAX_MAXART_TOUT 86400   /* one day max between articles from inn */
-#define MAX_RESP_TOUT 3600      /* one hour max to wait for response */
-
-/* the check / no-check filter value, i.e. roughly how many past
-   articles we take into account whilst doing the average for
-   check / no-check mode.
-   Ensure it's a float. */
-#define FILTERVALUE 50.0
-
-/* the maximum number of peers we'll handle (not connections) */
-#define MAX_HOSTS 100
-
-/* We try to keep article memory allocation below this limit. Doesn't work
-   very well, though. */
-#define SOFT_ARTICLE_BYTE_LIMIT (1024 * 1024 * 10) /* 10MB */
-
-/* define SELECT_RATIO to the number of times through the main loop before
-   checking on the fd from inn again.... */
-#define SELECT_RATIO 3
-
-
-#if defined (DBTIMES)
-
-  /* some small values for testing things. */
-
-#undef STATS_PERIOD
-#define STATS_PERIOD 30   /* 30 seconds */
-
-#undef STATS_RESET_PERIOD
-#define STATS_RESET_PERIOD (6 * 60) /* 6 minutes */
-
-#undef ARTICLE_STATS_PERIOD
-#define ARTICLE_STATS_PERIOD (6 * 60) /* 7 minutes */
-
-#undef CLOSE_PERIOD
-#define CLOSE_PERIOD (3 * 60)   /* 5 minutes */
-
-#endif /* DBTIMES */
-
-
-/* Additional OS-specific defines.  These should really be moved into
-   configure at some point. */
-
-/* Some broken system (all SunOS versions) have a lower limit for the
-   maximum number of stdio files that can be open, than the limit of open
-   file the OS will let you have. If this value is > 0 (and ``stdio-fdmax''
-   is *not* used in the config file), then all non-stdio file descriptors
-   will be kept above this value (by dup'ing them). */
-#if defined (sun)
-# if defined (__SVR4)
-#  define MAX_STDIO_FD 256
-# else
-#  define MAX_STDIO_FD 128
-# endif
-#else
-# define MAX_STDIO_FD 0
-#endif
-
-/* some timer constants */
-
-typedef enum { TMR_IDLE = TMR_APPLICATION, TMR_BACKLOGSTATS,
-  TMR_STATUSFILE, TMR_NEWARTICLE, TMR_READART, TMR_PREPART, TMR_READ,
-  TMR_WRITE, TMR_CALLBACK, TMR_MAX
-} TMRTYPE;
-
-#endif /* innfeed_h__ */
diff --git a/innfeed/innlistener.c b/innfeed/innlistener.c
deleted file mode 100644 (file)
index c684dde..0000000
+++ /dev/null
@@ -1,784 +0,0 @@
-/*  $Id: innlistener.c 6716 2004-05-16 20:26:56Z rra $
-**
-**  The implementation of the innfeed InnListener class.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <time.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "article.h"
-#include "buffer.h"
-#include "configfile.h"
-#include "endpoint.h"
-#include "host.h"
-#include "innlistener.h"
-#include "nntp.h"
-#include "tape.h"
-
-#define LISTENER_INPUT_BUFFER (1024 * 8) /* byte size of the input buffer */
-#define EOF_SLEEP_TIME 1       /* seconds to sleep when EOF on InputFile */
-
-struct innlistener_s 
-{
-    EndPoint myep ;
-
-    Host *myHosts ;
-    size_t hostLen ;
-    Buffer inputBuffer ;
-    bool dummyListener ;
-    bool dynamicPeers ;
-    TimeoutId inputEOFSleepId ;
-
-    InnListener next ;
-};
-
-static unsigned int listenerCount = 0 ;
-static InnListener listenerList = NULL ;
-
-InnListener mainListener ;
-
-static FILE *droppedFp = NULL ;
-static long droppedCount = 0 ;
-static int droppedFileCount = 0 ;
-static char *dropArtFile = NULL ;
-static bool fastExit = false ;
-
-extern const char *pidFile ;
-extern const char *InputFile ;
-extern bool RollInputFile ;
-extern bool genHtml ;
-
-
-static void giveArticleToPeer (InnListener lis,
-                               Article article, const char *peerName) ;
-static void newArticleCommand (EndPoint ep, IoStatus i,
-                               Buffer *buffs, void *data) ;
-static void wakeUp (TimeoutId id, void *data) ;
-static void writeCheckPoint (int offsetAdjust) ;
-static void dropArticle (const char *peer, Article article) ;
-static void listenerCleanup (void) ;
-
-static bool inited = false ;
-
-
-void listenerLogStatus (FILE *fp)
-{
-  fprintf (fp,"%sListener Status:%s\n",
-           genHtml ? "<B>" : "", genHtml ? "</B>" : "") ;
-  fprintf (fp,"    Dropped article file: %s\n",dropArtFile) ;
-  fprintf (fp,"   Dropped article count: %ld\n",(long) droppedCount) ;
-  fprintf (fp,"\n") ;
-}
-
-InnListener newListener (EndPoint endp, bool isDummy, bool dynamicPeers)
-{
-  InnListener l = xcalloc (1, sizeof(struct innlistener_s)) ;
-  Buffer *readArray ;
-
-  if (!inited)
-    {
-      inited = true ;
-      atexit (listenerCleanup) ;
-    }
-  
-  l->myep = endp ;
-
-  l->hostLen = MAX_HOSTS ;
-  l->myHosts = xcalloc (l->hostLen, sizeof(Host)) ;
-
-  l->inputBuffer = newBuffer (LISTENER_INPUT_BUFFER) ;
-  l->dummyListener = isDummy ;
-  l->dynamicPeers = dynamicPeers ;
-
-  addPointerFreedOnExit ((char *)bufferBase(l->inputBuffer)) ;
-  addPointerFreedOnExit ((char *)l->myHosts) ;
-  addPointerFreedOnExit ((char *)l) ;
-
-  readArray = makeBufferArray (bufferTakeRef (l->inputBuffer), NULL) ;
-  prepareRead (endp,readArray,newArticleCommand,l,1) ;
-
-  l->next = listenerList ;
-  listenerList = l ;
-
-  listenerCount++ ;
-
-  return l ;
-}
-
-void gPrintListenerInfo (FILE *fp, unsigned int indentAmt)
-{
-  InnListener p ;
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sGlobal InnListener list : %p (count %d) {\n",
-           indent,(void *) listenerList,listenerCount) ;
-  for (p = listenerList ; p != NULL ; p = p->next)
-    printListenerInfo (p,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-
-void printListenerInfo (InnListener listener, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sInnListener : %p {\n",indent,(void *) listener) ;
-  fprintf (fp,"%s    endpoint : %p\n", indent,(void *) listener->myep) ;
-  fprintf (fp,"%s    dummy-listener : %s\n",indent,
-           boolToString (listener->dummyListener)) ;
-  fprintf (fp,"%s    dynamicPeers : %s\n",indent,
-           boolToString (listener->dynamicPeers)) ;
-
-  fprintf (fp,"%s    input-buffer {\n",indent) ;
-  printBufferInfo (listener->inputBuffer,fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s    }\n",indent) ;
-
-  fprintf (fp,"%s    hosts {\n",indent) ;
-  for (i = 0 ; i < listener->hostLen ; i++)
-    {
-#if 0
-      if (listener->myHosts [i] != NULL)
-        printHostInfo (listener->myHosts [i],fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s        %p\n",indent,(void *) listener->myHosts[i]) ;
-#endif
-    }
-  
-  fprintf (fp,"%s    }\n",indent) ;
-  
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-  /* Unlink the pidFile if and only if it is our pidFile.
-     There is still a racecondition here but very small. */
-static void unlinkPidFile (void)
-{
-  FILE *fp;
-  char buf[32];
-
-  if ((fp = fopen(pidFile, "r")) == NULL)
-    return;
-
-  if (fgets(buf, 32, fp) != NULL && atoi(buf) == getpid())
-    unlink(pidFile);
-  fclose(fp);
-}
-
-  /* Close down all hosts on this listener. When they're all gone the
-     Listener will be deleted. */
-void shutDown (InnListener l)
-{
-  unsigned int i ;
-  unsigned int count ;
-
-  d_printf (1,"Shutting down the listener\n") ;
-
-  /* When shutting down the mainListener, stop writing to the
-     StatusFile and remove our pidFile. */
-  if (l == mainListener)
-    {
-      /*hostCleanup (); should do this but .. */
-      hostSetStatusFile ("/dev/null");
-      unlinkPidFile();
-    }
-
-  closeDroppedArticleFile () ;
-  
-  if (l->myep != NULL)
-    {
-      if (l->inputEOFSleepId != 0)
-       removeTimeout (l->inputEOFSleepId) ;
-      l->inputEOFSleepId = 0 ;
-      delEndPoint (l->myep) ;
-    }
-  l->myep = NULL ;
-  
-  for (i = 0, count = 0 ; i < l->hostLen ; i++)
-    if (l->myHosts [i] != NULL) 
-      {
-        hostClose (l->myHosts[i]) ;
-        count++ ;
-      }
-
-  if (count == 0 || fastExit)
-    {
-      time_t now = theTime () ;
-      char dateString [30] ;
-
-      gHostStats();
-      strlcpy (dateString,ctime (&now),sizeof (dateString)) ;
-      dateString [24] = '\0' ;
-
-      if (fastExit)
-        notice ("ME finishing (quickly) at %s", dateString) ;
-      else
-        notice ("ME finishing at %s", dateString) ;
-
-      unlinkPidFile();
-      exit (0) ;
-    }
-}
-
-
-bool listenerAddPeer (InnListener listener, Host hostObj)
-{
-  unsigned int i ;
-
-  d_printf (1,"Adding peer: %s\n", hostPeerName (hostObj)) ;
-  
-  for (i = 0 ; i < listener->hostLen ; i++)
-    {
-      if (listener->myHosts [i] == NULL)
-        {
-          listener->myHosts [i] = hostObj ;
-
-          return true ;
-        }
-    }
-
-  return false ;
-}
-
-
-/* return true if this listener doesn't ever generate articles. */
-bool listenerIsDummy (InnListener listener)
-{
-  return listener->dummyListener ;
-}
-
-/* Called by the Host when it (the Host) is about to delete itself. */
-unsigned int listenerHostGone (InnListener listener, Host host)
-{
-  unsigned int i ;
-  unsigned int someThere = 0 ;
-
-  d_printf (1,"Host is gone: %s\n", hostPeerName (host)) ;
-  
-  for (i = 0 ; i < listener->hostLen ; i++)
-    if (listener->myHosts [i] == host)
-      listener->myHosts [i] = NULL ;
-    else if (listener->myHosts [i] != NULL)
-      someThere++ ;
-
-  return someThere ;
-}
-
-
-/* called by the Host when it has nothing to do. */
-void listenerHostIsIdle (InnListener listener, Host host)
-{
-  ASSERT (listener != NULL) ;
-  ASSERT (host != NULL) ;
-
-  d_printf (1,"Host is idle: %s\n", hostPeerName (host)) ;
-  
-  if (!listener->dummyListener)
-    return ;
-
-  /* if this listener is a dummy (i.e. not generating articles cause we're
-     just dealing with backlog files) then forget about the host and when
-     last one is gone we exit. */
-
-  hostClose (host) ;
-}
-
-
-void openInputFile (void)
-{
-  int fd, i, mainFd ;
-  off_t offset ;
-  char buf [32], *p ;
-
-  ASSERT (InputFile && *InputFile) ;
-
-  fd = open(InputFile, O_RDWR) ;
-  if (fd < 0)
-    die ("open %s: %s\n", InputFile, strerror(errno)) ;
-
-  mainFd = getMainEndPointFd() ;
-  if (fd != mainFd)
-    {
-      if (dup2(fd, mainFd) < 0)
-       die ("dup2 %d %d: %s\n", fd, mainFd, strerror(errno)) ;
-      close (fd);
-    }
-
-  i = read(mainFd, buf, sizeof (buf)) ;
-  if (i < 0)
-    die ("read %s: %s\n", InputFile, strerror(errno)) ;
-  else if (i > 0)
-    {
-      p = buf;
-      buf [ sizeof(buf) - 1 ] = '\0';
-      offset = (off_t) strtol (p, &p, 10) ;
-      if (offset > 0 && *p == '\n')
-       lseek (mainFd, offset, SEEK_SET) ;
-      else
-       lseek (mainFd, 0, SEEK_SET) ;
-    }
-  syslog(LOG_NOTICE, "ME opened %s", InputFile);
-}
-
-
-int listenerConfigLoadCbk (void *data UNUSED)
-{
-  int bval ;
-
-  if (getBool (topScope,"fast-exit",&bval,NO_INHERIT))
-    fastExit = (bval ? true : false) ;
-
-  return 1 ;
-}
-
-/**********************************************************************/
-/**                     STATIC PRIVATE FUNCTIONS                     **/
-/**********************************************************************/
-
-
-/* EndPoint callback function for when the InnListener's fd is ready for
-   reading. */
-static void newArticleCommand (EndPoint ep, IoStatus i,
-                               Buffer *buffs, void *data)
-{
-  InnListener lis = (InnListener) data ;
-  char *msgid, *msgidEnd ;
-  char *fileName, *fileNameEnd ;
-  char *peer, *peerEnd ;
-  char *cmd, *endc ;
-  char *bbase = bufferBase (buffs [0]) ;
-  size_t blen = bufferDataSize (buffs [0]) ;
-  Buffer *readArray ;
-  static int checkPointCounter ;
-  char *s;
-
-  ASSERT (ep == lis->myep) ;
-
-  bufferAddNullByte  (buffs [0]) ;
-  
-  if (i == IoEOF)
-    {
-      if ( lis == mainListener && InputFile != NULL )
-       {
-         if ( RollInputFile )
-           {
-             syslog(LOG_NOTICE, "ME reached EOF in %s", InputFile);
-             openInputFile () ;
-             RollInputFile = false ;
-             readArray = makeBufferArray (bufferTakeRef (buffs [0]),NULL) ;
-             prepareRead (ep, readArray, newArticleCommand, data, 1) ;
-           }
-         else
-           {
-             lis->inputEOFSleepId =
-               prepareSleep (wakeUp, EOF_SLEEP_TIME, data) ;
-
-           }
-       }
-      else 
-        {
-          d_printf (1,"Got EOF on listener\n") ;
-          notice ("ME source lost . Exiting");
-         shutDown (lis) ;
-        }
-    }
-  else if (i == IoFailed)
-    {
-      errno = endPointErrno (ep) ;
-#if HAVE_SOCKETPAIR
-      if (errno != ECONNABORTED)
-#endif
-      syswarn ("ME source read error, exiting") ;
-      d_printf (1,"Got IO Error on listener\n") ;
-      shutDown (lis) ;
-    }
-  else if (strchr (bbase, '\n') == NULL) /* partial read */
-    {
-      /* check for input corrupted by NULs - if they
-         precede the newline, we never get out of here */
-      if (strlen(bbase) < blen)
-        {
-          warn ("ME source format bad, exiting: %s", bbase) ;
-          shutDown (lis) ;
-
-          return ;
-        }
-      if (blen == bufferSize(buffs [0])) {
-        if (!expandBuffer (buffs [0], BUFFER_EXPAND_AMOUNT)) {
-          warn ("ME error expanding input buffer") ;
-          shutDown (lis) ;
-          return ;
-        }
-      }
-      readArray = makeBufferArray (bufferTakeRef (buffs [0]),NULL) ;
-      if (!prepareRead (ep, readArray, newArticleCommand, data, 1)) {
-        warn ("ME error prepare read failed") ;
-        freeBufferArray (readArray) ;
-        shutDown (lis) ;
-        return ;
-      }
-    }
-  else
-    {
-      /* now iterate over each full command we got on the input. */
-      cmd = bbase ;
-      while ((cmd < (bbase + blen)) && ((endc = strchr (cmd,'\n')) != NULL))
-        {
-          Article article ;
-          char *next = endc + 1;
-
-          if (*next == '\r')
-            next++ ;
-
-          endc-- ;
-          if (*endc != '\r')
-            endc++ ;
-
-          *endc = '\0' ;
-
-         /* check for input corrupted by NULs - if they are preceded
-            by newline, we may skip a large chunk without noticing */
-         if (*next == '\0' && next < bbase + blen)
-            {
-              warn ("ME source format bad, exiting: %s", cmd) ;
-              shutDown (lis) ;
-
-              return ;
-            }
-          
-          d_printf (2,"INN Command: %s\n", cmd) ;
-
-          /* pick out the leading string (the filename) */
-          if ((fileName = findNonBlankString (cmd,&fileNameEnd)) == NULL)
-            {
-              warn ("ME source format bad, exiting: %s", cmd) ;
-              shutDown (lis) ;
-
-              return ;
-            }
-          
-          *fileNameEnd = '\0' ; /* for the benefit of newArticle() */
-
-          /* now pick out the next string (the message id) */
-          if ((msgid = findNonBlankString (fileNameEnd + 1,&msgidEnd)) == NULL)
-            {
-              *fileNameEnd = ' ' ; /* to make syslog work properly */
-              warn ("ME source format bad, exiting: %s", cmd) ;
-              shutDown (lis) ;
-
-              return ;
-            }
-
-          *msgidEnd = '\0' ;    /* for the benefit of newArticle() */
-          
-          /* now create an article object and give it all the peers on the
-             rest of the command line. Will return null if file is missing. */
-          article = newArticle (fileName, msgid) ;
-          *fileNameEnd = ' ' ;
-
-          /* Check the message ID length */
-          if (strlen(msgid) > NNTP_MSGID_MAXLEN) {
-            warn ("ME message id exceeds limit of %d octets: %s",
-                  NNTP_MSGID_MAXLEN, msgid) ;
-            *(msgidEnd+1) = '\0' ;
-          }
-          *msgidEnd = ' ' ;
-
-          /* Check if message ID starts with < and ends with > */
-          if (*msgid != '<' || *(msgidEnd-1) != '>') {
-            warn ("ME source format bad, exiting: %s", cmd) ;
-            *(msgidEnd+1) = '\0';
-          }
-
-          /* now get all the peernames off the rest of the command lines */
-          peerEnd = msgidEnd ;
-          do 
-            {
-              *peerEnd = ' ' ;
-
-              /* pick out the next peer name */
-              if ((peer = findNonBlankString (peerEnd + 1,&peerEnd))==NULL)
-                break ;     /* even no peer names is OK. */ /* XXX REALLY? */
-
-              *peerEnd = '\0' ;
-              
-              /* See if this is a valid peername */
-              for(s = peer; *s; s++)
-                if (!CTYPE(isalnum, *s) && *s != '.' && *s != '-' && *s != '_')
-                  break;
-              if (*s != 0) {
-                  warn ("ME invalid peername %s", peer) ;
-                  continue;
-              }
-              if (article != NULL)
-                giveArticleToPeer (lis,article,peer) ;
-            }
-          while (peerEnd < endc) ;
-
-          delArticle (article) ;
-          
-          cmd = next ;
-
-         /* write a checkpoint marker if we've done another large chunk */
-         if (InputFile && *InputFile && ++checkPointCounter == 1000)
-           {
-             /* adjust the seek pointer value by the current location
-                within the input buffer */
-             writeCheckPoint (blen - (cmd - bbase)) ;
-             checkPointCounter = 0 ;
-           }
-
-        }
-
-      if (*cmd != '\0')         /* partial command left in buffer */
-        {
-          Buffer *bArr ;
-          unsigned int leftAmt = blen - (cmd - bbase) ;
-
-          ASSERT (cmd != bbase) ;
-          /* first we shift whats left in the buffer down to the bottom */
-          memmove (bbase,cmd,leftAmt) ;
-          bufferSetDataSize (buffs [0],leftAmt) ;
-      
-          bArr = makeBufferArray (bufferTakeRef (buffs [0]),NULL) ;
-      
-          if ( !prepareRead (lis->myep, bArr, newArticleCommand, lis, 1) )
-            {
-              warn ("ME error prepare read failed") ;
-
-              freeBufferArray (bArr) ;
-              
-              shutDown (lis) ;
-
-              return ;
-            }
-        }
-      else if ( !readIsPending (lis->myep) ) 
-        {                       /* XXX read should never be pending here */
-          Buffer *bArr = makeBufferArray (bufferTakeRef (buffs [0]),NULL) ;
-      
-          bufferSetDataSize (buffs [0],0) ;
-      
-          if ( !prepareRead (lis->myep, bArr, newArticleCommand, lis, 1) )
-            {
-              warn ("ME error prepare read failed") ;
-
-              shutDown (lis) ;
-
-              return ;
-            }
-        }
-    }
-
-  freeBufferArray (buffs) ;
-}
-
-/* EndPoint callback function for when the sleep due to 
-   having reached EOF on InputFile is done. */
-static void wakeUp (TimeoutId id, void *data)
-{
-  InnListener lis = (InnListener) data ;
-  Buffer *readArray ;
-
-  ASSERT (id == lis->inputEOFSleepId) ;
-
-  lis->inputEOFSleepId = 0 ;
-  readArray = makeBufferArray (bufferTakeRef (lis->inputBuffer), NULL) ;
-  prepareRead (lis->myep,readArray,newArticleCommand,lis,1) ;
-}
-
-
-/* Find the Host object for the peer and hand off a reference to the
-   article for it to transmit. */
-static void giveArticleToPeer (InnListener lis,
-                               Article article, const char *peerName)
-{
-  unsigned int i ;
-
-  for (i = 0 ; i < lis->hostLen ; i++)
-    if (lis->myHosts[i] != NULL)
-      if (strcmp (peerName,hostPeerName (lis->myHosts [i])) == 0)
-        {
-          d_printf (1,"Giving article to peer: %s\n", peerName) ;
-          hostSendArticle (lis->myHosts [i],artTakeRef (article)) ;
-          break ;
-        }
-
-  if (i == lis->hostLen)
-    {
-      d_printf (1,"Failed to give article to peer: -%s-\n", peerName) ;
-      
-      if (lis->dynamicPeers)
-       {
-         Host newHostObj;
-
-          d_printf (1, "Adding peer dynamically\n") ;
-          
-          newHostObj = newDefaultHost (lis, peerName);
-
-          if (newHostObj == NULL)
-            {
-              /* Most likely we couldn't get the lock, i.e. the
-                peer is blocked.
-              */
-              dropArticle (peerName,article) ;
-            }
-          else if ( !listenerAddPeer (lis, newHostObj) )
-            {
-              /* XXX need to remember we've gone over the limit and not try
-                 to add any more. */
-              warn ("ME internal too many hosts. (max is %lu)",
-                    (unsigned long) lis->hostLen) ;
-              dropArticle (peerName,article) ;
-            }
-          else
-           {
-             d_printf (1,"Giving article to peer: %s\n", peerName) ;
-             hostSendArticle (newHostObj,artTakeRef (article)) ;
-           }
-        }
-      else
-        {
-          dropArticle (peerName,article) ;
-        }
-    }
-}
-
-
-static void writeCheckPoint (int offsetAdjust)
-{
-  char offsetString[16], *writePointer ;
-  off_t offset ;
-  int writeBytes, writeReturn, mainFd ;
-             
-  mainFd = getMainEndPointFd() ;
-  offset = lseek (mainFd, 0, SEEK_CUR) ;
-  if (offset < 0)
-    syslog (LOG_ERR, "ME tell(mainFd): %m") ;
-  else
-    {
-      snprintf (offsetString, sizeof(offsetString), "%ld\n",
-                     (long)(offset - offsetAdjust) ) ;
-      if ( lseek (mainFd, 0, SEEK_SET) != 0 )
-       syslog (LOG_ERR, "ME seek(mainFd, 0, 0): %m") ;
-      else
-       {
-         writeBytes = strlen (offsetString) ;
-         writePointer = offsetString ;
-         do
-           { 
-             writeReturn = write (mainFd, writePointer, writeBytes) ;
-             if (writeReturn < 0)
-               {
-                 syslog (LOG_ERR,"ME write input checkpoint: %m") ;
-                 break ;
-               }
-             writePointer += writeReturn ;
-             writeBytes -= writeReturn ;
-           } while (writeBytes) ;
-         if ( lseek (mainFd, offset, SEEK_SET) != offset )
-           die ("ME seek(mainFd, %ld, SEEK_SET): %s\n", (long)offset,
-                strerror(errno) ) ;
-       }
-    }
-}
-
-
-void openDroppedArticleFile (void) 
-{
-  pid_t myPid = getpid () ;
-  const char *tapeDir = getTapeDirectory() ;
-  size_t len;
-
-  if (dropArtFile != NULL)
-    free (dropArtFile) ;
-
-  len = pathMax(tapeDir) + 1;
-  dropArtFile = xmalloc(len);
-  snprintf (dropArtFile,len,"%s/innfeed-dropped.%c%06d",
-            tapeDir, droppedFileCount + 'A', (int) myPid) ;
-
-  if ((droppedFp = fopen (dropArtFile,"w")) == NULL)
-    {
-      syswarn ("ME cant open %s: loosing articles", dropArtFile) ;
-
-      free (dropArtFile) ;
-      dropArtFile = NULL ;
-      
-      if ((droppedFp = fopen ("/dev/null","w")) == NULL)
-        {
-          die ("ME error opening /dev/null") ;
-        }
-    }
-
-  
-}
-
-void closeDroppedArticleFile (void)
-{
-  off_t pos ;
-
-  if (droppedFp == NULL)
-    return ;
-
-  fflush (droppedFp) ;
-  pos = ftello (droppedFp) ;
-
-  fclose (droppedFp) ;
-  droppedFp = NULL ;
-
-  if (pos == 0 && dropArtFile != NULL)
-    unlink (dropArtFile) ;
-  else if (pos != 0 && dropArtFile == NULL)
-    warn ("ME lost %ld articles", droppedCount) ;
-  else if (pos != 0)
-    notice ("ME dropped %ld articles", droppedCount) ;
-     
-  droppedFileCount = (droppedFileCount + 1) % 26 ;
-  droppedCount = 0 ;
-}
-
-static void dropArticle (const char *peerName, Article article)
-{
-  static bool logged = false ;
-
-  if (!logged)
-    {
-      warn ("ME dropping articles into %s", dropArtFile) ;
-      logged = true ;
-    }
-  
-  droppedCount++ ;
-  fprintf (droppedFp,"%s %s %s\n",artFileName (article),
-           artMsgId (article), peerName) ;
-}
-
-
-static void listenerCleanup (void)
-{
-  free (dropArtFile) ;
-  dropArtFile = NULL ;
-}
diff --git a/innfeed/innlistener.h b/innfeed/innlistener.h
deleted file mode 100644 (file)
index 1c7c1e0..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*  $Id: innlistener.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  The public interface to the InnListener class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The public interface of the things that listens to commands from INN. It
-**  receives lines of the form:
-**
-**      filename msgid peer1 peer2 peer3
-**
-**  and turns them into Article objects and hands those Articles off to the
-**  Host objects.
-*/
-
-#if ! defined ( innlistener_h__ )
-#define innlistener_h__
-
-#include <stdio.h>
-
-#include "misc.h"
-
-
-extern InnListener mainListener ;
-
-/* Initialization of the InnListener object. If it fails then returns
-  NULL. ENDPOINT is the endpoint where the article info will come
-  from. A dummy listener exists when processing backlog files and is
-  there just to help drive the process. */
-InnListener newListener (EndPoint endp, bool isDummy, bool dynamicPeers) ;
-
-/* print some useful debugging information about the Listener and all its
- * Hosts and all their Connecitons/Article/Buffers etc. to the given FILE.
- */
-void gPrintListenerInfo (FILE *fp, unsigned int indentAmt) ;
-void printListenerInfo (InnListener listener, FILE *fp, unsigned int indentAmt) ;
-
-/* Called by the Host when it is about to delete itself */
-unsigned int listenerHostGone (InnListener listener, Host host) ;
-
-/* Called to hook up the given Host to the Listener. */
-bool listenerAddPeer (InnListener listener, Host hostObj) ;
-
-/* true if the listener is a dummy. */
-bool listenerIsDummy (InnListener listener) ;
-
-/*
- * This gets called to stop accepting new articles from innd. Typically
- * called by the signal handler, or when the listener gets EOF on its input
- * (in channel mode)
- */
-void shutDown (InnListener cxn) ;
-
-/* Callback fired after config file is loaded */
-int listenerConfigLoadCbk (void *data) ;
-
-  /* stop a specific host. */
-void shutDownHost (InnListener cxn, const char *peerName) ;
-
-  /* Called by the Host when it has nothing to do (so it can be shut down
-     if necessary). */
-void listenerHostIsIdle (InnListener listener, Host host) ;
-
-void openInputFile (void) ;
-
-void openDroppedArticleFile (void) ;
-void closeDroppedArticleFile (void) ;
-
-void listenerLogStatus (FILE *fp) ;
-
-#endif /* innlistener_h__ */
diff --git a/innfeed/main.c b/innfeed/main.c
deleted file mode 100644 (file)
index 9ff6537..0000000
+++ /dev/null
@@ -1,967 +0,0 @@
-/*  $Id: main.c 6956 2004-06-29 22:41:35Z rra $
-**
-**  Main routines for the innfeed program.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <netdb.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#if defined(HAVE_UNIX_DOMAIN_SOCKETS)
-# include <sys/un.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "storage.h"
-
-#include "article.h"
-#include "buffer.h"
-#include "configfile.h"
-#include "connection.h"
-#include "endpoint.h"
-#include "host.h"
-#include "innlistener.h"
-#include "misc.h"
-#include "tape.h"
-
-#define INHERIT 1
-#define NO_INHERIT 0
-
-/* exports */
-bool talkToSelf ;
-extern int debugWrites ;
-bool sigFlag = false ;
-const char *InputFile ;
-char *configFile = NULL ;
-bool RollInputFile = false ;
-char *pidFile = NULL ;
-bool useMMap = false ;
-void (*gPrintInfo) (void) ;
-char *dflTapeDir;
-/* these are used by imapfeed */
-char *deliver_username  = NULL;
-char *deliver_authname  = NULL;
-char *deliver_password  = NULL;
-char *deliver_realm     = NULL;
-const char *deliver_rcpt_to   = "+%s";
-char *deliver_to_header = NULL;
-
-/* imports */
-extern char *versionInfo ;
-#if defined (sun)
-extern char *optarg ;           /* needed for Solaris */
-extern int optind;
-#endif
-extern bool genHtml ;
-
-extern void openInputFile (void);
-
-/* privates */
-static char *logFile ;
-static char *newsspool ;
-
-static void sigemt (int sig) ;
-static void sigalrm (int sig) ;
-static void sigchld (int sig) ;
-static void sigint (int sig) ;
-static void sigquit (int sig) ;
-static void sighup (int sig) ;
-static void sigterm (int sig) ;
-static void sigusr (int sig) ;
-static void usage (int) ;
-static void gprintinfo (void) ;
-static void openLogFile (void) ;
-static void writePidFile (void) ;
-static int mainOptionsProcess (void *data) ;
-static int mainConfigLoadCbk (void *data) ;
-static void mainCleanup (void) ;
-
-static char *bopt = NULL ;
-static char *aopt = NULL ;
-static char *popt = NULL ;
-static bool Mopt = false ;
-static bool Zopt = false ;
-static bool Dopt = false ;
-static int debugLevel = 0 ;
-static unsigned int initialSleep = 2 ;
-static char *sopt = NULL ;
-static char *lopt = NULL ;
-static bool eopt = false ;
-static int elimit = 0 ;
-
-int main (int argc, char **argv)
-{
-  EndPoint ep ;
-  InnListener listener ;
-  int optVal, fd, rval ;
-  const char *subProgram = NULL ;
-  bool seenV = false ;
-  bool dynamicPeers = false ;
-  time_t now = theTime() ;
-  char dateString [30] ;
-  char *copt = NULL ;
-  char *debugFile;
-  bool checkConfig = false ;
-  bool val;
-
-  strlcpy (dateString,ctime(&now),sizeof (dateString)) ;
-
-  message_program_name = strrchr (argv [0],'/');
-  if (message_program_name == NULL)
-    message_program_name = argv [0] ;
-  else
-    message_program_name++;
-
-  gPrintInfo = gprintinfo ;
-
-  openlog (message_program_name,(int)(L_OPENLOG_FLAGS|LOG_PID),LOG_INN_PROG) ;
-  if (!innconf_read(NULL)) {
-      syslog(LOG_ERR, "cant read inn.conf\n");
-      exit(1);
-  }
-
-#if defined (HAVE_MMAP)
-  useMMap = true ;
-#else
-  useMMap = false ;
-#endif
-
-  message_handlers_die (2, error_log_stderr_date, message_log_syslog_err) ;
-  message_handlers_warn (1, message_log_syslog_warning);
-  message_handlers_notice (1, message_log_syslog_notice) ;
-
-#define OPT_STRING "a:b:c:Cd:e:hl:mMo:p:S:s:vxyz"
-
-  while ((optVal = getopt (argc,argv,OPT_STRING)) != EOF)
-    {
-      switch (optVal) 
-        {
-          case 'a':
-            aopt = optarg ;
-            break ;
-
-          case 'b':
-            if ( !isDirectory (optarg) )
-              logAndExit (1,"Not a directory: %s\n",optarg) ;
-            bopt = optarg ;
-            break ;
-
-          case 'C':
-            checkConfig = true ;
-            break ;
-
-          case 'c':
-            copt = optarg ;
-            break ;
-
-          case 'd':
-            loggingLevel = atoi (optarg) ;
-            debugLevel = loggingLevel ;
-            Dopt = true ;
-            break ;
-
-          case 'e':
-            eopt = true ;
-            elimit = atoi (optarg) ;
-            if (elimit <= 0)
-              {
-                fprintf (stderr,"Illegal value for -e option\n") ;
-                usage (1) ;
-              }
-            break ;
-
-          case 'h':
-            usage (0) ;
-
-          case 'l':
-            lopt = optarg ;
-            break ;
-
-          case 'M':
-            Mopt = true ;
-            useMMap = false ;
-            break ;
-
-          case 'm':
-            artLogMissingArticles (true) ;
-            break ;
-
-          case 'o':
-            artSetMaxBytesInUse (atoi (optarg)) ;
-            break ;
-
-          case 'p':
-            popt = optarg ;
-            break ;
-
-          case 's':
-            subProgram = optarg ;
-            break ;
-
-          case 'S':
-            sopt = optarg ;
-            break ;
-
-          case 'v':
-            seenV = true ;
-            break ;
-
-          case 'x':
-            talkToSelf = true ;
-            break ;
-
-          case 'y':
-            dynamicPeers = true ;
-            break ;
-
-          case 'z':
-            Zopt = true ;
-            break ;
-
-          default:
-            usage (1) ;        
-        }
-    }
-
-  argc -= optind;
-  argv += optind;
-
-  if (argc > 1)
-    usage (1) ;
-  else if (argc == 1)
-    InputFile = *argv;
-
-  if (seenV)
-    {
-      warn ("%s version: %s\n",message_program_name, versionInfo) ;
-      exit (0) ;
-    }
-
-  /* make sure we have valid fds 0, 1 & 2 so it is not taken by
-    something else, probably openlog().  fd 0 will be freopen()ed on the
-    inputFile, the subProgram, or ourself.  fd 1 and fd 2 will
-    be freopen()ed on the log file (or will stay pointed at /dev/null).
-    
-    without doing this, if the descriptors were closed then the
-    freopen calls on some systems (like BSDI 2.1) will really close
-    whatever has aquired the stdio descriptors, such as the socket
-    to syslogd.
-    
-    XXX possible problems:  what if fd 0 is closed but no inputFile,
-    XXX subProgram or talkToSelf is true?  it will not be freopen()ed, so
-    XXX innfeed won't have any fresh data (besides, fd 0 is only writable
-    XXX here).  perhaps a warning should be issued.
-    */
-  do
-    {
-      fd = open("/dev/null", O_WRONLY);
-      switch (fd)
-        {
-          case -1:
-            logAndExit (1,"open(\"/dev/null\", O_WRONLY): %s",
-                        strerror (errno));
-            break;
-          case 0:
-          case 1:
-          case 2:
-            /* good, we saved an fd from being trounced */
-            break;
-          default:
-            close(fd);
-        }
-    } while (fd < 2);
-
-  if ( !checkConfig ) 
-    {
-      notice ("ME starting %s at %s", versionInfo, dateString) ;
-    }
-
-  val = true;
-  if (!SMsetup(SM_PREOPEN, (void *)&val)) {
-      syslog(LOG_ERR, "cant setup the storage subsystem\n");
-      exit(1);
-  }
-  if (!SMinit()) {
-      d_printf(0, "Storage manager initialization failed\n");
-      syslog(LOG_ERR, "Storage manager initialization failed\n");
-      exit(1);
-  }
-
-  if (subProgram == NULL && talkToSelf == false)
-    {
-      struct stat buf ;
-
-      if (fstat (0,&buf) < 0)
-        logAndExit (1,"ME oserr fstat stdin: %s", strerror (errno)) ;
-      else if (S_ISREG (buf.st_mode))
-        InputFile = "";
-    }
-
-  /*
-   * set up the config file name and then read the file in. Order is important.
-   */
-  configAddLoadCallback (mainOptionsProcess,(checkConfig ? stderr : NULL)) ;
-  configAddLoadCallback (tapeConfigLoadCbk,(checkConfig ? stderr : NULL)) ;
-
-  configAddLoadCallback (endpointConfigLoadCbk,(checkConfig ? stderr : NULL));
-  configAddLoadCallback (hostConfigLoadCbk,(checkConfig ? stderr : NULL)) ;
-  configAddLoadCallback (cxnConfigLoadCbk,(checkConfig ? stderr : NULL)) ;
-  configAddLoadCallback (mainConfigLoadCbk,(checkConfig ? stderr : NULL)) ;
-  configAddLoadCallback (listenerConfigLoadCbk,(checkConfig ? stderr : NULL));
-
-  if (copt != NULL && *copt == '\0')
-    {
-      logOrPrint (LOG_CRIT,(checkConfig ? stderr : NULL),
-                  "Empty pathname for ``-c'' option") ;
-      exit (1) ;
-    }
-  configFile = buildFilename(innconf->pathetc, copt ? copt : CONFIG_FILE);
-  dflTapeDir = buildFilename(innconf->pathspool, TAPE_DIRECTORY);
-
-  rval = readConfig (configFile,(checkConfig ? stderr : NULL),
-                     checkConfig,loggingLevel > 0);
-
-  if (subProgram != NULL && (talkToSelf == true || InputFile))
-    {
-      d_printf (0,"Cannot specify '-s' with '-x' or an input file\n") ;
-      syslog (LOG_ERR,"Incorrect arguments: '-s' with '-x' or an input file\n");
-      usage (1) ;
-    }
-
-  if (checkConfig)
-    {
-      if (!rval)
-        {
-          fprintf (stderr,"config loading failed.\n") ;
-          exit (1) ;
-        }
-      else
-        {
-          fprintf (stderr,"config loading succeeded.\n") ;
-          exit (0) ;
-        }
-    }
-  else if (!rval)
-    exit (1) ;
-
-  debugFile = buildFilename (innconf->pathlog, DEBUG_FILE);
-  if (loggingLevel == 0 && fileExistsP (debugFile))
-    loggingLevel = 1 ;
-
-  if (logFile == NULL && ! isatty (fileno (stderr)))
-    logFile = buildFilename (innconf->pathlog, LOG_FILE) ;
-
-  if (logFile)
-    openLogFile () ;
-
-  openfds = 4 ;                 /* stdin, stdout, stderr and syslog */
-
-  writePidFile ();
-
-  if (subProgram != NULL)
-    {
-      int fds [2] ;
-      int pid ;
-
-      if (pipe (fds) < 0)
-        sysdie ("ME fatal pipe") ;
-
-      if ((pid = fork ()) < 0)
-        {
-          sysdie ("ME fatal fork") ;
-        }
-      else if (pid == 0)
-        {                       /* child */
-          close (fds[0]) ;
-          close (0) ;
-          close (1) ;
-          close (2) ;
-          dup2 (fds[1],1) ;
-          dup2 (fds[1],2) ;
-          execlp ("sh", "sh", "-c", subProgram, (char *) 0) ;
-          perror ("execlp") ;
-          exit (1) ;
-        }
-      else
-        {                       /* parent */
-          close (0) ;
-          dup2 (fds[0],0) ;
-          close (fds[1]) ;
-          xsignal(SIGCHLD,sigchld) ;
-          openfds++ ;
-        }
-    }
-  else  if (talkToSelf)
-    {
-        /* We're not really getting information from innd or a subprogram,
-           but are just processing backlog files. We set up a pipe to ourself
-           that we never write to, to simulate an idle innd. */
-      int pipefds [2] ;
-
-      if (pipe (pipefds) != 0)
-        sysdie ("ME fatal pipe") ;
-
-      close (0) ;
-      dup2 (pipefds [0], 0) ;
-
-      openfds++ ;
-      openfds++ ;
-    }
-
-  if (chdir (newsspool) != 0)
-    sysdie ("ME fatal chdir %s", newsspool) ;
-
-    /* hook up the endpoint to the source of new article information (usually
-       innd). */
-  ep = newEndPoint (0) ;        /* fd 0, i.e. stdin */
-
-    /* now arrange for this endpoint to always be the first one checked for
-       possible activity. */
-  setMainEndPoint (ep) ;
-
-  listener = newListener (ep, talkToSelf,dynamicPeers) ;
-  mainListener = listener ;
-
-  sleep (initialSleep) ;
-
-  if (innconf->rlimitnofile >= 0)
-    if (setfdlimit (innconf->rlimitnofile) < 0)
-      syswarn ("ME oserr setrlimit(RLIM_NOFILE,%ld)", innconf->rlimitnofile) ;
-
-  if (innconf->timer > 0)
-    TMRinit (TMR_MAX) ;
-
-  configHosts (talkToSelf) ;
-
-  if (InputFile && *InputFile) {
-    openInputFile () ;
-  }
-
-  /* handle signal to shutdown */
-  setSigHandler (SIGTERM,sigterm) ;
-  setSigHandler (SIGQUIT,sigquit) ;
-
-  /* handle signal to reload config */
-  setSigHandler (SIGHUP,sighup) ;
-
-  /* handle signal to print snapshot. */
-  setSigHandler (SIGINT,sigint) ;
-
-  /* handle signal to roll input file */
-  setSigHandler (SIGALRM,sigalrm) ;
-
-  /* handle signal to flush all the backlog files */
-  setSigHandler (SIGCHLD,sigemt) ;
-
-  /* we can increment and decrement logging levels by sending SIGUSR{1,2} */
-  setSigHandler (SIGUSR1,sigusr) ;
-  setSigHandler (SIGUSR2,sigusr) ;
-
-  atexit (mainCleanup) ;
-  
-  Run () ;
-
-  exit (0) ;
-}
-
-static void usage (int val)
-{
-  fprintf (stderr,"usage: %s [ options ] [ file ]\n\n",
-           message_program_name) ;
-  fprintf (stderr,"Version: %s\n\n",versionInfo) ;
-  fprintf (stderr,"Config file: %s\n",CONFIG_FILE) ;
-  fprintf (stderr,"Backlog directory: %s/%s\n", innconf->pathspool, TAPE_DIRECTORY) ;
-  fprintf (stderr,"\nLegal options are:\n") ;
-  fprintf (stderr,"\t-a dir      Use the given directory as the top of the article spool\n") ;
-
-  fprintf (stderr,"\t-b dir      Use the given directory as the the storage\n");
-  fprintf (stderr,"\t            place for backlog files and lock files.\n");
-
-  fprintf (stderr,"\t-c file     Use the given file as the config file instead of the\n");
-  fprintf (stderr,"\t            default of %s\n",CONFIG_FILE);
-
-  fprintf (stderr,"\t-C          Check the config file and then exit.\n") ;
-  fprintf (stderr,"\t-d num      set the logging level to num (an integer).\n");
-  fprintf (stderr,"\t            Larger value means more logging. 0 means no\n");
-  fprintf (stderr,"\t            logging. The default is 0\n");
-
-  fprintf (stderr,"\t-e bytes    Keep the output backlog files to no bigger\n");
-  fprintf (stderr,"\t            than %.2f times this number\n",LIMIT_FUDGE);
-
-  fprintf (stderr,"\t-h          print this message\n");
-
-  fprintf (stderr,"\t-l file     redirect stderr and stdout to the given file.\n");
-  fprintf (stderr,"\t            When run under INN they normally are redirected to\n");
-  fprintf (stderr,"\t            /dev/null. This is needed if using '-d'.\n");
-
-  fprintf (stderr,"\t-m          Log information on all missing articles\n");
-
-  fprintf (stderr,"\t-M          Turn *off* use of mmap\n") ;
-#if ! defined (HAVE_MMAP)
-  fprintf (stderr,"\t            (a no-op as this excutable has been built without mmap support\n") ;
-#endif
-
-  fprintf (stderr,"\t-p file     Write the process id to the given file\n") ;
-  fprintf (stderr,"\t            instead of the default of %s\n",PID_FILE);
-  fprintf (stderr,"\t            A relative path is relative to %s\n", innconf->pathrun) ;
-
-  fprintf (stderr,"\t-s command  run the given command in a subprocess and use\n");
-  fprintf (stderr,"\t            its output as article information instead of\n");
-  fprintf (stderr,"\t            running under innd\n");
-
-  fprintf (stderr,"\t-S file     Use the give filename instead of innfeed.status\n") ;
-  fprintf (stderr,"\t            relative pathnames start from %s\n", innconf->pathlog) ;
-
-  fprintf (stderr,"\t-v          print version information\n");
-
-  fprintf (stderr,"\t-x          Do not read any article information off stdin,\n");
-  fprintf (stderr,"\t            but simply process backlog files and then exit\n");
-  fprintf (stderr,"\t            when done\n");
-
-  fprintf (stderr,"\t-y          Add peers dynamically. If an unrecognized peername\n");
-  fprintf (stderr,"\t            is received from innd, then it is presumed to also\n");
-  fprintf (stderr,"\t            be the ip name and a new peer binding is set up\n");
-
-  fprintf (stderr,"\t-z          have each of the connections issue their own stats\n");
-  fprintf (stderr,"\t            whenever they close, or whenever their controller\n");
-  fprintf (stderr,"\t            issues its own stats\n");
-
-  exit (val) ;
-}
-
-static void sigterm (int sig UNUSED)
-{
-  notice ("ME received shutdown signal") ;
-  shutDown (mainListener) ;
-}
-
-static void sigquit (int sig UNUSED)
-{
-  sigterm (0) ;
-}
-
-static void sigint (int sig UNUSED)
-{
-  gprintinfo () ;
-}
-
-static void sighup (int sig UNUSED)
-{
-  notice ("ME reloading config file %s", configFile) ;
-
-  if (!readConfig (configFile,NULL,false,loggingLevel > 0))
-    {
-      die ("ME config aborting, error parsing config file") ;
-    }
-
-  configHosts (talkToSelf) ;
-}
-
-static void sigemt (int sig UNUSED)
-{
-  gFlushTapes () ;
-}
-
-static void sigalrm (int sig UNUSED)
-{
-  if (InputFile == NULL)
-    warn ("ME signal SIGALRM in non-funnel-file mode ignored") ;
-  else 
-    {
-      RollInputFile = true;
-      syslog(LOG_NOTICE, "ME preparing to roll %s", InputFile);
-    }
-}
-
-static void sigchld (int sig UNUSED)
-{
-#if 0
-  wait (&status) ;              /* we don't care */
-#endif
-
-  xsignal (sig,sigchld) ;
-}
-
-  /* SIGUSR1 increments logging level. SIGUSR2 decrements. */
-static void sigusr (int sig)
-{
-  if (sig == SIGUSR1) {
-    loggingLevel++ ;
-    notice ("ME increasing logging level to %d", loggingLevel) ;
-  } else if (sig == SIGUSR2 && loggingLevel > 0) {
-    loggingLevel-- ;
-    notice ("ME decreasing logging level to %d", loggingLevel) ;
-  }    
-}
-
-static void openLogFile (void)
-{
-  FILE *fpr ;
-
-  if (logFile)
-    {
-      fpr = freopen (logFile,"a",stdout) ;
-      if (fpr != stdout)
-        logAndExit (1,"freopen (%s, \"a\", stdout): %s",
-                    logFile, strerror (errno)) ;
-      
-      fpr = freopen (logFile,"a",stderr) ;
-      if (fpr != stderr)
-        logAndExit (1,"freopen (%s, \"a\", stderr): %s",
-                    logFile, strerror (errno)) ;
-      
-#if defined (HAVE_SETBUFFER)
-      setbuffer (stdout, NULL, 0) ;
-      setbuffer (stderr, NULL, 0) ;
-#else
-      setbuf (stdout, NULL) ;
-      setbuf (stderr, NULL) ;
-#endif
-    }
-}
-
-static void writePidFile (void)
-{
-  FILE *F;
-  int pid;
-
-  if (pidFile == NULL)
-    logAndExit (1,"NULL pidFile\n") ;
-
-  /* Record our PID. */
-  pid = getpid();
-  if ((F = fopen(pidFile, "w")) == NULL)
-    {
-      syslog(LOG_ERR, "ME cant fopen %s %m", pidFile);
-    }
-  else
-    {
-      if (fprintf(F, "%ld\n", (long)pid) == EOF || ferror(F))
-       {
-         syslog(LOG_ERR, "ME cant fprintf %s %m", pidFile);
-        }
-      if (fclose(F) == EOF)
-       {
-         syslog(LOG_ERR, "ME cant fclose %s %m", pidFile);
-        }
-      if (chmod(pidFile, 0664) < 0)
-       {
-         syslog(LOG_ERR, "ME cant chmod %s %m", pidFile);
-        }
-    }
-}
-
-static void gprintinfo (void)
-{
-  char *snapshotFile;
-  FILE *fp;
-  time_t now = theTime() ;
-
-  snapshotFile = buildFilename(innconf->pathlog, SNAPSHOT_FILE);
-  fp = fopen (snapshotFile,"a") ;
-  if (fp == NULL)
-    {
-      syswarn ("ME fopen %s", snapshotFile) ;
-      free(snapshotFile);
-      return ;
-    }
-  free(snapshotFile);
-
-#if defined (HAVE_SETBUFFER)
-  setbuffer (fp, NULL, 0) ;
-#else
-  setbuf (fp, NULL) ;
-#endif
-
-  fprintf (fp,"----------------------------System snaphot taken at: %s\n",
-           ctime (&now)) ;
-  gPrintListenerInfo (fp,0) ;
-  fprintf (fp,"\n\n\n\n") ;
-  gPrintHostInfo (fp,0) ;
-  fprintf (fp,"\n\n\n\n") ;
-  gPrintCxnInfo (fp,0) ;
-  fprintf (fp,"\n\n\n\n") ;
-  gPrintArticleInfo (fp,0) ;
-  fprintf (fp,"\n\n\n\n") ;
-  gPrintBufferInfo (fp,0) ;
-  fprintf (fp,"\n\n\n\n") ;
-  fclose (fp) ;
-}
-
-/* called after the config file is loaded and after the config data has
-  been updated with command line options. */
-static int mainConfigLoadCbk (void *data)
-{
-  FILE *fp = (FILE *) data ;
-  char *p ;
-  long ival ;
-  int bval ;
-
-  if (getString (topScope,"news-spool", &p,NO_INHERIT))
-    {
-      if ( !isDirectory (p) && isDirectory (innconf->patharticles) )
-        {
-          logOrPrint (LOG_WARNING,fp,
-                      "ME config: definition of news-spool (%s) is a"
-                      " non-existant directory. Using %s",p,
-                      innconf->patharticles) ;
-          p = xstrdup (innconf->patharticles) ;
-        }
-      else if (!isDirectory (p))
-        logAndExit (1,"Bad spool directories: %s, %s\n",p,innconf->patharticles) ;
-    }
-  else if (!isDirectory (innconf->patharticles))
-    logAndExit (1,"ME config: no definition of news-spool, and %s is no good",
-                innconf->patharticles);
-  else
-    p = xstrdup (innconf->patharticles) ;
-  newsspool = p ;
-
-  /***************************************************/
-  
-  if (getString (topScope,"input-file",&p,NO_INHERIT))
-    {
-      if (*p != '\0')
-       InputFile = buildFilename (getTapeDirectory(),p) ;
-      else
-       InputFile = "" ;
-      free (p) ;
-    }
-  
-  if (getString (topScope,"pid-file",&p,NO_INHERIT))
-    {
-      pidFile = buildFilename (innconf->pathrun,p) ;
-      free (p) ;
-    }
-  else
-    pidFile = buildFilename (innconf->pathrun,PID_FILE) ;
-  
-  if (getInteger (topScope,"debug-level",&ival,NO_INHERIT))
-    loggingLevel = (unsigned int) ival ;
-  
-  
-  if (getInteger (topScope,"initial-sleep",&ival,NO_INHERIT))
-    initialSleep = (unsigned int) ival ;
-  
-  
-  if (getBool (topScope,"use-mmap",&bval,NO_INHERIT))
-    useMMap = (bval ? true : false) ;
-
-  
-  if (getString (topScope,"log-file",&p,NO_INHERIT))
-    {
-      logFile = buildFilename (innconf->pathlog,p) ;
-      free (p) ;
-    }
-
-   /* For imap/lmtp delivering */
-  if (getString (topScope,"deliver-username",&p, NO_INHERIT))
-    {   
-        deliver_username = p;
-      /* don't need to free */
-    }
-
-  if (getString (topScope,"deliver-authname",&p, NO_INHERIT))
-    {
-      deliver_authname = p;
-      /* don't need to free */
-    }
-
-  if (getString (topScope,"deliver-password",&p, NO_INHERIT))
-    {
-      deliver_password = p;
-      /* don't need to free */
-    }
-
-  if (getString (topScope,"deliver-realm",&p, NO_INHERIT))
-    {
-      deliver_realm = p;
-      /* don't need to free */
-    }
-
-  if (getString (topScope,"deliver-rcpt-to",&p, NO_INHERIT))
-    {
-      deliver_rcpt_to = p;
-      /* don't need to free */
-    }
-
-  if (getString (topScope,"deliver-to-header",&p, NO_INHERIT))
-    {
-      deliver_to_header = p;
-      /* don't need to free */
-    }
-
-  
-
-  return 1 ;
-}
-
-/*
- * called after config file is loaded but before other callbacks, so we
- * can adjust config file values from options. They will be validated in the
- * second callback.
- */
-static int mainOptionsProcess (void *data UNUSED)
-{
-  value *v ;
-
-  if (bopt != NULL)
-    {
-      if ((v = findValue (topScope,"backlog-directory",NO_INHERIT)) != NULL) 
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (bopt) ;
-        }
-      else
-        addString (topScope,"backlog-directory",xstrdup (bopt)) ;
-    }
-
-  if (aopt != NULL)
-    {
-      if ((v = findValue (topScope,"news-spool",NO_INHERIT)) != NULL)
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (aopt) ;
-        }
-      else
-        addString (topScope,"news-spool",xstrdup (aopt)) ;
-    }
-
-  if (sopt != NULL)
-    {
-      if ((v = findValue (topScope,"status-file",NO_INHERIT)) != NULL)
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (sopt) ;
-        }
-      else
-        addString (topScope,"status-file",xstrdup (sopt)) ;
-    }
-
-
-  if (Dopt)
-    {
-      if ((v = findValue (topScope,"debug-level",NO_INHERIT)) != NULL)
-        v->v.int_val = debugLevel ;
-      else
-        addInteger (topScope,"debug-level",debugLevel) ;
-    }
-
-  
-  if (eopt || talkToSelf)
-    {
-      if (talkToSelf)
-        elimit = 0 ;
-      
-      if ((v = findValue (topScope,"backlog-limit",NO_INHERIT)) != NULL)
-        v->v.int_val = elimit ;
-      else
-        addInteger (topScope,"backlog-limit",elimit) ;
-    }
-
-  
-  if (Mopt)
-    {
-      if ((v = findValue (topScope,"use-mmap",NO_INHERIT)) != NULL)
-        v->v.bool_val = 0 ;
-      else
-        addBoolean (topScope,"use-mmap",0) ;
-    }
-  
-
-  if (popt != NULL)
-    {
-      if ((v = findValue (topScope,"pid-file",NO_INHERIT)) != NULL)
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (popt) ;
-        }
-      else
-        addString (topScope,"pid-file",xstrdup (popt)) ;
-    }
-
-  if (Zopt)
-    {
-      if ((v = findValue (topScope,"connection-stats",NO_INHERIT)) != NULL)
-        v->v.bool_val = 1 ;
-      else
-        addBoolean (topScope,"connection-stats",1) ;
-    }
-
-  if (lopt != NULL)
-    {
-      if ((v = findValue (topScope,"log-file",NO_INHERIT)) != NULL)
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (lopt) ;
-        }
-      else
-        addString (topScope,"log-file",xstrdup (lopt)) ;
-    }
-
-  if (InputFile != NULL)
-    {
-      if ((v = findValue (topScope,"input-file",NO_INHERIT)) != NULL)
-        {
-          free (v->v.charp_val) ;
-          v->v.charp_val = xstrdup (InputFile) ;
-        }
-      else
-        addString (topScope,"input-file",xstrdup (InputFile)) ;
-    }
-
-  return 1 ;
-}
-
-
-
-static void mainCleanup (void)
-{
-  free ((void *)configFile) ;
-  free ((void *)pidFile) ;
-  free (logFile) ;
-  free (newsspool) ;
-  configFile = NULL ;
-  pidFile = NULL ;
-  logFile = NULL ;
-  newsspool = NULL ;
-}
-
-
-void mainLogStatus (FILE *fp)
-{
-  fprintf (fp,"%sGlobal configuration parameters:%s\n",
-           genHtml ? "<B>" : "", genHtml ? "</B>" : "") ;
-  fprintf (fp,"          Mode: ") ;
-  if (InputFile != NULL)
-    fprintf (fp,"Funnel file") ;
-  else if (talkToSelf)
-    fprintf (fp,"Batch") ;
-  else
-    fprintf (fp,"Channel") ;
-  if (InputFile != NULL)
-    fprintf (fp,"   (%s)",(*InputFile == '\0' ? "stdin" : InputFile)) ;
-  fprintf (fp,"\n") ;
-  fprintf (fp,"    News spool: %s\n",newsspool) ;
-  fprintf (fp,"      Pid file: %s\n",pidFile) ;
-  fprintf (fp,"      Log file: %s\n",(logFile == NULL ? "(none)" : logFile));
-  fprintf (fp,"   Debug level: %2ld                Mmap: %s\n",
-           (long)loggingLevel,boolToString(useMMap)) ;
-  fprintf (fp,"\n") ;
-}
diff --git a/innfeed/misc.c b/innfeed/misc.c
deleted file mode 100644 (file)
index 0da269d..0000000
+++ /dev/null
@@ -1,782 +0,0 @@
-/*  $Id: misc.c 7420 2005-10-09 04:40:13Z eagle $
-**
-**  Helper routines for the innfeed program.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <time.h>
-
-/* FIXME: Default to a max length of 256 characters for path names if the
-   host headers doesn't give better information.  Should be replaced by the
-   code from Stevens. */
-#ifndef PATH_MAX
-# define PATH_MAX 256
-#endif
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "endpoint.h"
-#include "misc.h"
-#include "tape.h"
-
-unsigned int openfds ;
-int debuggingOutput ;
-unsigned int loggingLevel ;
-char **PointersFreedOnExit ;
-
-bool debuggingDump = true ;
-extern void (*gPrintInfo) (void) ;
-void (*gCleanUp) (void) = 0 ;
-
-
-/* Log a message to stderr, called from warn or die.  Mostly the same as the
-   standard message_log_stderr, but prepends the date to each line. */
-void
-error_log_stderr_date(int len UNUSED, const char *fmt, va_list args, int err)
-{
-    char timebuff[30];
-    time_t now;
-    struct tm *tm;
-
-    now = time(NULL);
-    tm = localtime(&now);
-    strftime(timebuff, sizeof(timebuff), "%Y-%m-%d %H:%M:%S", tm);
-    fprintf(stderr, "%s %s: ", timebuff,
-            (message_program_name ? message_program_name : "UNKNOWN"));
-    vfprintf(stderr, fmt, args);
-    if (err) fprintf(stderr, ": %s", strerror(err));
-    fprintf(stderr, "\n");
-}
-
-/* If desired, print out the state of innfeed, call a cleanup function, and
-   then dump core.  Used as an exit handler for die. */
-int
-dump_core(void)
-{
-#if SNAPSHOT_ON_DIE
-    if (debuggingDump && gPrintInfo != NULL)
-        (*gPrintInfo)();
-#endif
-
-    if (gCleanUp != NULL)
-        (*gCleanUp)();
-  
-    if (CORE_DIRECTORY != NULL)
-        chdir(CORE_DIRECTORY);
-    else
-        chdir(getTapeDirectory());
-  
-    sleep(5);
-    abort();
-
-    /* Not reached. */
-    return 1;
-}
-
-/* An alternate version of die, used when we don't want to dump core.  This
-   should somehow eventually be phased out to simplify things; it's
-   basically a copy of die() from lib/error.c that ignores the cleanup
-   handler and has innfeed's handlers hard-coded (ugh). */
-void
-logAndExit(int status, const char *format, ...)
-{
-    va_list args;
-    int length;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    va_start(args, format);
-    error_log_stderr_date(length, format, args, 0);
-    va_end(args);
-    va_start(args, format);
-    message_log_syslog_err(length, format, args, 0);
-    va_end(args);
-    exit(status);
-}
-
-
-
-void d_printf (unsigned int level, const char *fmt, ...) 
-{
-  static pid_t myPid ;
-  char timeString [30] ;
-  time_t now ;
-  va_list ap ;
-    
-  if (myPid == 0)
-    myPid = getpid ()  ;
-  
-  if (loggingLevel < level)
-    return ;
-  
-  now = theTime() ;
-  /* strip off leading day name */
-  strlcpy (timeString, ctime (&now) + 4, sizeof (timeString)) ;
-  timeString [15] = '\0' ;      /* strip off trailing year and newline */
-
-  va_start (ap, fmt) ;
-  fprintf (stderr, "%s %s[%ld]: ",timeString,
-           (message_program_name ? message_program_name : "UNKNOWN"),
-           (long) myPid) ;
-  vfprintf (stderr, fmt, ap) ;
-  va_end (ap) ;
-}
-
-void logOrPrint (int level, FILE *fp, const char *fmt, ...)
-{
-  va_list ap ;
-
-  va_start (ap,fmt) ;
-  if (fp != NULL)
-    {
-      vfprintf (fp,fmt,ap) ;
-      fputc ('\n',fp) ;
-    }
-  else
-    {
-      char buffer [512] ;      /* gag me */
-
-      vsnprintf (buffer,sizeof (buffer),fmt,ap) ;
-      syslog (level,"%s",buffer) ;
-    }
-  va_end (ap) ;
-}
-
-
-
-/* return true if the file exists and is a regular file. */
-bool fileExistsP (const char *filename)
-{
-  struct stat buf ;
-
-  if (stat (filename,&buf) < 0)
-    return false ;
-
-  return (S_ISREG (buf.st_mode) ? true : false) ;
-}
-
-
-bool isDirectory (const char *filename)
-{
-  struct stat buf ;
-
-  if (stat (filename,&buf) < 0)
-    return false ;
-
-  return (S_ISDIR (buf.st_mode) ? true : false) ;
-}
-
-
-
-bool getNntpResponse (char *p, int *code, char **rest)
-{
-  bool rval = true ;
-  int cd = 0 ;
-  int digits = 0 ;
-
-  if (rest)
-    *rest = 0 ;
-  *code = 0 ;
-
-  if (p == NULL)
-    return false ;
-  
-  while (*p && CTYPE (isspace, *p))
-    p++ ;
-
-  while (*p && CTYPE (isdigit, *p))
-    {
-      digits++ ;
-      cd = (cd * 10) + (*p - '0') ;
-      p++ ;
-    }
-
-  if (digits != 3)
-    return false ;
-  
-  if (*p == '-')
-    p++ ;
-  
-  while (*p && CTYPE (isspace, *p))
-    p++ ;
-      
-  if (rest)
-    *rest = p ;
-
-  *code = cd ;
-  
-  return rval ;
-}
-
-
-
-/* Pull out a message id from a response on to a streaming command */
-char *getMsgId (const char *p)
-{
-  const char *q ;
-  char *rval ;
-  
-  while (*p && CTYPE (isspace, *p)) p++ ;
-  while (*p && !CTYPE (isspace, *p)) p++ ; /* skip response code */
-  while (*p && CTYPE (isspace, *p)) p++ ;
-
-  if ( *p == '\0' )
-    return NULL ;
-
-  q = p ;
-  while ( *q && !CTYPE (isspace, *q) )
-    q++ ;
-
-  rval = xstrndup (p, q - p) ;
-
-  return rval ;
-}
-
-
-
-
-char *findNonBlankString (char *ptr, char **tail)
-{
-  char *p, *q ;
-
-  for (p = ptr ; *p && CTYPE (isspace, *p) ; p++)
-    /* nada */ ;
-  if ( ! *p )
-    return NULL ;
-
-  for (q = p ; *q && !CTYPE (isspace, *q) ; q++)
-    /* nada */ ;
-
-  *tail = q ;
-
-  return p ;
-}
-
-
-/* strtok can't handle zero length tokens. */
-char *mystrtok (char *line, const char *sep)
-{
-  static char *newPoint ;
-  char *oldline ;
-  
-  if (line == NULL && newPoint == NULL)
-    return NULL ;
-
-  if (line != NULL)
-    {
-      oldline = line ;
-      while (*line != '\0' && strchr (sep,*line) == NULL)
-        line++ ;
-
-      if (*line == '\0')
-        newPoint = NULL ;
-      else
-        {
-          newPoint = line + 1 ;
-          *line = '\0' ;
-        }
-    }
-  else
-    {
-      if (newPoint == NULL)
-        return NULL ;
-      
-      oldline = newPoint ;
-      line = oldline ;
-      
-      while (*line != '\0' && strchr (sep,*line) == NULL)
-        line++ ;
-
-      if (*line == '\0')
-        newPoint = NULL ;
-      else
-        {
-          newPoint = line + 1 ;
-          *line = '\0' ;
-        }
-    }
-
-  return oldline ;
-}
-
-
-
-void trim_ws (char *string)
-{
-  char *p ;
-  unsigned int len ;
-
-  assert (string != NULL) ;
-
-  len = strlen (string) ;
-  if (len == 0)
-    return ;
-  
-  for (p = string + len - 1 ; p >= string && CTYPE (isspace, *p) ; p--)
-    /* nada */ ;
-  *++p = '\0' ;
-}
-
-
-#if 0
-/* Scribble on top of memory we're about to free. */
-void deadBeef (void *base, size_t byteCount)
-{
-  unsigned char *b = (unsigned char *) base ;
-  int i ;
-
-#if 0
-
-  memset (base, 0, byteCount) ;
-
-#else
-
-  assert (b != NULL) ;
-
-  for (i = 0 ; i < ((int) byteCount) - 4 ; i += 4)
-    {
-#if 0
-      *((int *) (b + i)) = 0xdeadbeef ;
-#else
-      b [i + 0] = (unsigned char) 0xde ;
-      b [i + 1] = (unsigned char) 0xad ;
-      b [i + 2] = (unsigned char) 0xbe ;
-      b [i + 3] = (unsigned char) 0xef ;
-#endif
-    }
-  
-  switch (byteCount % 4)
-    {
-      case 0:
-        *(b + i + 3) = (unsigned char) 0xef ;
-        
-      case 3:
-        *(b + i + 2) = (unsigned char) 0xbe ;
-
-      case 2:
-        *(b + i + 1) = (unsigned char) 0xad ;
-
-      case 1:
-        *b = (unsigned char) 0xde ;
-    }
-
-#endif
-}
-#endif 
-
-/* Not using plain flock or lockf 'cause I don't want to waste file
-   descriptors. This routine is based on the file shlock.c from INN. */
-bool lockFile (const char *fileName)
-{
-  char buff [20] ;
-  char tmpName [PATH_MAX], realName [PATH_MAX] ;
-  char *p ;
-  int fd, i ;
-  pid_t pid = getpid () ;
-
-  strlcpy (realName,fileName,sizeof (realName)) ;
-  if ((p = strrchr (realName, '/')) != NULL)
-    {
-      *p = '\0' ;
-      snprintf (tmpName, sizeof(tmpName), "%s/lockf%ld", realName,
-                (long) pid) ;
-      *p = '/' ;
-    }
-  else
-    snprintf (tmpName, sizeof(tmpName), "lockf%ld", (long) pid) ;
-  
-  /* Create the temporary name for the lock file. */
-  while ((fd = open (tmpName, O_RDWR | O_CREAT | O_EXCL, 0644)) < 0)
-    {
-      switch (errno)
-        {
-          default:
-            unlink (tmpName) ;
-            syswarn ("ME lock file open: %s", tmpName) ;
-            return false ;
-
-          case EEXIST:
-            if (unlink (tmpName) < 0)
-              {
-                syswarn ("ME lock file unlink: %s", tmpName) ;
-                return false ;
-              }
-            break;
-        }
-    }
-
-  /* stick our pid in the temp file. */
-  snprintf (buff,sizeof(buff),"%ld\n",(long) pid) ;
-  if (write (fd,buff,(size_t) strlen (buff)) != (int) strlen (buff))
-    {
-      syswarn ("ME lock file pid-write") ;
-      close (fd) ;
-      unlink (tmpName) ;
-      return false ;
-    }
-  close (fd) ;
-
-  /* now link the real name to the temp file. */
-  while (link (tmpName,realName) < 0)
-    {
-      switch (errno) 
-        {
-          default:              /* opps. bailing out. */
-            syswarn ("ME lock file link: %s", realName) ;
-            unlink (tmpName) ;
-            return false ;
-
-          case EEXIST:          
-            /* the real lock file exists. So pull out the pid in there and
-               see if that process is still alive. */
-            if ((fd = open (realName,O_RDONLY)) < 0)
-              {
-                syswarn ("ME lock file open: %s", realName) ;
-                unlink (tmpName) ;
-                return false ;
-              }
-
-            if ((i = read (fd,buff,sizeof (buff) - 1)) <= 0)
-              {
-                close (fd) ;
-                unlink (tmpName) ;
-                return false ;
-              }
-            close (fd) ;
-            
-            buff [i] = '\0' ;
-            pid = (pid_t) atol (buff) ;
-            if (pid <= 0)
-              {
-                warn ("ME lock bad-pid info in %s: %s", realName, buff) ;
-                unlink (tmpName) ;
-                return false ;
-              }
-
-            /* now send a null signal to the process named inside to see if
-               it's still alive. */
-            if (kill (pid,0) == 0)
-              {
-                warn ("ME lock in-use already: %s by pid %ld", realName,
-                      (unsigned long) pid);
-                unlink (tmpName) ;
-                return false ;    /* process is still alive */
-              }
-
-            /* process that took out the lock is gone */
-            if (unlink (realName) < 0)
-              {
-                syswarn ("ME lock file unlink: %s", realName) ;
-                unlink (tmpName) ;
-                return false ;
-              }
-        }
-    }
-
-  unlink (tmpName) ;
-
-  return true ;
-}
-
-
-void unlockFile (const char *lockfile)
-{
-  unlink (lockfile) ;
-}
-
-
-bool endsIn (const char *string, const char *tail)
-{
-  size_t len = strlen (tail) ;
-  size_t slen = strlen (string) ;
-
-  if (slen < len)
-    return false ;
-  else if (strcmp (string + slen - len, tail) == 0)
-    return true ;
-  else
-    return false ;
-}
-
-      
-/* append the contents of src to dest. src is removed if append if
-   successful */
-bool appendFile (const char *dest, const char *src)
-{
-  FILE *inTmp, *outTmp ;
-  char buff [BUFSIZ] ;
-  size_t rval ;
-
-      /* append the outputFilename file to the inputFilename file */
-  if ((outTmp = fopen (dest, "a")) == NULL)
-    die ("fopen (%s): %s",dest, strerror (errno)) ;
-  if ((inTmp = fopen (src, "r")) == NULL)
-    die ("fopen (%s): %s",src, strerror (errno)) ;
-
-  while ((rval = fread (buff,sizeof (char),BUFSIZ,inTmp)) > 0)
-    {
-      if (fwrite (buff,sizeof (char), rval, outTmp) != rval)
-        die ("fwrite: %s", strerror (errno)) ;
-    }
-
-  if (ferror (inTmp))
-    die ("Error on inTmp in newTape") ;
-  if (ferror (outTmp))
-    die ("Error on outTmp in newTape") ;
-
-  if (fclose (inTmp) != 0)
-    die ("fclose (inTmp): appendFile (%s,%s): %s",dest,src,strerror (errno)) ;
-      
-  if (fclose (outTmp) != 0)
-    die ("fclose (outTmp): appendFile (%s,%s): %s",dest,src,strerror (errno)) ;
-
-  if (unlink (src) != 0)
-    die ("unlink (%s): %s", src, strerror (errno)) ;
-
-  return true ;
-}
-
-
-/* return true if file1 is older than file2 */
-bool isOlder (const char *file1, const char *file2)
-{
-  struct stat buf1 ;
-  struct stat buf2 ;
-
-  if (stat (file1,&buf1) < 0)
-    return false ;
-
-  if (stat (file2,&buf2) < 0)
-    return false ;
-
-  return ((buf1.st_mtime < buf2.st_mtime) ? true : false) ;
-}
-
-
-void freeCharP (char *charp)
-{
-  free (charp) ;
-}
-
-
-/* return the length of the file reference by the given file descriptor */
-long fileLength (int fd)
-{
-  struct stat buf ;
-
-  if (fstat (fd,&buf) < 0)
-    return false ;
-
-  return ((long) buf.st_size) ;
-}
-
-
-
-const char *boolToString (bool val)
-{
-  return val ? "true" : "false" ;
-}
-
-void addPointerFreedOnExit (char *pointerToFree)
-{
-  static int totalPointers = 0 ;
-  static int nextPointer = 0 ;
-
-  if (nextPointer == 0 || nextPointer == totalPointers - 1)
-    {
-      int i;
-
-      totalPointers += 16 ;
-      if (PointersFreedOnExit == NULL)
-       PointersFreedOnExit = xmalloc (sizeof(char *) * totalPointers) ;
-      else
-       PointersFreedOnExit =
-         xrealloc (PointersFreedOnExit, sizeof(char *) * totalPointers) ;
-
-      for (i = nextPointer; i < totalPointers; i++)
-       PointersFreedOnExit [i] = NULL;
-    }
-  PointersFreedOnExit [nextPointer++] = pointerToFree ;
-}
-
-/* malloc a buffer and build the filename in it. */
-char *buildFilename (const char *directory, const char *fname)
-{
-  int len = 0 ;
-  char *p = NULL ;
-
-  if (fname == NULL)
-    return NULL ;
-
-  if (directory == NULL)
-    directory = "." ;
-  
-  len = strlen (directory) + strlen (fname) + 2 + 1 ;
-
-  if (len < pathMax(directory) - 2)
-    {
-      p = xmalloc (len) ;
-      p [0] = '\0' ;
-      if (fname [0] != '/')
-        {
-          strlcat (p,directory,len) ;
-          if (p [strlen(p) - 1] != '/')
-            strlcat (p,"/",len) ;
-        }
-      strlcat (p,fname,len) ;
-    }
-
-  return p ;
-}
-
-
-
-/* borrows heavily from the shrinkfile program by chongo. */
-bool shrinkfile (FILE *fp, long size, char *name, const char *mode)
-{
-  long currlen = ftello (fp) ;
-  char *tmpname ;
-  char buffer [BUFSIZ] ;
-  FILE *tmpFp ;
-  int c ;
-  int i ;
-  int fd ;
-
-  if (currlen <= size)
-    {
-      d_printf (1,"No need to shrink file (%s %ld vs %ld\n",
-               name,size,currlen) ;
-      return true ;
-    }
-
-  /* create a temp file. */
-  tmpname = concat (name,".XXXXXX",(char *)0) ;
-  fd = mkstemp (tmpname) ;
-
-  if (fd < 0)
-    {
-      syswarn ("ME error creating temp shrink file for %s", name) ;
-      free (tmpname) ;
-      return false ;
-    }
-
-  if ((tmpFp = fdopen (fd,"w")) == NULL)
-    {
-      syswarn ("ME error opening temp shrink file %s", tmpname) ;
-      free (tmpname) ;
-      return false ;
-    }
-
-  if (fseeko (fp,currlen - size,SEEK_SET) != 0)
-    {
-      fclose (tmpFp) ;
-      warn ("ME error seeking to point %ld in %s", currlen - size, name) ;
-      free (tmpname) ;
-      return false ;
-    }
-
-  /* find the end of the next line in the shrinking file. */
-  while ((c = fgetc (fp)) != '\n')
-    if (c == EOF)
-      {
-        warn ("ME no newline in shrinking file %s", name) ;
-        fclose (tmpFp) ;
-        fseeko (fp,currlen,SEEK_SET) ;
-        free (tmpname) ;
-        return false ;
-    }
-
-  /* copy the tail of the shrinking file to the temp file. */
-  while ((i = fread (buffer,1,sizeof (buffer),fp)) > 0)
-    {
-      if (fwrite (buffer,1,i,tmpFp) != (size_t) i)
-        {
-          fclose (tmpFp) ;
-          syswarn ("ME fwrite failed to temp shrink file %s", tmpname) ;
-          fseeko (fp,currlen, SEEK_SET) ;
-          free (tmpname) ;
-          return false ;
-        }
-    }
-
-  if (i < 0)
-    logAndExit (1,"ME fread failed on file %s: %s",name, strerror (errno)) ;
-
-  fclose (tmpFp) ;
-
-  if (unlink (name) != 0)
-    logAndExit (1,"ME oserr unlink %s: %s",name, strerror (errno)) ;
-
-  /* we're in the same directory so this is ok. */
-  if (rename (tmpname,name) != 0)
-    logAndExit (1,"ME oserr rename %s, %s: %s", tmpname, name,
-                strerror (errno)) ;
-  
-  if (freopen (name,mode,fp) != fp)
-    logAndExit (1,"ME freopen on shrink file failed %s: %s", name,
-                strerror (errno)) ;
-
-  fseeko (fp,0,SEEK_END) ;
-  size = ftello (fp) ;
-
-  notice ("ME file %s shrunk from %ld to %ld", name, currlen, size) ;
-
-  free (tmpname) ;
-  
-  return true ;
-}
-
-
-
-long pathMax (const char *pathname UNUSED)
-{
-  static long rval = 0 ;
-
-  if (rval > 0)
-    return rval ;
-  
-#if defined (PATH_MAX)
-
-  rval = PATH_MAX ;
-
-#elif defined (_POSIX_PATH_MAX)
-
-  rval = _POSIX_PATH_MAX ;
-
-#elif defined (DO_HAVE_PATHCONF) && defined (_PC_PATH_MAX)
-
-  if (pathname == NULL)
-    pathname = "/tmp" ;
-  
-  rval = pathconf (pathname,_PC_PATH_MAX) ;
-
-#else
-
-  rval = 255 ;
-  if (!logged) 
-    {
-      syslog (LOG_ERR,NO_PATH_MAX,rval) ;
-      logged = true ;
-    }
-  
-#endif
-
-  return rval ;
-}
diff --git a/innfeed/misc.h b/innfeed/misc.h
deleted file mode 100644 (file)
index 4036b13..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*  $Id: misc.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  Miscellaneous utility functions for innfeed.
-**
-**  Written by James Brister <brister@vix.com>
-*/
-
-#if ! defined ( misc_h__ )
-#define misc_h__
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <sys/types.h>
-
-/* These typedefs are all here because C is too stupid to let me multiply
-   define typedefs to the same things (as C++ will). Hence I can't redeclare
-   the typedefs to get around recursive header file includes (like host.h and
-   connection.h would need if they contained their own typedefs). */
-
-typedef struct article_s *Article ;             /* see article.h */
-typedef struct buffer_s *Buffer ;               /* see buffer.h */
-typedef struct commander_s *Commander ;         /* see commander.h */
-typedef struct config_s *Config ;               /* see config.h */
-typedef struct connection_s *Connection ;       /* see connection.h */
-typedef struct endpoint_s *EndPoint ;           /* see endpoint.h */
-typedef struct host_s *Host ;                   /* see host.h */
-typedef struct innlistener_s *InnListener ;     /* see innlistener.h */
-typedef struct tape_s *Tape ;                   /* see tape.h */
-
-typedef int TimeoutId ;                         /* see endpoint.h */
-typedef enum {                                  /* see endpoint.h */
-  IoDone, IoIncomplete, IoFailed, IoEOF, IoProgress
-} IoStatus ; 
-
-typedef void (*EndpRWCB) (EndPoint e,           /* see endpoint.h */
-                          IoStatus i, Buffer *b, void *d) ;
-typedef void (*EndpTCB) (TimeoutId tid, void *d) ; /* see endpoint.h */
-typedef void (*EndpWorkCbk) (EndPoint ep, void *data) ;
-
-
-/* debugging information */
-extern unsigned int loggingLevel ;     /* if 0 then d_printf is a no-op */
-
-/* the current count of file desccriptors */
-extern unsigned int openfds ;
-
-/* if level <= loggingLevel then print */
-void d_printf (unsigned int level, const char *fmt, ...) __attribute__ ((__format__ (printf, 2, 3)));
-
-/* for the gethostbyname() error code */
-const char *host_err_str (void) ;
-
-/* parse a reponse line into it's code and body. *rest will end up pointing
-   into the middle of p */
-bool getNntpResponse (char *p, int *code, char **rest) ;
-
-/* parse out the first field of a nntp response code as a message-id. Caller
-   must free the return value when done. */
-char *getMsgId (const char *p) ;
-
-/* pick out the next non-blank string inside PTR. TAIL is set to point at
-   the first blank (or NULL) after the string. Returns a pointer into PTR */
-char *findNonBlankString (char *ptr, char **tail) ;
-
-/* if fp is not NULL then print to it, otherwise syslog at the level. */
-void logOrPrint (int level, FILE *fp, const char *fmt, ...)
-  __attribute__ ((__format__ (printf, 3, 4)));
-
-/* Error handling functions for use with warn and die. */
-void error_log_stderr_date(int len, const char *fmt, va_list args, int err);
-
-/* Do cleanup and then abort, for use with die. */
-int dump_core(void);
-
-/* Alternate die that doesn't invoke an error handler. */
-void logAndExit (int exitVal, const char *fmt, ...)
-  __attribute__ ((__format__ (printf, 2, 3)));
-
-/* return true of the file exists and is a regular file */
-bool fileExistsP (const char *filename) ;
-
-/* return true if file exists and is a directory */
-bool isDirectory (const char *filename) ;
-
-char *mystrtok (char *string, const char *sep) ;
-
-/* remove trailing whitespace */
-void trim_ws (char *string) ;
-
-/* locks the peer and returns true or returns false */
-bool lockPeer (const char *peerName) ;
-
-/* return true if the end of string matches tail. */
-bool endsIn (const char *string, const char *tail) ;
-
-/* scribble over then free up the null-terminated string */
-void freeCharP (char *charp) ;
-
-/* append the contents of src to dest. src is removed if append if
-   successful */
-bool appendFile (const char *dest, const char *src) ;
-
-/* return the length of the file reference by the given file descriptor */
-long fileLength (int fd) ;
-
-bool lockFile (const char *fileName) ;
-void unlockFile (const char *lockfile) ;
-
-
-/* return true if file1 is older than file2 */
-bool isOlder (const char *file1, const char *file2) ;
-
-/* converts val into a printable string */
-const char *boolToString (bool val) ;
-
-/* memory leak checker helper. */
-void addPointerFreedOnExit (char *pointerToFree) ;
-
-/* splice direcotory and fname together and return free'able string */
-char *buildFilename (const char *directory, const char *fname) ;
-
-/* string the file opened by FP to the give SIZE. The NEWNAME is the name
-   of the file to have after truncation. FP will be reopened for writing on
-   the new file and will be positioned at the end */
-bool shrinkfile (FILE *fp, long size, char *name, const char *mode) ;
-
-/* max length of pathname */
-long pathMax (const char *pathname) ;
-
-#define ASSERT(x) do{if (!(x))die("assertion -- %s -- failed in file %s line %d",#x,__FILE__,__LINE__);}while(0)
-
-#define INDENT_INCR 5
-#define INDENT_BUFFER_SIZE 80
-#if ! defined (MIN)
-#define MIN(A,B) ((A) < (B) ? (A) : (B))
-#endif
-
-#endif /* misc_h__ */
diff --git a/innfeed/procbatch.in b/innfeed/procbatch.in
deleted file mode 100644 (file)
index 7a203af..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Thu May 16 10:32:02 1996 +0200
-# Project:      INN -- innfeed
-# File:         procbatch.pl
-# RCSId:        $Id: procbatch.in 6648 2004-01-25 20:07:11Z rra $
-#
-# Description: Take a file of the form generated by innd in the out.going
-#             directory ("Wnm*") and separate it into tape files for inn.
-#
-# Thanks to Clayton O'Neill <coneill@premier.net> for serious speed
-# improvments. 
-# 
-
-#
-#      Hmm, perhaps we should try to read "backlog-directory"
-#      from innfeed.conf. Oh well.
-#
-$tapeDir = $inn'pathspool . "/innfeed"; #'
-$destDir = $inn'spooltemp ; #'
-$spoolArts = $inn'patharticles ; #'
-$outGoing = $inn'pathoutgoing; #'
-
-##
-## Everything below here should probably be left alone.
-##
-
-$0 =~ s!.*/!! ;
-
-require 'getopts.pl' ;
-
-$usage = "$0 [ -q ][ -v ][ -u ][ -e host ][ -d dir ][ -c [ -s dir ]][ -m [-t dir ]] inn-batchfile\n
-  -e host    to process on entries for only that host
-  -d dir     to put the output file(s) in that directory ($destDir)
-  -c         to check pathnames of articles before storing them
-  -s dir     to specify where the news articles are
-             ($spoolArts)
-  -m         to have $0 move the new files to the backlog directory.
-  -t dir     to specify the backlog directory ($tapeDir)
-  -u         to unlink the input files when finished
-  -v         for verbosity
-  -q         quiet mode; only display error messages. Good for cron jobs.
-
-$0 will take an inn funnel file (normally a file in
-$outGoing), or an innfeed ``dropped'' file, 
-which is presumed to be of the format:
-
-       pathname message-id peer1 peer2 peer3 ...
-
-and will break it up into files peer1.tmp peer2.tmp peer3.tmp... Each of
-these files wil be of the format:
-
-       pathname message-id
-
-that is the same as innfeed's backlog file format. Simply rename these files
-to peer1 peer2 peer3 in a running innfeed's backlog directory and they will be
-picked up automatically and processed by innfeed. Use the '-m' flag and
-they'll be moved automatically.
-" ;
-
-$opt_u = $opt_h = "";  # shut up, perl -w
-&Getopts ("he:t:s:d:cvumq") || die $usage ;
-
-die $usage if ( $opt_h ) ;
-die "Cannot specify both -q and -v\n\n" . $usage if ($opt_q && $opt_v);
-
-$spoolArts = $opt_s if $opt_s ;
-$destDir = $opt_d if $opt_d ;
-$tapeDir = $opt_t if $opt_t ;
-$inputFile = shift ;
-
-die $usage if !$inputFile ;
-unless (-f $inputFile) {
-       exit if $opt_q;
-       die "No such file: $inputFile\n\n" . $usage;
-}
-die "No such directory: $spoolArts\n\n" . $usage if ( ! -d $spoolArts && $opt_c ) ;
-die "No such directory: $destDir\n\n" . $usage if ( ! -d $destDir ) ;
-die "No such directory: $tapeDir\n\n" . $usage if ( ! -d $tapeDir && $opt_m ) ;
-
-print "Using $inputFile\n" if $opt_v ;
-open (INPUT,"<$inputFile") || die "$0: open ($inputFile): $!\n" ;
-
-while (<INPUT>) {
-       chop ;
-       @F = split ;
-
-        # Check the format of the line vigorously      
-        next unless (m!^\S+/\d+ <.+@.+> \S+! || m!^@[0-9A-F]+@ <.+@.+> \S+!) ;  
-
-       if ( $opt_c ) {
-               if ( ! -f "$spoolArts/$F[0]" )  {
-                       $missing++ ;
-                       print "Dropping file: $spoolArts/$F[0]\n" if $opt_v ;
-                       next ;
-               }
-       }
-
-       for ($i = 2 ; $i <= $#F ; $i++) {
-               $host = $F[$i] ;
-               next if ($opt_e && $opt_e ne $host) ;
-
-               # Keep out host names with any funny characters (from 
-               # corrupted files)
-                if ($host !~ /^[-\._0-9A-Za-z]+$/) {
-                        warn "$0: bad site name ignored: \"$host\"\n";
-                        next;
-                }
-
-               if ($hosts{$host}) {
-                       print {$hosts{$host}} "$F[0] $F[1]\n";
-               } else {
-                       $outputFile = "$destDir/$host.tmp" ;
-                       print "Starting $host\n" if ($opt_v);
-                       $hosts{$host}=$host;
-                       open ($hosts{$host},">>$outputFile") || 
-                               die "open >>$outputFile: $!\n" ;
-                       print {$hosts{$host}} "$F[0] $F[1]\n";
-               }
-       }
-}
-close (INPUT) ;
-
-foreach $host (keys %hosts) {
-       close($hosts{$host});
-       $outputFile = "$destDir/$host.tmp" ;
-       $tmpTape = "$tapeDir/$host.tmp" ;
-       $tapeFile = "$tapeDir/$host" ;
-       if ( $opt_m ) {
-               if ($outputFile ne $tmpTape) {
-                       $cmd = "mv $outputFile $tmpTape" ;
-                       system ($cmd) ;
-                       die "$0: $cmd: failed\n" unless ($? == 0) ;
-               }
-
-               $cmd = "cat $tmpTape |sort -u >> $tapeFile && rm -f $tmpTape" ;
-               system ($cmd) ;
-               die "$0: $cmd: failed\n" unless ($? == 0) ;
-       }
-}
-
-unlink($inputFile) if ($opt_u);
-
-print "$missing articles dropped\n" if ( $opt_v && $missing > 0 ) ;
diff --git a/innfeed/startinnfeed.c b/innfeed/startinnfeed.c
deleted file mode 100644 (file)
index f8523cb..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*  $Id: startinnfeed.c 7065 2004-12-19 21:49:18Z rra $
-**
-**  Raise system limits and exec innfeed.
-**
-**  This is a setuid root wrapper around innfeed to increase system limits
-**  (file descriptor limits and stack and data sizes).  In order to prevent
-**  abuse, it uses roughly the same security model as inndstart; only the
-**  news user can run this program, and it attempts to drop privileges when
-**  doing operations that don't require it.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <syslog.h>
-#include <errno.h>
-#include <grp.h>
-#include <pwd.h>
-
-/* FreeBSD 3.4 RELEASE needs <sys/time.h> before <sys/resource.h>. */
-#if HAVE_SETRLIMIT
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# endif
-# include <sys/resource.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-/* Options for debugging malloc. */
-#ifdef USE_DMALLOC
-# define DMALLOC_OPTIONS \
-    "DMALLOC_OPTIONS=debug=0x4e405c3,inter=100,log=innfeed-logfile"
-#endif
-
-
-int
-main(int argc, char *argv[])
-{
-    struct passwd *     pwd;
-    struct group *      grp;
-    uid_t               news_uid;
-    gid_t               news_gid;
-    char **             innfeed_argv;
-    char *              spawn_path;
-    int                 i;
-
-#if HAVE_SETRLIMIT
-    struct rlimit       rl;
-#endif
-
-    openlog("innfeed", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_handlers_warn(1, message_log_syslog_warning);
-    message_handlers_die(1, message_log_syslog_err);
-
-    /* Convert NEWSUSER and NEWSGRP to a UID and GID.  getpwnam() and
-       getgrnam() don't set errno normally, so don't print strerror() on
-       failure; it probably contains garbage.*/
-    pwd = getpwnam(NEWSUSER);
-    if (!pwd) die("can't getpwnam(%s)", NEWSUSER);
-    news_uid = pwd->pw_uid;
-    grp = getgrnam(NEWSGRP);
-    if (!grp) die("can't getgrnam(%s)", NEWSGRP);
-    news_gid = grp->gr_gid;
-
-    /* Exit if run by another user. */
-    if (getuid() != news_uid)
-        die("ran by UID %lu, who isn't %s (%lu)", (unsigned long) getuid(),
-            NEWSUSER, (unsigned long) news_uid);
-
-    /* Drop privileges to read inn.conf. */
-    if (seteuid(news_uid) < 0)
-        sysdie("can't seteuid(%lu)", (unsigned long) news_uid);
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Regain privileges to increase system limits. */
-    if (seteuid(0) < 0) sysdie("can't seteuid(0)");
-    if (innconf->rlimitnofile >= 0)
-        if (setfdlimit(innconf->rlimitnofile) < 0)
-            syswarn("can't set file descriptor limit to %ld",
-                    innconf->rlimitnofile);
-
-    /* These calls will fail on some systems, such as HP-UX 11.00.  On those
-       systems, we just blindly assume that the stack and data limits are
-       high enough (they generally are). */
-#if HAVE_SETRLIMIT
-    rl.rlim_cur = RLIM_INFINITY;
-    rl.rlim_max = RLIM_INFINITY;
-# ifdef RLIMIT_DATA
-    setrlimit(RLIMIT_DATA, &rl);
-# endif
-#endif /* HAVE_SETRLIMIT */
-
-    /* Permanently drop privileges. */
-    if (setuid(news_uid) < 0 || getuid() != news_uid)
-        sysdie("can't setuid to %lu", (unsigned long) news_uid);
-
-    /* Check for imapfeed -- continue to use "innfeed" in variable
-       names for historical reasons regardless */
-    if ((argc > 1) && (strcmp(argv[1],"imapfeed") == 0))
-    {
-        argc--;
-       argv++;
-        spawn_path = concat(innconf->pathbin, "/imapfeed", (char *) 0);
-    }
-    else
-        spawn_path = concat(innconf->pathbin, "/innfeed",  (char *) 0);
-
-
-    /* Build the argument vector for innfeed. */
-    innfeed_argv = xmalloc((argc + 1) * sizeof(char *));
-    innfeed_argv[0] = spawn_path;
-    for (i = 1; i <= argc; i++)
-        innfeed_argv[i] = argv[i];
-    innfeed_argv[argc] = NULL;
-
-    /* Set debugging malloc options. */
-#ifdef USE_DMALLOC
-    putenv(DMALLOC_OPTIONS);
-#endif
-
-    /* Exec innfeed. */
-    execv(innfeed_argv[0], innfeed_argv);
-    sysdie("can't exec %s", innfeed_argv[0]);
-
-    /* Not reached. */
-    return 1;
-}
diff --git a/innfeed/tape.c b/innfeed/tape.c
deleted file mode 100644 (file)
index a37f5c6..0000000
+++ /dev/null
@@ -1,1294 +0,0 @@
-/*  $Id: tape.c 6716 2004-05-16 20:26:56Z rra $
-**
-**  The implementation of the innfeed Tape class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The implementation of the Tape class. Tapes are read-only or write-only
-**  files that are accessed sequentially. Their basic unit of i/o is an
-**  Article. Tapes work out of a single directory and manage all file names
-**  themselves.
-**
-**  Tapes will checkpoint themselves periodically so that when innfeed exits
-**  or crashes things can restart close to where they were last. The period
-**  checkpointing is handled entirely by the Tape class, but the checkpoint
-**  period needs to be set by some external user before the first tape is
-**  created.
-*/
-
-#include "innfeed.h"
-#include "config.h"
-#include "clibrary.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#if defined (HAVE_DIRENT_H)
-#include <dirent.h>
-typedef struct dirent DIRENTRY ;
-#else
-#include <sys/dir.h>
-typedef struct direct DIRENTRY ;
-#endif
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-
-#include "article.h"
-#include "configfile.h"
-#include "endpoint.h"
-#include "tape.h"
-
-extern char *dflTapeDir;
-extern bool genHtml ;
-
-#if 0
-/* a structure for temporary storage of articles. */
-typedef struct q_e_s
-{
-    Article article ;
-    struct q_e_s *next ;
-} *QueueElem ;
-#endif
-
-/* The Tape class type. */
-struct tape_s
-{
-    /* the pathname of the file the administrator can drop in by hand. */
-    char *handFilename ;
-
-    /* the pathname of the file the Tape will read from */
-    char *inputFilename ;
-
-    /* the pathname of the file the Tape will write to. */
-    char *outputFilename ;
-
-    /* the pathname of the file used in locking */
-    char *lockFilename ;
-
-    /* the peer we're doing this for. */
-    char *peerName ;
-    
-    FILE *inFp ;                /* input FILE */
-    FILE *outFp ;               /* output FILE */
-
-    time_t lastRotated ;        /* time files last got switched */
-    bool checkNew ;             /* set bool when we need to check for
-                                   hand-crafted file. */
-    
-#if 0
-    /* the tape holds a small output queue in memory to avoid thrashing. */
-    QueueElem head ;            
-    QueueElem tail ;
-    unsigned int qLength ;             /* amount on the queue */
-#endif
-    
-    long outputSize ;           /* the current size of the output file. */
-    long lossage ;
-
-    /* the number of bytes we try to keep the output under. We actually
-       wait for the outputSize to get 10% greater than this amount before
-       shrinking the file down again. A value of zero means no limit. */
-    long outputLowLimit ;
-    long outputHighLimit ;
-    double backlogFactor ;
-    
-    bool scribbled ;            /* have we scribbled a checkpoint value in
-                                   the file. */
-    long tellpos ;              /* for input file checkpointing. */
-    bool changed ;              /* true if tape was read since last
-                                   checkpoint or start. */
-
-    /* true if articles that are output are NOT later input. */
-    bool noRotate ;     
-
-    /* true if no articles should ever be spooled */
-    bool noBacklog ;
-};
-
-
-static void checkpointTape (Tape tape) ;
-static void removeTapeGlobally (Tape tape) ;
-static void addTapeGlobally (Tape tape) ;
-static void prepareFiles (Tape tape) ;
-static void tapeCkNewFileCbk (TimeoutId id, void *d) ;
-static void tapeCheckpointCallback (TimeoutId id, void *d) ;
-#if 0
-static void flushTape (Tape tape) ;
-#endif
-static void tapesSetCheckNew (void) ;
-static void initTape (Tape nt) ;
-static void tapeCleanup (void) ;
-
-
-
-/* pathname of directory we store tape files in. */
-static char *tapeDirectory ;
-
-/* the callback ID of the checkpoint timer callback. */
-static TimeoutId checkPtId ;
-static TimeoutId ckNewFileId ;
-
-/* number of seconds between tape checkpoints. */
-static unsigned int tapeCkPtPeriod ;
-static unsigned int tapeCkNewFilePeriod ;
-
-static time_t rotatePeriod = TAPE_ROTATE_PERIOD ;
-
-/* global list of tapes so we can checkpoint them periodically */
-static Tape *activeTapes ;
-
-/* Size of the activeTapes array */
-static size_t activeTapeSize ;
-
-/* index of last element in activeTapes that's being used. */
-static size_t activeTapeIdx ;
-
-#if 0
-/* default limit of the size of output tapes. */
-static long defaultSizeLimit ;
-#endif
-
-unsigned int tapeHighwater ;
-
-bool debugShrinking = false ;
-
-extern bool talkToSelf ;        /* main.c */
-
-
-
-
-/* callback when config file is loaded */
-int tapeConfigLoadCbk (void *data)
-{
-  int rval = 1 ;
-  long iv ;
-  int bv ;
-  FILE *fp = (FILE *) data ;
-  char *dir, *p ;
-
-  if (getString (topScope,"backlog-directory",&p,NO_INHERIT))
-    {
-      dir = buildFilename(innconf->pathspool, p);
-      free(p);
-      if (tapeDirectory != NULL && strcmp (tapeDirectory,dir) != 0)
-        {
-          warn ("ME config: cannot change backlog-directory of a running"
-                " process") ;
-          free (dir) ;
-          dir = xstrdup (tapeDirectory) ;
-        }
-
-      if (!isDirectory (dir) && isDirectory (dflTapeDir))
-        {
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: definition of backlog-directory (%s) is a"
-                      " non-existant directory. Using %s",
-                      dir,dflTapeDir) ;
-          free (dir) ;
-          dir = xstrdup (dflTapeDir) ;
-        }
-      else if (!isDirectory (dir))
-        logAndExit (1,"ME config: no usable value for backlog-directory") ;
-    }
-  else if (!isDirectory (dflTapeDir))
-  {
-    logAndExit (1,"ME config: no usable value for backlog-directory") ;
-    return -1; /* not reached */
-  }
-  else
-    dir = xstrdup (dflTapeDir) ;
-  
-  if (tapeDirectory != NULL)
-    free (tapeDirectory) ;
-  tapeDirectory = dir ;
-
-
-  
-  if (getInteger (topScope,"backlog-highwater",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld","backlog-highwater",
-                      iv,"global scope",(long)TAPE_HIGHWATER);
-          iv = TAPE_HIGHWATER ;
-        }
-    }
-  else
-    iv = TAPE_HIGHWATER ;
-  tapeHighwater = (unsigned int) iv ;
-
-
-  
-  if (getInteger (topScope,"backlog-rotate-period",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld",
-                      "backlog-rotate-period",
-                      iv,"global scope",(long)TAPE_ROTATE_PERIOD);
-          iv = TAPE_ROTATE_PERIOD ;
-        }
-    }
-  else
-    iv = TAPE_ROTATE_PERIOD ;
-  rotatePeriod = (unsigned int) iv ;
-
-
-  if (getInteger (topScope,"backlog-ckpt-period",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld",
-                      "backlog-ckpt-period",iv,
-                      "global scope",(long)TAPE_CHECKPOINT_PERIOD);
-          iv = TAPE_CHECKPOINT_PERIOD ;
-        }
-    }
-  else
-    iv = TAPE_CHECKPOINT_PERIOD ;
-  tapeCkPtPeriod = (unsigned int) iv ;
-
-
-  if (getInteger (topScope,"backlog-newfile-period",&iv,NO_INHERIT))
-    {
-      if (iv < 0)
-        {
-          rval = 0 ;
-          logOrPrint (LOG_ERR,fp,
-                      "ME config: value of %s (%ld) in %s cannot be less"
-                      " than 0. Using %ld",
-                      "backlog-newfile-period",
-                      iv,"global scope",(long)TAPE_NEWFILE_PERIOD);
-          iv = TAPE_NEWFILE_PERIOD ;
-        }
-    }
-  else
-    iv = TAPE_NEWFILE_PERIOD ;
-  tapeCkNewFilePeriod = (unsigned int) iv ;
-
-
-  if (getBool (topScope,"debug-shrinking",&bv,NO_INHERIT))
-    debugShrinking = (bv ? true : false) ;
-  
-  return rval ;
-}
-
-
-/* Create a new Tape object. There are three potential files involved in
-   I/O. 'peerName' is what  the admin may have dropped in by
-   hand. 'peerName.input' is the file that was being used as input the last
-   time things were run. 'peerName.output' is the file that was being used
-   as output. The file 'peerName' is appended to 'peerName.input' (or
-   renamed if 'peerName.input' doesn't exist). Then 'peerName.output' is
-   appeneded (or renamed) to 'peerName.input' */
-
-static bool inited = false ;
-Tape newTape (const char *peerName, bool dontRotate)
-{
-  Tape nt = xmalloc (sizeof(struct tape_s)) ;
-  size_t pLen = strlen (peerName) ;
-  size_t dLen = strlen (tapeDirectory) ;
-
-  if (!inited)
-    {
-      inited = true ;
-      atexit (tapeCleanup) ;
-    }
-  
-  ASSERT (nt != NULL) ;
-
-  if (endsIn (peerName,INPUT_TAIL))
-    die ("Sorry, can't have a peer name ending in \"%s\"",INPUT_TAIL) ;
-
-  if (endsIn (peerName,OUTPUT_TAIL))
-    die ("Sorry, can't have a peer name ending in \"%s\"",OUTPUT_TAIL) ;
-
-  if (endsIn (peerName,LOCK_TAIL))
-    die ("Sorry, can't have a peer name ending in \"%s\"",LOCK_TAIL) ;
-
-  nt->peerName = xstrdup (peerName) ;
-  
-  nt->handFilename = xmalloc (pLen + dLen + 2) ;
-  sprintf (nt->handFilename,"%s/%s",tapeDirectory,peerName) ;
-
-  nt->lockFilename = xmalloc (pLen + dLen + strlen(LOCK_TAIL) + 2) ;
-  sprintf (nt->lockFilename,"%s/%s%s",tapeDirectory,peerName,LOCK_TAIL) ;
-
-  nt->inputFilename = xmalloc (pLen + dLen + strlen(INPUT_TAIL) + 2) ;
-  sprintf (nt->inputFilename,"%s/%s%s",tapeDirectory,peerName,INPUT_TAIL) ;
-
-  nt->outputFilename = xmalloc (pLen + dLen + strlen(OUTPUT_TAIL) + 2) ;
-  sprintf (nt->outputFilename,"%s/%s%s",tapeDirectory,peerName,OUTPUT_TAIL) ;
-
-  if ( !lockFile (nt->lockFilename) )
-    {
-      warn ("ME lock failed for host: %s", nt->lockFilename) ;
-      
-      free (nt->handFilename) ;
-      free (nt->lockFilename) ;
-      free (nt->inputFilename) ;
-      free (nt->outputFilename) ;
-      free (nt) ;
-
-      return NULL ;
-    }
-
-  nt->noRotate = false ;        /* for first time prepare */
-  initTape (nt) ;
-  nt->noRotate = dontRotate ;
-
-  addTapeGlobally (nt) ;
-
-  if (checkPtId == 0 && tapeCkPtPeriod > 0)     /* only done once. */
-    checkPtId = prepareSleep (tapeCheckpointCallback,tapeCkPtPeriod,NULL);
-
-  if (ckNewFileId == 0 && tapeCkNewFilePeriod > 0)
-    ckNewFileId = prepareSleep (tapeCkNewFileCbk,tapeCkNewFilePeriod,NULL) ;
-
-  return nt ;
-}
-
-static void initTape (Tape nt)
-{
-  value *peerVal = findPeer (nt->peerName) ;
-  scope *s = (peerVal == NULL ? NULL : peerVal->v.scope_val) ;
-
-  nt->inFp = NULL ;
-  nt->outFp = NULL ;
-
-  nt->lastRotated = 0 ;
-  nt->checkNew = false ;
-  
-#if 0
-  nt->head = NULL ;
-  nt->tail = NULL ;
-  nt->qLength = 0 ;
-#endif
-
-  nt->scribbled = false ;
-  nt->tellpos = 0 ;
-
-  nt->changed = false ;
-  
-  nt->outputSize = 0 ;
-  nt->lossage = 0 ;
-
-  nt->noBacklog = false ;
-  nt->backlogFactor = 0.0 ;
-  nt->outputLowLimit = 0 ;
-  nt->outputHighLimit = 0 ;
-
-  if (!talkToSelf)
-    {
-      int bval ;
-
-      if (getBool (s, "no-backlog", &bval, INHERIT))
-        nt->noBacklog = (bval ? true : false);
-      else
-        nt->noBacklog = TAPE_DISABLE;
-
-      if (getInteger (s,"backlog-limit",&nt->outputLowLimit,INHERIT))
-        {
-          if (!getReal (s,"backlog-factor",&nt->backlogFactor,INHERIT))
-            {
-              if (!getInteger (s,"backlog-limit-highwater",
-                               &nt->outputHighLimit,INHERIT))
-                {
-                  warn ("%s no backlog-factor or backlog-high-limit",
-                        nt->peerName) ;
-                  nt->outputLowLimit = 0 ;
-                  nt->outputHighLimit = 0 ;
-                  nt->backlogFactor = 0.0 ;
-                }
-            }
-          else
-            nt->outputHighLimit = (long)(nt->outputLowLimit * nt->backlogFactor);
-        }
-      else
-        warn ("ME config: no definition for required key backlog-limit") ;
-    }
-  
-  d_printf (1, "%s spooling: %s\n", nt->peerName, 
-          nt->noBacklog ? "disabled" : "enabled");
-
-  d_printf (1,"%s tape backlog limit: [%ld %ld]\n",nt->peerName,
-           nt->outputLowLimit,
-           nt->outputHighLimit) ;
-  
-  prepareFiles (nt) ;
-}
-
-
-void gFlushTapes (void)
-{
-  unsigned int i ;
-
-  notice ("ME flushing tapes") ;
-  for (i = 0 ; i < activeTapeIdx ; i++)
-    tapeFlush (activeTapes [i]) ;
-}
-
-
-
-/* close the input and output tapes and reinitialize everything in the
-  tape. */
-void tapeFlush (Tape tape)
-{
-  if (tape->inFp != NULL)
-    {
-      checkpointTape (tape) ;
-      fclose (tape->inFp) ;
-    }
-
-  if (tape->outFp != NULL)
-    fclose (tape->outFp) ;
-
-  initTape (tape) ;
-}
-
-
-
-void gPrintTapeInfo (FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sGlobal Tape List : (count %lu) {\n",
-           indent,(unsigned long) activeTapeIdx) ;
-
-  for (i = 0 ; i < activeTapeIdx ; i++)
-    printTapeInfo (activeTapes [i],fp,indentAmt + INDENT_INCR) ;
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-void tapeLogGlobalStatus (FILE *fp)
-{
-  fprintf (fp,"%sBacklog file global values:%s\n",
-           genHtml ? "<B>" : "", genHtml ? "</B>" : "") ;
-  fprintf (fp,"        directory: %s\n",tapeDirectory) ;
-  fprintf (fp,"    rotate period: %-3ld seconds\n",(long) rotatePeriod) ;
-  fprintf (fp,"checkpoint period: %-3ld seconds\n",(long) tapeCkPtPeriod) ;
-  fprintf (fp,"   newfile period: %-3ld seconds\n",(long) tapeCkNewFilePeriod);
-  fprintf (fp,"\n") ;
-}
-
-
-void tapeLogStatus (Tape tape, FILE *fp)
-{
-  if (tape == NULL)
-    fprintf (fp,"(no tape)\n") ;
-  else if (tape->noBacklog)
-      fprintf (fp,"                 spooling: DISABLED\n");
-  else if (tape->outputLowLimit == 0)
-      fprintf (fp,"                 spooling: UNLIMITED\n");
-  else 
-    {
-      fprintf (fp,"                 backlog low limit: %ld\n",
-               tape->outputLowLimit) ;
-      fprintf (fp,"               backlog upper limit: %ld",
-               tape->outputHighLimit) ;
-      if (tape->backlogFactor > 0.0)
-        fprintf (fp," (factor %1.2f)",tape->backlogFactor) ;
-      fputc ('\n',fp) ;
-      fprintf (fp,"                 backlog shrinkage: ") ;
-      fprintf (fp,"%ld bytes (from current file)\n",tape->lossage) ;
-    }
-}
-
-void printTapeInfo (Tape tape, FILE *fp, unsigned int indentAmt)
-{
-  char indent [INDENT_BUFFER_SIZE] ;
-  unsigned int i ;
-#if 0
-  QueueElem qe ;
-#endif
-  
-  for (i = 0 ; i < MIN(INDENT_BUFFER_SIZE - 1,indentAmt) ; i++)
-    indent [i] = ' ' ;
-  indent [i] = '\0' ;
-
-  fprintf (fp,"%sTape : %p {\n",indent,(void *) tape) ;
-
-  if (tape == NULL)
-    {
-      fprintf (fp,"%s}\n",indent) ;
-      return ;
-    }
-  
-  fprintf (fp,"%s    master-file : %s\n", indent, tape->handFilename) ;
-  fprintf (fp,"%s    input-file : %s\n", indent, tape->inputFilename) ;
-  fprintf (fp,"%s    output-file : %s\n",indent, tape->outputFilename) ;
-  fprintf (fp,"%s    lock-file : %s\n",indent, tape->lockFilename) ;
-  fprintf (fp,"%s    peerName : %s\n",indent,tape->peerName) ;
-  fprintf (fp,"%s    input-FILE : %p\n",indent, (void *) tape->inFp) ;
-  fprintf (fp,"%s    output-FILE : %p\n",indent, (void *) tape->outFp) ;
-  fprintf (fp,"%s    output-limit : %ld\n",indent, tape->outputLowLimit) ;
-
-#if 0
-  fprintf (fp,"%s    in-memory article queue (length  %d) {\n",indent,
-           tape->qLength) ;
-
-  for (qe = tape->head ; qe != NULL ; qe = qe->next)
-    {
-#if 0
-      printArticleInfo (qe->article,fp,indentAmt + INDENT_INCR) ;
-#else
-      fprintf (fp,"%s    %p\n",indent,qe->article) ;
-#endif
-    }
-
-  fprintf (fp,"%s    }\n",indent) ;
-#endif
-
-  fprintf (fp,"%s    tell-position : %ld\n",indent,(long) tape->tellpos) ;
-  fprintf (fp,"%s    input-FILE-changed : %s\n",indent,
-           boolToString (tape->changed)) ;
-
-  fprintf (fp,"%s    no-rotate : %s\n",indent, boolToString (tape->noRotate));
-  
-  fprintf (fp,"%s}\n",indent) ;
-}
-
-
-
-
-/* delete the tape. Spools the in-memory articles to disk. */
-void delTape (Tape tape)
-{
-  struct stat st ;
-  
-  if (tape == NULL)
-    return ;
-
-#if 1
-  
-  if (tape->outFp != NULL && fclose (tape->outFp) != 0)
-    syswarn ("ME ioerr fclose %s", tape->outputFilename) ;
-
-  if (stat(tape->outputFilename, &st) == 0 && st.st_size == 0)
-    {
-      d_printf (1,"removing empty output tape: %s\n",tape->outputFilename) ;
-      unlink (tape->outputFilename) ;
-    }
-  
-  tape->outFp = NULL ;
-  tape->outputSize = 0 ;
-
-#else
-  
-  tapeClose (tape) ;
-
-#endif
-
-  if (tape->inFp != NULL)
-    {
-      checkpointTape (tape) ;
-      fclose (tape->inFp) ;
-    }
-
-  unlockFile (tape->lockFilename) ;
-
-  freeCharP (tape->handFilename) ;
-  freeCharP (tape->inputFilename) ;
-  freeCharP (tape->outputFilename) ;
-  freeCharP (tape->lockFilename) ;
-  freeCharP (tape->peerName) ;
-             
-  removeTapeGlobally (tape) ;
-  
-  free (tape) ;
-}
-
-
-void tapeTakeArticle (Tape tape, Article article)
-{
-#if 0
-  QueueElem elem ;
-#endif
-  int amt ;
-  const char *fname, *msgid ;
-
-  ASSERT (tape != NULL) ;
-
-  /* return immediately if spooling disabled - jgarzik */
-  if (tape->noBacklog)
-    {
-      delArticle (article) ;
-      return;
-    }
-
-  fname = artFileName (article) ;
-  msgid = artMsgId (article) ;
-  amt = fprintf (tape->outFp,"%s %s\n", fname, msgid) ;
-
-  /* I'd rather know where I am each time, and I don't trust all
-    fprintf's to give me character counts. */
-#if defined (TRUST_FPRINTF)
-
-  tape->outputSize += amt ;
-
-#else
-#if defined (NO_TRUST_STRLEN)
-
-  tape->outputSize = ftello (tape->outFp) ;
-
-#else
-
-  tape->outputSize += strlen(fname) + strlen(msgid) + 2 ; /* " " + "\n" */
-
-#endif
-#endif
-  
-  delArticle (article) ;
-
-  if (debugShrinking)
-    {
-      struct stat sb ;
-
-      fflush (tape->outFp) ;
-      
-      if (fstat (fileno (tape->outFp),&sb) != 0)
-        syswarn ("ME oserr fstat %s",tape->outputFilename) ;
-      else if (sb.st_size != tape->outputSize) 
-        syslog (LOG_ERR,"fstat and ftello do not agree: %ld %ld for %s\n",
-                (long)sb.st_size,tape->outputSize,tape->outputFilename) ;
-    }
-  
-  if (tape->outputHighLimit > 0 && tape->outputSize >= tape->outputHighLimit)
-    {
-      long oldSize = tape->outputSize ;
-      shrinkfile (tape->outFp,tape->outputLowLimit,tape->outputFilename,"a+");
-      tape->outputSize = ftello (tape->outFp) ;
-      tape->lossage += oldSize - tape->outputSize ;
-    }
-}
-
-
-/* Pick an article off a tape and return it. NULL is returned if there
-   are no more articles. */
-Article getArticle (Tape tape)
-{
-  char line [2048] ;            /* ick. 1024 for filename + 1024 for msgid */
-  char *p, *q ;
-  char *msgid, *filename ;
-  Article art = NULL ;
-  time_t now = theTime() ;
-
-  ASSERT (tape != NULL) ;
-
-  if (tape->inFp == NULL && (now - tape->lastRotated) > rotatePeriod)
-    prepareFiles (tape) ;       /* will flush queue too. */
-
-  while (tape->inFp != NULL && art == NULL)
-    {
-      tape->changed = true ;
-      
-      if (fgets (line,sizeof (line), tape->inFp) == NULL)
-        {
-          if (ferror (tape->inFp))
-            syswarn ("ME ioerr on tape file %s", tape->inputFilename) ;
-          else if ( !feof (tape->inFp) )
-            syswarn ("ME oserr fgets %s", tape->inputFilename) ;
-          
-          if (fclose (tape->inFp) != 0)
-            syswarn ("ME ioerr fclose %s", tape->inputFilename) ;
-
-          d_printf (1,"No more articles on tape %s\n",tape->inputFilename) ;
-
-          tape->inFp = NULL ;
-          tape->scribbled = false ;
-
-          unlink (tape->inputFilename) ;
-
-          if ((now - tape->lastRotated) > rotatePeriod)
-            prepareFiles (tape) ; /* rotate files to try next. */
-        }
-      else
-        {
-          msgid = filename = NULL ;
-          
-          for (p = line ; *p && CTYPE(isspace, *p) ; p++) /* eat whitespace */
-            /* nada */ ;
-
-          if (*p != '\0')
-            {
-              q = strchr (p,' ') ;
-
-              if (q != NULL)
-                {
-                  filename = p ;
-                  *q = '\0' ;
-      
-                  for (q++ ; *q && CTYPE(isspace, *q) ; q++)
-                    /* nada */ ;
-
-                  if (*q != '\0')
-                    {
-                      if (((p = strchr (q, ' ')) != NULL) ||
-                          ((p = strchr (q, '\n')) != NULL))
-                        *p = '\0' ;
-
-                      if (p != NULL)
-                        msgid = q ;
-                      else
-                        filename = NULL ; /* no trailing newline or blank */
-                    }
-                  else
-                    filename = NULL ; /* line had one field and some blanks */
-                }
-              else
-                filename = NULL ; /* line only had one field */
-            }
-
-          /* See if message ID looks valid. */
-          if (msgid) {
-            for (p = msgid; *p; p++)
-              ;
-            if (p > msgid) p--;
-            if (*msgid != '<' || *p != '>') {
-              warn ("ME tape invalid messageID in %s: %s",
-                    tape->inputFilename,msgid);
-              msgid = NULL;
-            }
-          }
-
-          if (filename != NULL && msgid != NULL)
-            art = newArticle (filename, msgid) ;
-
-          /* art may be NULL here if the file is no longer valid. */
-        }
-    }
-  
-#if 0
-  /* now we either have an article or there is no more on disk */
-  if (art == NULL)
-    {
-      if (tape->inFp != NULL && ((c = fgetc (tape->inFp)) != EOF))
-        ungetc (c,tape->inFp) ; /* shouldn't happen */
-      else if (tape->inFp != NULL)
-        {
-          /* last article read was the end of the tape. */
-          if (fclose (tape->inFp) != 0)
-            syswarn ("ME ioerr fclose %s", tape->inputFilename) ;
-          
-          tape->inFp = NULL ;
-          tape->scribbled = false ;
-          
-          /* toss out the old input file and prepare the new one */
-          unlink (tape->inputFilename) ;
-          
-          if (now - tape->lastRotated > rotatePeriod)
-            prepareFiles (tape) ;
-        }
-    }
-#endif
-  
-  if (art == NULL)
-    d_printf (2,"%s All out of articles in the backlog\n", tape->peerName) ;
-  else
-    d_printf (2,"%s Peeled article %s from backlog\n",tape->peerName,
-             artMsgId (art)) ;
-      
-  return art ;
-}
-
-
-/****************************************************/
-/**                  CLASS FUNCTIONS               **/
-/****************************************************/
-
-/* Cause all the Tapes to checkpoint themselves. */
-void checkPointTapes (void)
-{
-  unsigned int i ;
-
-  for (i = 0 ; i < activeTapeIdx ; i++)
-    checkpointTape (activeTapes [i]) ;
-}
-
-
-/* make all the tapes set their checkNew flag. */
-static void tapesSetCheckNew (void) 
-{
-  unsigned int i ;
-
-  for (i = 0 ; i < activeTapeIdx ; i++)
-    activeTapes[i]->checkNew = true ;
-}
-
-
-#if 0
-/* Set the pathname of the directory for storing tapes in. */
-void setTapeDirectory (const char *newDir)
-{
-  /* the activeTape variable gets set when the first Tape object
-     is created */
-  if (activeTapes != NULL)
-    {
-      syslog (LOG_CRIT,"Resetting backlog directory") ;
-      abort() ;
-    }
-  
-  if (tapeDirectory != NULL)
-    freeCharP (tapeDirectory) ;
-  
-  tapeDirectory = xstrdup (newDir) ;
-
-  addPointerFreedOnExit (tapeDirectory) ;
-}
-#endif
-
-/* Get the pathname of the directory tapes are stored in. */
-const char *getTapeDirectory (void)
-{
-  ASSERT (tapeDirectory != NULL) ;
-
-#if 0
-  if (tapeDirectory == NULL)
-    {
-      tapeDirectory = xstrdup (dflTapeDir) ;
-      addPointerFreedOnExit (tapeDirectory) ;
-    }
-#endif
-  
-  return tapeDirectory ;
-}
-
-
-#if 0
-void setOutputSizeLimit (long val)
-{
-  defaultSizeLimit = val ;
-}
-#endif
-
-
-
-
-
-
-/**********************************************************************/
-/*                          PRIVATE FUNCTIONS                         */
-/**********************************************************************/
-
-
-/* Add a new tape to the class-level list of active tapes.  */
-static void addTapeGlobally (Tape tape)
-{
-  ASSERT (tape != NULL) ;
-  
-  if (activeTapeSize == activeTapeIdx)
-    {
-      unsigned int i ;
-      
-      activeTapeSize += 10 ;
-      if (activeTapes != NULL)
-        activeTapes = xrealloc (activeTapes, sizeof(Tape) * activeTapeSize) ;
-      else
-        activeTapes = xmalloc (sizeof(Tape) * activeTapeSize) ;
-
-      for (i = activeTapeIdx ; i < activeTapeSize ; i++)
-        activeTapes [i] = NULL ;
-    }
-  activeTapes [activeTapeIdx++] = tape ;
-}
-
-
-/* Remove a tape for the class-level list of active tapes. */
-static void removeTapeGlobally (Tape tape)
-{
-  unsigned int i ;
-
-  if (tape == NULL)
-    return ;
-  
-  ASSERT (activeTapeIdx > 0) ;
-  
-  for (i = 0 ; i < activeTapeIdx ; i++)
-    if (activeTapes [i] == tape)
-      break ;
-
-  ASSERT (i < activeTapeIdx) ;
-
-  for ( ; i < (activeTapeIdx - 1) ; i++)
-    activeTapes [i] = activeTapes [i + 1] ;
-
-  activeTapes [--activeTapeIdx] = NULL ;
-
-  if (activeTapeIdx == 0)
-    {
-      free (activeTapes) ;
-      activeTapes = NULL ;
-    }
-}
-
-
-/* Have a tape checkpoint itself so that next process can pick up where
-   this one left off. */
-static void checkpointTape (Tape tape)
-{
-  if (tape->inFp == NULL)       /* no input file being read. */
-    return ;
-
-  if (!tape->changed)   /* haven't read since last checkpoint */
-    {
-      d_printf (1,"Not checkpointing unchanged tape: %s\n", tape->peerName) ;
-      return ;
-    }
-  
-  if ((tape->tellpos = ftello (tape->inFp)) < 0)
-    {
-      syswarn ("ME oserr ftello %s", tape->inputFilename) ;
-      return ;
-    }
-
-  /* strlen of "18446744073709551616\n" (2^64) */
-#define BITS64 21
-
-  /* make sure we're not right at the beginning of the file so we can write. */
-  if (tape->tellpos > BITS64)
-    {
-      rewind (tape->inFp) ;
-
-      /* scribble blanks over the first lines characters */
-      if (!tape->scribbled) 
-        {
-          int currloc = 0 ;
-          int c ;
-
-          while ((c = fgetc (tape->inFp)) != '\n' || currloc <= BITS64)
-            if (c == EOF)
-              return ;
-            else
-              currloc++ ;
-
-          rewind (tape->inFp) ;
-          
-          while (currloc-- > 0)
-            fputc (' ',tape->inFp) ;
-
-          rewind (tape->inFp) ;
-
-          fflush (tape->inFp) ;
-          tape->scribbled = true ;
-        }
-      
-      fprintf (tape->inFp,"%ld",tape->tellpos) ;
-
-      if (fseeko (tape->inFp,tape->tellpos,SEEK_SET) != 0)
-        syswarn ("ME oserr fseeko(%s,%ld,SEEK_SET)",tape->inputFilename,
-                 tape->tellpos) ;
-    }
-  
-  tape->changed = false ;
-}
-
-
-
-/* Prepare the tape file(s) for input and output */
-
-/* For a given Tape there are
- * three possible files: PEER.input PEER and
- * PEER.output. PEER.input and PEER.output are private to
- * innfeed. PEER is where a sysadmin can drop a file that (s)he
- * wants to inject into the process. If the first line of the input file
- * contains only an integer (possibly surrounded by spaces), then this is
- * taken to be the position to seek to before reading.
- *
- * prepareFiles will process them in a manner much like the following shell
- * commands:
- *
- * if [ ! -f PEER.input ]; then
- *     if [ -f PEER ]; then mv PEER PEER.input
- *     elif [ -f PEER.output ]; then mv PEER.output PEER; fi
- * fi
- *
- * At this point PEER.input is opened for reading if it exists.
- *
- * The checkpoint file is left as-is unless the PEER.input file
- * happens to be newer that the checkpoint file.
- */
-static void prepareFiles (Tape tape)
-{
-  bool inpExists ;
-  bool outExists ;
-  bool newExists ;
-
-#if 0
-  /* flush any in memory articles to disk */
-  if (tape->head != NULL && tape->outFp != NULL)
-    flushTape(tape) ;
-#endif
-
-  tape->tellpos = 0 ;
-
-  /*  First time through, or something external has set checkNew */
-  if (tape->lastRotated == 0 || tape->checkNew)
-    {
-      newExists = fileExistsP (tape->handFilename) ;
-      if (newExists)
-        notice ("%s new hand-prepared backlog file", tape->peerName) ;
-    }
-  else
-    newExists = false ;
-  
-  if (tape->lastRotated == 0)    /* first time here */
-    {
-      inpExists = fileExistsP (tape->inputFilename) ;
-      outExists = fileExistsP (tape->outputFilename) ;
-    }
-  else
-    {
-      inpExists = (tape->inFp != NULL) ? true : false ; /* can this ever be true?? */
-      outExists = (tape->outFp != NULL && tape->outputSize > 0) ? true : false ;
-    }
-  
-
-  /* move the hand-dropped file to the input file if needed. */
-  if (newExists && !inpExists)
-    {
-      if (rename (tape->handFilename,tape->inputFilename) != 0)
-        syswarn ("ME oserr rename %s, %s", tape->handFilename,
-                 tape->inputFilename);
-      else
-        {
-          notice ("%s grabbing external tape file", tape->peerName) ;
-          inpExists = true ;
-        }
-    }
-  
-  /* now move the output file to the input file, if needed and only if in
-     not in NOROTATE mode. */
-  if (outExists && !inpExists && !tape->noRotate)
-    {
-      if (tape->outFp != NULL)
-        {
-          fclose (tape->outFp) ;
-          tape->outFp = NULL ;
-        }
-      
-      if (rename (tape->outputFilename,tape->inputFilename) != 0)
-        syswarn ("ME oserr rename %s, %s", tape->outputFilename,
-                 tape->inputFilename) ;
-      else
-        inpExists = true ;
-
-      outExists = false ;
-    }
-
-  /* now open up the input file and seek to the proper position. */
-  if (inpExists)
-    {
-      int c ;
-      long flength ;
-      
-      if ((tape->inFp = fopen (tape->inputFilename,"r+")) == NULL)
-        syswarn ("ME fopen %s", tape->inputFilename) ;
-      else
-        {
-          char buffer [64] ;
-
-          if (fgets (buffer,sizeof (buffer) - 1, tape->inFp) == NULL)
-            {
-              if (feof (tape->inFp))
-                {
-                  d_printf (1,"Empty input file: %s\n",tape->inputFilename) ;
-                  unlink (tape->inputFilename) ;
-                }
-              else
-                syswarn ("ME oserr fgets %s", tape->inputFilename) ;
-              
-              fclose (tape->inFp) ;
-              tape->inFp = NULL ;
-              tape->scribbled = false ;
-            }
-          else
-            {
-              unsigned int len = strlen (buffer) ;
-              long newPos = 0 ;
-
-              if (len > 0 && buffer [len - 1] == '\n')
-                buffer [--len] = '\0' ;
-
-              if (len > 0 && strspn (buffer,"0123456789 \n") == len)
-                {
-                  if (sscanf (buffer,"%ld",&newPos) == 1)
-                    {
-                      tape->scribbled = true ;
-                      tape->tellpos = newPos ;
-                    }
-                }
-
-              if ((flength = fileLength (fileno (tape->inFp))) < tape->tellpos)
-                {
-                  warn ("ME tape short: %s %ld %ld", tape->inputFilename,
-                        flength, tape->tellpos) ;
-                  tape->tellpos = 0 ;
-                }
-              else if (tape->tellpos == 0)
-                rewind (tape->inFp) ;
-              else if (fseeko (tape->inFp,tape->tellpos - 1,SEEK_SET) != 0)
-                syswarn ("ME oserr fseeko(%s,%ld,SEEK_SET)",
-                         tape->inputFilename,tape->tellpos) ;
-              else if ((c = fgetc (tape->inFp)) != '\n')
-                {
-                  while (c != EOF && c != '\n')
-                    c = fgetc (tape->inFp) ;
-                  
-                  if (c == EOF)
-                    {
-                      fclose (tape->inFp) ;
-                      unlink (tape->inputFilename) ;
-                      tape->inFp = NULL ;
-                      tape->scribbled = false ;
-                      prepareFiles (tape) ;
-                    }
-                  else
-                    {
-                      long oldPos = tape->tellpos ;
-                      
-                      tape->changed = true ;
-                      checkpointTape (tape) ;
-
-                      warn ("ME internal checkpoint line boundary missed:"
-                            " %s %ld vs. %ld",tape->inputFilename,
-                              tape->tellpos, oldPos) ;
-                    }
-                }
-            }
-        }
-    }
-  
-  tape->lastRotated = theTime() ;
-  tape->checkNew = false ;
-
-  /* now open up the output file. */
-  if (tape->outFp == NULL)
-    {
-      if ((tape->outFp = fopen (tape->outputFilename,"a+")) == NULL)
-        {
-          syswarn ("ME tape open failed (a+) %s", tape->outputFilename) ;
-          return ;
-        }
-      fseeko (tape->outFp,0,SEEK_END) ;
-      tape->outputSize = ftello (tape->outFp) ;
-      tape->lossage = 0 ;
-    }
-}
-
-
-static void tapeCkNewFileCbk (TimeoutId id, void *d UNUSED)
-{
-  ASSERT (id == ckNewFileId) ;
-  ASSERT (tapeCkNewFilePeriod > 0) ;
-
-  tapesSetCheckNew () ;
-
-  ckNewFileId = prepareSleep (tapeCkNewFileCbk,tapeCkNewFilePeriod,NULL) ;
-}
-
-
-/* The timer callback function that will checkpoint all the active tapes. */
-static void tapeCheckpointCallback (TimeoutId id, void *d UNUSED)
-{
-  ASSERT (id == checkPtId) ;
-  ASSERT (tapeCkPtPeriod > 0) ;
-  
-  d_printf (1,"Checkpointing tapes\n") ;
-  
-  checkPointTapes () ;
-
-  checkPtId = prepareSleep (tapeCheckpointCallback,tapeCkPtPeriod,NULL) ;
-}
-
-
-
-#if 0
-static void flushTape (Tape tape)
-{
-  QueueElem elem ;
-
-  /* flush out queue to disk. */
-  elem = tape->head ;
-  while (elem != NULL)
-    {
-      tape->head = tape->head->next ;
-      fprintf (tape->outFp,"%s %s\n", artFileName (elem->article),
-               artMsgId (elem->article)) ;
-      
-      delArticle (elem->article) ;
-      
-      free (elem) ;
-      elem = tape->head ;
-    }
-  tape->tail = NULL ;
-  tape->qLength = 0;
-      
-
-  /* I'd rather know where I am each time, and I don't trust all
-     fprintf's to give me character counts. */
-  tape->outputSize = ftello (tape->outFp) ;
-  if (debugShrinking)
-    {
-      struct stat buf ;
-      static bool logged = false ;
-      
-      fflush (tape->outFp) ;
-      if (fstat (fileno (tape->outFp),&buf) != 0 && !logged)
-        {
-          syslog (LOG_ERR,FSTAT_FAILURE,tape->outputFilename) ;
-          logged = true ;
-        }
-      else if (buf.st_size != tape->outputSize)
-        {
-          warn ("ME fstat and ftello do not agree for %s",
-                tape->outputFilename) ;
-          logged = true ;
-        }
-    }
-  
-  if (tape->outputHighLimit > 0 && tape->outputSize > tape->outputHighLimit)
-    {
-      shrinkfile (tape->outFp,tape->outputLowLimit,tape->outputFilename,"a+");
-      tape->outputSize = ftello (tape->outFp) ;
-    }
-}
-#endif
-
-
-static void tapeCleanup (void)
-{
-  free (tapeDirectory) ;
-  tapeDirectory = NULL ;
-}
diff --git a/innfeed/tape.h b/innfeed/tape.h
deleted file mode 100644 (file)
index 2c53772..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*  $Id: tape.h 6648 2004-01-25 20:07:11Z rra $
-**
-**  The public interface to the Tape class.
-**
-**  Written by James Brister <brister@vix.com>
-**
-**  The Tape class simulates a mag tape.  It only reads or writes Articles.  A
-**  tape is either in an Input or Output state.  When an Article is given to a
-**  Tape it will store the Article in memory until it reaches a highwater mark
-**  at which point it dumps all it's articles to disk.
-**
-**  Input tapes generate article objects on request if the underlying tape
-**  file has info in it.  The Tapes take care of cleaning up used-up files as
-**  needed.
-*/
-
-#if ! defined ( tape_h__ )
-#define tape_h__
-
-#include <stdio.h>
-
-#include "misc.h"
-
-
-/* If dontRotate is true, then any articles that get written to the tape
-   will never be read back in again. This is for the batch-mode-only case
-   where articles written to tape were done so 'cause the remote
-   temporarily rejected them. */
-Tape newTape (const char *peerName, bool dontRotate) ;
-
-void gPrintTapeInfo (FILE *fp, unsigned int inedntAmt) ;
-void printTapeInfo (Tape tape, FILE *fp, unsigned int indentAmt) ;
-
-/* deletes the tape objects. If it has any articles cached then it dumps
-   them to the disk. */
-void delTape (Tape tape) ;
-
-/* give an article to the Tape for storage */
-void tapeTakeArticle (Tape tape, Article article) ;
-
-/* get a new article from an Input tape. */
-Article getArticle (Tape tape) ;
-
-/* close the input and output files and reopen them. */
-void gFlushTapes (void) ;
-void tapeFlush (Tape tape) ;
-
-
-/**************************************************/
-/*               CLASS LEVEL FUNCTIONS            */
-/**************************************************/
-
-/* get all the active input tapes to checkpoint their current positions */
-void checkPointTapes (void) ;
-
-/* get the name of the directory tapes are being stored in. */
-const char *getTapeDirectory (void) ;
-
-/* set the size limit of the output tapes. Default is zero which is no
-   limit. */
-void setOutputSizeLimit (long limit) ;
-
-int tapeConfigLoadCbk (void *data) ;
-
-void tapeLogGlobalStatus (FILE *fp) ;
-void tapeLogStatus (Tape tape, FILE *fp) ;
-
-#endif /* tape_h__ */
diff --git a/innfeed/testListener.pl b/innfeed/testListener.pl
deleted file mode 100644 (file)
index 0265506..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/perl
-# 
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Wed Jan  3 00:09:01 1996
-# Project:      INN -- innfeed
-# File:         testListener.pl
-# RCSId:        $Id: testListener.pl 6312 2003-05-04 21:40:11Z rra $
-# Description:  Generate news files for testing the innfeed feeder.
-#
-#               Run like this:
-#
-#                      testListener.pl -t 30 -d tmp | innfeed
-#
-#              or like this:
-#
-#                      innfeed -s 'perl testListener.pl -t 30 -d tmp'
-# 
-
-$0 =~ s!.*/!! ;
-
-require 'getopts.pl' ;
-
-$usage = "$0 [ -a -b name -d directory -c count -t sleep-amt -r -u ] peers\n" .
-    "  -a is for duplicate article id's periodically\n" .
-    "  -u is for random unlinking of article\n" .
-    "  -b add bogus peername periodically\n" .
-    "  -d is the directory where articles show be written.\n" .
-    "  -c is how many articles to create (0 the default meamns no limit)\n" .
-    "  -t is the number of seconds to sleep between each article.\n" .
-    "  -r is to have articles be created in NNTP ready format\n" ;
-
-&Getopts ("a:b:c:d:t:rl:h:") || die $usage ;
-
-die $usage if $opt_h ;
-$total = $opt_c ;
-
-$sleepAmt = 1 ;
-$sleepAmt = $opt_t if ($opt_t =~ /^[\d\.]+/) ;
-
-$lineCount = 50 ;
-$lineCount = $opt_l if ($opt_l =~ /^\d+$/) ;
-
-$directory = "." ;
-$directory = $opt_d if $opt_d ;
-
-$bogus = $opt_b ;
-if ( $bogus && $bogus !~ /^[a-zA-Z]+$/ ) {
-    print "The bogus peername must contain only letters\n" ;
-}
-    
-$cr = ($opt_r ? "\r" : "") ;
-
-$SIG{'INT'} = 'IGNORE' ;
-$SIG{'TERM'} = 'sigHup' ;
-$SIG{'QUIT'} = 'sigHup' ;
-$SIG{'HUP'} = 'sigHup' ;
-
-sub sigHup {
-       exit (1) ;
-}
-
-
-$monstr = "JanFebMarAprMayJunJulAugSepOctNovDec" ;
-$letstr = "abcdefghijklmnopqrstuvwxyz" ;
-
-sub createArticle {
-       local ($counter) = @_ ;
-       local ($filename,$msgid,$i) ;
-       local ($time) = $^T ;
-       local ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
-                                                  = gmtime($time);
-       local ($index) = $counter ;
-
-
-       if ($opt_a && ((int (rand (4)) % 2) == 0)) {
-               $index = int ($index / 2) ;
-       }
-
-       $msgid = "<$index.$$.$time\@home.octet.com.au>" ;
-
-       $filename = sprintf ("%s/SampleArticle.%06d",$directory,$index) ;
-
-       open (ARTICLE,">$filename") || 
-               die "open ($filename): $!\n" ;
-       print ARTICLE  "Path: home.octet.com.au!not-for-mail$cr\n" ;
-       print ARTICLE "From: brister\@home.octet.com.au$cr\n" ;
-       print ARTICLE "Newsgroups: junk,local.test$cr\n" ;
-       print ARTICLE "Subject: Test$cr\n" ;
-       print ARTICLE "Date: " ;
-
-       printf ARTICLE "%d %s %d %02d:%02d:%02d UTC$cr\n",
-               $mday, substr($monstr,$mon * 3, 3), $year + 1900,
-               $hour, $min, $sec ;
-
-       print ARTICLE "Organization: None that I can think of$cr\n" ;
-       print ARTICLE "Lines: 5$cr\n" ;
-       print ARTICLE "Distribution: world$cr\n" ;
-       print ARTICLE "Message-ID: $msgid$cr\n" ;
-       print ARTICLE "NNTP-Posting-Host: localhost$cr\n" ;
-       print ARTICLE "$cr\n" ;
-       
-       for ($i = 0 ; $i < $lineCount ; $i++) {
-               print ARTICLE "x" x ($lineCount + 1), "$cr\n";
-       }
-       print ARTICLE ".This line has a leading dot.$cr\n" ;
-       print ARTICLE "And the next line only has a dot.$cr\n" ;
-       if ($opt_r) {
-           print ARTICLE "..$cr\n" ;
-       } else {
-           print ARTICLE ".$cr\n" ;
-       }
-       print ARTICLE "And the next line has just two dots...$cr\n" ;
-       print ARTICLE "...$cr\n" ;
-       print ARTICLE "foo$cr\n" ;
-       print ARTICLE "And the next line is the last line of the article$cr\n" ;
-       print ARTICLE "and it only has a single dot on it.$cr\n" ;
-       if ($opt_r) {
-           print ARTICLE "..$cr\n" ;
-       } else {
-           print ARTICLE ".$cr\n" ;
-       }
-
-
-       close (ARTICLE) ;
-
-       return ($msgid, $filename) ;
-}
-
-srand ;
-
-
-$| = 1 ;
-
-if ( ! -t STDERR ) {
-    open (STDERR,">>/tmp/TESTLISTENER.LOG") || die ;
-}
-
-srand ;
-$sleepAmt = 1 if ($sleepAmt < 0) ;
-
-foreach $peer ( @ARGV ) {
-    $PEERS{$peer} = 1 ;
-}
-
-die "Must give peernames on command line:\n$usage" if ( ! @ARGV ) ;
-
-for ( $i = 0 ; $total == 0 || $i < $total ; $i++ ) {
-       ($msgid,$filename) = &createArticle ($i) ;
-       if ($opt_a && ((rand (3) % 3) == 0)) { 
-               print TTY "Removing file $filename\n" ;
-               unlink ($filename) if $opt_u ;
-       }
-       print "$filename $msgid @ARGV" ;
-       print " $bogus" if ($bogus && (rand (5) % 5) == 0) ;
-       print "\n" ;
-           
-       select (undef,undef,undef,(rand ($sleepAmt-1) + 1)) if $sleepAmt ;
-}
-
-sleep 11500 unless -f STDOUT ;
diff --git a/lib/Makefile b/lib/Makefile
deleted file mode 100644 (file)
index 54210bb..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top    = ..
-CFLAGS  = $(GCFLAGS)
-
-# The base library files that are always compiled and included.
-SOURCES       = buffer.c cleanfrom.c clientactive.c clientlib.c concat.c \
-               conffile.c confparse.c daemonize.c date.c dbz.c defdist.c \
-               fdflags.c fdlimit.c genid.c getfqdn.c getmodaddr.c gettime.c \
-               hash.c hashtab.c innconf.c inndcomm.c list.c localopen.c \
-               lockfile.c makedir.c md5.c messages.c mmap.c parsedate.c \
-               qio.c radix32.c readin.c remopen.c reservedfd.c resource.c \
-               sendarticle.c sendpass.c sequence.c sockaddr.c timer.c tst.c \
-               uwildmat.c vector.c version.c wire.c xfopena.c xmalloc.c \
-               xsignal.c xwrite.c
-
-# Sources for additional functions only built to replace missing system ones.
-EXTRA_SOURCES = fseeko.c ftello.c getpagesize.c hstrerror.c inet_aton.c \
-               inet_ntoa.c memcmp.c mkstemp.c pread.c pwrite.c setenv.c \
-               setproctitle.c strcasecmp.c strerror.c strlcat.c strlcpy.c \
-               strspn.c strtok.c
-
-OBJECTS       = $(LIBOBJS) $(SOURCES:.c=.o)
-LOBJECTS      = $(OBJECTS:.o=.lo)
-
-.SUFFIXES: .lo
-
-all: libinn.$(EXTLIB) perl.o
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPUB) libinn.$(EXTLIB) $D$(PATHLIB)/libinn.$(EXTLIB)
-
-clobber clean distclean:
-       rm -f *.o *.lo libinn.la libinn.a parsedate.c parsedate
-       rm -f profiled perl$(PROFSUFFIX).o libinn$(PROFSUFFIX).a
-       rm -f libinn_pure_*.a .pure
-       rm -rf .libs
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES) ../include/*.h
-
-libinn.la: $(OBJECTS) $(LOBJECTS)
-       $(LIBLD) $(LDFLAGS) -o $@ $(LOBJECTS) $(LIBS) \
-           -rpath $(PATHLIB) -version-info 2:0:0
-
-libinn.a: $(OBJECTS)
-       ar r $@ $(OBJECTS)
-       $(RANLIB) libinn.a
-
-.c.o .c.lo:
-       $(LIBCC) $(CFLAGS) -c $*.c
-
-perl.o: perl.c
-       $(CC) $(CFLAGS) $(PERLINC) $(LDFLAGS) -c perl.c
-
-../include/inn/system.h:
-       (cd ../include && $(MAKE))
-
-parsedate.c: parsedate.y
-       @echo Expect 6 shift/reduce conflicts
-       $(YACC) parsedate.y
-       @mv y.tab.c parsedate.c
-
-parsedate: parsedate.c gettime.o
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ -DTEST -DYYDEBUG parsedate.c gettime.o
-
-##  Profiling.  The rules are a bit brute-force, but good enough.
-profiled: libinn$(PROFSUFFIX).a perl$(PROFSUFFIX).o
-       date >$@
-
-libinn$(PROFSUFFIX).a perl$(PROFSUFFIX).o: $(OBJECTS) perl.o
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) libinn.a
-       $(MAKEPROFILING) perl.o
-       mv libinn.a libinn$(PROFSUFFIX).a
-       mv perl.o perl$(PROFSUFFIX).o
-       $(RANLIB) libinn$(PROFSUFFIX).a
-       rm -f $(OBJECTS)
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend: Makefile $(SOURCES) $(EXTRA_SOURCES) perl.c ../include/inn/system.h
-       $(MAKEDEPEND) '$(CFLAGS) $(PERLINC)' $(SOURCES) $(EXTRA_SOURCES) perl.c
-
-# Special dependency to teach make to build the include directory properly.
-../include/inn/defines.h: ../include/inn/system.h
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-buffer.o: buffer.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/buffer.h ../include/inn/defines.h ../include/libinn.h
-cleanfrom.o: cleanfrom.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-clientactive.o: clientactive.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/libinn.h ../include/nntp.h ../include/paths.h
-clientlib.o: clientlib.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h
-concat.o: concat.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/libinn.h ../include/config.h
-conffile.o: conffile.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/conffile.h ../include/libinn.h
-confparse.o: confparse.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/confparse.h ../include/inn/defines.h \
-  ../include/inn/hashtab.h ../include/inn/messages.h \
-  ../include/inn/vector.h ../include/libinn.h
-daemonize.o: daemonize.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h
-date.o: date.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-dbz.o: dbz.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/dbz.h ../include/libinn.h ../include/inn/messages.h \
-  ../include/inn/defines.h ../include/inn/innconf.h ../include/inn/mmap.h \
-  ../include/libinn.h
-defdist.o: defdist.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/paths.h
-fdflags.o: fdflags.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-fdlimit.o: fdlimit.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-genid.o: genid.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h
-getfqdn.o: getfqdn.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h ../include/paths.h
-getmodaddr.o: getmodaddr.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h
-gettime.o: gettime.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/libinn.h ../include/config.h
-hash.o: hash.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/md5.h ../include/inn/defines.h ../include/libinn.h
-hashtab.o: hashtab.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/hashtab.h ../include/inn/defines.h ../include/libinn.h
-innconf.o: innconf.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/confparse.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h \
-  ../include/inn/vector.h ../include/libinn.h ../include/paths.h
-inndcomm.o: inndcomm.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/portable/socket.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inndcomm.h ../include/libinn.h \
-  ../include/paths.h
-list.o: list.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/list.h ../include/inn/defines.h
-localopen.o: localopen.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h
-lockfile.o: lockfile.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-makedir.o: makedir.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-md5.o: md5.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/md5.h ../include/inn/defines.h
-messages.o: messages.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h
-mmap.o: mmap.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h \
-  ../include/inn/mmap.h
-parsedate.o: parsedate.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-qio.o: qio.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/qio.h ../include/inn/defines.h ../include/libinn.h
-radix32.o: radix32.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-readin.o: readin.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-remopen.o: remopen.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h
-reservedfd.o: reservedfd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-resource.o: resource.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-sendarticle.o: sendarticle.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h ../include/nntp.h
-sendpass.o: sendpass.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h
-sequence.o: sequence.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/sequence.h ../include/inn/defines.h
-sockaddr.o: sockaddr.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h ../include/libinn.h
-timer.o: timer.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h \
-  ../include/inn/timer.h ../include/libinn.h
-tst.o: tst.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/tst.h ../include/inn/defines.h ../include/libinn.h
-uwildmat.o: uwildmat.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-vector.o: vector.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/vector.h ../include/inn/defines.h ../include/libinn.h
-version.o: version.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/inn/version.h
-wire.o: wire.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/wire.h ../include/inn/defines.h ../include/libinn.h
-xfopena.o: xfopena.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-xmalloc.o: xmalloc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h ../include/libinn.h
-xsignal.o: xsignal.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/libinn.h ../include/config.h
-xwrite.o: xwrite.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h
-fseeko.o: fseeko.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-ftello.o: ftello.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-getpagesize.o: getpagesize.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h
-hstrerror.o: hstrerror.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-inet_aton.o: inet_aton.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-inet_ntoa.o: inet_ntoa.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-memcmp.o: memcmp.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h
-mkstemp.o: mkstemp.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/time.h ../include/config.h
-pread.o: pread.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-pwrite.o: pwrite.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-setenv.o: setenv.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-setproctitle.o: setproctitle.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/setproctitle.h \
-  ../include/config.h ../include/inn/messages.h ../include/inn/defines.h
-strcasecmp.o: strcasecmp.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-strerror.o: strerror.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h
-strlcat.o: strlcat.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-strlcpy.o: strlcpy.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-strspn.o: strspn.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-strtok.o: strtok.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h
-perl.o: perl.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h
diff --git a/lib/buffer.c b/lib/buffer.c
deleted file mode 100644 (file)
index dc3c0a3..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*  $Id: buffer.c 5463 2002-05-06 05:40:46Z rra $
-**
-**  Counted, reusable memory buffer.
-**
-**  A buffer is an allocated bit of memory with a known size and a separate
-**  data length.  It's intended to store strings and can be reused repeatedly
-**  to minimize the number of memory allocations.  Buffers increase in
-**  increments of 1K.
-**
-**  A buffer contains a notion of the data that's been used and the data
-**  that's been left, used when the buffer is an I/O buffer where lots of data
-**  is buffered and then slowly processed out of the buffer.  The total length
-**  of the data is used + left.  If a buffer is just used to store some data,
-**  used can be set to 0 and left stores the length of the data.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/buffer.h"
-#include "libinn.h"
-
-/*
-**  Allocate a new struct buffer and initialize it.
-*/
-struct buffer *
-buffer_new(void)
-{
-    struct buffer *buffer;
-
-    buffer = xmalloc(sizeof(struct buffer));
-    buffer->size = 0;
-    buffer->used = 0;
-    buffer->left = 0;
-    buffer->data = NULL;
-    return buffer;
-}
-
-
-/*
-**  Resize a buffer to be at least as large as the provided second argument.
-**  Resize buffers to multiples of 1KB to keep the number of reallocations to
-**  a minimum.  Refuse to resize a buffer to make it smaller.
-*/
-void
-buffer_resize(struct buffer *buffer, size_t size)
-{
-    if (size < buffer->size)
-        return;
-    buffer->size = (size + 1023) & ~1023UL;
-    buffer->data = xrealloc(buffer->data, buffer->size);
-}
-
-
-/*
-**  Replace whatever data is currently in the buffer with the provided data.
-*/
-void
-buffer_set(struct buffer *buffer, const char *data, size_t length)
-{
-    if (length > 0) {
-        buffer_resize(buffer, length);
-        memmove(buffer->data, data, length);
-    }
-    buffer->left = length;
-    buffer->used = 0;
-}
-
-
-/*
-**  Append data to a buffer.  The new data shows up as additional unused data
-**  at the end of the buffer.  Resize the buffer to multiples of 1KB.
-*/
-void
-buffer_append(struct buffer *buffer, const char *data, size_t length)
-{
-    size_t total;
-
-    if (length == 0)
-        return;
-    total = buffer->used + buffer->left;
-    buffer_resize(buffer, total + length);
-    buffer->left += length;
-    memcpy(buffer->data + total, data, length);
-}
-
-
-/*
-**  Swap the contents of two buffers.
-*/
-void
-buffer_swap(struct buffer *one, struct buffer *two)
-{
-    struct buffer tmp;
-
-    tmp = *one;
-    *one = *two;
-    *two = tmp;
-}
diff --git a/lib/cleanfrom.c b/lib/cleanfrom.c
deleted file mode 100644 (file)
index 94e6de5..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*  $Id: cleanfrom.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-
-
-#define LPAREN '('
-#define RPAREN ')'
-
-
-/*
-**  Clean up a from line, making the following transformations:
-**     address                 address
-**     address (stuff)         address
-**     stuff <address>         address
-*/
-void HeaderCleanFrom(char *from)
-{
-    char               *p;
-    char               *end;
-    int                        len;
-
-    if ((len = strlen(from)) == 0)
-       return;
-    /* concatenate folded header */
-    for (p = end = from ; p < from + len ;) {
-       if (*p == '\n') {
-           if ((p + 1 < from + len) && ISWHITE(p[1])) {
-               if ((p - 1 >= from) && (p[-1] == '\r')) {
-                   end--;
-                   *end = p[1];
-                   p += 2;
-               } else {
-                   *end = p[1];
-                   p++;
-               }
-           } else {
-               *end = '\0';
-               break;
-           }
-       } else
-           *end++ = *p++;
-    }
-    if (end != from)
-       *end = '\0';
-
-    /* Do pretty much the equivalent of sed's "s/(.*)//g"; */
-    while ((p = strchr(from, LPAREN)) && (end = strchr(p, RPAREN))) {
-       while (*++end)
-           *p++ = *end;
-       *p = '\0';
-    }
-
-    /* Do pretty much the equivalent of sed's "s/\".*\"//g"; */
-    while ((p = strchr(from, '"')) && (end = strchr(p, '"'))) {
-       while (*++end)
-           *p++ = *end;
-       *p = '\0';
-    }
-
-    /* Do the equivalent of sed's "s/.*<\(.*\)>/\1/" */
-    if ((p = strrchr(from, '<')) && (end = strrchr(p, '>'))) {
-       while (++p < end)
-           *from++ = *p;
-       *from = '\0';
-    }
-
-    /* drop white spaces */
-    if ((len = strlen(from)) == 0)
-       return;
-    for (p = end = from ; p < from + len ;) {
-       if (ISWHITE(*p)) {
-           p++;
-           continue;
-       }
-       *end++ = *p++;
-    }
-    if (end != from)
-       *end = '\0';
-}
diff --git a/lib/clientactive.c b/lib/clientactive.c
deleted file mode 100644 (file)
index 8e7e741..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*  $Id: clientactive.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-
-static char    *CApathname;
-static FILE    *CAfp;
-
-
-/*
-**  Get a copy of the active file for a client host to use, locally or
-**  remotely.
-*/
-FILE *
-CAopen(FILE *FromServer, FILE *ToServer)
-{
-    char *path;
-
-    /* Use a local (or NFS-mounted) copy if available.  Make sure we don't
-     * try to delete it when we close it. */
-    path = concatpath(innconf->pathdb, _PATH_CLIENTACTIVE);
-    CAfp = fopen(path, "r");
-    free(path);
-    if (CAfp != NULL) {
-       CApathname = NULL;
-       return CAfp;
-    }
-
-    /* Use the active file from the server */
-    return CAlistopen(FromServer, ToServer, (char *)NULL);
-}
-
-
-/*
-**  Internal library routine.
-*/
-FILE *
-CA_listopen(char *pathname, FILE *FromServer, FILE *ToServer,
-            const char *request)
-{
-    char       buff[BUFSIZ];
-    char       *p;
-    int                oerrno;
-    FILE       *F;
-
-    F = fopen(pathname, "w");
-    if (F == NULL)
-       return NULL;
-
-    /* Send a LIST command to and capture the output. */
-    if (request == NULL)
-       fprintf(ToServer, "list\r\n");
-    else
-       fprintf(ToServer, "list %s\r\n", request);
-    fflush(ToServer);
-
-    /* Get the server's reply to our command. */
-    if (fgets(buff, sizeof buff, FromServer) == NULL
-     || strncmp(buff, NNTP_LIST_FOLLOWS, strlen(NNTP_LIST_FOLLOWS)) != 0) {
-       oerrno = errno;
-       /* Only call CAclose() if opened through CAopen() */
-       if (strcmp(CApathname, pathname) == 0)
-            CAclose();
-       errno = oerrno;
-       return NULL;
-    }
-
-    /* Slurp up the rest of the response. */
-    while (fgets(buff, sizeof buff, FromServer) != NULL) {
-       if ((p = strchr(buff, '\r')) != NULL)
-           *p = '\0';
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '.' && buff[1] == '\0') {
-           if (ferror(F) || fflush(F) == EOF || fclose(F) == EOF)
-               break;
-           return fopen(pathname, "r");
-       }
-       fprintf(F, "%s\n", buff);
-    }
-
-    /* Ran out of input before finding the terminator; quit. */
-    oerrno = errno;
-    fclose(F);
-    CAclose();
-    errno = oerrno;
-    return NULL;
-}
-
-
-/*
-**  Use the NNTP list command to get a file from a server.  Default is
-**  the active file, otherwise ask for whatever is in the request param.
-*/
-FILE *
-CAlistopen(FILE *FromServer, FILE *ToServer, const char *request)
-{
-    int fd, oerrno;
-
-    /* Gotta talk to the server -- see if we can. */
-    if (FromServer == NULL || ToServer == NULL) {
-       errno = EBADF;
-       return NULL;
-    }
-
-    CApathname = concatpath(innconf->pathtmp, _PATH_TEMPACTIVE);
-    fd = mkstemp(CApathname);
-    if (fd < 0) {
-        oerrno = errno;
-        free(CApathname);
-        CApathname = 0;
-        errno = oerrno;
-        return NULL;
-    }
-    close(fd);
-    return CAfp = CA_listopen(CApathname, FromServer, ToServer, request);
-}
-
-
-
-/*
-**  Close the file opened by CAopen or CAlistopen.
-*/
-void
-CAclose(void)
-{
-    if (CAfp) {
-       fclose(CAfp);
-       CAfp = NULL;
-    }
-    if (CApathname != NULL) {
-       unlink(CApathname);
-       CApathname = NULL;
-    }
-}
diff --git a/lib/clientlib.c b/lib/clientlib.c
deleted file mode 100644 (file)
index b0d0268..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*  $Id: clientlib.c 6155 2003-01-19 19:58:25Z rra $
-**
-**  Routines compatible with the NNTP "clientlib" routines.
-*/
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-
-
-FILE   *ser_rd_fp = NULL;
-FILE   *ser_wr_fp = NULL;
-char   ser_line[NNTP_STRLEN + 2];
-
-
-/*
-**  Get the name of the NNTP server.  Ignore the filename; we use
-**  our own configuration stuff.  Return pointer to static data.
-*/
-char *
-getserverbyfile(char *file UNUSED)
-{
-    static char        buff[256];
-
-    strlcpy(buff, innconf->server, sizeof(buff));
-    return buff;
-}
-
-
-/*
-**  Get a connection to the remote news server.  Return server's reply
-**  code or -1 on error.
-*/
-int
-server_init(char *host, int port)
-{
-    char       line2[NNTP_STRLEN];
-
-    /* This interface may be used by clients that assume C News behavior and
-       won't read inn.conf themselves. */
-    if (innconf == NULL)
-        if (!innconf_read(NULL))
-            return -1;
-
-    if (NNTPconnect(host, port, &ser_rd_fp, &ser_wr_fp, ser_line) < 0) {
-       if (ser_line[0] == '\0')
-           /* I/O problem. */
-           return -1;
-
-       /* Server rejected connection; return it's reply code. */
-       return atoi(ser_line);
-    }
-
-    /* Send the INN command; if understood, use that reply. */
-    put_server("mode reader");
-    if (get_server(line2, (int)sizeof line2) < 0)
-       return -1;
-    if (atoi(line2) != NNTP_BAD_COMMAND_VAL)
-       strlcpy(ser_line, line2, sizeof(ser_line));
-
-    /* Connected; return server's reply code. */
-    return atoi(ser_line);
-}
-
-
-#define CANTPOST       \
-    "NOTE:  This machine does not have permission to post articles"
-#define CANTUSE                \
-       "This machine does not have permission to use the %s news server.\n"
-/*
-**  Print a message based on the the server's initial response.
-**  Return -1 if server wants us to go away.
-*/
-int
-handle_server_response(int response, char *host)
-{
-    char       *p;
-
-    switch (response) {
-    default:
-       printf("Unknown response code %d from %s.\n", response, host);
-       return -1;
-     case NNTP_GOODBYE_VAL:
-       if (atoi(ser_line) == response) {
-           p = &ser_line[strlen(ser_line) - 1];
-           if (*p == '\n' && *--p == '\r')
-               *p = '\0';
-           if (p > &ser_line[3]) {
-               printf("News server %s unavailable: %s\n", host,
-                       &ser_line[4]);
-               return -1;
-           }
-       }
-       printf("News server %s unavailable, try later.\n", host);
-       return -1;
-    case NNTP_ACCESS_VAL:
-       printf(CANTUSE, host);
-       return -1;
-    case NNTP_NOPOSTOK_VAL:
-       printf("%s.\n", CANTPOST);
-       /* FALLTHROUGH */
-    case NNTP_POSTOK_VAL:
-       break;
-    }
-    return 0;
-}
-
-
-/*
-**  Send a line of text to the server.
-*/
-void
-put_server(const char *buff)
-{
-    fprintf(ser_wr_fp, "%s\r\n", buff);
-    fflush(ser_wr_fp);
-}
-
-
-/*
-**  Get a line of text from the server, strip trailing \r\n.
-**  Return -1 on error.
-*/
-int
-get_server(char *buff, int buffsize)
-{
-    char       *p;
-
-    if (fgets(buff, buffsize, ser_rd_fp) == NULL)
-       return -1;
-    p = &buff[strlen(buff)];
-    if (p >= &buff[2] && p[-2] == '\r' && p[-1] == '\n')
-       p[-2] = '\0';
-    return 0;
-}
-
-
-/*
-**  Send QUIT and close the server.
-*/
-void
-close_server(void)
-{
-    char       buff[NNTP_STRLEN];
-
-    if (ser_wr_fp != NULL && ser_rd_fp != NULL) {
-       put_server("QUIT");
-       fclose(ser_wr_fp);
-       ser_wr_fp = NULL;
-
-       get_server(buff, (int)sizeof buff);
-       fclose(ser_rd_fp);
-       ser_rd_fp = NULL;
-    }
-}
diff --git a/lib/concat.c b/lib/concat.c
deleted file mode 100644 (file)
index 97c7909..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*  $Id: concat.c 4234 2000-12-21 03:43:02Z rra $
-**
-**  Concatenate strings with dynamic memory allocation.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Usage:
-** 
-**       string = concat(string1, string2, ..., (char *) 0);
-**       path = concatpath(base, name);
-**
-**  Dynamically allocates (using xmalloc) sufficient memory to hold all of
-**  the strings given and then concatenates them together into that
-**  allocated memory, returning a pointer to it.  Caller is responsible for
-**  freeing.  Assumes xmalloc is available.  The last argument must be a
-**  null pointer (to a char *, if you actually find a platform where it
-**  matters).
-**
-**  concatpath is similar, except that it only takes two arguments.  If the
-**  second argument begins with / or ./, a copy of it is returned;
-**  otherwise, the first argument, a slash, and the second argument are
-**  concatenated together and returned.  This is useful for building file
-**  names where names that aren't fully qualified are qualified with some
-**  particular directory.
-*/
-
-#include "config.h"
-#include "libinn.h"
-
-#include <stdarg.h>
-#if STDC_HEADERS
-# include <string.h>
-#endif
-
-/* Abbreviation for cleaner code. */
-#define VA_NEXT(var, type)      ((var) = (type) va_arg(args, type))
-
-/* ANSI C requires at least one named parameter. */
-char *
-concat(const char *first, ...)
-{
-    va_list args;
-    char *result, *p;
-    const char *string;
-    size_t length = 0;
-
-    /* Find the total memory required. */
-    va_start(args, first);
-    for (string = first; string != NULL; VA_NEXT(string, const char *))
-        length += strlen(string);
-    va_end(args);
-    length++;
-
-    /* Create the string.  Doing the copy ourselves avoids useless string
-       traversals of result, if using strcat, or string, if using strlen to
-       increment a pointer into result, at the cost of losing the native
-       optimization of strcat if any. */
-    result = xmalloc(length);
-    p = result;
-    va_start(args, first);
-    for (string = first; string != NULL; VA_NEXT(string, const char *))
-        while (*string != '\0')
-            *p++ = *string++;
-    va_end(args);
-    *p = '\0';
-
-    return result;
-}
-
-
-char *
-concatpath(const char *base, const char *name)
-{
-    if (name[0] == '/' || (name[0] == '.' && name[1] == '/'))
-        return xstrdup(name);
-    else
-        return concat(base, "/", name, (char *) 0);
-}
diff --git a/lib/conffile.c b/lib/conffile.c
deleted file mode 100644 (file)
index 359a7e5..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*  $Id: conffile.c 6733 2004-05-16 23:01:23Z rra $
-**
-**  Routines for reading in incoming.conf-style config files.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "conffile.h"
-#include "libinn.h"
-
-static int getconfline(CONFFILE *F, char *buffer, int length) {
-  if (F->f) {
-    fgets(buffer, length, F->f);
-    if (ferror(F->f)) {
-      return 1;
-    }
-  } else if (F->array) {
-    strlcpy(buffer, F->array[F->lineno], F->sbuf);
-  }
-  F->lineno++;
-  if (strlen (F->buf) >= F->sbuf - 1) {
-    return 1; /* Line too long */
-  } else {
-    return 0;
-  }
-}
-
-static int cfeof(CONFFILE *F) {
-  if (F->f) {
-    return feof(F->f);
-  } else if (F->array) {
-    return (F->lineno == F->array_len);
-  } else {
-    return 1;
-  }
-}
-
-static char *CONFgetword(CONFFILE *F)
-{
-  char *p;
-  char *s;
-  char *t;
-  char *word;
-  bool flag, comment;
-
-  if (!F) return (NULL);       /* No conf file */
-  if (!F->buf || !F->buf[0]) {
-    if (cfeof (F)) return (NULL);
-    if (!F->buf) {
-      F->sbuf = BIG_BUFFER;
-      F->buf = xmalloc(F->sbuf);
-    }
-    if (getconfline(F, F->buf, F->sbuf) != 0)
-      return (NULL); /* Line too long */
-  }
-  do {
-     /* Ignore blank and comment lines. */
-     if ((p = strchr(F->buf, '\n')) != NULL)
-       *p = '\0';
-     for (p = F->buf; *p == ' ' || *p == '\t' ; p++);
-     flag = true;
-     if ((*p == '\0' || *p == '#') && !cfeof(F)) {
-       flag = false;
-       if (getconfline(F, F->buf, F->sbuf))
-         return (NULL); /* Line too long */
-       continue;
-     }
-     break;
-  } while (!cfeof(F) || !flag);
-
-  comment = false;
-  if (*p == '"') { /* double quoted string ? */
-    p++;
-    do {
-      for (t = p; (*t != '"' || (*t == '"' && *(t - 1) == '\\')) &&
-             *t != '\0'; t++);
-      if (*t == '\0') {
-        if (strlen(F->buf) >= F->sbuf - 2)
-          return (NULL); /* Line too long */
-        *t++ = '\n';
-        *t = '\0';
-        if (getconfline(F, t, F->sbuf - strlen(F->buf)))
-          return (NULL); /* Line too long */
-        if ((s = strchr(t, '\n')) != NULL)
-          *s = '\0';
-      }
-      else 
-        break;
-    } while (!cfeof(F));
-    if (*t != '"')
-      return (NULL);
-    *t++ = '\0';
-  }
-  else {
-    for (t = p; *t != ' ' && *t != '\t' && *t != '\0'; t++)
-      if (*t == '#' && (t == p || *(t - 1) != '\\')) {
-        comment = true;
-        break;
-      }
-    if (*t != '\0')
-      *t++ = '\0';
-  }
-  if (*p == '\0' && cfeof(F)) return (NULL);
-  word = xstrdup (p);
-  p = F->buf;
-  if (!comment)
-    for (; *t != '\0'; t++)
-      *p++ = *t;
-  *p = '\0';
-
-  return (word);
-}
-
-CONFFILE *CONFfopen(char *filename)
-{
-  FILE *f;
-  CONFFILE *ret;
-
-  f = fopen(filename, "r");
-  if (!f)
-    return(0);
-  ret = xmalloc(sizeof(CONFFILE));
-  if (!ret) {
-    fclose(f);
-    return(0);
-  }
-  ret->filename = xstrdup(filename);
-  ret->buf = 0;
-  ret->sbuf = 0;
-  ret->lineno = 0;
-  ret->f = f;
-  ret->array = NULL;
-  return(ret);
-}
-
-void CONFfclose(CONFFILE *f)
-{
-  if (!f) return;              /* No conf file */
-  fclose(f->f);
-  if (f->buf)
-    free(f->buf);
-  if (f->filename)
-    free(f->filename);
-  free(f);
-}
-
-CONFTOKEN *CONFgettoken(CONFTOKEN *toklist, CONFFILE *file)
-{
-  char *word;
-  static CONFTOKEN ret = {CONFstring, 0};
-  int i;
-
-  if (ret.name) {
-    free(ret.name);
-    ret.name = 0;
-  }
-  word = CONFgetword(file);
-  if (!word)
-    return(0);
-  if (toklist) {
-    for (i = 0; toklist[i].type; i++) {
-       if (strcmp(word, toklist[i].name) == 0) {
-         free(word);
-         return(&toklist[i]);
-       }
-    }
-  }
-  ret.name = word;
-  return(&ret);
-}
diff --git a/lib/confparse.c b/lib/confparse.c
deleted file mode 100644 (file)
index c12b1ef..0000000
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*  $Id: confparse.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Parse a standard block-structured configuration file syntax.
-**
-**  Herein are all the parsing and access functions for the configuration
-**  syntax used by INN.  See doc/config-* for additional documentation.
-**
-**  All entry point functions begin with config_*.  config_parse_file is
-**  the entry point for most of the work done in this file; all other
-**  functions access the parse tree that config_parse_file generates.
-**
-**  Functions are named by the structure or basic task they work on:
-**
-**      parameter_*     config_parameter structs.
-**      group_*         config_group structs.
-**      file_*          config_file structs (including all I/O).
-**      token_*         The guts of the lexer.
-**      parse_*         The guts of the parser.
-**      error_*         Error reporting functions.
-**      convert_*       Converting raw parameter values.
-**
-**  Each currently open file is represented by a config_file struct, which
-**  contains the current parse state for that file, including the internal
-**  buffer, a pointer to where in the buffer the next token starts, and the
-**  current token.  Inclusion of additional files is handled by maintaining a
-**  stack of config_file structs, so when one file is finished, the top struct
-**  popped off the stack and parsing continues where it left off.
-**
-**  Since config_file structs contain the parse state, they're passed as an
-**  argument to most functions.
-**
-**  A config_file struct contains a token struct, representing the current
-**  token.  The configuration file syntax is specifically designed to never
-**  require lookahead to parse; all parse decisions can be made on the basis
-**  of the current state and a single token.  A token consists of a type and
-**  an optional attached string.  Note that strings are allocated by the lexer
-**  but are never freed by the lexer!  Any token with an associated string
-**  should have that string copied into permanent storage (like the params
-**  hash of a config_group) or freed.  error_unexpected_token will do the
-**  latter.
-**
-**  Errors in the lexer are indicated by setting the token to TOKEN_ERROR.
-**  All parsing errors are indicated by setting the error flag in the current
-**  config_file struct.  Error recovery is *not* implemented by the current
-**  algorithm; it would add a lot of complexity to the parsing algorithm and
-**  the results still probably shouldn't be used by the calling program, so it
-**  would only be useful to catch more than one syntax error per invocation
-**  and it isn't expected that syntax errors will be that common.  Instead, if
-**  something fails to parse, the whole parser unwinds and returns failure.
-**
-**  The config_param_* functions are used to retrieve the values of
-**  parameters; each use a convert_* function to convert the raw parameter
-**  value to the type specified by the user.  group_parameter_get can
-**  therefore be the same for all parameter types, with all of the variations
-**  encapsulated in the convert_* functions.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-
-#include "inn/confparse.h"
-#include "inn/hashtab.h"
-#include "inn/messages.h"
-#include "inn/vector.h"
-#include "libinn.h"
-
-
-/* The types of tokens seen in configuration files. */
-enum token_type {
-    TOKEN_CRLF,
-    TOKEN_STRING,
-    TOKEN_QSTRING,
-    TOKEN_PARAM,
-    TOKEN_LBRACE,
-    TOKEN_RBRACE,
-    TOKEN_LANGLE,
-    TOKEN_RANGLE,
-    TOKEN_LBRACKET,
-    TOKEN_RBRACKET,
-    TOKEN_SEMICOLON,
-    TOKEN_EOF,
-    TOKEN_ERROR
-};
-
-/* The parse status of a file.  Variables marked internal are only used by
-   file_* functions; other functions don't need to look at them.  Other
-   variables are marked by what functions are responsible for maintaining
-   them. */
-struct config_file {
-    int fd;                     /* Internal */
-    char *buffer;               /* Internal */
-    size_t bufsize;             /* Internal */
-    const char *filename;       /* file_open */
-    unsigned int line;          /* token_newline and token_quoted_string */
-    bool error;                 /* Everyone */
-
-    /* Set by file_* and token_*.  current == NULL indicates we've not yet
-       read from the file. */
-    char *current;
-
-    /* Normally set by token_*, but file_read and file_read_more may set token
-       to TOKEN_ERROR or TOKEN_EOF when those conditions are encountered.  In
-       that situation, they also return false. */
-    struct {
-        enum token_type type;
-        char *string;
-    } token;
-};
-
-/* The types of parameters, used to distinguish the values of the union in the
-   config_parameter_s struct. */
-enum value_type {
-    VALUE_UNKNOWN,
-    VALUE_BOOL,
-    VALUE_INTEGER,
-    VALUE_NUMBER,
-    VALUE_STRING,
-    VALUE_LIST,
-    VALUE_INVALID
-};
-
-/* Each setting is represented by one of these structs, stored in the params
-   hash of a config group.  Since all of a config_group must be in the same
-   file (either group->file for regular groups or group->included for groups
-   whose definition is in an included file), we don't have to stash a file
-   name here for error reporting but can instead get that from the enclosing
-   group. */
-struct config_parameter {
-    char *key;
-    char *raw_value;
-    unsigned int line;          /* For error reporting. */
-    enum value_type type;
-    union {
-        bool boolean;
-        long integer;
-        double number;
-        char *string;
-        struct vector *list;
-    } value;
-};
-
-/* The type of a function that converts a raw parameter value to some other
-   data type, storing the result in its second argument and returning true on
-   success or false on failure. */
-typedef bool (*convert_func)(struct config_parameter *, const char *, void *);
-
-/* The basic element of configuration data, a group of parameters.  This is
-   the only struct that is exposed to callers, and then only as an opaque
-   data structure. */
-struct config_group {
-    char *type;
-    char *tag;
-    char *file;                 /* File in which the group starts. */
-    unsigned int line;          /* Line number where the group starts. */
-    char *included;             /* For group <file>, the included file. */
-    struct hash *params;
-
-    struct config_group *parent;
-    struct config_group *child;
-    struct config_group *next;
-};
-
-
-/* Parameter handling, used by the hash table stored in a config_group. */
-static const void *parameter_key(const void *p);
-static bool parameter_equal(const void *k, const void *p);
-static void parameter_free(void *p);
-
-/* Hash traversal function to collect parameters into a vector. */
-static void parameter_collect(void *, void *);
-
-/* Group handling. */
-static struct config_group *group_new(const char *file, unsigned int line,
-                                      const char *type, const char *tag);
-static void group_free(struct config_group *);
-static bool group_parameter_get(struct config_group *group, const char *key,
-                                void *result, convert_func convert);
-
-/* Parameter type conversion functions.  All take the parameter, the file, and
-   a pointer to where the result can be placed. */
-static bool convert_boolean(struct config_parameter *, const char *, void *);
-static bool convert_integer(struct config_parameter *, const char *, void *);
-static bool convert_string(struct config_parameter *, const char *, void *);
-
-/* File I/O.  Many other functions also manipulate config_file structs; see
-   the struct definition for notes on who's responsible for what. */
-static struct config_file *file_open(const char *filename);
-static bool file_read(struct config_file *);
-static bool file_read_more(struct config_file *, ptrdiff_t offset);
-static void file_close(struct config_file *);
-
-/* The basic lexer function.  The token is stashed in file; the return value
-   is just for convenience and duplicates that information. */
-static enum token_type token_next(struct config_file *);
-
-/* Handler functions for specific types of tokens.  These should only be
-   called by token_next. */
-static void token_simple(struct config_file *, enum token_type type);
-static void token_newline(struct config_file *);
-static void token_string(struct config_file *);
-static void token_quoted_string(struct config_file *);
-
-/* Handles whitespace for the rest of the lexer. */
-static bool token_skip_whitespace(struct config_file *);
-
-/* Handles comments for the rest of the lexer. */
-static bool token_skip_comment(struct config_file *);
-
-/* Parser functions to parse the named syntactic element. */
-static bool parse_group_contents(struct config_group *, struct config_file *);
-static enum token_type parse_parameter(struct config_group *,
-                                       struct config_file *, char *key);
-
-/* Error reporting functions. */
-static void error_bad_unquoted_char(struct config_file *, char bad);
-static void error_unexpected_token(struct config_file *,
-                                   const char *expecting);
-
-
-/*
-**  Return the key from a parameter struct, used by the hash table.
-*/
-static const void *
-parameter_key(const void *p)
-{
-    const struct config_parameter *param = p;
-
-    return param->key;
-}
-
-
-/*
-**  Check to see if a provided key matches the key of a parameter struct,
-**  used by the hash table.
-*/
-static bool
-parameter_equal(const void *k, const void *p)
-{
-    const char *key = k;
-    const struct config_parameter *param = p;
-
-    return strcmp(key, param->key) == 0;
-}
-
-
-/*
-**  Free a parameter, used by the hash table.
-*/
-static void
-parameter_free(void *p)
-{
-    struct config_parameter *param = p;
-
-    free(param->key);
-    free(param->raw_value);
-    if (param->type == VALUE_STRING) {
-        free(param->value.string);
-    } else if (param->type == VALUE_LIST) {
-        vector_free(param->value.list);
-    }
-    free(param);
-}
-
-
-/*
-**  Report an unexpected character while parsing a regular string and set the
-**  current token type to TOKEN_ERROR.
-*/
-static void
-error_bad_unquoted_char(struct config_file *file, char bad)
-{
-    warn("%s:%u: invalid character '%c' in unquoted string", file->filename,
-         file->line, bad);
-    file->token.type = TOKEN_ERROR;
-    file->error = true;
-}
-
-
-/*
-**  Report an unexpected token.  If the token is TOKEN_ERROR, don't print an
-**  additional error message.  Takes a string saying what token was expected.
-**  Sets the token to TOKEN_ERROR and frees the associated string if the
-**  current token type is TOKEN_STRING, TOKEN_QSTRING, or TOKEN_PARAM.
-*/
-static void
-error_unexpected_token(struct config_file *file, const char *expecting)
-{
-    const char *name;
-    bool string = false;
-
-    /* If the bad token type is a string, param, or quoted string, free the
-       string associated with the token to avoid a memory leak. */
-    if (file->token.type != TOKEN_ERROR) {
-        switch (file->token.type) {
-        case TOKEN_STRING:      name = "string";        string = true; break;
-        case TOKEN_QSTRING:     name = "quoted string"; string = true; break;
-        case TOKEN_PARAM:       name = "parameter";     string = true; break;
-        case TOKEN_CRLF:        name = "end of line";   break;
-        case TOKEN_LBRACE:      name = "'{'";           break;
-        case TOKEN_RBRACE:      name = "'}'";           break;
-        case TOKEN_LANGLE:      name = "'<'";           break;
-        case TOKEN_RANGLE:      name = "'>'";           break;
-        case TOKEN_LBRACKET:    name = "'['";           break;
-        case TOKEN_RBRACKET:    name = "']'";           break;
-        case TOKEN_SEMICOLON:   name = "';'";           break;
-        case TOKEN_EOF:         name = "end of file";   break;
-        default:                name = "unknown token"; break;
-        }
-        warn("%s:%u: parse error: saw %s, expecting %s", file->filename,
-             file->line, name, expecting);
-    }
-    if (string) {
-        free(file->token.string);
-        file->token.string = NULL;
-    }
-    file->token.type = TOKEN_ERROR;
-    file->error = true;
-}
-
-
-/*
-**  Handle a simple token (a single character), advancing the file->current
-**  pointer past it and setting file->token as appropriate.
-*/
-static void
-token_simple(struct config_file *file, enum token_type type)
-{
-    file->current++;
-    file->token.type = type;
-    file->token.string = NULL;
-}
-
-
-/*
-**  Handle a newline.  Skip any number of comments after the newline,
-**  including reading more data from the file if necessary, and update
-**  file->line as needed.
-*/
-static void
-token_newline(struct config_file *file)
-{
-    /* If we're actually positioned on a newline, update file->line and skip
-       over it.  Try to handle CRLF correctly, as a single line terminator
-       that only increments the line count once, while still treating either
-       CR or LF alone as line terminators in their own regard. */
-    if (*file->current == '\n') {
-        file->current++;
-        file->line++;
-    } else if (*file->current == '\r') {
-        if (file->current[1] == '\n')
-            file->current += 2;
-        else if (file->current[1] != '\0')
-            file->current++;
-        else {
-            if (!file_read(file)) {
-                file->current++;
-                return;
-            }
-            if (*file->current == '\n')
-                file->current++;
-        }
-        file->line++;
-    }
-
-    if (!token_skip_whitespace(file))
-        return;
-    while (*file->current == '#') {
-        if (!token_skip_comment(file))
-            return;
-        if (!token_skip_whitespace(file))
-            return;
-    }
-    file->token.type = TOKEN_CRLF;
-    file->token.string = NULL;
-}
-
-
-/*
-**  Handle a string.  Only some characters are allowed in an unquoted string;
-**  check that, since otherwise it could hide syntax errors.  Any whitespace
-**  ends the token.  We have to distinguish between TOKEN_PARAM and
-**  TOKEN_STRING; the former ends in a colon, unlike the latter.
-*/
-static void
-token_string(struct config_file *file)
-{
-    int i;
-    bool status;
-    ptrdiff_t offset;
-    bool done = false;
-    bool colon = false;
-
-    /* Use an offset from file->current rather than a pointer that moves
-       through the buffer, since the base of file->current can change during a
-       file_read_more() call and we don't want to have to readjust a
-       pointer.  If we have to read more, adjust our counter back one
-       character, since the nul was replaced by a new, valid character. */
-    i = 0;
-    while (!done) {
-        switch (file->current[i]) {
-        case '\t':  case '\r':  case '\n':  case ' ':   case ';':
-            done = true;
-            break;
-        case '"':   case '<':   case '>':   case '[':
-        case '\\':  case ']':   case '{':   case '}':
-            error_bad_unquoted_char(file, file->current[i]);
-            return;
-        case ':':
-            if (colon) {
-                error_bad_unquoted_char(file, file->current[i]);
-                return;
-            }
-            colon = true;
-            break;
-        case '\0':
-            offset = file->current - file->buffer;
-            status = file_read_more(file, offset);
-            if (status)
-                i--;
-            else
-                done = true;
-            break;
-        default:
-            if (colon) {
-                error_bad_unquoted_char(file, ':');
-                return;
-            }
-        }
-        if (!done)
-            i++;
-    }
-    file->token.type = colon ? TOKEN_PARAM : TOKEN_STRING;
-    file->token.string = xstrndup(file->current, i - colon);
-    file->current += i;
-}
-
-
-/*
-**  Handle a quoted string.  This token is unique as the only token that can
-**  contain whitespace, even newlines if they're escaped, so we also have to
-**  update file->line as we go.  Note that the quotes *are* included in the
-**  string we stash in file->token, since they should be part of the raw_value
-**  of a parameter.
-*/
-static void
-token_quoted_string(struct config_file *file)
-{
-    int i;
-    ptrdiff_t offset;
-    bool status;
-    bool done = false;
-
-    /* Use an offset from file->current rather than a pointer that moves
-       through the buffer, since the base of file->current can change during a
-       file_read_more() call and we don't want to have to readjust a pointer.
-       If we have to read more, adjust our counter back one character, since
-       the nul was replaced by a new, valid character. */
-    for (i = 1; !done; i++) {
-        switch (file->current[i]) {
-        case '"':
-            done = true;
-            break;
-        case '\r':
-        case '\n':
-            warn("%s:%u: no close quote seen for quoted string",
-                 file->filename, file->line);
-            file->token.type = TOKEN_ERROR;
-            file->error = true;
-            return;
-        case '\\':
-            i++;
-            if (file->current[i] == '\n')
-                file->line++;
-
-            /* CRLF should count as one line terminator.  Handle most cases of
-               that here, but the case where CR is at the end of one buffer
-               and LF at the beginning of the next has to be handled in the \0
-               case below. */
-            if (file->current[i] == '\r') {
-                file->line++;
-                if (file->current[i + 1] == '\n')
-                    i++;
-            }
-            break;
-        case '\0':
-            offset = file->current - file->buffer;
-            status = file_read_more(file, offset);
-            if (status)
-                i--;
-            else {
-                warn("%s:%u: end of file encountered while parsing quoted"
-                     " string", file->filename, file->line);
-                file->token.type = TOKEN_ERROR;
-                file->error = true;
-                return;
-            }
-
-            /* If the last character of the previous buffer was CR and the
-               first character that we just read was LF, the CR must have been
-               escaped which means that the LF is part of it, forming a CRLF
-               line terminator.  Skip over the LF. */
-            if (file->current[i] == '\r' && file->current[i + 1] == '\n')
-                i++;
-
-            break;
-        default:
-            break;
-        }
-    }
-    file->token.type = TOKEN_QSTRING;
-    file->token.string = xstrndup(file->current, i);
-    file->current += i;
-}
-
-
-/*
-**  Skip over a comment line at file->current, reading more data as necessary.
-**  Stop when an end of line is encountered, positioning file->current
-**  directly after the end of line.  Returns false on end of file or a read
-**  error, true otherwise.
-*/
-static bool
-token_skip_comment(struct config_file *file)
-{
-    char *p = file->current;
-
-    while (*p != '\0' && *p != '\n' && *p != '\r')
-        p++;
-    while (*p == '\0') {
-        if (!file_read(file))
-            return false;
-        p = file->current;
-        while (*p != '\0' && *p != '\n' && *p != '\r')
-            p++;
-    }
-
-    /* CRLF should count as a single line terminator, but it may be split
-       across a read boundary.  Try to handle that case correctly. */
-    if (*p == '\n')
-        p++;
-    else if (*p == '\r') {
-        p++;
-        if (*p == '\n')
-            p++;
-        else if (*p == '\0') {
-            if (!file_read(file))
-                return false;
-            p = file->current;
-            if (*p == '\n')
-                p++;
-        }
-    }
-    file->current = p;
-    file->line++;
-    return true;
-}
-
-/*
-**  Skip over all whitespace at file->current, reading more data as
-**  necessary.  Stop when the first non-whitespace character is encountered or
-**  at end of file, leaving file->current pointing appropriately.  Returns
-**  true if non-whitespace is found and false on end of file or a read error.
-*/
-static bool
-token_skip_whitespace(struct config_file *file)
-{
-    char *p = file->current;
-
-    while (*p == ' ' || *p == '\t')
-        p++;
-    while (*p == '\0') {
-        if (!file_read(file))
-            return false;
-        p = file->current;
-        while (*p == ' ' || *p == '\t')
-            p++;
-    }
-    file->current = p;
-    return true;
-}
-
-
-/*
-**  The basic lexer function.  Read the next token from a configuration file.
-**  Returns the token, which is also stored in file.  Lexer failures set the
-**  token to TOKEN_ERROR.
-*/
-static enum token_type
-token_next(struct config_file *file)
-{
-    /* If file->current is NULL, we've never read from the file.  There is
-       special handling for a comment at the very beginning of a file, since
-       normally we only look for comments after newline tokens.
-
-       If we do see a # at the beginning of the first line, let token_newline
-       deal with it.  That function can cope with file->current not pointing
-       at a newline.  We then return the newline token as the first token in
-       the file. */
-    if (file->current == NULL) {
-        if (!file_read(file))
-            return file->token.type;
-        if (!token_skip_whitespace(file))
-            return file->token.type;
-        if (*file->current == '#') {
-            token_newline(file);
-            return file->token.type;
-        }
-    } else {
-        if (!token_skip_whitespace(file))
-            return file->token.type;
-    }
-
-    /* Almost all of our tokens can be recognized by the first character; the
-       only exception is telling strings from parameters.  token_string
-       handles both of those and sets file->token.type appropriately.
-       Comments are handled by token_newline. */
-    switch (*file->current) {
-    case '{':   token_simple(file, TOKEN_LBRACE);       break;
-    case '}':   token_simple(file, TOKEN_RBRACE);       break;
-    case '<':   token_simple(file, TOKEN_LANGLE);       break;
-    case '>':   token_simple(file, TOKEN_RANGLE);       break;
-    case '[':   token_simple(file, TOKEN_LBRACKET);     break;
-    case ']':   token_simple(file, TOKEN_RBRACKET);     break;
-    case ';':   token_simple(file, TOKEN_SEMICOLON);    break;
-    case '\r':  token_newline(file);                    break;
-    case '\n':  token_newline(file);                    break;
-    case '"':   token_quoted_string(file);              break;
-    default:    token_string(file);                     break;
-    }
-
-    return file->token.type;
-}
-
-
-/*
-**  Open a new configuration file and return config_file representing the
-**  parse state of that file.  We assume that we don't have to make a copy of
-**  the filename argument.  Default to stdio BUFSIZ for our buffer size, since
-**  it's generally reasonably chosen with respect to disk block sizes, memory
-**  consumption, and the like.
-*/
-static struct config_file *
-file_open(const char *filename)
-{
-    struct config_file *file;
-
-    file = xmalloc(sizeof(*file));
-    file->filename = filename;
-    file->fd = open(filename, O_RDONLY);
-    if (file->fd < 0) {
-        free(file);
-        return NULL;
-    }
-    file->buffer = xmalloc(BUFSIZ);
-    file->bufsize = BUFSIZ;
-    file->current = NULL;
-    file->line = 1;
-    file->token.type = TOKEN_ERROR;
-    file->error = false;
-    return file;
-}
-
-
-/*
-**  Read some data from a configuration file, handling errors (by reporting
-**  them with warn) and returning true if there's data left and false on EOF
-**  or a read error.
-*/
-static bool
-file_read(struct config_file *file)
-{
-    ssize_t status;
-
-    status = read(file->fd, file->buffer, file->bufsize - 1);
-    if (status < 0) {
-        syswarn("%s: read error", file->filename);
-        file->token.type = TOKEN_ERROR;
-        file->error = true;
-    } else if (status == 0) {
-        file->token.type = TOKEN_EOF;
-    }
-    if (status <= 0)
-        return false;
-    file->buffer[status] = '\0';
-    file->current = file->buffer;
-
-    /* Reject nuls, since otherwise they would cause strange problems. */
-    if (strlen(file->buffer) != (size_t) status) {
-        warn("%s: invalid NUL character found in file", file->filename);
-        return false;
-    }
-    return true;
-}
-
-
-/*
-**  Read additional data from a configuration file when there's some partial
-**  data in the buffer already that we want to save.  Takes the config_file
-**  struct and an offset from file->buffer specifying the start of the data
-**  that we want to preserve.  Resizes the buffer if offset is 0.  Returns
-**  false on EOF or a read error, true otherwise.
-*/
-static bool
-file_read_more(struct config_file *file, ptrdiff_t offset)
-{
-    char *start;
-    size_t amount;
-    ssize_t status;
-
-    if (offset > 0) {
-        size_t left;
-
-        left = file->bufsize - offset - 1;
-        memmove(file->buffer, file->buffer + offset, left);
-        file->current -= offset;
-        start = file->buffer + left;
-        amount = offset;
-    } else {
-        file->buffer = xrealloc(file->buffer, file->bufsize + BUFSIZ);
-        file->current = file->buffer;
-        start = file->buffer + file->bufsize - 1;
-        amount = BUFSIZ;
-        file->bufsize += BUFSIZ;
-    }
-    status = read(file->fd, start, amount);
-    if (status < 0)
-        syswarn("%s: read error", file->filename);
-    if (status <= 0)
-        return false;
-    start[status] = '\0';
-
-    /* Reject nuls, since otherwise they would cause strange problems. */
-    if (strlen(start) != (size_t) status) {
-        warn("%s: invalid NUL character found in file", file->filename);
-        return false;
-    }
-    return true;
-}
-
-
-/*
-**  Close a file and free the resources associated with it.
-*/
-static void
-file_close(struct config_file *file)
-{
-    close(file->fd);
-    free(file->buffer);
-    free(file);
-}
-
-
-/*
-**  Given a config_group with the type and tag already filled in and a
-**  config_file with the buffer positioned after the opening brace of the
-**  group, read and add parameters to the group until encountering a close
-**  brace.  Returns true on a successful parse, false on an error that
-**  indicates the group should be discarded.
-*/
-static bool
-parse_group_contents(struct config_group *group, struct config_file *file)
-{
-    enum token_type token;
-
-    token = token_next(file);
-    while (!file->error) {
-        switch (token) {
-        case TOKEN_PARAM:
-            token = parse_parameter(group, file, file->token.string);
-            while (token == TOKEN_CRLF || token == TOKEN_SEMICOLON)
-                token = token_next(file);
-            break;
-        case TOKEN_CRLF:
-            token = token_next(file);
-            break;
-        case TOKEN_EOF:
-            return true;
-        default:
-            error_unexpected_token(file, "parameter");
-            break;
-        }
-    }
-    return false;
-}
-
-
-/*
-**  Parse a parameter.  Takes the group we're currently inside, the
-**  config_file parse state, and the key of the parameter.  Returns the next
-**  token after the parameter, and also checks to make sure that it's
-**  something legal (end of line, end of file, or a semicolon).
-*/
-static enum token_type
-parse_parameter(struct config_group *group, struct config_file *file,
-                char *key)
-{
-    enum token_type token;
-
-    token = token_next(file);
-    if (token == TOKEN_STRING || token == TOKEN_QSTRING) {
-        struct config_parameter *param;
-        unsigned int line;
-        char *value;
-
-        /* Before storing the parameter, check to make sure that the next
-           token is valid.  If it isn't, chances are high that the user has
-           tried to set a parameter to a value containing spaces without
-           quoting the value. */
-        value = file->token.string;
-        line = file->line;
-        token = token_next(file);
-        switch (token) {
-        default:
-            error_unexpected_token(file, "semicolon or newline");
-            free(value);
-            break;
-        case TOKEN_CRLF:
-        case TOKEN_SEMICOLON:
-        case TOKEN_EOF:
-            param = xmalloc(sizeof(*param));
-            param->key = key;
-            param->raw_value = value;
-            param->type = VALUE_UNKNOWN;
-            param->line = line;
-            if (!hash_insert(group->params, key, param)) {
-                warn("%s:%u: duplicate parameter %s", file->filename, line,
-                     key);
-                free(param->raw_value);
-                free(param->key);
-                free(param);
-            }
-            return token;
-        }
-    } else {
-        error_unexpected_token(file, "parameter value");
-    }
-
-    /* If we fell through, we encountered some sort of error.  Free allocated
-       memory and return an error token. */
-    free(key);
-    return TOKEN_ERROR;
-}
-
-
-/*
-**  Allocate a new config_group and set the initial values of all of the
-**  struct members.
-*/
-static struct config_group *
-group_new(const char *file, unsigned int line, const char *type,
-          const char *tag)
-{
-    struct config_group *group;
-
-    group = xmalloc(sizeof(*group));
-    group->type = xstrdup(type);
-    group->tag = (tag == NULL) ? NULL : xstrdup(tag);
-    group->file = xstrdup(file);
-    group->included = NULL;
-    group->line = line;
-    group->params = hash_create(4, hash_string, parameter_key,
-                                parameter_equal, parameter_free);
-    group->parent = NULL;
-    group->child = NULL;
-    group->next = NULL;
-    return group;
-}
-
-
-/*
-**  Free a config_group and all associated storage.
-*/
-static void
-group_free(struct config_group *group)
-{
-    free(group->type);
-    if (group->tag != NULL)
-        free(group->tag);
-    free(group->file);
-    if (group->included != NULL)
-        free(group->included);
-    hash_free(group->params);
-    free(group);
-}
-
-
-/*
-**  Accessor function for the group type.
-*/
-const char *
-config_group_type(struct config_group *group)
-{
-    return group->type;
-}
-
-
-/*
-**  Accessor function for the group tag.
-*/
-const char *
-config_group_tag(struct config_group *group)
-{
-    return group->tag;
-}
-
-
-/*
-**  Parse a configuration file, returning the config_group that's the root of
-**  the tree represented by that file (and any other files that it includes).
-**  Returns NULL on a parse failure.
-*/
-struct config_group *
-config_parse_file(const char *filename, ...)
-{
-    struct config_group *group;
-    struct config_file *file;
-    bool success;
-
-    file = file_open(filename);
-    if (file == NULL) {
-        syswarn("open of %s failed", filename);
-        return NULL;
-    }
-    group = group_new(filename, 1, "GLOBAL", NULL);
-    success = parse_group_contents(group, file);
-    file_close(file);
-    return success ? group : NULL;
-}
-
-
-/*
-**  Given a config_group representing the root of a configuration structure,
-**  recursively free the entire structure.
-*/
-void
-config_free(struct config_group *group)
-{
-    group_free(group);
-}
-
-
-/*
-**  Convert a given parameter value to a boolean, returning true if successful
-**  and false otherwise.
-*/
-static bool
-convert_boolean(struct config_parameter *param, const char *file,
-                void *result)
-{
-    static const char *const truevals[] = { "yes", "on", "true", NULL };
-    static const char *const falsevals[] = { "no", "off", "false", NULL };
-    bool *value = result;
-    int i;
-
-    if (param->type == VALUE_BOOL) {
-        *value = param->value.boolean;
-        return true;
-    } else if (param->type != VALUE_UNKNOWN) {
-        warn("%s:%u: %s is not a boolean", file, param->line, param->key);
-        return false;
-    }
-    param->type = VALUE_BOOL;
-    for (i = 0; truevals[i] != NULL; i++)
-        if (strcmp(param->raw_value, truevals[i]) == 0) {
-            param->value.boolean = true;
-            *value = true;
-            return true;
-        }
-    for (i = 0; falsevals[i] != NULL; i++)
-        if (strcmp(param->raw_value, falsevals[i]) == 0) {
-            param->value.boolean = false;
-            *value = false;
-            return true;
-        }
-    param->type = VALUE_INVALID;
-    warn("%s:%u: %s is not a boolean", file, param->line, param->key);
-    return false;
-}
-
-
-/*
-**  Convert a given parameter value to an integer, returning true if
-**  successful and false otherwise.
-*/
-static bool
-convert_integer(struct config_parameter *param, const char *file,
-                void *result)
-{
-    long *value = result;
-    char *p;
-
-    if (param->type == VALUE_INTEGER) {
-        *value = param->value.integer;
-        return true;
-    } else if (param->type != VALUE_UNKNOWN) {
-        warn("%s:%u: %s is not an integer", file, param->line, param->key);
-        return false;
-    }
-
-    /* Do a syntax check even though strtol would do some of this for us,
-       since otherwise some syntax errors may go silently undetected. */
-    p = param->raw_value;
-    if (*p == '-')
-        p++;
-    for (; *p != '\0'; p++)
-        if (*p < '0' || *p > '9')
-            break;
-    if (*p != '\0') {
-        warn("%s:%u: %s is not an integer", file, param->line, param->key);
-        return false;
-    }
-
-    /* Do the actual conversion with strtol. */
-    errno = 0;
-    param->value.integer = strtol(param->raw_value, NULL, 10);
-    if (errno != 0) {
-        warn("%s:%u: %s doesn't convert to an integer", file, param->line,
-             param->key);
-        return false;
-    }
-    *value = param->value.integer;
-    param->type = VALUE_INTEGER;
-    return true;
-}
-
-
-/*
-**  Convert a parameter value to a string, interpreting it as a quoted string,
-**  and returning true if successful and false otherwise.  Does none of the
-**  initial type checking, since convert_string should have already done that.
-*/
-static bool
-convert_string_quoted(struct config_parameter *param, const char *file,
-                      void *result)
-{
-    const char **value = result;
-    size_t length;
-    char *src, *dest;
-
-    length = strlen(param->raw_value) - 2;
-    param->value.string = xmalloc(length + 1);
-    src = param->raw_value + 1;
-    dest = param->value.string;
-    for (; *src != '"' && *src != '\0'; src++) {
-        if (*src != '\\') {
-            *dest++ = *src;
-        } else {
-            src++;
-
-            /* This should implement precisely the semantics of backslash
-               escapes in quoted strings in C. */
-            switch (*src) {
-            case 'a':   *dest++ = '\a'; break;
-            case 'b':   *dest++ = '\b'; break;
-            case 'f':   *dest++ = '\f'; break;
-            case 'n':   *dest++ = '\n'; break;
-            case 'r':   *dest++ = '\r'; break;
-            case 't':   *dest++ = '\t'; break;
-            case 'v':   *dest++ = '\v'; break;
-
-            case '\n':  break;  /* Escaped newlines disappear. */
-
-            case '\\':
-            case '\'':
-            case '"':
-            case '?':
-                *dest++ = *src;
-                break;
-
-            case '\0':
-                /* Should never happen; the tokenizer should catch this. */
-                warn("%s:%u: unterminated string", file, param->line);
-                goto fail;
-
-            default:
-                /* FIXME: \<octal>, \x, \u, and \U not yet implemented; the
-                   last three could use the same basic code.  Think about
-                   whether the escape should generate a single 8-bit character
-                   or a UTF-8 encoded character; maybe the first two generate
-                   the former and \u and \U generate the latter? */
-                warn("%s:%u: unrecognized escape '\\%c'", file, param->line,
-                     *src);
-                goto fail;
-            }
-        }
-    }
-    *dest = '\0';
-
-    /* The tokenizer already checked this for most cases but could miss the
-       case where the final quote mark is escaped with a backslash. */
-    if (*src != '"') {
-        warn("%s:%u: unterminated string (no closing quote)", file,
-             param->line);
-        goto fail;
-    }
-
-    param->type = VALUE_STRING;
-    *value = param->value.string;
-    return true;
-
- fail:
-    free(param->value.string);
-    return false;
-}
-
-
-/*
-**  Convert a given parameter value to a string, returning true if successful
-**  and false otherwise.
-*/
-static bool
-convert_string(struct config_parameter *param, const char *file, void *result)
-{
-    const char **value = result;
-
-    if (param->type == VALUE_STRING) {
-        *value = param->value.string;
-        return true;
-    } else if (param->type != VALUE_UNKNOWN) {
-        warn("%s:%u: %s is not an string", file, param->line, param->key);
-        return false;
-    }
-
-    if (*param->raw_value == '"') {
-        return convert_string_quoted(param, file, result);
-    } else {
-        param->value.string = xstrdup(param->raw_value);
-        param->type = VALUE_STRING;
-        *value = param->value.string;
-        return true;
-    }
-}
-
-
-/*
-**  Given a group, query it for the given parameter and then when the
-**  parameter is found, check to see if it's already marked invalid.  If so,
-**  fail quietly; otherwise, hand it off to the conversion function to do
-**  type-specific work, returning the result.  Returns true if the parameter
-**  is found in the group or one of its parents and convert can successfully
-**  convert the raw value and put it in result, false otherwise (either for
-**  the parameter not being found or for it being the wrong type).
-*/
-static bool
-group_parameter_get(struct config_group *group, const char *key, void *result,
-                    convert_func convert)
-{
-    struct config_group *current = group;
-
-    while (current != NULL) {
-        struct config_parameter *param;
-
-        param = hash_lookup(group->params, key);
-        if (param != NULL) {
-            if (param->type == VALUE_INVALID)
-                return false;
-            else
-                return (*convert)(param, group->file, result);
-        }
-        current = group->parent;
-    }
-    return false;
-}
-
-
-/*
-**  All of the config_param_* functions do the following:
-**
-**  Given a group, query it for the given parameter, interpreting its value as
-**  the appropriate type and returning it in the third argument.  Returns true
-**  on success, false on failure (such as the parameter not being set or an
-**  error), and report errors via warn.
-*/
-bool
-config_param_boolean(struct config_group *group, const char *key,
-                     bool *result)
-{
-    return group_parameter_get(group, key, result, convert_boolean);
-}
-
-bool
-config_param_integer(struct config_group *group, const char *key,
-                     long *result)
-{
-    return group_parameter_get(group, key, result, convert_integer);
-}
-
-bool
-config_param_string(struct config_group *group, const char *key,
-                    const char **result)
-{
-    return group_parameter_get(group, key, result, convert_string);
-}
-
-
-/*
-**  A hash traversal function to add all parameter keys to the vector provided
-**  as the second argument.
-*/
-static void
-parameter_collect(void *element, void *cookie)
-{
-    struct config_parameter *param = element;
-    struct vector *params = cookie;
-
-    vector_add(params, param->key);
-}
-
-
-/*
-**  Returns a newly allocated vector of all of the config parameters in a
-**  group, including the inherited ones (not implemented yet).
-*/
-struct vector *
-config_params(struct config_group *group)
-{
-    struct vector *params;
-    size_t size;
-
-    /* Size the vector, which we can do accurately for now. */
-    params = vector_new();
-    size = hash_count(group->params);
-    vector_resize(params, size);
-
-    /* Now, walk the hash to build the vector of params. */
-    hash_traverse(group->params, parameter_collect, params);
-    return params;
-}
-
-
-/*
-**  Report an error in a given parameter.  Used so that the file and line
-**  number can be included in the error message.
-*/
-void
-config_error_param(struct config_group *group, const char *key,
-                   const char *fmt, ...)
-{
-    va_list args;
-    ssize_t length;
-    char *message, *file;
-    struct config_parameter *param;
-
-    va_start(args, fmt);
-    length = vsnprintf(NULL, 0, fmt, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    message = xmalloc(length + 1);
-    va_start(args, fmt);
-    vsnprintf(message, length + 1, fmt, args);
-    va_end(args);
-
-    param = hash_lookup(group->params, key);
-    if (param == NULL)
-        warn("%s", message);
-    else {
-        file = (group->included != NULL ? group->included : group->file);
-        warn("%s:%u: %s", file, param->line, message);
-    }
-
-    free(message);
-}
-
-
-/*
-**  Stubs for functions not yet implemented.
-*/
-struct config_group *
-config_find_group(struct config_group *group UNUSED, const char *type UNUSED)
-{
-    return NULL;
-}
-
-struct config_group *
-config_next_group(struct config_group *group UNUSED)
-{
-    return NULL;
-}
-
-bool
-config_param_real(struct config_group *group UNUSED, const char *key UNUSED,
-                  double *result UNUSED)
-{
-    return false;
-}
-
-bool
-config_param_list(struct config_group *group UNUSED, const char *key UNUSED,
-                  struct vector *result UNUSED)
-{
-    return false;
-}
-
-void
-config_error_group(struct config_group *group UNUSED, const char *fmt UNUSED,
-                   ...)
-{
-}
diff --git a/lib/daemonize.c b/lib/daemonize.c
deleted file mode 100644 (file)
index 689bccd..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*  $Id: daemonize.c 6395 2003-07-12 19:13:49Z rra $
-**
-**  Become a long-running daemon.
-**
-**  Usage:
-**
-**      daemonize(path);
-**
-**  Performs all of the various system-specific stuff required to become a
-**  long-running daemon.  Also chdir to the provided path (which is where
-**  core dumps will go on most systems).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-void
-daemonize(const char *path)
-{
-    int status;
-    int fd;
-
-    /* Fork and exit in the parent to disassociate from the current process
-       group and become the leader of a new process group. */
-    status = fork();
-    if (status < 0)
-        sysdie("cant fork");
-    else if (status > 0)
-        _exit(0);
-
-    /* setsid() should take care of disassociating from the controlling
-       terminal, and FreeBSD at least doesn't like TIOCNOTTY if you don't
-       already have a controlling terminal.  So only use the older TIOCNOTTY
-       method if setsid() isn't available. */
-#if HAVE_SETSID
-    if (setsid() < 0)
-        syswarn("cant become session leader");
-#elif defined(TIOCNOTTY)
-    fd = open("/dev/tty", O_RDWR);
-    if (fd >= 0) {
-        if (ioctl(fd, TIOCNOTTY, NULL) < 0)
-            syswarn("cant disassociate from the terminal");
-        close(fd);
-    }
-#endif /* defined(TIOCNOTTY) */
-
-    if (chdir(path) < 0)
-        syswarn("cant chdir to %s", path);
-
-    fd = open("/dev/null", O_RDWR, 0);
-    if (fd != -1) {
-       dup2(fd, STDIN_FILENO);
-       dup2(fd, STDOUT_FILENO);
-       dup2(fd, STDERR_FILENO);
-       if (fd > 2)
-           close(fd);
-    }
-}
diff --git a/lib/date.c b/lib/date.c
deleted file mode 100644 (file)
index 3296b3a..0000000
+++ /dev/null
@@ -1,637 +0,0 @@
-/*  $Id: date.c 7136 2005-03-11 19:18:27Z rra $
-**
-**  Date parsing and conversion routines.
-**
-**  Provides various date parsing and conversion routines, including
-**  generating Date headers for posted articles.  Note that the parsedate
-**  parser is separate from this file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <time.h>
-
-#include "libinn.h"
-
-/*
-**  Time constants.
-**
-**  Do not translate these names.  RFC 822 by way of RFC 1036 requires that
-**  weekday and month names *not* be translated.  This is why we use static
-**  tables rather than strftime for building dates, to avoid locale
-**  interference.
-*/
-
-static const char WEEKDAY[7][4] = {
-    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
-static const char MONTH[12][4] = {
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
-    "Nov", "Dec"
-};
-
-/* Number of days in a month. */
-static const int MONTHDAYS[] = {
-    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/* Non-numeric time zones.  Supporting these is required to support the
-   obsolete date format of RFC 2822.  The military time zones are handled
-   separately. */
-static const struct {
-    const char name[4];
-    long offset;
-} ZONE_OFFSET[] = {
-    { "UT", 0 },                { "GMT", 0 },
-    { "EDT", -4 * 60 * 60 },    { "EST", -5 * 60 * 60 },
-    { "CDT", -5 * 60 * 60 },    { "CST", -6 * 60 * 60 },
-    { "MDT", -6 * 60 * 60 },    { "MST", -7 * 60 * 60 },
-    { "PDT", -7 * 60 * 60 },    { "PST", -8 * 60 * 60 },
-};
-
-
-/*
-**  Time parsing macros.
-*/
-
-/* Whether a given year is a leap year. */
-#define ISLEAP(year) \
-    (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
-
-
-/*
-**  RFC 2822 date parsing rules.
-*/
-
-/* The data structure to store a rule.  The interpretation of the other fields
-   is based on the value of type.  For NUMBER, read between min and max
-   characters and convert to a number.  For LOOKUP, look for max characters
-   and find that string in the provided table (with size elements).  For
-   DELIM, just make sure that we see the character stored in delimiter. */
-struct rule {
-    enum {
-        TYPE_NUMBER,
-        TYPE_LOOKUP,
-        TYPE_DELIM
-    } type;
-    char delimiter;
-    const char (*table)[4];
-    size_t size;
-    int min;
-    int max;
-};
-
-
-/*
-**  Given a time as a time_t, return the offset in seconds of the local time
-**  zone from UTC at that time (adding the offset to UTC time yields local
-**  time).  If the second argument is true, the time represents the current
-**  time and in that circumstance we can assume that timezone/altzone are
-**  correct.  (We can't for arbitrary times in the past.)
-*/
-static long
-local_tz_offset(time_t date, bool current UNUSED)
-{
-    struct tm *tm;
-#if !HAVE_TM_GMTOFF
-    struct tm local, gmt;
-    long offset;
-#endif
-
-    tm = localtime(&date);
-
-#if !HAVE_TM_GMTOFF && HAVE_VAR_TIMEZONE
-    if (current)
-        return (tm->tm_isdst > 0) ? -altzone : -timezone;
-#endif
-
-#if HAVE_TM_GMTOFF
-    return tm->tm_gmtoff;
-#else
-    /* We don't have any easy returnable value, so we call both localtime
-       and gmtime and calculate the difference.  Assume that local time is
-       never more than 24 hours away from UTC and ignore seconds. */
-    local = *tm;
-    tm = gmtime(&date);
-    gmt = *tm;
-    offset = local.tm_yday - gmt.tm_yday;
-    if (offset < -1) {
-        /* Local time is in the next year. */
-        offset = 24;
-    } else if (offset > 1) {
-        /* Local time is in the previous year. */
-        offset = -24;
-    } else {
-        offset *= 24;
-    }
-    offset += local.tm_hour - gmt.tm_hour;
-    offset *= 60;
-    offset += local.tm_min - gmt.tm_min;
-    return offset * 60;
-#endif /* !HAVE_TM_GMTOFF */
-}
-
-
-/*
-**  Given a time_t, a flag saying whether to use local time, a buffer, and
-**  the length of the buffer, write the contents of a valid RFC 2822 / RFC
-**  1036 Date header into the buffer (provided it's long enough).  Returns
-**  true on success, false if the buffer is too long.  Use snprintf rather
-**  than strftime to be absolutely certain that locales don't result in the
-**  wrong output.  If the time is -1, obtain and use the current time.
-*/
-bool
-makedate(time_t date, bool local, char *buff, size_t buflen)
-{
-    time_t realdate;
-    struct tm *tmp_tm;
-    struct tm tm;
-    long tz_offset;
-    int tz_hour_offset, tz_min_offset, tz_sign;
-    size_t date_length;
-    const char *tz_name;
-
-    /* Make sure the buffer is large enough.  A complete RFC 2822 date with
-       spaces wherever FWS is required and the optional weekday takes:
-
-                    1         2         3
-           1234567890123456789012345678901
-           Sat, 31 Aug 2002 23:45:18 +0000
-
-       31 characters, plus another character for the trailing nul.  The buffer
-       will need to have another six characters of space to get the optional
-       trailing time zone comment. */
-    if (buflen < 32)
-        return false;
-
-    /* Get the current time if the provided time is -1. */
-    realdate = (date == (time_t) -1) ? time(NULL) : date;
-
-    /* RFC 2822 says the timezone offset is given as [+-]HHMM, so we have to
-       separate the offset into a sign, hours, and minutes.  Dividing the
-       offset by 36 looks like it works, but will fail for any offset that
-       isn't an even number of hours, and there are half-hour timezones. */
-    if (local) {
-        tmp_tm = localtime(&realdate);
-        tm = *tmp_tm;
-        tz_offset = local_tz_offset(realdate, date == (time_t) -1);
-        tz_sign = (tz_offset < 0) ? -1 : 1;
-        tz_offset *= tz_sign;
-        tz_hour_offset = tz_offset / 3600;
-        tz_min_offset = (tz_offset % 3600) / 60;
-    } else {
-        tmp_tm = gmtime(&realdate);
-        tm = *tmp_tm;
-        tz_sign = 1;
-        tz_hour_offset = 0;
-        tz_min_offset = 0;
-    }
-
-    /* tz_min_offset cannot be larger than 60 (by basic mathematics).  If
-       through some insane circumtances, tz_hour_offset would be larger,
-       reject the time as invalid rather than generate an invalid date. */
-    if (tz_hour_offset > 24)
-        return false;
-
-    /* Generate the actual date string, sans the trailing time zone comment
-       but with the day of the week and the seconds (both of which are
-       optional in the standard). */
-    snprintf(buff, buflen, "%3.3s, %d %3.3s %d %02d:%02d:%02d %c%02d%02d",
-             &WEEKDAY[tm.tm_wday][0], tm.tm_mday, &MONTH[tm.tm_mon][0],
-             1900 + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec,
-             (tz_sign > 0) ? '+' : '-', tz_hour_offset, tz_min_offset);
-    date_length = strlen(buff);
-
-    /* Now, get a pointer to the time zone abbreviation, and if there is
-       enough room in the buffer, add it to the end of the date string as a
-       comment. */
-    if (!local) {
-        tz_name = "UTC";
-    } else {
-#if HAVE_TM_ZONE
-        tz_name = tm.tm_zone;
-#elif HAVE_VAR_TZNAME
-        tz_name = tzname[(tm.tm_isdst > 0) ? 1 : 0];
-#else
-        tz_name = NULL;
-#endif
-    }
-    if (tz_name != NULL && date_length + 4 + strlen(tz_name) <= buflen) {
-        snprintf(buff + date_length, buflen - date_length, " (%s)", tz_name);
-    }
-    return true;
-}
-
-
-/*
-**  Given a struct tm representing a calendar time in UTC, convert it to
-**  seconds since epoch.  Returns (time_t) -1 if the time is not
-**  convertable.  Note that this function does not canonicalize the provided
-**  struct tm, nor does it allow out of range values or years before 1970.
-*/
-static time_t
-mktime_utc(const struct tm *tm)
-{
-    time_t result = 0;
-    int i;
-
-    /* We do allow some ill-formed dates, but we don't do anything special
-       with them and our callers really shouldn't pass them to us.  Do
-       explicitly disallow the ones that would cause invalid array accesses
-       or other algorithm problems. */
-    if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 70)
-        return (time_t) -1;
-
-    /* Convert to a time_t. */
-    for (i = 1970; i < tm->tm_year + 1900; i++)
-        result += 365 + ISLEAP(i);
-    for (i = 0; i < tm->tm_mon; i++)
-        result += MONTHDAYS[i];
-    if (tm->tm_mon > 1 && ISLEAP(tm->tm_year + 1900))
-        result++;
-    result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
-    result = 60 * result + tm->tm_min;
-    result = 60 * result + tm->tm_sec;
-    return result;
-}
-
-
-/*
-**  Check the ranges of values in a struct tm to make sure that the date was
-**  well-formed.  Assumes that the year has already been correctly set to
-**  something (but may be before 1970).
-*/
-static bool
-valid_tm(const struct tm *tm)
-{
-    if (tm->tm_sec > 60 || tm->tm_min > 59 || tm->tm_hour > 23)
-        return false;
-    if (tm->tm_mday < 1 || tm->tm_mon < 0 || tm->tm_mon > 11)
-        return false;
-
-    /* Make sure that the day isn't past the end of the month, allowing for
-       leap years. */
-    if (tm->tm_mday > MONTHDAYS[tm->tm_mon]
-        && (tm->tm_mon != 1 || tm->tm_mday > 29
-            || !ISLEAP(tm->tm_year + 1900)))
-        return false;
-
-    /* We can't handle years before 1970. */
-    if (tm->tm_year < 70)
-        return false;
-
-    return true;
-}
-
-
-/*
-**  Parse a date in the format used in NNTP commands such as NEWGROUPS and
-**  NEWNEWS.  The first argument is a string of the form YYYYMMDD and the
-**  second a string of the form HHMMSS.  The third argument is a boolean
-**  flag saying whether the date is specified in local time; if false, the
-**  date is assumed to be in UTC.  Returns the time_t corresponding to the
-**  given date and time or (time_t) -1 in the event of an error.
-*/
-time_t
-parsedate_nntp(const char *date, const char *hour, bool local)
-{
-    const char *p;
-    size_t datelen;
-    time_t now, result;
-    struct tm tm;
-    struct tm *current;
-    int century;
-
-    /* Accept YYMMDD and YYYYMMDD.  The first is what RFC 977 requires.  The
-       second is what the revision of RFC 977 will require. */
-    datelen = strlen(date);
-    if ((datelen != 6 && datelen != 8) || strlen(hour) != 6)
-        return (time_t) -1;
-    for (p = date; *p; p++)
-        if (!CTYPE(isdigit, *p))
-            return (time_t) -1;
-    for (p = hour; *p; p++)
-        if (!CTYPE(isdigit, *p))
-            return (time_t) -1;
-
-    /* Parse the date into a struct tm, skipping over the century part of
-       the year, if any.  We'll deal with it in a moment. */
-    tm.tm_isdst = -1;
-    p = date + datelen - 6;
-    tm.tm_year = (p[0] - '0') * 10 + p[1] - '0';
-    tm.tm_mon  = (p[2] - '0') * 10 + p[3] - '0' - 1;
-    tm.tm_mday = (p[4] - '0') * 10 + p[5] - '0';
-    p = hour;
-    tm.tm_hour = (p[0] - '0') * 10 + p[1] - '0';
-    tm.tm_min  = (p[2] - '0') * 10 + p[3] - '0';
-    tm.tm_sec  = (p[4] - '0') * 10 + p[5] - '0';
-
-    /* Four-digit years are the easy case.
-
-       For two-digit years, RFC 977 says "The closest century is assumed as
-       part of the year (i.e., 86 specifies 1986, 30 specifies 2030, 99 is
-       1999, 00 is 2000)."  draft-ietf-nntpext-base-10.txt simplifies this
-       considerably and is what we implement:
-
-         If the first two digits of the year are not specified, the year is
-         to be taken from the current century if YY is smaller than or equal
-         to the current year, otherwise the year is from the previous
-         century.
-
-       This implementation assumes "current year" means the last two digits
-       of the current year.  Note that this algorithm interacts poorly with
-       clients with a slightly fast clock around the turn of a century, as
-       it may send 00 for the year when the year on the server is still xx99
-       and have it taken to be 99 years in the past.  But 2000 has come and
-       gone, and by 2100 news clients *really* should have started using UTC
-       for everything like the new draft recommends. */
-    if (datelen == 8) {
-        tm.tm_year += (date[0] - '0') * 1000 + (date[1] - '0') * 100;
-        tm.tm_year -= 1900;
-    } else {
-        now = time(NULL);
-        current = local ? localtime(&now) : gmtime(&now);
-        century = current->tm_year / 100;
-        if (tm.tm_year > current->tm_year % 100)
-            century--;
-        tm.tm_year += century * 100;
-    }
-
-    /* Ensure that all of the date components are within valid ranges. */
-    if (!valid_tm(&tm))
-        return (time_t) -1;
-
-    /* tm contains the broken-down date; convert it to a time_t.  mktime
-       assumes the supplied struct tm is in the local time zone; if given a
-       time in UTC, use our own routine instead. */
-    result = local ? mktime(&tm) : mktime_utc(&tm);
-    return result;
-}
-
-
-/*
-**  Skip any amount of CFWS (comments and folding whitespace), the RFC 2822
-**  grammar term for whitespace, CRLF pairs, and possibly nested comments that
-**  may contain escaped parens.  We also allow simple newlines since we don't
-**  always deal with wire-format messages.  Note that we do not attempt to
-**  ensure that CRLF or a newline is followed by whitespace.  Returns the new
-**  position of the pointer.
-*/
-static const char *
-skip_cfws(const char *p)
-{
-    int nesting = 0;
-
-    for (; *p != '\0'; p++) {
-        switch (*p) {
-        case ' ':
-        case '\t':
-        case '\n':
-            break;
-        case '\r':
-            if (p[1] != '\n')
-                return p;
-            p++;
-            break;
-        case '(':
-            nesting++;
-            break;
-        case ')':
-            if (nesting == 0)
-                return p;
-            nesting--;
-            break;
-        case '\\':
-            if (nesting == 0 || p[1] == '\0')
-                return p;
-            p++;
-            break;
-        default:
-            if (nesting == 0)
-                return p;
-            break;
-        }
-    }
-    return p;
-}
-
-
-/*
-**  Parse a single number.  Takes the parsing rule that we're applying and
-**  returns a pointer to the new position of the parse stream.  If there
-**  aren't enough digits, return NULL.
-*/
-static const char *
-parse_number(const char *p, const struct rule *rule, int *value)
-{
-    int count;
-
-    *value = 0;
-    for (count = 0; *p != '\0' && count < rule->max; p++, count++) {
-        if (*p < '0' || *p > '9')
-            break;
-        *value = *value * 10 + (*p - '0');
-    }
-    if (count < rule->min || count > rule->max)
-        return NULL;
-    return p;
-}
-
-
-/*
-**  Parse a single string value that has to be done via table lookup.  Takes
-**  the parsing rule that we're applying.  Puts the index number of the string
-**  if found into the value pointerand returns the new position of the string,
-**  or NULL if the string could not be found in the table.
-*/
-static const char *
-parse_lookup(const char *p, const struct rule *rule, int *value)
-{
-    size_t i;
-
-    for (i = 0; i < rule->size; i++)
-        if (strncasecmp(rule->table[i], p, rule->max) == 0) {
-            p += rule->max;
-            *value = i;
-            return p;
-        }
-    return NULL;
-}
-
-
-/*
-**  Apply a set of date parsing rules to a string.  Returns the new position
-**  in the parse string if this succeeds and NULL if it fails.  As part of the
-**  parse, stores values into the value pointer in the array of rules that was
-**  passed in.  Takes an array of rules and a count of rules in that array.
-*/
-static const char *
-parse_by_rule(const char *p, const struct rule rules[], size_t count,
-              int *values)
-{
-    size_t i;
-    const struct rule *rule;
-
-    for (i = 0; i < count; i++) {
-        rule = &rules[i];
-
-        switch (rule->type) {
-        case TYPE_DELIM:
-            if (*p != rule->delimiter)
-                return NULL;
-            p++;
-            break;
-        case TYPE_LOOKUP:
-            p = parse_lookup(p, rule, &values[i]);
-            if (p == NULL)
-                return NULL;
-            break;
-        case TYPE_NUMBER:
-            p = parse_number(p, rule, &values[i]);
-            if (p == NULL)
-                return NULL;
-            break;
-        }
-
-        p = skip_cfws(p);
-    }
-    return p;
-}
-
-
-/*
-**  Parse a legacy time zone.  This uses the parsing rules in RFC 2822,
-**  including assigning an offset of 0 to all single-character military time
-**  zones due to their ambiguity in practice.  Returns the new position in the
-**  parse stream or NULL if we failed to parse the zone.
-*/
-static const char *
-parse_legacy_timezone(const char *p, long *offset)
-{
-    const char *end;
-    size_t max, i;
-
-    for (end = p; *end != '\0' && !CTYPE(isspace, *end); end++)
-        ;
-    if (end == p)
-        return NULL;
-    max = end - p;
-    for (i = 0; i < ARRAY_SIZE(ZONE_OFFSET); i++)
-        if (strncasecmp(ZONE_OFFSET[i].name, p, max) == 0) {
-            p += strlen(ZONE_OFFSET[i].name);
-            *offset = ZONE_OFFSET[i].offset;
-            return p;
-        }
-    if (max == 1 && CTYPE(isalpha, *p) && *p != 'J' && *p != 'j') {
-        *offset = 0;
-        return p + 1;
-    }
-    return NULL;
-}
-
-
-/*
-**  Parse an RFC 2822 date, accepting the normal and obsolete syntax.  Takes a
-**  pointer to the beginning of the date and the length.  Returns the
-**  translated time in seconds since epoch, or (time_t) -1 on error.
-*/
-time_t
-parsedate_rfc2822(const char *date)
-{
-    const char *p;
-    int zone_sign;
-    long zone_offset;
-    struct tm tm;
-    int values[8];
-    time_t result;
-
-    /* The basic rules.  Note that we don't bother to check whether the day of
-       the week is accurate or not. */
-    static const struct rule base_rule[] = {
-        { TYPE_LOOKUP, 0,   WEEKDAY, 7,  3, 3 },
-        { TYPE_DELIM,  ',', NULL,    0,  1, 1 },
-        { TYPE_NUMBER, 0,   NULL,    0,  1, 2 },
-        { TYPE_LOOKUP, 0,   MONTH,   12, 3, 3 },
-        { TYPE_NUMBER, 0,   NULL,    0,  2, 4 },
-        { TYPE_NUMBER, 0,   NULL,    0,  2, 2 },
-        { TYPE_DELIM,  ':', NULL,    0,  1, 1 },
-        { TYPE_NUMBER, 0,   NULL,    0,  2, 2 }
-    };
-
-    /* Optional seconds at the end of the time. */
-    static const struct rule seconds_rule[] = {
-        { TYPE_DELIM,  ':', NULL,    0,  1, 1 },
-        { TYPE_NUMBER, 0,   NULL,    0,  2, 2 }
-    };
-
-    /* Numeric time zone. */
-    static const struct rule zone_rule[] = {
-        { TYPE_NUMBER, 0,   NULL,    0,  4, 4 }
-    };
-
-    /* Start with a clean slate. */
-    memset(&tm, 0, sizeof(struct tm));
-    memset(values, 0, sizeof(values));
-
-    /* Parse the base part of the date.  The initial day of the week is
-       optional. */
-    p = skip_cfws(date);
-    if (CTYPE(isalpha, *p))
-        p = parse_by_rule(p, base_rule, ARRAY_SIZE(base_rule), values);
-    else
-        p = parse_by_rule(p, base_rule + 2, ARRAY_SIZE(base_rule) - 2,
-                          values + 2);
-    if (p == NULL)
-        return (time_t) -1;
-
-    /* Stash the results into a struct tm.  Values are associated with the
-       rule number of the same index. */
-    tm.tm_mday = values[2];
-    tm.tm_mon = values[3];
-    tm.tm_year = values[4];
-    tm.tm_hour = values[5];
-    tm.tm_min = values[7];
-
-    /* Parse seconds if they're present. */
-    if (*p == ':') {
-        p = parse_by_rule(p, seconds_rule, ARRAY_SIZE(seconds_rule), values);
-        if (p == NULL)
-            return (time_t) -1;
-        tm.tm_sec = values[1];
-    }
-
-    /* Time zone.  Unfortunately this is weird enough that we can't use nice
-       parsing rules for it. */
-    if (*p == '-' || *p == '+') {
-        zone_sign = (*p == '+') ? 1 : -1;
-        p = parse_by_rule(p + 1, zone_rule, ARRAY_SIZE(zone_rule), values);
-        if (p == NULL)
-            return (time_t) -1;
-        zone_offset = ((values[0] / 100) * 60 + values[0] % 100) * 60;
-        zone_offset *= zone_sign;
-    } else {
-        p = parse_legacy_timezone(p, &zone_offset);
-        if (p == NULL)
-            return (time_t) -1;
-    }
-
-    /* Fix up the year, using the RFC 2822 rules.  Remember that tm_year
-       stores the year - 1900. */
-    if (tm.tm_year < 50)
-        tm.tm_year += 100;
-    else if (tm.tm_year >= 1000)
-        tm.tm_year -= 1900;
-
-    /* Done parsing.  Make sure there's nothing left but CFWS and range-check
-       our results and then convert the struct tm to seconds since epoch and
-       then apply the time zone offset. */
-    p = skip_cfws(p);
-    if (*p != '\0')
-        return (time_t) -1;
-    if (!valid_tm(&tm))
-        return (time_t) -1;
-    result = mktime_utc(&tm);
-    return (result == (time_t) -1) ? result : result - zone_offset;
-}
diff --git a/lib/dbz.c b/lib/dbz.c
deleted file mode 100644 (file)
index 6671df1..0000000
--- a/lib/dbz.c
+++ /dev/null
@@ -1,1785 +0,0 @@
-/*
-  dbz.c  V6.1.1
-
-Copyright 1988 Jon Zeeff (zeeff@b-tech.ann-arbor.mi.us)
-You can use this code in any manner, as long as you leave my name on it
-and don't hold me responsible for any problems with it.
-
-Hacked on by gdb@ninja.UUCP (David Butler); Sun Jun  5 00:27:08 CDT 1988
-
-Various improvments + INCORE by moraes@ai.toronto.edu (Mark Moraes)
-
-Major reworking by Henry Spencer as part of the C News project.
-
-Minor lint and CodeCenter (Saber) fluff removal by Rich $alz (March, 1991).
-Non-portable CloseOnExec() calls added by Rich $alz (September, 1991).
-Added "writethrough" and tagmask calculation code from
-<rob@violet.berkeley.edu> and <leres@ee.lbl.gov> by Rich $alz (December, 1992).
-Merged in MMAP code by David Robinson, formerly <david@elroy.jpl.nasa.gov>
-now <david.robinson@sun.com> (January, 1993).
-
-Major reworking by Clayton O'Neill (coneill@oneill.net).  Removed all the
-C News and backwards compatible cruft.  Ripped out all the tagmask stuff
-and replaced it with hashed .pag entries.  This removes the need for
-base file access.  Primary bottleneck now appears to be the hash
-algorithm and search().  You can change DBZ_INTERNAL_HASH_SIZE in
-dbz.h to increase the size of the stored hash.
-
-These routines replace dbm as used by the usenet news software
-(it's not a full dbm replacement by any means).  It's fast and
-simple.  It contains no AT&T code.
-
-The dbz database exploits the fact that when news stores a <key,value>
-tuple, the `value' part is a seek offset into a text file, pointing to
-a copy of the `key' part.  This avoids the need to store a copy of
-the key in the dbz files. 
-
-The basic format of the database is two hash tables, each in it's own
-file. One contains the offsets into the history text file , and the
-other contains a hash of the message id.  A value is stored by
-indexing into the tables using a hash value computed from the key;
-collisions are resolved by linear probing (just search forward for an
-empty slot, wrapping around to the beginning of the table if
-necessary).  Linear probing is a performance disaster when the table
-starts to get full, so a complication is introduced.  Each file actually
-contains one *or more* tables, stored sequentially in the files, and
-the length of the linear-probe sequences is limited.  The search (for
-an existing item or an empy slot always starts in the first table of
-the hash file, and whenever MAXRUN probes have been done in table N,
-probing continues in table N+1.  It is best not to overflow into more
-than 1-2 tables or else massive performance degradation may occur.
-Choosing the size of the database is extremely important because of this.
-
-The table size is fixed for any particular database, but is determined
-dynamically when a database is rebuilt.  The strategy is to try to pick
-the size so the first table will be no more than 2/3 full, that being
-slightly before the point where performance starts to degrade.  (It is
-desirable to be a bit conservative because the overflow strategy tends
-to produce files with holes in them, which is a nuisance.)
-
-Tagged hash + offset fuzzy technique merged by Sang-yong Suh (Nov, 1997)
-
-Fixed a bug handling larger than 1Gb history offset by Sang-yong Suh(1998)
-Similar fix was suggested by Mike Hucka <hucka@umich.edu> (Jan, 1998) for
-dbz-3.3.2.
-
-Limited can't tag warnings once per dbzinit() by Sang-yong Suh (May, 1998)
-
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include "dbz.h"
-#include "inn/messages.h"
-#include "inn/innconf.h"
-#include "inn/mmap.h"
-#include "libinn.h"
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-/*
- * "LIA" = "leave it alone unless you know what you're doing".
- *
- * DBZTEST      Generate a standalone program for testing and benchmarking
- * DEFSIZE     default table size (not as critical as in old dbz)
- * NMEMORY     number of days of memory for use in sizing new table (LIA)
- * MAXRUN      length of run which shifts to next table (see below) (LIA)
- */
-
-static int dbzversion = 6;     /* for validating .dir file format */
-
-#ifdef DO_TAGGED_HASH
-/* assume that for tagged hash, we don't want more than 4byte of_t even if
- * off_t is 8 bytes -- people who use tagged-hash are usually short on 
- * RAM.
- */
-#define of_t long
-#else
-#define of_t           off_t
-#endif
-#define        SOF             (sizeof(of_t))
-#define        NOTFOUND        ((of_t)-1)
-#ifdef DO_TAGGED_HASH
-
-#define OVERFLOW
-#ifdef OVERFLOW
-#include <limits.h>
-#endif
-
-/* MAXDROPBITS is the maximum number of bits dropped from the offset value.
-   The least significant bits are dropped.  The space is used to
-   store hash additional bits, thereby increasing the possibility of the
-   hash detection */
-#define MAXDROPBITS    4       /* max # of bits to drop from the offset */
-
-/* MAXFUZZYLENGTH is the maximum in the offset value due to the MAXDROPBITS */
-#define MAXFUZZYLENGTH ((1 << MAXDROPBITS) - 1)
-
-/*
- * We assume that unused areas of a binary file are zeros, and that the
- * bit pattern of `(of_t)0' is all zeros.  The alternative is rather
- * painful file initialization.  Note that okayvalue(), if OVERFLOW is
- * defined, knows what value of an offset would cause overflow.
- */
-#define VACANT         ((of_t)0)
-#define BIAS(o)                ((o)+1)         /* make any valid of_t non-VACANT */
-#define UNBIAS(o)      ((o)-1)         /* reverse BIAS() effect */
-
-#define HASTAG(o)      ((o)&taghere)
-#define TAG(o)         ((o)&tagbits)
-#define NOTAG(o)       ((o)&~tagboth)
-#define CANTAG(o)      (((o)&tagboth) == 0)
-#define MKTAG(v)       (((v)<<conf.tagshift)&tagbits)
-
-#ifndef NOTAGS
-#define TAGENB         0x80    /* tag enable is top bit, tag is next 7 */
-#define TAGMASK        0x7f
-#define TAGSHIFT       24
-#else
-#define TAGENB         0       /* no tags */
-#define TAGMASK        0
-#define TAGSHIFT       0
-#endif
-
-/*
- * Stdio buffer for base-file reads.  Message-IDs (all news ever needs to
- * read) are essentially never longer than 64 bytes, and the typical stdio
- * buffer is so much larger that it is much more expensive to fill.
- */
-
-static of_t tagbits;           /* pre-shifted tag mask */
-static of_t taghere;           /* pre-shifted tag-enable bit */
-static of_t tagboth;           /* tagbits|taghere */
-static int canttag_warned;             /* flag to control can't tag warning */
-
-#endif /* DO_TAGGED_HASH */
-
-/* Old dbz used a long as the record type for dbz entries, which became
- * really gross in places because of mixed references.  We define these to
- * make it a bit easier if we want to store more in here.
- */
-
-/* A new, from-scratch database, not built as a rebuild of an old one, needs
- * to know table size.  Normally the user supplies this info, but there have
- * to be defaults.  Making this too small can have devestating effects on
- * history speed for the current history implementation whereas making it too
- * big just wastes disk space, so err on the side of caution.  This may still
- * be a bit too small.  Assume people using tagged hash are running somewhat
- * smaller servers.
- */
-#ifndef DEFSIZE
-
-#ifdef DO_TAGGED_HASH
-#define DEFSIZE                1000003         /* I need a prime number */
-#else
-#define        DEFSIZE         10000000
-#endif
-
-#endif /* DEFSIZE */
-/*
- * We read configuration info from the .dir file into this structure,
- * so we can avoid wired-in assumptions for an existing database.
- *
- * Among the info is a record of recent peak usages, so that a new table
- * size can be chosen intelligently when rebuilding.  10 is a good
- * number of usages to keep, since news displays marked fluctuations
- * in volume on a 7-day cycle.
- */
-#ifndef NMEMORY
-#define        NMEMORY 10      /* # days of use info to remember */
-#endif
-#define        NUSEDS  (1+NMEMORY)
-
-typedef struct {
-    long tsize;                        /* table size */
-    long used[NUSEDS];          /* entries used today, yesterday, ... */
-    long vused[NUSEDS];                /* ditto for text size */
-    int valuesize;             /* size of table values, == sizeof(dbzrec) */
-    int fillpercent;            /* fillpercent/100 is the percent full we'll
-                                  try to keep the .pag file */
-    of_t tagenb;               /* unshifted tag-enable bit */
-    of_t tagmask;              /* unshifted tag mask */
-    int tagshift;              /* shift count for tagmask and tagenb */
-    int dropbits;              /* number of bits to discard from offset */
-    int lenfuzzy;              /* num of fuzzy characters in offset */
-} dbzconfig;
-static dbzconfig conf;
-
-/*
- * Default dbzoptions to
- */
-static dbzoptions options = {
-    false,             /* write through off */
-    INCORE_NO,         /* index/pag from disk */
-#ifdef HAVE_MMAP
-    INCORE_MMAP,       /* exists mmap'ed. ignored in tagged hash mode */
-#else
-    INCORE_NO,         /* exists from disk. ignored in tagged hash mode */
-#endif
-    true               /* non-blocking writes */
-};
-
-/*
- * Data structure for recording info about searches.
- */
-typedef struct {
-    of_t place;                /* current location in file */
-    int tabno;                 /* which table we're in */
-    int run;                   /* how long we'll stay in this table */
-#              ifndef MAXRUN
-#              define  MAXRUN  100
-#              endif
-    HASH hash;                 /* the key's hash code */
-    unsigned long shorthash;    /* integer version of the hash, used for
-                                  determining the entries location.
-                                  Tagged_hash stores the 31-bit hash here */
-    of_t tag;          /* tag we are looking for */
-    int aborted;               /* has i/o error aborted search? */
-} searcher;
-#define        FRESH   ((searcher *)NULL)
-
-/*
- * Arguably the searcher struct for a given routine ought to be local to
- * it, but a fetch() is very often immediately followed by a store(), and
- * in some circumstances it is a useful performance win to remember where
- * the fetch() completed.  So we use a global struct and remember whether
- * it is current.
- */
-static searcher srch;
-static searcher *prevp;        /* &srch or FRESH */
-
-/* Structure for hash tables */
-typedef struct {
-    int fd;                     /* Non-blocking descriptor for writes */
-    off_t pos;                  /* Current offset into the table */
-    int reclen;                 /* Length of records in the table */
-    dbz_incore_val incore;      /* What we're using core for */
-    void *core;                 /* Pointer to in-core table */
-} hash_table;
-
-/* central data structures */
-static bool opendb = false;     /* Indicates if a database is currently open */
-static FILE *dirf;             /* descriptor for .dir file */
-static bool readonly;          /* database open read-only? */
-#ifdef DO_TAGGED_HASH
-static FILE *basef;            /* descriptor for base file */
-static char *basefname;                /* name for not-yet-opened base file */
-static hash_table pagtab;       /* pag hash table, stores hash + offset */
-#else
-static hash_table idxtab;       /* index hash table, used for data retrieval */
-static hash_table etab;         /* existance hash table, used for existance checks */
-#endif
-static bool dirty;             /* has a store() been done? */
-static erec empty_rec;          /* empty rec to compare against
-                                  initalized in dbzinit */
-
-/* misc. forwards */
-static bool getcore(hash_table *tab);
-static bool putcore(hash_table *tab);
-static bool getconf(FILE *df, dbzconfig *cp);
-static int  putconf(FILE *f, dbzconfig *cp);
-static void start(searcher *sp, const HASH hash, searcher *osp);
-#ifdef DO_TAGGED_HASH
-static of_t search(searcher *sp);
-static bool set_pag(searcher *sp, of_t value);
-#else
-static bool search(searcher *sp);
-#endif
-static bool set(searcher *sp, hash_table *tab, void *value);
-
-/* file-naming stuff */
-static char dir[] = ".dir";
-#ifdef DO_TAGGED_HASH
-static char pag[] = ".pag";
-#else
-static char idx[] = ".index";
-static char exists[] = ".hash";
-#endif
-
-int dbzneedfilecount(void) {
-#ifdef DO_TAGGED_HASH
-    return 2; /* basef and dirf are fopen()'ed and kept */
-#else
-    return 1; /* dirf is fopen()'ed and kept */
-#endif
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - dbzconfbase - reconfigure dbzconf from base file size.
- */
-static void
-config_by_text_size(dbzconfig *c, of_t basesize)
-{
-    int                        i;
-    unsigned long      m;
-
-    /* if no tag requested, just return. */
-    if ((c->tagmask | c->tagenb) == 0)
-       return;
-
-    /* Use 10 % larger base file size.  Sometimes the offset overflows */
-    basesize += basesize / 10;
-
-    /* calculate tagging from old file */
-    for (m = 1, i = 0; m < (unsigned long)basesize; i++, m <<= 1)
-       continue;
-    /* if we had more tags than the default, use the new data */
-    c->dropbits = 0;
-    while (m > (1 << TAGSHIFT)) {
-       if (c->dropbits >= MAXDROPBITS)
-           break;
-       c->dropbits++;
-       m >>= 1;
-       i--;
-    }
-    c->tagenb = TAGENB;
-    c->tagmask = TAGMASK;
-    c->tagshift = TAGSHIFT;
-    if ((c->tagmask | c->tagenb) && m > (1 << TAGSHIFT)) {
-       c->tagshift = i;
-       c->tagmask = (~(unsigned long)0) >> (i + 1);
-       c->tagenb = (c->tagmask << 1) & ~c->tagmask;
-    }
-    c->lenfuzzy = (int)(1 << c->dropbits) - 1;
-
-    m = (c->tagmask | c->tagenb) << c->tagshift;
-    if (m & (basesize >> c->dropbits)) {
-       fprintf(stderr, "m 0x%lx size 0x%lx\n", m, basesize);
-       exit(1);
-    }
-}
-#endif /* DO_TAGGED_HASH */
-
-/*
- - create and truncate .pag, .idx, or .hash files
- - return false on error
- */
-static bool
-create_truncate(const char *name, const char *pag1)
-{
-    char *fn;
-    FILE *f;
-
-    fn = concat(name, pag1, (char *) 0);
-    f = Fopen(fn, "w", TEMPORARYOPEN);
-    free(fn);
-    if (f == NULL) {
-       syswarn("unable to create/truncate %s", pag1);
-       return false;
-    } else
-        Fclose(f);
-    return true;
-}
-
-/* dbzfresh - set up a new database, no historical info
- * Return true for success, false for failure
- * name - base name; .dir and .pag must exist
- * size - table size (0 means default)
- */
-bool
-dbzfresh(const char *name, off_t size)
-{
-    char *fn;
-    dbzconfig c;
-    FILE *f;
-#ifdef DO_TAGGED_HASH
-    struct stat sb;
-    of_t m;
-#endif
-
-    if (opendb) {
-       warn("dbzfresh: database already open");
-       return false;
-    }
-    if (size != 0 && size < 2) {
-       warn("dbzfresh: preposterous size (%ld)", (long) size);
-       return false;
-    }
-
-    /* get default configuration */
-    if (!getconf(NULL, &c))
-       return false;   /* "can't happen" */
-
-#ifdef DO_TAGGED_HASH
-    /* and mess with it as specified */
-    if (size != 0)
-       c.tsize = size;
-    m = c.tagmask;
-    c.tagshift = 0;
-    while (!(m & 1)) {
-       m >>= 1;
-       c.tagshift++;
-    }
-    c.tagmask = m;
-    c.tagenb = (m << 1) & ~m;
-    c.dropbits = 0;
-    c.lenfuzzy = 0;
-
-    /* if big enough basb file exists, update config */
-    if (stat(name, &sb) != -1)
-       config_by_text_size(&c, sb.st_size);
-#else
-    /* set the size as specified, make sure we get at least 2 bytes
-       of implicit hash */
-    if (size != 0)
-       c.tsize = size > (64 * 1024) ? size : 64 * 1024;
-#endif
-
-    /* write it out */
-    fn = concat(name, dir, (char *) 0);
-    f = Fopen(fn, "w", TEMPORARYOPEN);
-    free(fn);
-    if (f == NULL) {
-       syswarn("dbzfresh: unable to write config");
-       return false;
-    }
-    if (putconf(f, &c) < 0) {
-       Fclose(f);
-       return false;
-    }
-    if (Fclose(f) == EOF) {
-       syswarn("dbzfresh: fclose failure");
-       return false;
-    }
-
-    /* create and truncate .pag, or .index/.hash files */
-#ifdef DO_TAGGED_HASH
-    if (!create_truncate(name, pag))
-       return false;
-#else
-    if (!create_truncate(name, idx))
-       return false;
-    if (!create_truncate(name, exists))
-       return false;
-#endif /* DO_TAGGED_HASH */
-
-    /* and punt to dbzinit for the hard work */
-    return dbzinit(name);
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - isprime - is a number prime?
- */
-static bool
-isprime(long x)
-{
-    static int quick[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 0 };
-    int *ip;
-    long div1, stop;
-
-    /* hit the first few primes quickly to eliminate easy ones */
-    /* this incidentally prevents ridiculously small tables */
-    for (ip = quick; (div1 = *ip) != 0; ip++)
-       if (x % div1 == 0) {
-           debug("isprime: quick result on %ld", x);
-           return false;
-       }
-
-    /* approximate square root of x */
-    for (stop = x; x/stop < stop; stop >>= 1)
-       continue;
-    stop <<= 1;
-
-    /* try odd numbers up to stop */
-    for (div1 = *--ip; div1 < stop; div1 += 2)
-       if (x%div1 == 0)
-           return false;
-
-    return true;
-}
-#endif
-
-/*
- * dbzsize  - what's a good table size to hold this many entries?
- * contents - size of table (0 means return the default)
- */
-long
-dbzsize(off_t contents)
-{
-    of_t            n;
-
-    if (contents <= 0) {       /* foulup or default inquiry */
-       debug("dbzsize: preposterous input (%ld)", (long) contents);
-       return DEFSIZE;
-    }
-
-    if ((conf.fillpercent > 0) && (conf.fillpercent < 100))
-       n = (contents / conf.fillpercent) * 100;
-    else 
-       n = (contents * 3) / 2; /* try to keep table at most 2/3's full */
-
-    /* Make sure that we get at least 2 bytes of implicit hash */
-    if (n < (64 * 1024))
-       n = 64 * 1024;
-
-#ifdef DO_TAGGED_HASH
-    if (!(n & 1))
-        n += 1;                        /* make it odd */
-    debug("dbzsize: tentative size %ld", n);
-    while (!isprime(n))                /* look for a prime */
-       n += 2;
-#endif
-
-    debug("dbzsize: final size %ld", (long) n);
-    return n;
-}
-
-/* dbzagain - set up a new database to be a rebuild of an old one
- * Returns true on success, false on failure
- * name - base name; .dir and .pag must exist
- * oldname - basename, all must exist
- */
-bool
-dbzagain(const char *name, const char *oldname)
-{
-    char *fn;
-    dbzconfig c;
-    bool result;
-    int i;
-    long top;
-    FILE *f;
-    int newtable;
-    of_t newsize;
-#ifdef DO_TAGGED_HASH
-    long vtop;
-    struct stat sb;
-#endif
-
-    if (opendb) {
-       warn("dbzagain: database already open");
-       return false;
-    }
-
-    /* pick up the old configuration */
-    fn = concat(oldname, dir, (char *) 0);
-    f = Fopen(fn, "r", TEMPORARYOPEN);
-    free(fn);
-    if (f == NULL) {
-       syswarn("dbzagain: cannot open old .dir file");
-       return false;
-    }
-    result = getconf(f, &c);
-    Fclose(f);
-    if (!result) {
-       syswarn("dbzagain: getconf failed");
-       return false;
-    }
-
-    /* tinker with it */
-    top = 0;
-    newtable = 0;
-    for (i = 0; i < NUSEDS; i++) {
-       if (top < c.used[i])
-           top = c.used[i];
-       if (c.used[i] == 0)
-           newtable = 1;       /* hasn't got full usage history yet */
-    }
-    if (top == 0) {
-       debug("dbzagain: old table has no contents!");
-       newtable = 1;
-    }
-    for (i = NUSEDS-1; i > 0; i--)
-       c.used[i] = c.used[i-1];
-    c.used[0] = 0;
-
-#ifdef DO_TAGGED_HASH
-    vtop = 0;
-    for (i = 0; i < NUSEDS; i++) {
-       if (vtop < c.vused[i])
-           vtop = c.vused[i];
-       if (c.vused[i] == 0)
-           newtable = 1;       /* hasn't got full usage history yet */
-    }
-    if (top != 0 && vtop == 0) {
-       debug("dbzagain: old table has no contents!");
-       newtable = 1;
-    }
-    for (i = NUSEDS-1; i > 0; i--)
-       c.vused[i] = c.vused[i-1];
-    c.vused[0] = 0;
-
-    /* calculate tagging from old file */
-    if (stat(oldname, &sb) != -1 && vtop < sb.st_size)
-       vtop = sb.st_size;
-    config_by_text_size(&c, vtop);
-#endif
-
-    newsize = dbzsize(top);
-    if (!newtable || newsize > c.tsize)        /* don't shrink new table */
-       c.tsize = newsize;
-
-    /* write it out */
-    fn = concat(name, dir, (char *) 0);
-    f = Fopen(fn, "w", TEMPORARYOPEN);
-    free(fn);
-    if (f == NULL) {
-       syswarn("dbzagain: unable to write new .dir");
-       return false;
-    }
-    i = putconf(f, &c);
-    Fclose(f);
-    if (i < 0) {
-       warn("dbzagain: putconf failed");
-       return false;
-    }
-
-    /* create and truncate .pag, or .index/.hash files */
-#ifdef DO_TAGGED_HASH
-    if (!create_truncate(name, pag))
-       return false;
-#else
-    if (!create_truncate(name, idx))
-       return false;
-    if (!create_truncate(name, exists))
-       return false;
-#endif
-
-    /* and let dbzinit do the work */
-    return dbzinit(name);
-}
-
-static bool
-openhashtable(const char *base, const char *ext, hash_table *tab,
-             const size_t reclen, const dbz_incore_val incore)
-{
-    char *name;
-    int oerrno;
-
-    name = concat(base, ext, (char *) 0);
-    if ((tab->fd = open(name, readonly ? O_RDONLY : O_RDWR)) < 0) {
-       syswarn("openhashtable: could not open raw");
-        oerrno = errno;
-       free(name);
-        errno = oerrno;
-       return false;
-    }
-    free(name);
-
-    tab->reclen = reclen;
-    close_on_exec(tab->fd, true);
-    tab->pos = -1;
-
-    /* get first table into core, if it looks desirable and feasible */
-    tab->incore = incore;
-    if (tab->incore != INCORE_NO) {
-       if (!getcore(tab)) {
-           syswarn("openhashtable: getcore failure");
-            oerrno = errno;
-           close(tab->fd);
-            errno = oerrno;
-           return false;
-       }
-    }
-
-    if (options.nonblock && nonblocking(tab->fd, true) < 0) {
-       syswarn("fcntl: could not set nonblock");
-        oerrno = errno;
-       close(tab->fd);
-       errno = oerrno;
-       return false;
-    }
-    return true;
-}
-
-static void closehashtable(hash_table *tab) {
-    close(tab->fd);
-    if (tab->incore == INCORE_MEM)
-       free(tab->core);
-    if (tab->incore == INCORE_MMAP) {
-#if defined(HAVE_MMAP)
-       if (munmap(tab->core, conf.tsize * tab->reclen) == -1) {
-           syswarn("closehashtable: munmap failed");
-       }
-#else
-       warn("closehashtable: can't mmap files");
-#endif
-    }
-}
-
-#ifdef DO_TAGGED_HASH
-static bool
-openbasefile(const char *name)
-{
-    basef = Fopen(name, "r", DBZ_BASE);
-    if (basef == NULL) {
-       syswarn("dbzinit: basefile open failed");
-        basefname = xstrdup(name);
-    } else
-       basefname = NULL;
-    if (basef != NULL)
-       close_on_exec(fileno(basef), true);
-    if (basef != NULL)
-        setvbuf(basef, NULL, _IOFBF, 64);
-    return true;
-}
-#endif /* DO_TAGGED_HASH */
-
-/*
- * dbzinit - open a database, creating it (using defaults) if necessary
- *
- * We try to leave errno set plausibly, to the extent that underlying
- * functions permit this, since many people consult it if dbzinit() fails.
- * return true for success, false for failure
- */
-bool
-dbzinit(const char *name)
-{
-    char *fname;
-
-    if (opendb) {
-       warn("dbzinit: dbzinit already called once");
-       errno = 0;
-       return false;
-    }
-
-    /* open the .dir file */
-    fname = concat(name, dir, (char *) 0);
-    if ((dirf = Fopen(fname, "r+", DBZ_DIR)) == NULL) {
-       dirf = Fopen(fname, "r", DBZ_DIR);
-       readonly = true;
-    } else
-       readonly = false;
-    free(fname);
-    if (dirf == NULL) {
-       syswarn("dbzinit: can't open .dir file");
-       return false;
-    }
-    close_on_exec(fileno(dirf), true);
-
-    /* pick up configuration */
-    if (!getconf(dirf, &conf)) {
-       warn("dbzinit: getconf failure");
-       Fclose(dirf);
-       errno = EDOM;   /* kind of a kludge, but very portable */
-       return false;
-    }
-
-    /* open pag or idx/exists file */
-#ifdef DO_TAGGED_HASH
-    if (!openhashtable(name, pag, &pagtab, SOF, options.pag_incore)) {
-       Fclose(dirf);
-       return false;
-    }
-    if (!openbasefile(name)) {
-       close(pagtab.fd);
-       Fclose(dirf);
-       return false;
-    }
-    tagbits = conf.tagmask << conf.tagshift;
-    taghere = conf.tagenb << conf.tagshift;
-    tagboth = tagbits | taghere;
-    canttag_warned = 0;
-#else
-    if (!openhashtable(name, idx, &idxtab, sizeof(of_t), options.pag_incore)) {
-       Fclose(dirf);
-       return false;
-    }
-    if (!openhashtable(name, exists, &etab, sizeof(erec),
-               options.exists_incore)) {
-       Fclose(dirf);
-       return false;
-    }
-#endif
-
-    /* misc. setup */
-    dirty = false;
-    opendb = true;
-    prevp = FRESH;
-    memset(&empty_rec, '\0', sizeof(empty_rec));
-    debug("dbzinit: succeeded");
-    return true;
-}
-
-/* dbzclose - close a database
- */
-bool
-dbzclose(void)
-{
-    bool ret = true;
-
-    if (!opendb) {
-       warn("dbzclose: not opened!");
-       return false;
-    }
-
-    if (!dbzsync())
-       ret = false;
-
-#ifdef DO_TAGGED_HASH
-    closehashtable(&pagtab);
-    if (Fclose(basef) == EOF) {
-        syswarn("dbzclose: fclose(basef) failed");
-       ret = false;
-    }
-    if (basefname != NULL)
-       free(basefname);
-    basef = NULL;
-#else
-    closehashtable(&idxtab);
-    closehashtable(&etab);
-#endif
-
-    if (Fclose(dirf) == EOF) {
-       syswarn("dbzclose: fclose(dirf) failed");
-       ret = false;
-    }
-
-    debug("dbzclose: %s", (ret == true) ? "succeeded" : "failed");
-    if (ret)
-       opendb = false;
-    return ret;
-}
-
-/* dbzsync - push all in-core data out to disk
- */
-bool
-dbzsync(void)
-{
-    bool ret = true;
-
-    if (!opendb) {
-       warn("dbzsync: not opened!");
-       return false;
-    }
-
-    if (!dirty)
-       return true;;
-
-#ifdef DO_TAGGED_HASH
-    if (!putcore(&pagtab)) {
-#else
-    if (!putcore(&idxtab) || !putcore(&etab)) {
-#endif
-       warn("dbzsync: putcore failed");
-       ret = false;
-    }
-
-    if (putconf(dirf, &conf) < 0)
-       ret = false;
-
-    debug("dbzsync: %s", ret ? "succeeded" : "failed");
-    return ret;
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - okayvalue - check that a value can be stored
- */
-static int
-okayvalue(of_t value)
-{
-    if (HASTAG(value))
-       return(0);
-#ifdef OVERFLOW
-    if (value == LONG_MAX)     /* BIAS() and UNBIAS() will overflow */
-       return(0);
-#endif
-    return(1);
-}
-#endif
-
-/* dbzexists - check if the given message-id is in the database */
-bool
-dbzexists(const HASH key)
-{
-#ifdef DO_TAGGED_HASH
-    off_t value;
-
-    return (dbzfetch(key, &value) != 0);
-#else
-    
-    if (!opendb) {
-       warn("dbzexists: database not open!");
-       return false;
-    }
-
-    prevp = FRESH;
-    start(&srch, key, FRESH);
-    return search(&srch);
-#endif
-}
-
-/*
- * dbzfetch - get offset of an entry from the database
- *
- * Returns the offset of the text file for input key,
- * or -1 if NOTFOUND or error occurs.
- */
-bool
-dbzfetch(const HASH key, off_t *value)
-{
-#ifdef DO_TAGGED_HASH
-#define        MAX_NB2RD       (DBZMAXKEY + MAXFUZZYLENGTH + 2)
-#define MIN_KEY_LENGTH 6       /* strlen("<1@a>") + strlen("\t") */
-    char *bp, buffer[MAX_NB2RD];
-    int keylen, j, nb2r;
-    HASH hishash;
-    char *keytext = NULL;
-    of_t offset = NOTFOUND;
-#endif
-
-    prevp = FRESH;
-
-    if (!opendb) {
-       warn("dbzfetch: database not open!");
-       return false;
-    }
-
-    start(&srch, key, FRESH);
-#ifdef DO_TAGGED_HASH
-    /*
-     * nb2r: number of bytes to read from history file.
-     *       It can be reduced if history text is written as hashes only.
-     */
-    nb2r = sizeof(buffer) - 1;
-
-    while ((offset = search(&srch)) != NOTFOUND) {
-       debug("got 0x%lx", key_ptr);
-
-       /* fetch the key */
-       offset <<= conf.dropbits;
-       if (offset)             /* backspace 1 character to read '\n' */
-           offset--;
-       if (fseeko(basef, offset, SEEK_SET) != 0) {
-           syswarn("dbzfetch: seek failed");
-           return false;
-       }
-       keylen = fread(buffer, 1, nb2r, basef);
-       if (keylen < MIN_KEY_LENGTH) {
-           syswarn("dbzfetch: read failed");
-           return false;
-       }
-       buffer[keylen] = '\0';  /* terminate the string */
-
-       if (offset) {           /* find the '\n', the previous EOL */
-           if (keylen > conf.lenfuzzy)
-               keylen = conf.lenfuzzy; /* keylen is fuzzy distance now */
-           for (j=0,bp=buffer; j<keylen; j++,bp++)
-               if (*bp == '\n')
-                   break;
-           if (*bp != '\n') {
-               debug("dbzfetch: can't locate EOL");
-               /* pag entry should be deleted, but I'm lazy... */
-               continue;
-           }
-           offset++;
-           bp++;       /* now *bp is the start of key */
-       } else {
-           j = 0;      /* We are looking for the first history line. */
-           bp = buffer;
-       }
-
-       /* Does this history line really have same key? */
-       if (*bp == '[') {
-           if (!keytext)
-               keytext = HashToText(key);
-           if (memcmp(keytext, bp+1, sizeof(HASH)*2) != 0)
-               continue;
-       } else if (*bp == '<') {
-           char *p = strchr(bp+1, '\t');
-           if (!p)             /* history has a corrupted line */
-               continue;
-           *p = '\0';
-           hishash = HashMessageID(bp);
-           if (memcmp(&key, &hishash, sizeof(HASH)) != 0)
-               continue;
-       } else
-           continue;
-
-       /* we found it */
-       offset += j;
-       debug("fetch: successful");
-       *value = offset;
-       return true;
-    }
-
-    /* we didn't find it */
-    debug("fetch: failed");
-    prevp = &srch;                     /* remember where we stopped */
-    return false;
-#else  /* DO_TAGGED_HASH */
-    if (search(&srch) == true) {
-       /* Actually get the data now */
-       if ((options.pag_incore != INCORE_NO) && (srch.place < conf.tsize)) {
-           memcpy(value, &((of_t *)idxtab.core)[srch.place], sizeof(of_t));
-       } else {
-           if (pread(idxtab.fd, value, sizeof(of_t), srch.place * idxtab.reclen) != sizeof(of_t)) {
-               syswarn("fetch: read failed");
-               idxtab.pos = -1;
-               srch.aborted = 1;
-               return false;
-           }
-       }
-       debug("fetch: successful");
-       return true;
-    }
-
-    /* we didn't find it */
-    debug("fetch: failed");
-    prevp = &srch;                     /* remember where we stopped */
-    return false;
-#endif
-}
-
-/*
- * dbzstore - add an entry to the database
- * returns true for success and false for failure
- */
-DBZSTORE_RESULT
-dbzstore(const HASH key, off_t data)
-{
-#ifdef DO_TAGGED_HASH
-    of_t value;
-#else
-    erec     evalue;
-#endif
-
-    if (!opendb) {
-       warn("dbzstore: database not open!");
-       return DBZSTORE_ERROR;
-    }
-    if (readonly) {
-       warn("dbzstore: database open read-only");
-       return DBZSTORE_ERROR;
-    }
-
-#ifdef DO_TAGGED_HASH
-    /* copy the value in to ensure alignment */
-    memcpy(&value, &data, SOF);
-
-    /* update maximum offset value if necessary */
-    if (value > conf.vused[0])
-       conf.vused[0] = value;
-
-    /* now value is in fuzzy format */
-    value >>= conf.dropbits;
-    debug("dbzstore: (%ld)", (long) value);
-
-    if (!okayvalue(value)) {
-       warn("dbzstore: reserved bit or overflow in 0x%lx", value);
-       return DBZSTORE_ERROR;
-    }
-
-    /* find the place, exploiting previous search if possible */
-    start(&srch, key, prevp);
-    while (search(&srch) != NOTFOUND)
-       continue;
-
-    prevp = FRESH;
-    conf.used[0]++;
-    debug("store: used count %ld", conf.used[0]);
-    dirty = 1;
-    if (!set_pag(&srch, value))
-       return DBZSTORE_ERROR;
-    return DBZSTORE_OK;
-#else  /* DO_TAGGED_HASH */
-
-    /* find the place, exploiting previous search if possible */
-    start(&srch, key, prevp);
-    if (search(&srch) == true)
-       return DBZSTORE_EXISTS;
-
-    prevp = FRESH;
-    conf.used[0]++;
-    debug("store: used count %ld", conf.used[0]);
-    dirty = true;
-
-    memcpy(&evalue.hash, &srch.hash,
-          sizeof(evalue.hash) < sizeof(srch.hash) ? sizeof(evalue.hash) : sizeof(srch.hash));
-
-    /* Set the value in the index first since we don't care if it's out of date */
-    if (!set(&srch, &idxtab, (void *)&data))
-       return DBZSTORE_ERROR;
-    if (!set(&srch, &etab, &evalue))
-       return DBZSTORE_ERROR;
-    return DBZSTORE_OK;
-#endif /* DO_TAGGED_HASH */
-}
-
-/*
- * getconf - get configuration from .dir file
- *   df    - NULL means just give me the default 
- *   pf    - NULL means don't care about .pag 
- *   returns true for success, false for failure
- */
-static bool
-getconf(FILE *df, dbzconfig *cp)
-{
-    int                i;
-
-    /* empty file, no configuration known */
-#ifdef DO_TAGGED_HASH
-    if (df == NULL) {
-       cp->tsize = DEFSIZE;
-       for (i = 0; i < NUSEDS; i++)
-           cp->used[i] = 0;
-       for (i = 0; i < NUSEDS; i++)
-           cp->vused[i] = 0;
-       cp->valuesize = sizeof(of_t);
-       cp->fillpercent = 50;
-       cp->tagenb = TAGENB;
-       cp->tagmask = TAGMASK;
-       cp->tagshift = TAGSHIFT;
-       cp->dropbits = 0;
-       cp->lenfuzzy = 0;
-       debug("getconf: defaults (%ld, %c, (0x%lx/0x%lx<<%d %d))",
-              cp->tsize, cp->casemap, cp->tagenb, 
-              cp->tagmask, cp->tagshift, cp->dropbits);
-       return true;
-    }
-
-    i = fscanf(df, "dbz 6 %ld %d %d %ld %ld %d %d\n", &cp->tsize,
-               &cp->valuesize, &cp->fillpercent, &cp->tagenb,
-               &cp->tagmask, &cp->tagshift, &cp->dropbits);
-    if (i != 7) {
-       warn("dbz: bad first line in config");
-       return false;
-    }
-    if (cp->valuesize != sizeof(of_t)) {
-       warn("dbz: wrong of_t size (%d)", cp->valuesize);
-       return false;
-    }
-    cp->lenfuzzy = (int)(1 << cp->dropbits) - 1;
-#else  /* DO_TAGGED_HASH */
-    if (df == NULL) {
-       cp->tsize = DEFSIZE;
-       for (i = 0; i < NUSEDS; i++)
-           cp->used[i] = 0;
-       cp->valuesize = sizeof(of_t) + sizeof(erec);
-       cp->fillpercent = 66;
-       debug("getconf: defaults (%ld)", cp->tsize);
-       return true;
-    }
-
-    i = fscanf(df, "dbz 6 %ld %d %d\n", &cp->tsize,
-               &cp->valuesize, &cp->fillpercent);
-    if (i != 3) {
-        warn("dbz: bad first line in config");
-       return false;
-    }
-    if (cp->valuesize != (sizeof(of_t) + sizeof(erec))) {
-       warn("dbz: wrong of_t size (%d)", cp->valuesize);
-       return false;
-    }
-#endif /* DO_TAGGED_HASH */
-    debug("size %ld", cp->tsize);
-
-    /* second line, the usages */
-    for (i = 0; i < NUSEDS; i++)
-       if (!fscanf(df, "%ld", &cp->used[i])) {
-            warn("dbz: bad usage value in config");
-           return false;
-       }
-    debug("used %ld %ld %ld...", cp->used[0], cp->used[1], cp->used[2]);
-
-#ifdef DO_TAGGED_HASH
-    /* third line, the text usages */
-    for (i = 0; i < NUSEDS; i++)
-       if (!fscanf(df, "%ld", &cp->vused[i])) {
-            warn("dbz: bad text usage value in config");
-           return false;
-       }
-    debug("vused %ld %ld %ld...", cp->vused[0], cp->vused[1], cp->vused[2]);
-#endif /* DO_TAGGED_HASH */
-
-    return true;
-}
-
-/* putconf - write configuration to .dir file
- * Returns: 0 for success, -1 for failure
- */
-static int
-putconf(FILE *f, dbzconfig *cp)
-{
-    int i;
-    int ret = 0;
-
-    if (fseeko(f, 0, SEEK_SET) != 0) {
-       syswarn("dbz: fseeko failure in putconf");
-       ret = -1;
-    }
-
-#ifdef DO_TAGGED_HASH
-    fprintf(f, "dbz %d %ld %d %d %ld %ld %d %d\n", dbzversion, cp->tsize,
-               cp->valuesize, cp->fillpercent, cp->tagenb,
-               cp->tagmask, cp->tagshift, cp->dropbits);
-#else  /* DO_TAGGED_HASH */
-    fprintf(f, "dbz %d %ld %d %d\n", dbzversion, cp->tsize,
-                  cp->valuesize, cp->fillpercent);
-#endif /* DO_TAGGED_HASH */
-
-    for (i = 0; i < NUSEDS; i++)
-       fprintf(f, "%ld%c", cp->used[i], (i < NUSEDS-1) ? ' ' : '\n');
-
-#ifdef DO_TAGGED_HASH
-    for (i = 0; i < NUSEDS; i++)
-       fprintf(f, "%ld%c", cp->vused[i], (i < NUSEDS-1) ? ' ' : '\n');
-#endif
-
-    fflush(f);
-    if (ferror(f))
-       ret = -1;
-
-    debug("putconf status %d", ret);
-    return ret;
-}
-
-/* getcore - try to set up an in-core copy of file
- *
- * Returns: pointer to copy of file or NULL on errror
- */
-static bool
-getcore(hash_table *tab)
-{
-    char *it;
-    ssize_t nread;
-    size_t i;
-    struct stat st;
-    size_t length = conf.tsize * tab->reclen;
-
-    if (tab->incore == INCORE_MMAP) {
-#if defined(HAVE_MMAP)
-       if (fstat(tab->fd, &st) == -1) {
-           syswarn("dbz: getcore: fstat failed");
-           return false;
-       }
-       if (length > st.st_size) {
-           /* file too small; extend it */
-           if (ftruncate(tab->fd, length) == -1) {
-               syswarn("dbz: getcore: ftruncate failed");
-               return false;
-           }
-       }
-       it = mmap(NULL, length, readonly ? PROT_READ : PROT_WRITE | PROT_READ,
-                  MAP_SHARED, tab->fd, 0);
-       if (it == (char *)-1) {
-           syswarn("dbz: getcore: mmap failed");
-           return false;
-       }
-#if defined (MADV_RANDOM) && defined(HAVE_MADVISE)
-       /* not present in all versions of mmap() */
-       madvise(it, length, MADV_RANDOM);
-#endif
-#else
-       warn("dbz: getcore: can't mmap files");
-       return false;
-#endif
-    } else {
-       it = xmalloc(length);
-       
-       nread = read(tab->fd, it, length);
-       if (nread < 0) {
-           syswarn("dbz: getcore: read failed");
-           free(it);
-           return false;
-       }
-       
-       i = length - nread;
-       memset(it + nread, '\0', i);
-    }
-
-    tab->core = it;
-    return true;
-}
-
-/* putcore - try to rewrite an in-core table
- *
- * Returns true on success, false on failure
- */
-static bool
-putcore(hash_table *tab)
-{
-    size_t size;
-    ssize_t result;
-    
-    if (tab->incore == INCORE_MEM) {
-       if(options.writethrough)
-           return true;
-       nonblocking(tab->fd, false);
-       size = tab->reclen * conf.tsize;
-       result = xpwrite(tab->fd, tab->core, size, 0);
-       if (result < 0 || (size_t) result != size) {
-           nonblocking(tab->fd, options.nonblock);
-           return false;
-       }
-       nonblocking(tab->fd, options.nonblock);
-    }
-#ifdef HAVE_MMAP
-    if(tab->incore == INCORE_MMAP) {
-       msync(tab->core, conf.tsize * tab->reclen, MS_ASYNC);
-    }
-#endif
-    return true;
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - makehash31 : make 31-bit hash from HASH
- */
-static unsigned int
-makehash31(const HASH *hash)
-{
-    unsigned int h;
-    memcpy(&h, hash, sizeof(h));
-    return (h >> 1);
-}
-#endif
-
-/* start - set up to start or restart a search
- * osp == NULL is acceptable
- */
-static void
-start(searcher *sp, const HASH hash, searcher *osp)
-{
-#ifdef DO_TAGGED_HASH
-    unsigned int       h;
-
-    h = makehash31(&hash);
-    if (osp != FRESH && osp->shorthash == h) {
-       if (sp != osp)
-           *sp = *osp;
-       sp->run--;
-       debug("search restarted");
-    } else {
-       sp->shorthash = h;
-       sp->tag = MKTAG(h / conf.tsize);
-       sp->place = h % conf.tsize;
-       debug("hash %8.8lx tag %8.8lx place %ld",
-              sp->shorthash, sp->tag, sp->place);
-       sp->tabno = 0;
-       sp->run = -1;
-       sp->aborted = 0;
-    }
-
-#else  /* DO_TAGGED_HASH */
-    int tocopy;
-
-    if (osp != FRESH && !memcmp(&osp->hash, &hash, sizeof(hash))) {
-       if (sp != osp)
-           *sp = *osp;
-       sp->run--;
-       debug("search restarted");
-    } else {
-       sp->hash = hash;
-       tocopy = sizeof(hash) < sizeof(sp->shorthash) ? sizeof(hash) : sizeof(sp->shorthash);
-       /* Copy the bottom half of thhe hash into sp->shorthash */
-       memcpy(&sp->shorthash, (const char *)&hash + (sizeof(hash) - tocopy),
-               tocopy);
-       sp->shorthash >>= 1;
-       sp->tabno = 0;
-       sp->run = -1;
-       sp->aborted = 0;
-    }
-#endif /* DO_TAGGED_HASH */
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - search - conduct part of a search
- */
-static of_t                    /* NOTFOUND if we hit VACANT or error */
-search(searcher *sp)
-{
-    of_t value;
-    unsigned long taboffset = sp->tabno * conf.tsize;
-
-    if (sp->aborted)
-       return(NOTFOUND);
-
-    for (;;) {
-       /* go to next location */
-       if (sp->run++ == MAXRUN) {
-           sp->tabno++;
-           sp->run = 0;
-           taboffset = sp->tabno * conf.tsize;
-       }
-       sp->place = ((sp->shorthash + sp->run) % conf.tsize) + taboffset;
-       debug("search @ %ld", place);
-
-       /* get the tagged value */
-       if ((options.pag_incore != INCORE_NO) && (sp->place < conf.tsize)) {
-           debug("search: in core");
-           value = ((of_t *)pagtab.core)[sp->place];
-       } else {
-           off_t dest;
-           dest = sp->place * SOF;
-
-           /* read it */
-           errno = 0;
-           if (pread(pagtab.fd, &value, sizeof(value), dest) != sizeof(value)) {
-               if (errno != 0) {
-                   syswarn("dbz: search: read failed");
-                   pagtab.pos = -1;
-                   sp->aborted = 1;
-                   return(NOTFOUND);
-               } else
-                   value = VACANT;
-                pagtab.pos = -1;
-           } else
-                pagtab.pos += sizeof(value);
-       }
-
-       /* vacant slot is always cause to return */
-       if (value == VACANT) {
-           debug("search: empty slot");
-           return(NOTFOUND);
-       };
-
-       /* check the tag */
-       value = UNBIAS(value);
-       debug("got 0x%lx", value);
-       if (!HASTAG(value)) {
-           debug("tagless");
-           return(value);
-       } else if (TAG(value) == sp->tag) {
-           debug("match");
-           return(NOTAG(value));
-       } else {
-           debug("mismatch 0x%lx", TAG(value));
-       }
-    }
-    /* NOTREACHED */
-}
-
-#else  /* DO_TAGGED_HASH */
-
-/* search - conduct part of a search
- *
- * return false if we hit vacant rec's or error
- */
-static bool
-search(searcher *sp)
-{
-    erec value;
-    unsigned long taboffset = 0;
-
-    if (sp->aborted)
-       return false;
-
-    for (;;) {
-       /* go to next location */
-       if (sp->run++ == MAXRUN) {
-           sp->tabno++;
-           sp->run = 0;
-           taboffset = sp->tabno * conf.tsize;
-       }
-
-       sp->place = ((sp->shorthash + sp->run) % conf.tsize) + taboffset;
-       debug("search @ %ld", (long) sp->place);
-
-       /* get the value */
-       if ((options.exists_incore != INCORE_NO) && (sp->place < conf.tsize)) {
-           debug("search: in core");
-           memcpy(&value, &((erec *)etab.core)[sp->place], sizeof(erec)); 
-       } else {
-           off_t dest;
-           dest = sp->place * sizeof(erec);
-
-           /* read it */
-           errno = 0;
-           if (pread(etab.fd, &value, sizeof(erec), dest) != sizeof(erec)) {
-               if (errno != 0) {
-                   debug("search: read failed");
-                   etab.pos = -1;
-                   sp->aborted = 1;
-                   return false;
-               } else {
-                   memset(&value, '\0', sizeof(erec));
-               }
-           }
-
-           /* and finish up */
-           etab.pos += sizeof(erec);
-       }
-
-       /* Check for an empty record */
-       if (!memcmp(&value, &empty_rec, sizeof(erec))) {
-           debug("search: empty slot");
-           return false;
-       }
-
-       /* check the value */
-       debug("got 0x%.*s", DBZ_INTERNAL_HASH_SIZE, value.hash);
-       if (!memcmp(&value.hash, &sp->hash, DBZ_INTERNAL_HASH_SIZE)) {
-           return true;
-       }
-    }
-    /* NOTREACHED */
-}
-#endif /* DO_TAGGED_HASH */
-
-/* set - store a value into a location previously found by search
- *
- * Returns:  true success, false failure
- */
-static bool
-set(searcher *sp, hash_table *tab, void *value)
-{
-    off_t offset;
-    
-    if (sp->aborted)
-       return false;
-
-    /* If we have the index file in memory, use it */
-    if ((tab->incore != INCORE_NO) && (sp->place < conf.tsize)) {
-       void *where = (char *)tab->core + (sp->place * tab->reclen);
-
-       memcpy(where, value, tab->reclen);
-       debug("set: incore");
-       if (tab->incore == INCORE_MMAP) {
-           if (innconf->nfswriter) {
-               inn_mapcntl(where, tab->reclen, MS_ASYNC);
-           }
-           return true;
-       }
-       if (!options.writethrough)
-           return true;
-    }
-
-    /* seek to spot */
-    tab->pos = -1;             /* invalidate position memory */
-    offset = sp->place * tab->reclen;
-
-    /* write in data */
-    while (pwrite(tab->fd, value, tab->reclen, offset) != tab->reclen) {
-       if (errno == EAGAIN) {
-           fd_set writeset;
-           
-           FD_ZERO(&writeset);
-           FD_SET(tab->fd, &writeset);
-           if (select(tab->fd + 1, NULL, &writeset, NULL, NULL) < 1) {
-               syswarn("dbz: set: select failed");
-               sp->aborted = 1;
-               return false;
-           }
-           continue;
-       }
-       syswarn("dbz: set: write failed");
-       sp->aborted = 1;
-       return false;
-    }
-
-    debug("set: succeeded");
-    return true;
-}
-
-#ifdef DO_TAGGED_HASH
-/*
- - set_pag - store a value into a location previously found by search
- -       on the pag table.
- - Returns: true success, false failure
- */
-static bool
-set_pag(searcher *sp, of_t value)
-{
-    of_t v = value;
-
-    if (CANTAG(v)) {
-       v |= sp->tag | taghere;
-       if (v != UNBIAS(VACANT))        /* BIAS(v) won't look VACANT */
-#ifdef OVERFLOW
-           if (v != LONG_MAX)          /* and it won't overflow */
-#endif
-               value = v;
-    } else if (canttag_warned == 0) {
-       fprintf(stderr, "dbz.c(set): can't tag value 0x%lx", v);
-       fprintf(stderr, " tagboth = 0x%lx\n", tagboth);
-       canttag_warned = 1;
-    }
-    debug("tagged value is 0x%lx", value);
-    value = BIAS(value);
-
-    return set(sp, &pagtab, &value);
-}
-#endif /* DO_TAGGED_HASH */
-
-/* dbzsetoptions - set runtime options for the database.
- */
-void
-dbzsetoptions(const dbzoptions o)
-{
-    options = o;
-#ifndef HAVE_MMAP
-    /* Without a working mmap on files, we should avoid it. */
-    if (options.pag_incore == INCORE_MMAP) options.pag_incore = INCORE_NO;
-    if (options.exists_incore == INCORE_MMAP) options.exists_incore = INCORE_NO;
-#endif
-}
-
-/* dbzgetoptions - get runtime options for the database.
- */
-void
-dbzgetoptions(dbzoptions *o)
-{
-    *o = options;
-}
-
-
-#ifdef DBZTEST
-
-int
-timediffms(struct timeval start, struct timeval end)
-{
-    return (((end.tv_sec - start.tv_sec) * 1000) +
-           ((end.tv_usec - start.tv_usec)) / 1000);
-}
-
-void
-RemoveDBZ(char *filename)
-{
-    char *fn;
-
-#ifdef DO_TAGGED_HASH
-    fn = concat(filename, pag, (char *) 0);
-    unlink(fn);
-    free(fn);
-#else
-    fn = concat(filename, exists, (char *) 0);
-    unlink(fn);
-    free(fn);
-    fn = concat(filename, idx, (char *) 0);
-    unlink(fn);
-    free(fn);
-#endif
-    fn = concat(filename, dir, (char *) 0);
-    unlink(fn);
-    free(fn);
-}
-
-static void
-usage(void)
-{
-    fprintf(stderr, "usage: dbztest [-i] [-n|m] [-N] [-s size] <history>\n");
-#ifdef DO_TAGGED_HASH
-    fprintf(stderr, "  -i       initialize history. deletes .pag files\n");
-#else
-    fprintf(stderr, "  -i       initialize history. deletes .exists and .index files\n");
-#endif
-    fprintf(stderr, "  -n or m  use INCORE_NO, INCORE_MMAP. default = INCORE_MEM\n");
-    fprintf(stderr, "  -N       using nfswriter mode\n");
-    fprintf(stderr, "  -s size  number of history lines[2500000]\n");
-    fprintf(stderr, "  history  history text file\n");
-    exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
-    int  i, line;
-    FILE *fpi;
-    char ibuf[2048], *p;
-    HASH key;
-    off_t where;
-    int  initialize = 0, size = 2500000;
-    char *history = NULL;
-    dbzoptions opt;
-    dbz_incore_val incore = INCORE_MEM;
-    struct timeval start, end;
-    off_t ivalue;
-
-    innconf = xcalloc(1, sizeof(struct innconf));
-
-    for (i=1; i<argc; i++)
-       if (strcmp(argv[i], "-i") == 0)
-           initialize = 1;
-       else if (strcmp(argv[i], "-n") == 0)
-           incore = INCORE_NO;
-        else if (strcmp(argv[i], "-N") == 0)
-            innconf->nfswriter = true;
-       else if (strcmp(argv[i], "-m") == 0)
-#if defined(HAVE_MMAP)
-           incore = INCORE_MMAP;
-#else
-            fprintf (stderr, "can't mmap files\n");
-#endif
-       else if (strcmp(argv[i], "-s") == 0)
-           size = atoi(argv[++i]);
-       else if (*argv[i] != '-' && history == NULL)
-           history = argv[i];
-       else
-           usage();
-
-    if (history == NULL)
-       usage();
-    if ((fpi = fopen(history, "r")) == NULL) {
-       fprintf(stderr, "can't open %s\n", history);
-       usage();
-    }
-
-    dbzgetoptions(&opt);
-    opt.pag_incore = incore;
-    dbzsetoptions(opt);
-
-    if (initialize) {
-       RemoveDBZ(history);
-       gettimeofday(&start, NULL);
-       if (dbzfresh(history, dbzsize(size)) < 0) {
-           fprintf(stderr, "cant dbzfresh %s\n", history);
-           exit(1);
-       }
-       gettimeofday(&end, NULL);
-       printf("dbzfresh: %d msec\n", timediffms(start, end));
-    } else {
-       gettimeofday(&start, NULL);
-       if (dbzinit(history) < 0) {
-           fprintf(stderr, "cant dbzinit %s\n", history);
-           exit(1);
-       }
-       gettimeofday(&end, NULL);
-       printf("dbzinit: %d msec\n", timediffms(start, end));
-    }
-
-    gettimeofday(&start, NULL);
-    where = ftello(fpi);
-    for (line=1; fgets(ibuf, sizeof(ibuf), fpi); line++, where=ftello(fpi)) {
-       if (*ibuf == '<') {
-           if ((p = strchr(ibuf, '\t')) == NULL) {
-               fprintf(stderr, "ignoreing bad line: %s\n", ibuf);
-               continue;
-           }
-           *p = '\0';
-           key = HashMessageID(ibuf);
-       } else if (*ibuf == '[')
-           key = TextToHash(ibuf+1);
-       else
-           continue;
-       if (initialize) {
-           if (dbzstore(key, where) == DBZSTORE_ERROR) {
-               fprintf(stderr, "cant store %s\n", ibuf);
-               exit(1);
-           }
-       } else {
-           if (!dbzfetch(key, &ivalue)) {
-                   fprintf(stderr, "line %d can't fetch %s\n", line, ibuf);
-                   exit(1);
-               }
-       }
-    }
-    line--;
-    gettimeofday(&end, NULL);
-    i = timediffms(start, end);
-    printf("%s: %d lines %.3f msec/id\n",
-       (initialize) ? "dbzstore" : "dbzfetch",
-       line, (double)i / (double)line);
-
-    gettimeofday(&end, NULL);
-    dbzclose();
-    gettimeofday(&end, NULL);
-    printf("dbzclose: %d msec\n", timediffms(start, end));
-    return(0);
-}
-#endif /* DBZTEST */
diff --git a/lib/defdist.c b/lib/defdist.c
deleted file mode 100644 (file)
index 715a52f..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*  $Id: defdist.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "paths.h"
-
-
-typedef struct _DDENTRY {
-    char       *Pattern;
-    char       *Value;
-    int                Weight;
-} DDENTRY;
-
-struct _DDHANDLE {
-    int                Count;
-    DDENTRY    *Entries;
-    DDENTRY    *Current;
-};
-typedef struct _DDHANDLE       DDHANDLE;
-
-struct _DDHANDLE *
-DDstart(FILE *FromServer, FILE *ToServer)
-{
-    DDHANDLE   *h;
-    DDENTRY    *ep;
-    FILE       *F;
-    char       buff[BUFSIZ];
-    char       *p;
-    char       *q;
-    char        *path;
-    int                i;
-    int         fd;
-    char       *name = NULL;
-
-    /* Open the file. */
-    path = concatpath(innconf->pathetc, _PATH_DISTPATS);
-    F = fopen(path, "r");
-    free(path);
-    if (F == NULL) {
-       /* Not available locally; try remotely. */
-       if (FromServer == NULL || ToServer == NULL)
-           /* We're probably nnrpd running on the server and the
-            * file isn't installed.  Oh well. */
-           return NULL;
-        name = concatpath(innconf->pathtmp, _PATH_TEMPACTIVE);
-        fd = mkstemp(name);
-        if (fd < 0)
-            return NULL;
-        close(fd);
-       if ((F = CA_listopen(name, FromServer, ToServer,
-                   "distrib.pats")) == NULL)
-           return NULL;
-    }
-
-    /* Count lines. */
-    for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
-       continue;
-
-    /* Allocate space for the handle. */
-    if ((h = xmalloc(sizeof(DDHANDLE))) == NULL) {
-       i = errno;
-       fclose(F);
-       if (name != NULL)
-           unlink(name);
-       errno = i;
-       return NULL;
-    }
-    h->Count = 0;
-    h->Current = NULL;
-    if (i == 0) {
-        return NULL ;
-    } else if ((h->Entries = xmalloc(sizeof(DDENTRY) * i)) == NULL) {
-       i = errno;
-       free(h);
-       fclose(F);
-       if (name != NULL)
-           unlink(name);
-       errno = i;
-       return NULL;
-    }
-
-    fseeko(F, 0, SEEK_SET);
-    for (ep = h->Entries; fgets(buff, sizeof buff, F) != NULL; ) {
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '\0' || buff[0] == '#')
-           continue;
-       if ((p = strchr(buff, ':')) == NULL
-        || (q = strchr(p + 1, ':')) == NULL)
-           continue;
-       *p++ = '\0';
-       ep->Weight = atoi(buff);
-       ep->Pattern = xstrdup(p);
-       q = strchr(ep->Pattern, ':');
-       *q++ = '\0';
-       ep->Value = q;
-       ep++;
-    }
-    h->Count = ep - h->Entries;
-
-    fclose(F);
-    if (name != NULL)
-       unlink(name);
-    return h;
-}
-
-
-void
-DDcheck(DDHANDLE *h, char *group)
-{
-    DDENTRY    *ep;
-    int                i;
-    int                w;
-
-    if (h == NULL || group == NULL)
-       return;
-
-    w = h->Current ? h->Current->Weight : -1;
-    for (ep = h->Entries, i = h->Count; --i >= 0; ep++)
-       if (ep->Weight > w && uwildmat(group, ep->Pattern)) {
-           h->Current = ep;
-           w = ep->Weight;
-       }
-}
-
-
-char *
-DDend(DDHANDLE *h)
-{
-    static char        NIL[] = "";
-    char       *p;
-    int                i;
-    DDENTRY    *ep;
-
-    if (h == NULL) {
-       p = NIL;
-       return xstrdup(p);
-    }
-
-    if (h->Current == NULL)
-       p = NIL;
-    else
-       p = h->Current->Value;
-    p = xstrdup(p);
-
-    for (ep = h->Entries, i = h->Count; --i >= 0; ep++)
-       free(ep->Pattern);
-    free(h->Entries);
-    free(h);
-    return p;
-}
-
-#if    defined(TEST)
-int
-main(int ac, char *av[])
-{
-    struct _DDHANDLE   *h;
-    char               *p;
-    FILE               *FromServer;
-    FILE               *ToServer;
-    char               buff[SMBUF];
-
-    if (NNTPremoteopen(NNTP_PORT, &FromServer, &ToServer, buff) < 0) {
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if ((p = strchr(buff, '\r')) != NULL)
-           *p = '\0';
-       if (buff[0])
-           fprintf(stderr, "%s\n", buff);
-       else
-           perror("Can't connect");
-       exit(1);
-    }
-
-    if ((h = DDstart(FromServer, ToServer)) == NULL)
-       perror("Init failed, proceeding anyway");
-    while ((p = *++av) != NULL)
-       DDcheck(h, p);
-    p = DDend(h);
-    printf(">%s<\n", p);
-    exit(0);
-    /* NOTREACHED */
-}
-#endif /* defined(TEST) */
diff --git a/lib/fdflags.c b/lib/fdflags.c
deleted file mode 100644 (file)
index 55b3ceb..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*  $Id: fdflags.c 4740 2001-05-14 03:52:34Z rra $
-**
-**  Set or clear file descriptor flags.
-**
-**  Simple functions (wrappers around fcntl) to set or clear file descriptor
-**  flags like close on exec or nonblocking I/O.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-#include <errno.h>
-#include <fcntl.h>
-
-/*
-**  Set a file to close on exec.
-**
-**  One is supposed to retrieve the flags, add FD_CLOEXEC, and then set
-**  them, although I've never seen a system with any flags other than
-**  close-on-exec.  Do it right anyway; it's not that expensive.  Avoid
-**  changing errno.  Errors are ignored, since it generally doesn't cause
-**  significant harm to fail.
-*/
-void
-close_on_exec(int fd, bool flag)
-{
-    int oerrno;
-    int oflag;
-
-    oerrno = errno;
-    oflag = fcntl(fd, F_GETFD, 0);
-    if (oflag < 0) {
-        errno = oerrno;
-        return;
-    }
-    fcntl(fd, F_SETFD, flag ? (oflag | FD_CLOEXEC) : (oflag & ~FD_CLOEXEC));
-    errno = oerrno;
-}
-
-
-/*
-**  Set a file descriptor to nonblocking (or clear the nonblocking flag if
-**  flag is false).
-**
-**  Always use O_NONBLOCK; O_NDELAY is *not* the same thing historically.
-**  The semantics of O_NDELAY are that if the read would block, it returns 0
-**  instead.  This is indistinguishable from an end of file condition.
-**  POSIX added O_NONBLOCK, which requires read to return -1 and set errno
-**  to EAGAIN, which is what we want.
-**
-**  FNDELAY (4.3BSD) originally did the correct thing, although it has a
-**  different incompatibility (affecting all users of a socket rather than
-**  just a file descriptor and returning EWOULDBLOCK instead of EAGAIN) that
-**  we don't care about in INN.  Using it is *probably* safe, but BSD should
-**  also have the ioctl, and at least on Solaris FNDELAY does the same thing
-**  as O_NDELAY, not O_NONBLOCK.  So if we don't have O_NONBLOCK, fall back
-**  to the ioctl instead.
-**
-**  Reference:  Stevens, Advanced Unix Programming, pg. 364.
-**
-**  Note that O_NONBLOCK is known not to work on earlier versions of ULTRIX,
-**  SunOS, and AIX, possibly not setting the socket nonblocking at all,
-**  despite the fact that they do define it.  It works in later SunOS and,
-**  current AIX, however, and a 1999-10-25 survey of current operating
-**  systems failed to turn up any that didn't handle it correctly (as
-**  required by POSIX), while HP-UX 11.00 did use the broken return-zero
-**  semantics of O_NDELAY (most other operating systems surveyed treated
-**  O_NDELAY as synonymous with O_NONBLOCK).  Accordingly, we currently
-**  unconditionally use O_NONBLOCK.  If this causes too many problems, an
-**  autoconf test may be required.
-*/
-
-#ifdef O_NONBLOCK
-
-int
-nonblocking(int fd, bool flag)
-{
-    int mode;
-
-    mode = fcntl(fd, F_GETFL, 0);
-    if (mode < 0)
-        return -1;
-    mode = (flag ? (mode | O_NONBLOCK) : (mode & ~O_NONBLOCK));
-    return fcntl(fd, F_SETFL, mode);
-}
-
-#else /* !O_NONBLOCK */
-
-#include <sys/ioctl.h>
-#if HAVE_SYS_FILIO_H
-# include <sys/filio.h>
-#endif
-
-int
-nonblocking(int fd, bool flag)
-{
-    int state;
-
-    state = flag ? 1 : 0;
-    return ioctl(fd, FIONBIO, &state);
-}
-
-#endif /* !O_NONBLOCK */
diff --git a/lib/fdlimit.c b/lib/fdlimit.c
deleted file mode 100644 (file)
index 23cf19e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*  $Id: fdlimit.c 4511 2001-02-07 23:41:08Z rra $
-**
-**  Portably determine or set the limit on open file descriptors.
-**
-**  Pretty much all platforms these days have getrlimit and setrlimit, so
-**  prefer those, but for determining the current limit preserve the old
-**  portability (if we don't have getrlimit, try sysconf, then
-**  getdtablesize, then ulimit, and then try to find a hard-coded constant
-**  in <sys/param.h> and failing that fall back to the POSIX-guaranteed
-**  minimum of 20.
-**
-**  For setting the limit, only setrlimit is supported; if it isn't
-**  available, return -1 always.  We also refuse to set the limit to
-**  something higher than select can handle, checking against FD_SETSIZE.
-**
-**  Note that on some versions of Linux (2.2.x reported), sysconf may return
-**  the wrong value for the maximum file descriptors.  getrlimit is correct,
-**  so always prefer it.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#if HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-/* FreeBSD 3.4 RELEASE needs <sys/time.h> before <sys/resource.h>. */
-#if HAVE_GETRLIMIT || HAVE_SETRLIMIT
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# endif
-# include <sys/resource.h>
-#endif
-
-#include "libinn.h"
-
-#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
-
-int
-setfdlimit(unsigned int limit)
-{
-    struct rlimit rl;
-
-#ifdef FD_SETSIZE
-    if (limit > FD_SETSIZE) {
-        errno = EINVAL;
-        return -1;
-    }
-#endif
-
-    rl.rlim_cur = 0;
-    rl.rlim_max = 0;
-
-#if HAVE_GETRLIMIT
-    if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-        rl.rlim_cur = 0;
-        rl.rlim_max = 0;
-    }
-#endif
-
-    rl.rlim_cur = limit;
-    if (limit > rl.rlim_max)
-        rl.rlim_max = limit;
-    return setrlimit(RLIMIT_NOFILE, &rl);
-}
-
-#else /* !(HAVE_SETRLIMIT && RLIMIT_NOFILE) */
-
-int
-setfdlimit(unsigned int limit UNUSED)
-{
-    /* Unimplemented system call is close enough. */
-    errno = ENOSYS;
-    return -1;
-}
-
-#endif /* !(HAVE_SETRLIMIT && RLIMIT_NOFILE) */
-
-#if HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
-
-int
-getfdlimit(void)
-{
-    struct rlimit rl;
-
-    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
-        return -1;
-    return rl.rlim_cur;
-}
-
-#elif HAVE_SYSCONF
-
-int
-getfdlimit(void)
-{
-    return sysconf(_SC_OPEN_MAX);
-}
-
-#elif HAVE_GETDTABLESIZE
-
-int
-getfdlimit(void)
-{
-    return getdtablesize();
-}
-
-#elif HAVE_ULIMIT
-
-int
-getfdlimit(void)
-{
-# ifdef UL_GDESLIM
-    return ulimit(UL_GDESLIM, 0);
-# else
-    return ulimit(4, 0);
-# endif
-}
-
-#else /* no function mechanism available */
-# if HAVE_LIMITS_H
-#  include <limits.h>
-# endif
-# include <sys/param.h>
-
-int
-getfdcount(void)
-{
-# ifdef NOFILE
-    return NOFILE;
-# else
-    return 20;
-# endif
-}
-
-#endif
diff --git a/lib/fseeko.c b/lib/fseeko.c
deleted file mode 100644 (file)
index 01d1d26..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*  $Id: fseeko.c 3680 2000-07-29 22:54:52Z rra $
-**
-**  Replacement for a missing fseeko.
-**
-**  fseeko is a version of fseek that takes an off_t instead of a long.  For
-**  large file support (and because it's a more logical interface), INN uses
-**  fseeko unconditionally; if fseeko isn't provided by a platform but
-**  fpos_t is compatible with off_t (as in BSDI), define it in terms of
-**  fsetpos.  Otherwise, just call fseek (which won't work for files over
-**  2GB).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#if HAVE_LARGE_FPOS_T
-
-int
-fseeko(FILE *stream, off_t pos, int whence)
-{
-    fpos_t fpos;
-
-    switch (whence) {
-    case SEEK_SET:
-        fpos = pos;
-        return fsetpos(stream, &fpos);
-
-    case SEEK_END:
-        if (fseek(stream, 0, SEEK_END) < 0)
-            return -1;
-        if (pos == 0)
-            return 0;
-        /* Fall through. */
-
-    case SEEK_CUR:
-        if (fgetpos(stream, &fpos) < 0)
-            return -1;
-        fpos += pos;
-        return fsetpos(stream, &fpos);
-
-    default:
-        errno = EINVAL;
-        return -1;
-    }
-}
-
-#else /* !HAVE_LARGE_FPOS_T */
-
-int
-fseeko(FILE *stream, off_t pos, int whence)
-{
-    return fseek(stream, (long) pos, whence);
-}
-
-#endif /* !HAVE_LARGE_FPOS_T */
diff --git a/lib/ftello.c b/lib/ftello.c
deleted file mode 100644 (file)
index a3fcf62..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*  $Id: ftello.c 3681 2000-07-29 22:55:18Z rra $
-**
-**  Replacement for a missing ftello.
-**
-**  ftello is a version of ftell that returns an off_t instead of a long.
-**  For large file support (and because it's a more logical interface), INN
-**  uses ftello unconditionally; if ftello isn't provided by a platform but
-**  fpos_t is compatible with off_t (as in BSDI), define it in terms of
-**  fgetpos.  Otherwise, just call ftell (which won't work for files over
-**  2GB).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#if HAVE_LARGE_FPOS_T
-
-off_t
-ftello(FILE *stream)
-{
-    fpos_t fpos;
-
-    if (fgetpos(stream, &fpos) < 0) {
-        return -1;
-    } else {
-        return (off_t) fpos;
-    }
-}
-
-#else /* !HAVE_LARGE_FPOS_T */
-
-off_t
-ftello(FILE *stream)
-{
-    return (off_t) ftell(stream);
-}
-
-#endif /* !HAVE_LARGE_FPOS_T */
diff --git a/lib/genid.c b/lib/genid.c
deleted file mode 100644 (file)
index d9fa156..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*  $Id: genid.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Generate a message ID.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "libinn.h"
-
-/* Scale time back a bit, for shorter Message-ID's. */
-#define OFFSET 673416000L
-
-char *
-GenerateMessageID(char *domain)
-{
-    static char                buff[SMBUF];
-    static int         count;
-    char               *p;
-    char               sec32[10];
-    char               pid32[10];
-    TIMEINFO           Now;
-
-    if (GetTimeInfo(&Now) < 0)
-       return NULL;
-    Radix32(Now.time - OFFSET, sec32);
-    Radix32(getpid(), pid32);
-    if ((domain != NULL && innconf->domain == NULL) ||
-       (domain != NULL && innconf->domain != NULL
-         && strcmp(domain, innconf->domain) != 0)) {
-       p = domain;
-    } else {
-       if ((p = GetFQDN(domain)) == NULL)
-           return NULL;
-    }
-    snprintf(buff, sizeof(buff), "<%s$%s$%d@%s>", sec32, pid32, ++count, p);
-    return buff;
-}
diff --git a/lib/getfqdn.c b/lib/getfqdn.c
deleted file mode 100644 (file)
index 62781c1..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*  $Id: getfqdn.c 6155 2003-01-19 19:58:25Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <netdb.h>
-
-#include "libinn.h"
-#include "paths.h"
-
-
-/*
-**  Get the fully-qualified domain name for this host.
-*/
-char *GetFQDN(char *domain)
-{
-    static char                buff[SMBUF];
-    struct hostent     *hp;
-    char               *p;
-    char               **ap;
-#if    0
-    /* See comments below. */
-    char               temp[SMBUF + 2];
-#endif /* 0 */
-
-    /* Return any old results. */
-    if (buff[0])
-       return buff;
-
-    /* Try gethostname. */
-    if (gethostname(buff, (int)sizeof buff) < 0)
-       return NULL;
-    if (strchr(buff, '.') != NULL)
-       return buff;
-
-    /* See if DNS (or /etc/hosts) gives us a full domain name. */
-    if ((hp = gethostbyname(buff)) == NULL)
-       return NULL;
-#if    0
-    /* This code is a "feature" that allows multiple domains (NIS or
-     * DNS, I'm not sure) to work with a single INN server.  However,
-     * it turns out to cause more problems for people, and they have to
-     * use hacks like __switch_gethostbyname, etc.  So if you need this,
-     * turn it on, but don't complain to me. */
-    if (strchr(hp->h_name, '.') == NULL) {
-       /* Try to force DNS lookup if NIS/whatever gets in the way. */
-        strlcpy(temp, buff, sizeof(temp));
-        strlcat(temp, ".", sizeof(temp));
-       hp = gethostbyname(temp);
-    }
-#endif /* 0 */
-
-    /* First, see if the main name is a FQDN.  It should be. */
-    if (hp != NULL && strchr(hp->h_name, '.') != NULL) {
-       if (strlen(hp->h_name) < sizeof buff - 1) {
-           strlcpy(buff, hp->h_name, sizeof(buff));
-            return buff;
-        }
-       /* Doesn't fit; make sure we don't return bad data next time. */
-       buff[0] = '\0';
-       return hp->h_name;
-    }
-
-    /* Second, see if any aliases are. */
-    if ((ap = hp->h_aliases) != NULL)
-       while ((p = *ap++) != NULL)
-           if (strchr(p, '.') != NULL) {
-               /* Deja-vous all over again. */
-               if (strlen(p) < sizeof buff - 1) {
-                   strlcpy(buff, p, sizeof(buff));
-                    return buff;
-                }
-               buff[0] = '\0';
-               return p ;
-           }
-
-    /* Give up:  Get the domain config param and append it. */
-    if ((p = domain) == NULL || *p == '\0')
-       return NULL;
-    if (strlen(buff) + 1 + strlen(p) > sizeof buff - 1)
-       /* Doesn't fit. */
-       return NULL;
-    strlcat(buff, ".", sizeof(buff));
-    strlcat(buff, p, sizeof(buff));
-    return buff;
-}
diff --git a/lib/getmodaddr.c b/lib/getmodaddr.c
deleted file mode 100644 (file)
index 05b1c44..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*  $Id: getmodaddr.c 6155 2003-01-19 19:58:25Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-
-static char    *GMApathname = NULL;
-static FILE    *GMAfp = NULL;
-
-
-/*
-**  Close the file opened by GMAlistopen.
-*/
-static void
-GMAclose(void)
-{
-    if (GMAfp) {
-       fclose(GMAfp);
-       GMAfp = NULL;
-    }
-    if (GMApathname != NULL) {
-       unlink(GMApathname);
-        free(GMApathname);
-       GMApathname = NULL;
-    }
-}
-
-/*
-**  Internal library routine.
-*/
-static FILE *
-GMA_listopen(int fd, FILE *FromServer, FILE *ToServer, const char *request)
-{
-    char       buff[BUFSIZ];
-    char       *p;
-    int                oerrno;
-    FILE       *F;
-
-    F = fdopen(fd, "r+");
-    if (F == NULL)
-        return NULL;
-
-    /* Send a LIST command to and capture the output. */
-    if (request == NULL)
-       fprintf(ToServer, "list moderators\r\n");
-    else
-       fprintf(ToServer, "list %s\r\n", request);
-    fflush(ToServer);
-
-    /* Get the server's reply to our command. */
-    if (fgets(buff, sizeof buff, FromServer) == NULL
-     || strncmp(buff, NNTP_LIST_FOLLOWS, strlen(NNTP_LIST_FOLLOWS)) != 0) {
-       oerrno = errno;
-        fclose(F);
-       GMAclose();
-       errno = oerrno;
-       return NULL;
-    }
-
-    /* Slurp up the rest of the response. */
-    while (fgets(buff, sizeof buff, FromServer) != NULL) {
-       if ((p = strchr(buff, '\r')) != NULL)
-           *p = '\0';
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '.' && buff[1] == '\0') {
-           if (ferror(F) || fflush(F) == EOF || fseeko(F, 0, SEEK_SET) != 0)
-               break;
-           return F;
-       }
-       fprintf(F, "%s\n", buff);
-    }
-
-    /* Ran out of input before finding the terminator; quit. */
-    oerrno = errno;
-    fclose(F);
-    GMAclose();
-    errno = oerrno;
-    return NULL;
-}
-
-/*
-**  Read the moderators file, looking for a moderator.
-*/
-char *
-GetModeratorAddress(FILE *FromServer, FILE *ToServer, char *group,
-                   char *moderatormailer)
-{
-    static char                address[SMBUF];
-    char               *p;
-    char               *save;
-    char                *path;
-    char               buff[BUFSIZ];
-    char               name[SMBUF];
-    int                 fd;
-
-    strlcpy(name, group, sizeof(name));
-    address[0] = '\0';
-
-    if (FromServer==NULL || ToServer==NULL){
-
-        /*
-         *  This should be part of nnrpd or the like running on the server.
-         *  Open the server copy of the moderators file.
-         */
-        path = concatpath(innconf->pathetc, _PATH_MODERATORS);
-       GMAfp = fopen(path, "r");
-        free(path);
-    }else{
-        /*
-         *  Get a local copy of the moderators file from the server.
-         */
-        GMApathname = concatpath(innconf->pathtmp, _PATH_TEMPMODERATORS);
-        fd = mkstemp(GMApathname);
-        if (fd >= 0)
-            GMAfp = GMA_listopen(fd, FromServer, ToServer, "moderators");
-        else
-            GMAfp = NULL;
-
-       /* Fallback to the local copy if the server doesn't have it */
-       if (GMAfp == NULL) {
-            path = concatpath(innconf->pathetc, _PATH_MODERATORS);
-           GMAfp = fopen(path, "r");
-            free(path);
-        }
-    }
-
-    if (GMAfp != NULL) {
-       while (fgets(buff, sizeof buff, GMAfp) != NULL) {
-           /* Skip blank and comment lines. */
-           if ((p = strchr(buff, '\n')) != NULL)
-               *p = '\0';
-           if (buff[0] == '\0' || buff[0] == '#')
-               continue;
-
-           /* Snip off the first word. */
-           if ((p = strchr(buff, ':')) == NULL)
-               /* Malformed line... */
-               continue;
-           *p++ = '\0';
-
-           /* If it pattern-matches the newsgroup, the second field is a
-            * format for mailing, with periods changed to dashes. */
-           if (uwildmat(name, buff)) {
-               for (save = p; ISWHITE(*save); save++)
-                   continue;
-               for (p = name; *p; p++)
-                   if (*p == '.')
-                       *p = '-';
-               snprintf(address, sizeof(address), save, name);
-               break;
-           }
-       }
-
-        GMAclose();
-       if (address[0])
-           return address;
-    }
-
-    /* If we don't have an address, see if the config file has a default. */
-    if ((save = moderatormailer) == NULL)
-       return NULL;
-
-    for (p = name; *p; p++)
-       if (*p == '.')
-           *p = '-';
-    snprintf(address, sizeof(address), save, name);
-    return address;
-}
diff --git a/lib/getpagesize.c b/lib/getpagesize.c
deleted file mode 100644 (file)
index 62703ba..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*  $Id: getpagesize.c 5596 2002-08-17 21:29:35Z rra $
-**
-**  Replacement for a missing getpagesize.
-**
-**  Provides getpagesize implemented in terms of sysconf for those systems
-**  that don't have the getpagesize function.  Defaults to a page size of 16KB
-**  if sysconf isn't available either.
-*/
-
-#include "config.h"
-#include <unistd.h>
-
-int
-getpagesize(void)
-{
-    int pagesize;
-
-#ifdef _SC_PAGESIZE
-    pagesize = sysconf(_SC_PAGESIZE);
-#else
-    pagesize = 16 * 1024;
-#endif
-    return pagesize;
-}
diff --git a/lib/gettime.c b/lib/gettime.c
deleted file mode 100644 (file)
index 01703bb..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*  $Id: gettime.c 4135 2000-10-19 16:38:13Z kondou $
-**
-**  Find and return time information portably.
-*/
-#include "config.h"
-#include "libinn.h"
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-
-int
-GetTimeInfo(TIMEINFO *Now)
-{
-    static time_t       NextHour;
-    static long         LastTzone;
-    struct tm           *tm;
-    int                 secondsUntilNextHour;
-
-    struct timeval      tv;
-
-#ifndef HAVE_TM_GMTOFF
-    struct tm           local;
-    struct tm           gmt;
-#endif
-
-    /* Get the basic time. */
-    if (gettimeofday(&tv, (struct timezone *) 0) == -1)
-        return -1;
-    Now->time = tv.tv_sec;
-    Now->usec = tv.tv_usec;
-
-    /* Now get the timezone if the last time < HH:00:00 <= now for some HH.  */
-    if (NextHour <= Now->time) {
-        tm = localtime(&Now->time);
-        if (tm == NULL)
-            return -1;
-        secondsUntilNextHour = 60 * (60 - tm->tm_min) - tm->tm_sec;
-
-#ifdef HAVE_TM_GMTOFF
-        LastTzone = (0 - tm->tm_gmtoff) / 60;
-#else
-        /* To get the timezone, compare localtime with GMT. */
-        local = *tm;
-        if ((tm = gmtime(&Now->time)) == NULL)
-            return -1;
-        gmt = *tm;
-
-        /* Assume we are never more than 24 hours away. */
-        LastTzone = gmt.tm_yday - local.tm_yday;
-        if (LastTzone > 1)
-            LastTzone = -24;
-        else if (LastTzone < -1)
-            LastTzone = 24;
-        else
-            LastTzone *= 24;
-
-        /* Scale in the hours and minutes; ignore seconds. */
-        LastTzone += gmt.tm_hour - local.tm_hour;
-        LastTzone *= 60;
-        LastTzone += gmt.tm_min - local.tm_min;
-#endif  /* defined(HAVE_TM_GMTOFF) */
-
-        NextHour = Now->time + secondsUntilNextHour;
-    }
-    Now->tzone = LastTzone;
-    return 0;
-}
diff --git a/lib/hash.c b/lib/hash.c
deleted file mode 100644 (file)
index 2a7cbf3..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* This provides a generic hash function for use w/INN.  Currently
-   is implemented using MD5, but should probably have a mechanism for
-   choosing the hash algorithm and tagging the hash with the algorithm
-   used */
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#include "inn/md5.h"
-#include "libinn.h"
-
-static HASH empty= { { 0, 0, 0, 0, 0, 0, 0, 0,
-                      0, 0, 0, 0, 0, 0, 0, 0 }};
-
-/* cipoint - where in this message-ID does it become case-insensitive?
- *
- * The RFC822 code is not quite complete.  Absolute, total, full RFC822
- * compliance requires a horrible parsing job, because of the arcane
- * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi,
- * for example.  There are three or four things that might occur in the
- * domain part of a message-id that are case-sensitive.  They don't seem
- * to ever occur in real news, thank Cthulhu.  (What?  You were expecting
- * a merciful and forgiving deity to be invoked in connection with RFC822?
- * Forget it; none of them would come near it.)
- *
- * Returns: pointer into s, or NULL for "nowhere"
- */
-static const char *
-cipoint(const char *s, size_t size)
-{
-    char *p;
-    static const char post[] = "postmaster";
-    static int plen = sizeof(post) - 1;
-
-    if ((p = memchr(s, '@', size))== NULL)     /* no local/domain split */
-       return NULL;                            /* assume all local */
-    if ((p - (s + 1) == plen) && !strncasecmp(post, s+1, plen)) {
-       /* crazy -- "postmaster" is case-insensitive */
-       return s;
-    }
-    return p;
-}
-
-HASH
-Hash(const void *value, const size_t len)
-{
-    struct md5_context context;
-    HASH hash;
-
-    md5_init(&context);
-    md5_update(&context, value, len);
-    md5_final(&context);
-    memcpy(&hash,
-          &context.digest,
-          (sizeof(hash) < sizeof(context.digest)) ? sizeof(hash) : sizeof(context.digest));
-    return hash;
-}
-
-HASH
-HashMessageID(const char *MessageID)
-{
-    char                *new = NULL;
-    const char          *cip, *p = NULL;
-    char                *q;
-    int                 len;
-    HASH                hash;
-
-    len = strlen(MessageID);
-    cip = cipoint(MessageID, len);
-    if (cip != NULL) {
-        for (p = cip + 1; *p != '\0'; p++) {
-            if (!CTYPE(islower, *p)) {
-                new = xstrdup(MessageID);
-                break;
-            }
-        }
-    }
-    if (new != NULL)
-        for (q = new + (p - MessageID); *q != '\0'; q++)
-            *q = tolower(*q);
-    hash = Hash(new ? new : MessageID, len);
-    if (new != NULL)
-       free(new);
-    return hash;
-}
-
-/*
-**  Check if the hash is all zeros, and subseqently empty, see HashClear
-**  for more info on this.
-*/
-bool
-HashEmpty(const HASH h)
-{
-    return (memcmp(&empty, &h, sizeof(HASH)) == 0);
-}
-
-/*
-**  Set the hash to all zeros.  Using all zeros as the value for empty 
-**  introduces the possibility of colliding w/a value that actually hashes
-**  to all zeros, but that's fairly unlikely.
-*/
-void
-HashClear(HASH *hash)
-{
-    memset(hash, '\0', sizeof(HASH));
-}
-
-/*
-**  Convert the binary form of the hash to a form that we can use in error
-**  messages and logs.
-*/
-char *
-HashToText(const HASH hash)
-{
-    static const char  hex[] = "0123456789ABCDEF";
-    const char         *p;
-    unsigned int       i;
-    static char                hashstr[(sizeof(HASH)*2) + 1];
-
-    for (p = hash.hash, i = 0; i < sizeof(HASH); i++, p++) {
-       hashstr[i * 2] = hex[(*p & 0xF0) >> 4];
-       hashstr[(i * 2) + 1] = hex[*p & 0x0F];
-    }
-    hashstr[(sizeof(HASH) * 2)] = '\0';
-    return hashstr;
-}
-
-/*
-** Converts a hex digit and converts it to a int
-*/
-static
-int hextodec(const int c)
-{
-    return isdigit(c) ? (c - '0') : ((c - 'A') + 10);
-}
-
-/*
-**  Convert the ASCII representation of the hash back to the canonical form
-*/
-HASH
-TextToHash(const char *text)
-{
-    char                *q;
-    int                 i;
-    HASH                hash;
-
-    for (q = (char *)&hash, i = 0; i != sizeof(HASH); i++) {
-       q[i] = (hextodec(text[i * 2]) << 4) + hextodec(text[(i * 2) + 1]);
-    }
-    return hash;
-}
-
-/* This is rather gross, we compare like the last 4 bytes of the
-   hash are at the beginning because dbz considers them to be the
-   most significant bytes */
-int HashCompare(const HASH *h1, const HASH *h2) {
-    int i;
-    int tocomp = sizeof(HASH) - sizeof(unsigned long);
-    
-    if ((i = memcmp(&h1->hash[tocomp], &h1->hash[tocomp], sizeof(unsigned long))))
-       return i;
-    return memcmp(h1, h2, sizeof(HASH));
-}
diff --git a/lib/hashtab.c b/lib/hashtab.c
deleted file mode 100644 (file)
index ce0fa74..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*  $Id: hashtab.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  Generic hash table implementation.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  This is a generic hash table implementation with linear probing.  It
-**  takes a comparison function and a hashing function and stores void *.
-**
-**  Included for the use of callers is the hash function LOOKUP2 by Bob
-**  Jenkins, taken from <http://burtleburtle.net/bob/hash/>; see that web
-**  page for analysis and performance comparisons.  The performance of this
-**  hash is slightly worse than the standard sum and modulus hash function
-**  seen in many places but it produces fewer collisions.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "inn/hashtab.h"
-#include "libinn.h"
-
-/* Magic values for empty and deleted hash table slots. */
-#define HASH_EMPTY      ((void *) 0)
-#define HASH_DELETED    ((void *) 1)
-
-struct hash {
-    size_t size;                /* Allocated size. */
-    size_t mask;                /* Used to resolve a hash to an index. */
-    size_t nelements;           /* Total elements, including deleted. */
-    size_t ndeleted;            /* Number of deleted elements. */
-
-    unsigned long searches;     /* Count of lookups (for debugging). */
-    unsigned long collisions;   /* Count of collisions (for debugging). */
-    unsigned long expansions;   /* Count of hash resizes needed. */
-
-    hash_func hash;             /* Return hash of a key. */
-    hash_key_func key;          /* Given an element, returns its key. */
-    hash_equal_func equal;      /* Whether a key matches an element. */
-    hash_delete_func delete;    /* Called when a hash element is deleted. */
-
-    void **table;               /* The actual elements. */
-};
-
-
-/*
-**  Given a target table size, return the nearest power of two that's
-**  greater than or equal to that size, with a minimum size of four.  The
-**  minimum must be at least four to ensure that there is always at least
-**  one empty slot in the table given hash_find_slot's resizing of the table
-**  if it as least 75% full.  Otherwise, it would be possible for
-**  hash_find_slot to go into an infinite loop.
-*/
-static size_t
-hash_size(size_t target)
-{
-    int n;
-    size_t size;
-
-    size = target - 1;
-    for (n = 0; size > 0; n++)
-        size >>= 1;
-    size = 1 << n;
-    return (size < 4) ? 4 : size;
-}
-
-
-/*
-**  Create a new hash table.  The given size is rounded up to the nearest
-**  power of two for speed reasons (it greatly simplifies the use of the
-**  hash function).
-*/
-struct hash *
-hash_create(size_t size, hash_func hash_f, hash_key_func key_f,
-            hash_equal_func equal_f, hash_delete_func delete_f)
-{
-    struct hash *hash;
-
-    hash = xcalloc(1, sizeof(struct hash));
-    hash->hash = hash_f;
-    hash->key = key_f;
-    hash->equal = equal_f;
-    hash->delete = delete_f;
-    hash->size = hash_size(size);
-    hash->mask = hash->size - 1;
-    hash->table = xcalloc(hash->size, sizeof(void *));
-    return hash;
-}
-
-
-/*
-**  Free a hash and all resources used by it, and call the delete function
-**  on every element.
-*/
-void
-hash_free(struct hash *hash)
-{
-    size_t i;
-    void *entry;
-
-    for (i = 0; i < hash->size; i++) {
-        entry = hash->table[i];
-        if (entry != HASH_EMPTY && entry != HASH_DELETED)
-            (*hash->delete)(entry);
-    }
-    free(hash->table);
-    free(hash);
-}
-
-
-/*
-**  Internal search function used by hash_expand.  This is an optimized
-**  version of hash_find_slot that returns a pointer to the first empty
-**  slot, not trying to call the equality function on non-empty slots and
-**  assuming there are no HASH_DELETED slots.
-*/
-static void **
-hash_find_empty(struct hash *hash, const void *key)
-{
-    size_t slot;
-
-    slot = (*hash->hash)(key) & hash->mask;
-    while (1) {
-        if (hash->table[slot] == HASH_EMPTY)
-            return &hash->table[slot];
-
-        slot++;
-        if (slot >= hash->size)
-            slot -= hash->size;
-    }
-}
-
-
-/*
-**  Expand the hash table to be approximately 50% empty based on the number
-**  of elements in the hash.  This is done by allocating a new table and
-**  then calling hash_find_empty for each element in the previous table,
-**  recovering the key by calling hash->key on the element.
-*/
-static void
-hash_expand(struct hash *hash)
-{
-    void **old, **slot;
-    size_t i, size;
-
-    old = hash->table;
-    size = hash->size;
-    hash->size = hash_size((hash->nelements - hash->ndeleted) * 2);
-    hash->mask = hash->size - 1;
-    hash->table = xcalloc(hash->size, sizeof(void *));
-
-    hash->nelements = 0;
-    hash->ndeleted = 0;
-    for (i = 0; i < size; i++)
-        if (old[i] != HASH_EMPTY && old[i] != HASH_DELETED) {
-            slot = hash_find_empty(hash, (*hash->key)(old[i]));
-            *slot = old[i];
-            hash->nelements++;
-        }
-
-    hash->expansions++;
-    free(old);
-}
-
-
-/*
-**  Find a slot in the hash for a given key.  This is used both for
-**  inserting and deleting elements from the hash, as well as looking up
-**  entries.  Returns a pointer to the slot.  If insert is true, return the
-**  first empty or deleted slot.  If insert is false, return NULL if the
-**  element could not be found.
-**
-**  This function assumes that there is at least one empty slot in the
-**  hash; otherwise, it can loop infinitely.  It attempts to ensure this by
-**  always expanding the hash if it is at least 75% full; this will ensure
-**  that property for any hash size of 4 or higher.
-*/
-static void **
-hash_find_slot(struct hash *hash, const void *key, bool insert)
-{
-    void **deleted_slot = NULL;
-    void *entry;
-    size_t slot;
-
-    if (insert && hash->nelements * 4 >= hash->size * 3)
-        hash_expand(hash);
-
-    hash->searches++;
-
-    slot = (*hash->hash)(key) & hash->mask;
-    while (1) {
-        entry = hash->table[slot];
-        if (entry == HASH_EMPTY) {
-            if (!insert)
-                return NULL;
-
-            if (deleted_slot != NULL) {
-                *deleted_slot = HASH_EMPTY;
-                hash->ndeleted--;
-                return deleted_slot;
-            }
-            hash->nelements++;
-            return &hash->table[slot];
-        } else if (entry == HASH_DELETED) {
-            if (insert)
-                deleted_slot = &hash->table[slot];
-        } else if ((*hash->equal)(key, entry)) {
-            return &hash->table[slot];
-        }
-
-        hash->collisions++;
-        slot++;
-        if (slot >= hash->size)
-            slot -= hash->size;
-    }
-}
-
-
-/*
-**  Given a key, return the entry corresponding to that key or NULL if that
-**  key isn't present in the hash table.
-*/
-void *
-hash_lookup(struct hash *hash, const void *key)
-{
-    void **slot;
-
-    slot = hash_find_slot(hash, key, false);
-    return (slot == NULL) ? NULL : *slot;
-}
-
-
-/*
-**  Insert a new key/value pair into the hash, returning true if the
-**  insertion was successful and false if there is already a value in the
-**  hash with that key.
-*/
-bool
-hash_insert(struct hash *hash, const void *key, void *datum)
-{
-    void **slot;
-
-    slot = hash_find_slot(hash, key, true);
-    if (*slot != HASH_EMPTY)
-        return false;
-    *slot = datum;
-    return true;
-}
-
-
-/*
-**  Replace an existing hash value with a new data value, calling the delete
-**  function for the old data.  Returns true if the replacement was
-**  successful or false (without changing the hash) if the key whose value
-**  should be replaced was not found in the hash.
-*/
-bool
-hash_replace(struct hash *hash, const void *key, void *datum)
-{
-    void **slot;
-
-    slot = hash_find_slot(hash, key, false);
-    if (slot == NULL)
-        return false;
-    (*hash->delete)(*slot);
-    *slot = datum;
-    return true;
-}
-
-
-/*
-**  Delete a key out of the hash.  Returns true if the deletion was
-**  successful, false if the key could not be found in the hash.
-*/
-bool
-hash_delete(struct hash *hash, const void *key)
-{
-    bool result;
-
-    result = hash_replace(hash, key, HASH_DELETED);
-    if (result)
-        hash->ndeleted++;
-    return result;
-}
-
-
-/*
-**  For each element in the hash table, call the provided function, passing
-**  it the element and the opaque token that's passed to this function.
-*/
-void
-hash_traverse(struct hash *hash, hash_traverse_func callback, void *data)
-{
-    size_t i;
-    void *entry;
-
-    for (i = 0; i < hash->size; i++) {
-        entry = hash->table[i];
-        if (entry != HASH_EMPTY && entry != HASH_DELETED)
-            (*callback)(entry, data);
-    }
-}
-
-
-/*
-**  Returns a count of undeleted elements in the hash.
-*/
-unsigned long
-hash_count(struct hash *hash)
-{
-    return hash->nelements - hash->ndeleted;
-}
-
-
-/*
-**  Accessor functions for the debugging statistics.
-*/
-unsigned long
-hash_searches(struct hash *hash)
-{
-    return hash->searches;
-}
-
-unsigned long
-hash_collisions(struct hash *hash)
-{
-    return hash->collisions;
-}
-
-unsigned long
-hash_expansions(struct hash *hash)
-{
-    return hash->expansions;
-}
-
-
-/*
-**  Mix three 32-bit values reversibly.  This is the internal mixing
-**  function for the hash function.
-**
-**  For every delta with one or two bit set, and the deltas of all three
-**  high bits or all three low bits, whether the original value of a,b,c
-**  is almost all zero or is uniformly distributed,
-**
-**   * If mix() is run forward or backward, at least 32 bits in a,b,c
-**     have at least 1/4 probability of changing.
-**
-**   * If mix() is run forward, every bit of c will change between 1/3 and
-**     2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
-**
-**  mix() takes 36 machine instructions, but only 18 cycles on a superscalar
-**  machine (like a Pentium or a Sparc).  No faster mixer seems to work,
-**  that's the result of my brute-force search.  There were about 2^68
-**  hashes to choose from.  I (Bob Jenkins) only tested about a billion of
-**  those.
-*/
-#define MIX(a, b, c)                                    \
-    {                                                   \
-        (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13);     \
-        (b) -= (c); (b) -= (a); (b) ^= ((a) << 8);      \
-        (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13);     \
-        (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12);     \
-        (b) -= (c); (b) -= (a); (b) ^= ((a) << 16);     \
-        (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5);      \
-        (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3);      \
-        (b) -= (c); (b) -= (a); (b) ^= ((a) << 10);     \
-        (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15);     \
-    }
-
-
-/*
-**  Hash a variable-length key into a 32-bit value.
-**
-**  Takes byte sequence to hash and returns a 32-bit value.  A partial
-**  result can be passed as the third parameter so that large amounts of
-**  data can be hashed by subsequent calls, passing in the result of the
-**  previous call each time.  Every bit of the key affects every bit of the
-**  return value.  Every 1-bit and 2-bit delta achieves avalanche.  About
-**  (36 + 6n) instructions.
-**
-**  The best hash table sizes are powers of 2.  There is no need to mod with
-**  a prime (mod is sooo slow!).  If you need less than 32 bits, use a
-**  bitmask.  For example, if you need only 10 bits, do:
-**
-**      h = h & ((1 << 10) - 1);
-**
-**  In which case, the hash table should have 2^10 elements.
-**
-**  Based on code by Bob Jenkins <bob_jenkins@burtleburtle.net>, originally
-**  written in 1996.  The original license was:
-**
-**      By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use
-**      this code any way you wish, private, educational, or commercial.
-**      It's free.
-**
-**  See <http://burlteburtle.net/bob/hash/evahash.html> for discussion of
-**  this hash function.  Use for hash table lookup, or anything where one
-**  collision in 2^32 is acceptable.  Do NOT use for cryptographic purposes.
-*/
-unsigned long
-hash_lookup2(const char *key, size_t length, unsigned long partial)
-{
-    uint32_t a, b, c, len;
-
-    /* Set up the internal state.  a and b are initialized to a golden
-       ratio, an arbitrary value intended to avoid mapping all zeroes to all
-       zeroes. */
-    len = length;
-    a = b = 0x9e3779b9;
-    c = partial;
-
-#define S0(c)   ((uint32_t)(c))
-#define S1(c)   ((uint32_t)(c) << 8)
-#define S2(c)   ((uint32_t)(c) << 16)
-#define S3(c)   ((uint32_t)(c) << 24)
-
-    /* Handle most of the key. */
-    while (len >= 12) {
-        a += S0(key[0]) + S1(key[1]) + S2(key[2])  + S3(key[3]);
-        b += S0(key[4]) + S1(key[5]) + S2(key[6])  + S3(key[7]);
-        c += S0(key[8]) + S1(key[9]) + S2(key[10]) + S3(key[11]);
-        MIX(a, b, c);
-        key += 12;
-        len -= 12;
-   }
-
-    /* Handle the last 11 bytes.  All of the cases fall through. */
-    c += length;
-    switch (len) {
-    case 11: c += S3(key[10]);
-    case 10: c += S2(key[9]);
-    case  9: c += S1(key[8]);
-        /* The first byte of c is reserved for the length. */
-    case  8: b += S3(key[7]);
-    case  7: b += S2(key[6]);
-    case  6: b += S1(key[5]);
-    case  5: b += S0(key[4]);
-    case  4: a += S3(key[3]);
-    case  3: a += S2(key[2]);
-    case  2: a += S1(key[1]);
-    case  1: a += S0(key[0]);
-        /* case 0: nothing left to add. */
-    }
-    MIX(a, b, c);
-    return c;
-}
-
-
-/*
-**  A hash function for nul-terminated strings using hash_lookup2, suitable
-**  for passing to hash_create.
-*/
-unsigned long
-hash_string(const void *key)
-{
-    return hash_lookup2(key, strlen(key), 0);
-}
diff --git a/lib/hstrerror.c b/lib/hstrerror.c
deleted file mode 100644 (file)
index 3729560..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*  $Id: hstrerror.c 5556 2002-08-11 22:23:14Z rra $
-**
-**  Replacement for a missing hstrerror.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides hstrerror (strerror, but for h_errno from the resolver
-**  libraries) on those platforms that don't have it (most non-BSD).  This
-**  function is thread-safe unless called with an unknown h_errno.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <netdb.h>
-
-static const char * const errors[] = {
-    "No resolver error",                /* 0 NETDB_SUCCESS */
-    "Unknown host",                     /* 1 HOST_NOT_FOUND */
-    "Host name lookup failure",         /* 2 TRY_AGAIN */
-    "Unknown server error",             /* 3 NO_RECOVERY */
-    "No address associated with name",  /* 4 NO_ADDRESS / NO_DATA */
-};
-static int nerrors = (sizeof errors / sizeof errors[0]);
-
-/* If we're running the test suite, rename hstrerror to avoid conflicts with
-   the system version. */
-#if TESTING
-# define hstrerror test_hstrerror
-const char *test_hstrerror(int);
-#endif
-
-const char *
-hstrerror(int error)
-{
-    static char buf[32];
-
-    if (error == -1)
-        return "Internal resolver error";
-    if (error >= 0 && error < nerrors)
-        return errors[error];
-    snprintf(buf, sizeof(buf), "Resolver error %d", error);
-    return buf;
-}
diff --git a/lib/inet_aton.c b/lib/inet_aton.c
deleted file mode 100644 (file)
index bed9fa4..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*  $Id: inet_aton.c 5049 2001-12-12 09:06:00Z rra $
-**
-**  Replacement for a missing inet_aton.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine
-**  inet_aton for those platforms that don't have it.  inet_aton is
-**  thread-safe.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <netinet/in.h>
-
-/* If we're running the test suite, rename inet_ntoa to avoid conflicts with
-   the system version. */
-#if TESTING
-# define inet_aton test_inet_aton
-int test_inet_aton(const char *, struct in_addr *);
-#endif
-
-int
-inet_aton(const char *s, struct in_addr *addr)
-{
-    unsigned long octet[4], address;
-    const char *p;
-    int base, i;
-    int part = 0;
-
-    if (s == NULL) return 0;
-
-    /* Step through each period-separated part of the address.  If we see
-       more than four parts, the address is invalid. */
-    for (p = s; *p != 0; part++) {
-        if (part > 3) return 0;
-
-        /* Determine the base of the section we're looking at.  Numbers are
-           represented the same as in C; octal starts with 0, hex starts
-           with 0x, and anything else is decimal. */
-        if (*p == '0') {
-            p++;
-            if (*p == 'x') {
-                p++;
-                base = 16;
-            } else {
-                base = 8;
-            }
-        } else {
-            base = 10;
-        }
-
-        /* Make sure there's actually a number.  (A section of just "0"
-           would set base to 8 and leave us pointing at a period; allow
-           that.) */
-        if (*p == '.' && base != 8) return 0;
-        octet[part] = 0;
-
-        /* Now, parse this segment of the address.  For each digit, multiply
-           the result so far by the base and then add the value of the
-           digit.  Be careful of arithmetic overflow in cases where an
-           unsigned long is 32 bits; we need to detect it *before* we
-           multiply by the base since otherwise we could overflow and wrap
-           and then not detect the error. */
-        for (; *p != 0 && *p != '.'; p++) {
-            if (octet[part] > 0xffffffffUL / base) return 0;
-
-            /* Use a switch statement to parse each digit rather than
-               assuming ASCII.  Probably pointless portability.... */
-            switch (*p) {
-                case '0':           i = 0;  break;
-                case '1':           i = 1;  break;
-                case '2':           i = 2;  break;
-                case '3':           i = 3;  break;
-                case '4':           i = 4;  break;
-                case '5':           i = 5;  break;
-                case '6':           i = 6;  break;
-                case '7':           i = 7;  break;
-                case '8':           i = 8;  break;
-                case '9':           i = 9;  break;
-                case 'A': case 'a': i = 10; break;
-                case 'B': case 'b': i = 11; break;
-                case 'C': case 'c': i = 12; break;
-                case 'D': case 'd': i = 13; break;
-                case 'E': case 'e': i = 14; break;
-                case 'F': case 'f': i = 15; break;
-                default:            return 0;
-            }
-            if (i >= base) return 0;
-            octet[part] = (octet[part] * base) + i;
-        }
-
-        /* Advance over periods; the top of the loop will increment the
-           count of parts we've seen.  We need a check here to detect an
-           illegal trailing period. */
-        if (*p == '.') {
-            p++;
-            if (*p == 0) return 0;
-        }
-    }
-    if (part == 0) return 0;
-
-    /* IPv4 allows three types of address specification:
-
-           a.b
-           a.b.c
-           a.b.c.d
-
-       If there are fewer than four segments, the final segment accounts for
-       all of the remaining portion of the address.  For example, in the a.b
-       form, b is the final 24 bits of the address.  We also allow a simple
-       number, which is interpreted as the 32-bit number corresponding to
-       the full IPv4 address.
-
-       The first for loop below ensures that any initial segments represent
-       only 8 bits of the address and builds the upper portion of the IPv4
-       address.  Then, the remaining segment is checked to make sure it's no
-       bigger than the remaining space in the address and then is added into
-       the result. */
-    address = 0;
-    for (i = 0; i < part - 1; i++) {
-        if (octet[i] > 0xff) return 0;
-        address |= octet[i] << (8 * (3 - i));
-    }
-    if (octet[i] > (0xffffffffUL >> (i * 8))) return 0;
-    address |= octet[i];
-    if (addr != NULL) addr->s_addr = htonl(address);
-    return 1;
-}
diff --git a/lib/inet_ntoa.c b/lib/inet_ntoa.c
deleted file mode 100644 (file)
index 55a22d4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*  $Id: inet_ntoa.c 5049 2001-12-12 09:06:00Z rra $
-**
-**  Replacement for a missing or broken inet_ntoa.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine
-**  inet_ntoa for those platforms that don't have it or where it doesn't
-**  work right (such as on IRIX when using gcc to compile).  inet_ntoa is
-**  not thread-safe since it uses static storage (inet_ntop should be used
-**  instead when available).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <netinet/in.h>
-
-/* If we're running the test suite, rename inet_ntoa to avoid conflicts with
-   the system version. */
-#if TESTING
-# define inet_ntoa test_inet_ntoa
-const char *test_inet_ntoa(const struct in_addr);
-#endif
-
-const char *
-inet_ntoa(const struct in_addr in)
-{
-    static char buf[16];
-    const unsigned char *p;
-
-    p = (const unsigned char *) &in.s_addr;
-    sprintf(buf, "%u.%u.%u.%u",
-            (unsigned int) (p[0] & 0xff), (unsigned int) (p[1] & 0xff),
-            (unsigned int) (p[2] & 0xff), (unsigned int) (p[3] & 0xff));
-    return buf;
-}
diff --git a/lib/innconf.c b/lib/innconf.c
deleted file mode 100644 (file)
index f04510e..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-/*  $Id: innconf.c 7751 2008-04-06 14:35:40Z iulius $
-**
-**  Manage the global innconf struct.
-**
-**  The functions in this file collapse the parse tree for inn.conf into the
-**  innconf struct that's used throughout INN.  The code to collapse a
-**  configuration parse tree into a struct is fairly generic and should
-**  probably be moved into a separate library.
-**
-**  When adding new inn.conf parameters, make sure to add them in all of the
-**  following places:
-**
-**   * The table in this file.
-**   * include/inn/innconf.h
-**   * doc/pod/inn.conf.pod (and regenerate doc/man/inn.conf.5)
-**   * Add the default value to samples/inn.conf.in
-**
-**  Please maintain the current organization of parameters.  There are two
-**  different orders, one of which is a logical order used by the
-**  documentation, the include file, and the sample file, and the other of
-**  which is used in this file.  The order in this file is documentation of
-**  where each parameter is used, for later work at breaking up this mess
-**  of parameters into separate configuration groups for each INN subsystem.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#include "inn/confparse.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "paths.h"
-
-/* Instantiation of the global innconf variable. */
-struct innconf *innconf = NULL;
-
-/* Data types used to express the mappings from the configuration parse into
-   the innconf struct. */
-
-enum type {
-    TYPE_BOOLEAN,
-    TYPE_NUMBER,
-    TYPE_STRING
-};
-
-struct config {
-    const char *name;
-    size_t location;
-    enum type type;
-    struct {
-        bool boolean;
-        long integer;
-        const char *string;
-    } defaults;
-};
-
-/* The following macros are helpers to make it easier to define the table that
-   specifies how to convert the configuration file into a struct. */
-
-#define K(name)         (#name), offsetof(struct innconf, name)
-
-#define BOOL(def)       TYPE_BOOLEAN, { (def),     0,  NULL }
-#define NUMBER(def)     TYPE_NUMBER,  {     0, (def),  NULL }
-#define STRING(def)     TYPE_STRING,  {     0,     0, (def) }
-
-/* Accessor macros to get a pointer to a value inside a struct. */
-#define CONF_BOOL(conf, offset)   (bool *) (void *)((char *) (conf) + (offset))
-#define CONF_LONG(conf, offset)   (long *) (void *)((char *) (conf) + (offset))
-#define CONF_STRING(conf, offset) (char **)(void *)((char *) (conf) + (offset))
-
-/* Special notes:
-
-   checkincludedtext and localmaxartisize are used by both nnrpd and inews,
-   but inews should probably just let nnrpd do that checking.
-
-   organization is used by both nnrpd and inews.  Perhaps inews should just
-   let nnrpd set it.
-
-   mergetogroups is currently used by nnrpd for permission checking on
-   posting.  I think the check should always be performed based on the
-   newsgroup to which the user is actually posting, and nnrpd should let
-   innd do the merging.
-
-   useoverchan is only used in innd and overchan.  It should probably be
-   something the storage system knows.  Ideally, the storage system would
-   handle overchan itself, but that would require a lot of infrastructure;
-   in the interim, it could be something that programs could ask the
-   overview subsystem about.
-
-   doinnwatch and docnfsstat are used by rc.news currently, but really
-   should be grouped with the appropriate subsystem.
-
-   newsrequeue also uses nntplinklog, but the parameter should go away
-   completely anyway.
-
-   timer is currently used in various places, but it may be best to replace
-   it with individual settings for innd and innfeed, and any other code that
-   wants to use it.
-
-   maxforks is used by rnews and nnrpd.  I'm not sure this is that useful of
-   a setting to have.
-*/
-
-const struct config config_table[] = {
-    { K(domain),                STRING  (NULL) },
-    { K(enableoverview),        BOOL    (true) },
-    { K(fromhost),              STRING  (NULL) },
-    { K(groupbaseexpiry),       BOOL    (true) },
-    { K(mailcmd),               STRING  (NULL) },
-    { K(maxforks),              NUMBER  (10) },
-    { K(mta),                   STRING  (NULL) },
-    { K(nicekids),              NUMBER  (4) },
-    { K(ovmethod),              STRING  (NULL) },
-    { K(pathhost),              STRING  (NULL) },
-    { K(rlimitnofile),          NUMBER  (-1) },
-    { K(server),                STRING  (NULL) },
-    { K(sourceaddress),         STRING  (NULL) },
-    { K(sourceaddress6),        STRING  (NULL) },
-    { K(timer),                 NUMBER  (0) },
-
-    { K(patharchive),           STRING  (NULL) },
-    { K(patharticles),          STRING  (NULL) },
-    { K(pathbin),               STRING  (NULL) },
-    { K(pathcontrol),           STRING  (NULL) },
-    { K(pathdb),                STRING  (NULL) },
-    { K(pathetc),               STRING  (NULL) },
-    { K(pathfilter),            STRING  (NULL) },
-    { K(pathhttp),              STRING  (NULL) },
-    { K(pathincoming),          STRING  (NULL) },
-    { K(pathlog),               STRING  (NULL) },
-    { K(pathnews),              STRING  (NULL) },
-    { K(pathoutgoing),          STRING  (NULL) },
-    { K(pathoverview),          STRING  (NULL) },
-    { K(pathrun),               STRING  (NULL) },
-    { K(pathspool),             STRING  (NULL) },
-    { K(pathtmp),               STRING  (NULL) },
-
-    /* The following settings are specific to innd. */
-    { K(artcutoff),             NUMBER  (10) },
-    { K(badiocount),            NUMBER  (5) },
-    { K(bindaddress),           STRING  (NULL) },
-    { K(bindaddress6),          STRING  (NULL) },
-    { K(blockbackoff),          NUMBER  (120) },
-    { K(chaninacttime),         NUMBER  (600) },
-    { K(chanretrytime),         NUMBER  (300) },
-    { K(datamovethreshold),     NUMBER  (8192) },
-    { K(dontrejectfiltered),    BOOL    (false) },
-    { K(hiscachesize),          NUMBER  (0) },
-    { K(icdsynccount),          NUMBER  (10) },
-    { K(ignorenewsgroups),      BOOL    (false) },
-    { K(linecountfuzz),         NUMBER  (0) },
-    { K(logartsize),            BOOL    (true) },
-    { K(logcancelcomm),         BOOL    (false) },
-    { K(logipaddr),             BOOL    (true) },
-    { K(logsitename),           BOOL    (true) },
-    { K(maxartsize),            NUMBER  (1000000) },
-    { K(maxconnections),        NUMBER  (50) },
-    { K(mergetogroups),         BOOL    (false) },
-    { K(nntpactsync),           NUMBER  (200) },
-    { K(nntplinklog),           BOOL    (false) },
-    { K(noreader),              BOOL    (false) },
-    { K(pathalias),             STRING  (NULL) },
-    { K(pathcluster),           STRING  (NULL) },
-    { K(pauseretrytime),        NUMBER  (300) },
-    { K(peertimeout),           NUMBER  (3600) },
-    { K(port),                  NUMBER  (119) },
-    { K(readerswhenstopped),    BOOL    (false) },
-    { K(refusecybercancels),    BOOL    (false) },
-    { K(remembertrash),         BOOL    (true) },
-    { K(stathist),              STRING  (NULL) },
-    { K(status),                NUMBER  (0) },
-    { K(verifycancels),         BOOL    (false) },
-    { K(wanttrash),             BOOL    (false) },
-    { K(wipcheck),              NUMBER  (5) },
-    { K(wipexpire),             NUMBER  (10) },
-    { K(xrefslave),             BOOL    (false) },
-
-    /* The following settings are specific to nnrpd. */
-    { K(addnntppostingdate),    BOOL    (true) },
-    { K(addnntppostinghost),    BOOL    (true) },
-    { K(allownewnews),          BOOL    (true) },
-    { K(backoffauth),           BOOL    (false) },
-    { K(backoffdb),             STRING  (NULL) },
-    { K(backoffk),              NUMBER  (1) },
-    { K(backoffpostfast),       NUMBER  (0) },
-    { K(backoffpostslow),       NUMBER  (1) },
-    { K(backofftrigger),        NUMBER  (10000) },
-    { K(checkincludedtext),     BOOL    (false) },
-    { K(clienttimeout),         NUMBER  (600) },
-    { K(complaints),            STRING  (NULL) },
-    { K(initialtimeout),        NUMBER  (10) },
-    { K(keyartlimit),           NUMBER  (100000) },
-    { K(keylimit),              NUMBER  (512) },
-    { K(keymaxwords),           NUMBER  (250) },
-    { K(keywords),              BOOL    (false) },
-    { K(localmaxartsize),       NUMBER  (1000000) },
-    { K(maxcmdreadsize),        NUMBER  (BUFSIZ) },
-    { K(msgidcachesize),        NUMBER  (10000) },
-    { K(moderatormailer),       STRING  (NULL) },
-    { K(nfsreader),             BOOL    (false) },
-    { K(nfsreaderdelay),        NUMBER  (60) },
-    { K(nicenewnews),           NUMBER  (0) },
-    { K(nicennrpd),             NUMBER  (0) },
-    { K(nnrpdflags),            STRING  ("") },
-    { K(nnrpdauthsender),       BOOL    (false) },
-    { K(nnrpdloadlimit),        NUMBER  (16) },
-    { K(nnrpdoverstats),        BOOL    (false) },
-    { K(organization),          STRING  (NULL) },
-    { K(readertrack),           BOOL    (false) },
-    { K(spoolfirst),            BOOL    (false) },
-    { K(strippostcc),           BOOL    (false) },
-
-    /* The following settings are used by nnrpd and rnews. */
-    { K(nnrpdposthost),         STRING  (NULL) },
-    { K(nnrpdpostport),         NUMBER  (119) },
-
-    /* The following settings are specific to the storage subsystem. */
-    { K(articlemmap),           BOOL    (false) },
-    { K(cnfscheckfudgesize),    NUMBER  (0) },
-    { K(immediatecancel),       BOOL    (false) },
-    { K(keepmmappedthreshold),  NUMBER  (1024) },
-    { K(nfswriter),             BOOL    (false) },
-    { K(nnrpdcheckart),         BOOL    (true) },
-    { K(overcachesize),         NUMBER  (15) },
-    { K(ovgrouppat),            STRING  (NULL) },
-    { K(storeonxref),           BOOL    (true) },
-    { K(tradindexedmmap),       BOOL    (true) },
-    { K(useoverchan),           BOOL    (false) },
-    { K(wireformat),            BOOL    (false) },
-
-    /* The following settings are specific to the history subsystem. */
-    { K(hismethod),             STRING  (NULL) },
-
-    /* The following settings are specific to rc.news. */
-    { K(docnfsstat),            BOOL    (false) },
-    { K(innflags),              STRING  (NULL) },
-    { K(pgpverify),             BOOL    (false) },
-
-    /* The following settings are specific to innwatch. */
-    { K(doinnwatch),            BOOL    (true) },
-    { K(innwatchbatchspace),    NUMBER  (800) },
-    { K(innwatchlibspace),      NUMBER  (25000) },
-    { K(innwatchloload),        NUMBER  (1000) },
-    { K(innwatchhiload),        NUMBER  (2000) },
-    { K(innwatchpauseload),     NUMBER  (1500) },
-    { K(innwatchsleeptime),     NUMBER  (600) },
-    { K(innwatchspoolnodes),    NUMBER  (200) },
-    { K(innwatchspoolspace),    NUMBER  (8000) },
-
-    /* The following settings are specific to scanlogs. */
-    { K(logcycles),             NUMBER  (3) },
-};
-
-
-/*
-**  Set some defaults that cannot be included in the table because they depend
-**  on other elements or require function calls to set.  Called after the
-**  configuration file is read, so any that have to override what's read have
-**  to free whatever values are set by the file.
-*/
-static void
-innconf_set_defaults(void)
-{
-    char *value;
-
-    /* Some environment variables override settings in inn.conf. */
-    value = getenv("FROMHOST");
-    if (value != NULL) {
-        if (innconf->fromhost != NULL)
-            free(innconf->fromhost);
-        innconf->fromhost = xstrdup(value);
-    }
-    value = getenv("NNTPSERVER");
-    if (value != NULL) {
-        if (innconf->server != NULL)
-            free(innconf->server);
-        innconf->server = xstrdup(value);
-    }
-    value = getenv("ORGANIZATION");
-    if (value != NULL) {
-        if (innconf->organization != NULL)
-            free(innconf->organization);
-        innconf->organization = xstrdup(value);
-    }
-    value = getenv("INND_BIND_ADDRESS");
-    if (value != NULL) {
-        if (innconf->bindaddress != NULL)
-            free(innconf->bindaddress);
-        innconf->bindaddress = xstrdup(value);
-    }
-    value = getenv("INND_BIND_ADDRESS6");
-    if (value != NULL) {
-        if (innconf->bindaddress6 != NULL)
-            free(innconf->bindaddress6);
-        innconf->bindaddress6 = xstrdup(value);
-    }
-
-    /* Some parameters have defaults that depend on other parameters. */
-    if (innconf->fromhost == NULL)
-        innconf->fromhost = xstrdup(GetFQDN(innconf->domain));
-    if (innconf->pathhost == NULL)
-        innconf->pathhost = xstrdup(GetFQDN(innconf->domain));
-    if (innconf->pathtmp == NULL)
-        innconf->pathtmp = xstrdup(_PATH_TMP);
-
-    /* All of the paths are relative to other paths if not set except for
-       pathnews, which is required to be set by innconf_validate. */
-    if (innconf->pathbin == NULL)
-        innconf->pathbin = concatpath(innconf->pathnews, "bin");
-    if (innconf->pathfilter == NULL)
-        innconf->pathfilter = concatpath(innconf->pathbin, "filter");
-    if (innconf->pathdb == NULL)
-        innconf->pathdb = concatpath(innconf->pathnews, "db");
-    if (innconf->pathetc == NULL)
-        innconf->pathetc = concatpath(innconf->pathnews, "etc");
-    if (innconf->pathrun == NULL)
-        innconf->pathrun = concatpath(innconf->pathnews, "run");
-    if (innconf->pathlog == NULL)
-        innconf->pathlog = concatpath(innconf->pathnews, "log");
-    if (innconf->pathhttp == NULL)
-        innconf->pathhttp = xstrdup(innconf->pathlog);
-    if (innconf->pathspool == NULL)
-        innconf->pathspool = concatpath(innconf->pathnews, "spool");
-    if (innconf->patharticles == NULL)
-        innconf->patharticles = concatpath(innconf->pathspool, "articles");
-    if (innconf->pathoverview == NULL)
-        innconf->pathoverview = concatpath(innconf->pathspool, "overview");
-    if (innconf->pathoutgoing == NULL)
-        innconf->pathoutgoing = concatpath(innconf->pathspool, "outgoing");
-    if (innconf->pathincoming == NULL)
-        innconf->pathincoming = concatpath(innconf->pathspool, "incoming");
-    if (innconf->patharchive == NULL)
-        innconf->patharchive = concatpath(innconf->pathspool, "archive");
-
-    /* One other parameter depends on pathbin. */
-    if (innconf->mailcmd == NULL)
-        innconf->mailcmd = concatpath(innconf->pathbin, "innmail");
-}
-
-
-/*
-**  Given a config_group struct representing the inn.conf file, parse that
-**  into an innconf struct and return the newly allocated struct.  This
-**  routine should be pulled out into a library for smashing configuration
-**  file parse results into structs.
-*/
-static struct innconf *
-innconf_parse(struct config_group *group)
-{
-    unsigned int i;
-    bool *bool_ptr;
-    long *long_ptr;
-    const char *char_ptr;
-    char **string;
-    struct innconf *config;
-
-    config = xmalloc(sizeof(struct innconf));
-    for (i = 0; i < ARRAY_SIZE(config_table); i++)
-        switch (config_table[i].type) {
-        case TYPE_BOOLEAN:
-            bool_ptr = CONF_BOOL(config, config_table[i].location);
-            if (!config_param_boolean(group, config_table[i].name, bool_ptr))
-                *bool_ptr = config_table[i].defaults.boolean;
-            break;
-        case TYPE_NUMBER:
-            long_ptr = CONF_LONG(config, config_table[i].location);
-            if (!config_param_integer(group, config_table[i].name, long_ptr))
-                *long_ptr = config_table[i].defaults.integer;
-            break;
-        case TYPE_STRING:
-            if (!config_param_string(group, config_table[i].name, &char_ptr))
-                char_ptr = config_table[i].defaults.string;
-            string = CONF_STRING(config, config_table[i].location);
-            *string = (char_ptr == NULL) ? NULL : xstrdup(char_ptr);
-            break;
-        default:
-            die("internal error: invalid type in row %u of config table", i);
-            break;
-        }
-    return config;
-}
-
-
-/*
-**  Check the configuration file for consistency and ensure that mandatory
-**  settings are present.  Returns true if the file is okay and false
-**  otherwise.
-*/
-static bool
-innconf_validate(struct config_group *group)
-{
-    bool okay = true;
-    long threshold;
-
-    if (GetFQDN(innconf->domain) == NULL) {
-        warn("hostname does not resolve or domain not set in inn.conf");
-        okay = false;
-    }
-    if (innconf->mta == NULL) {
-        warn("must set mta in inn.conf");
-        okay = false;
-    }
-    if (innconf->pathnews == NULL) {
-        warn("must set pathnews in inn.conf");
-        okay = false;
-    }
-    if (innconf->hismethod == NULL) {
-        warn("must set hismethod in inn.conf");
-        okay = false;
-    }
-    if (innconf->enableoverview && innconf->ovmethod == NULL) {
-        warn("ovmethod must be set in inn.conf if enableoverview is true");
-        okay = false;
-    }
-    threshold = innconf->datamovethreshold;
-    if (threshold <= 0 || threshold > 1024 * 1024) {
-        config_error_param(group, "datamovethreshold",
-                           "maximum value for datamovethreshold is 1MB");
-        innconf->datamovethreshold = 1024 * 1024;
-    }
-    return okay;
-}
-
-
-/*
-**  Read in inn.conf.  Takes a single argument, which is either NULL to read
-**  the default configuration file or a path to an alternate configuration
-**  file to read.  Returns true if the file was read successfully and false
-**  otherwise.
-*/
-bool
-innconf_read(const char *path)
-{
-    struct config_group *group;
-    char *tmpdir;
-
-    if (innconf != NULL)
-        innconf_free(innconf);
-    if (path == NULL)
-        path = getenv("INNCONF");
-    group = config_parse_file(path == NULL ? _PATH_CONFIG : path);
-    if (group == NULL)
-        return false;
-
-    innconf = innconf_parse(group);
-    if (!innconf_validate(group))
-        return false;
-    config_free(group);
-    innconf_set_defaults();
-
-    /* It's not clear that this belongs here, but it was done by the old
-       configuration parser, so this is a convenient place to do it. */
-    tmpdir = getenv("TMPDIR");
-    if (tmpdir == NULL || strcmp(tmpdir, innconf->pathtmp) != 0)
-        if (setenv("TMPDIR", innconf->pathtmp, true) != 0) {
-            warn("cannot set TMPDIR in the environment");
-            return false;
-        }
-
-    return true;
-}
-
-
-/*
-**  Check an inn.conf file.  This involves reading it in and then additionally
-**  making sure that there are no keys defined in the inn.conf file that
-**  aren't recognized.  This doesn't have to be very fast (and isn't).
-**  Returns true if everything checks out successfully, and false otherwise.
-**
-**  A lot of code is duplicated with innconf_read here and should be
-**  refactored.
-*/
-bool
-innconf_check(const char *path)
-{
-    struct config_group *group;
-    struct vector *params;
-    size_t set, known;
-    bool found;
-    bool okay = true;
-
-    if (innconf != NULL)
-        innconf_free(innconf);
-    if (path == NULL)
-        path = getenv("INNCONF");
-    group = config_parse_file(path == NULL ? _PATH_CONFIG : path);
-    if (group == NULL)
-        return false;
-
-    innconf = innconf_parse(group);
-    if (!innconf_validate(group))
-        return false;
-
-    /* Now, do the work that innconf_read doesn't do.  Get a list of
-       parameters defined in innconf and then walk our list of valid
-       parameters and see if there are any set that we don't recognize. */
-    params = config_params(group);
-    for (set = 0; set < params->count; set++) {
-        found = false;
-        for (known = 0; known < ARRAY_SIZE(config_table); known++)
-            if (strcmp(params->strings[set], config_table[known].name) == 0)
-                found = true;
-        if (!found) {
-            config_error_param(group, params->strings[set],
-                               "unknown parameter %s", params->strings[set]);
-            okay = false;
-        }
-    }
-
-    /* Check and warn about a few other parameters. */
-    if (innconf->peertimeout < 3 * 60)
-        config_error_param(group, "peertimeout",
-                           "warning: NNTP draft (15) states inactivity"
-                           " timeouts MUST be at least three minutes");
-    if (innconf->clienttimeout < 3 * 60)
-        config_error_param(group, "clienttimeout",
-                           "warning: NNTP draft (15) states inactivity"
-                           " timeouts MUST be at least three minutes");
-
-    /* All done.  Free the parse tree and return. */
-    config_free(group);
-    return okay;
-}
-
-
-/*
-**  Free innconf, requiring some complexity since all strings stored in the
-**  innconf struct are allocated memory.  This routine is mostly generic to
-**  any struct smashed down from a configuration file parse.
-*/
-void
-innconf_free(struct innconf *config)
-{
-    unsigned int i;
-    char *p;
-
-    for (i = 0; i < ARRAY_SIZE(config_table); i++)
-        if (config_table[i].type == TYPE_STRING) {
-            p = *CONF_STRING(config, config_table[i].location);
-            if (p != NULL)
-                free(p);
-        }
-    free(config);
-}
-
-
-/*
-**  Print a single boolean value with appropriate quoting.
-*/
-static void
-print_boolean(FILE *file, const char *key, bool value,
-              enum innconf_quoting quoting)
-{
-    char *upper, *p;
-
-    switch (quoting) {
-    case INNCONF_QUOTE_NONE:
-        fprintf(file, "%s\n", value ? "true" : "false");
-        break;
-    case INNCONF_QUOTE_SHELL:
-        upper = xstrdup(key);
-        for (p = upper; *p != '\0'; p++)
-            *p = toupper(*p);
-        fprintf(file, "%s=%s; export %s;\n", upper, value ? "true" : "false",
-                upper);
-        free(upper);
-        break;
-    case INNCONF_QUOTE_PERL:
-        fprintf(file, "$%s = '%s';\n", key, value ? "true" : "false");
-        break;
-    case INNCONF_QUOTE_TCL:
-        fprintf(file, "set inn_%s \"%s\"\n", key, value ? "true" : "false");
-        break;
-    }
-}
-
-
-/*
-**  Print a single integer value with appropriate quoting.
-*/
-static void
-print_number(FILE *file, const char *key, long value,
-             enum innconf_quoting quoting)
-{
-    char *upper, *p;
-
-    switch (quoting) {
-    case INNCONF_QUOTE_NONE:
-        fprintf(file, "%ld\n", value);
-        break;
-    case INNCONF_QUOTE_SHELL:
-        upper = xstrdup(key);
-        for (p = upper; *p != '\0'; p++)
-            *p = toupper(*p);
-        fprintf(file, "%s=%ld; export %s;\n", upper, value, upper);
-        free(upper);
-        break;
-    case INNCONF_QUOTE_PERL:
-        fprintf(file, "$%s = %ld;\n", key, value);
-        break;
-    case INNCONF_QUOTE_TCL:
-        fprintf(file, "set inn_%s %ld\n", key, value);
-        break;
-    }
-}
-
-
-/*
-**  Print a single string value with appropriate quoting.
-*/
-static void
-print_string(FILE *file, const char *key, const char *value,
-             enum innconf_quoting quoting)
-{
-    char *upper, *p;
-    const char *letter;
-    static const char tcl_unsafe[] = "$[]{}\"\\";
-
-    switch (quoting) {
-    case INNCONF_QUOTE_NONE:
-        fprintf(file, "%s\n", value != NULL ? value : "");
-        break;
-    case INNCONF_QUOTE_SHELL:
-        upper = xstrdup(key);
-        for (p = upper; *p != '\0'; p++)
-            *p = toupper(*p);
-        fprintf(file, "%s='", upper);
-        for (letter = value; letter != NULL && *letter != '\0'; letter++) {
-            if (*letter == '\'')
-                fputs("'\\''", file);
-            else if (*letter == '\\')
-                fputs("\\\\", file);
-            else
-                fputc(*letter, file);
-        }
-        fprintf(file, "'; export %s;\n", upper);
-        free(upper);
-        break;
-    case INNCONF_QUOTE_PERL:
-        fprintf(file, "$%s = '", key);
-        for (letter = value; letter != NULL && *letter != '\0'; letter++) {
-            if (*letter == '\'' || *letter == '\\')
-                fputc('\\', file);
-            fputc(*letter, file);
-        }
-        fputs("';\n", file);
-        break;
-    case INNCONF_QUOTE_TCL:
-        fprintf(file, "set inn_%s \"", key);
-        for (letter = value; letter != NULL && *letter != '\0'; letter++) {
-            if (strchr(tcl_unsafe, *letter) != NULL)
-                fputc('\\', file);
-            fputc(*letter, file);
-        }
-        fputs("\"\n", file);
-        break;
-    }
-}
-
-
-/*
-**  Print a single paramter to the given file.  Takes an index into the table
-**  specifying the attribute to print and the quoting.
-*/
-static void
-print_parameter(FILE *file, size_t i, enum innconf_quoting quoting)
-{
-    bool bool_val;
-    long long_val;
-    const char *string_val;
-
-    switch (config_table[i].type) {
-    case TYPE_BOOLEAN:
-        bool_val = *CONF_BOOL(innconf, config_table[i].location);
-        print_boolean(file, config_table[i].name, bool_val, quoting);
-        break;
-    case TYPE_NUMBER:
-        long_val = *CONF_LONG(innconf, config_table[i].location);
-        print_number(file, config_table[i].name, long_val, quoting);
-        break;
-    case TYPE_STRING:
-        string_val = *CONF_STRING(innconf, config_table[i].location);
-        print_string(file, config_table[i].name, string_val, quoting);
-        break;
-    default:
-        die("internal error: invalid type in row %d of config table", i);
-        break;
-    }
-}
-
-
-/*
-**  Given a single parameter, find it in the table and print out its value.
-*/
-bool
-innconf_print_value(FILE *file, const char *key, enum innconf_quoting quoting)
-{
-    size_t i;
-
-    for (i = 0; i < ARRAY_SIZE(config_table); i++)
-        if (strcmp(key, config_table[i].name) == 0) {
-            print_parameter(file, i, quoting);
-            return true;
-        }
-    return false;
-}
-
-
-/*
-**  Dump the entire inn.conf configuration with appropriate quoting.
-*/
-void
-innconf_dump(FILE *file, enum innconf_quoting quoting)
-{
-    size_t i;
-
-    for (i = 0; i < ARRAY_SIZE(config_table); i++)
-        print_parameter(file, i, quoting);
-}
-
-
-/*
-**  Compare two innconf structs to see if they represent identical
-**  configurations.  This routine is mostly used for testing.  Prints warnings
-**  about where the two configurations differ and return false if they differ,
-**  true if they match.  This too should be moved into a config smashing
-**  library.
-*/
-bool
-innconf_compare(struct innconf *conf1, struct innconf *conf2)
-{
-    unsigned int i;
-    bool bool1, bool2;
-    long long1, long2;
-    const char *string1, *string2;
-    bool okay = true;
-
-    for (i = 0; i < ARRAY_SIZE(config_table); i++)
-        switch (config_table[i].type) {
-        case TYPE_BOOLEAN:
-            bool1 = *CONF_BOOL(conf1, config_table[i].location);
-            bool2 = *CONF_BOOL(conf2, config_table[i].location);
-            if (bool1 != bool2) {
-                warn("boolean variable %s differs: %d != %d",
-                     config_table[i].name, bool1, bool2);
-                okay = false;
-            }
-            break;
-        case TYPE_NUMBER:
-            long1 = *CONF_LONG(conf1, config_table[i].location);
-            long2 = *CONF_LONG(conf2, config_table[i].location);
-            if (long1 != long2) {
-                warn("integer variable %s differs: %ld != %ld",
-                     config_table[i].name, long1, long2);
-                okay = false;
-            }
-            break;
-        case TYPE_STRING:
-            string1 = *CONF_STRING(conf1, config_table[i].location);
-            string2 = *CONF_STRING(conf2, config_table[i].location);
-            if (string1 == NULL && string2 != NULL) {
-                warn("string variable %s differs: NULL != %s",
-                     config_table[i].name, string2);
-                okay = false;
-            } else if (string1 != NULL && string2 == NULL) {
-                warn("string variable %s differs: %s != NULL",
-                     config_table[i].name, string1);
-                okay = false;
-            } else if (string1 != NULL && string2 != NULL) {
-                if (strcmp(string1, string2) != 0) {
-                    warn("string variable %s differs: %s != %s",
-                         config_table[i].name, string1, string2);
-                    okay = false;
-                }
-            }
-            break;
-        default:
-            die("internal error: invalid type in row %d of config table", i);
-            break;
-        }
-    return okay;
-}
diff --git a/lib/inndcomm.c b/lib/inndcomm.c
deleted file mode 100644 (file)
index 28d5366..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*  $Id: inndcomm.c 7597 2007-01-16 23:11:05Z eagle $
-**
-**  Library routines to let other programs control innd.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include "portable/socket.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inndcomm.h"
-#include "libinn.h"
-#include "paths.h"
-
-static char                    *ICCsockname = NULL;
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-static struct sockaddr_un      ICCserv;
-static struct sockaddr_un      ICCclient;
-#endif
-static int                     ICCfd;
-static int                     ICCtimeout;
-const char                     *ICCfailure;
-
-
-/*
-**  Set the timeout.
-*/
-void
-ICCsettimeout(int i)
-{
-    ICCtimeout = i;
-}
-
-
-/*
-**  Get ready to talk to the server.
-*/
-int
-ICCopen(void)
-{
-    int mask, oerrno, fd;
-    int size = 65535;
-
-    if (innconf == NULL) {
-       if (!innconf_read(NULL)) {
-           ICCfailure = "innconf";
-           return -1;
-       }
-    }
-    /* Create a temporary name.  mkstemp is complete overkill here and is used
-       only because it's convenient.  We don't use it properly, since we
-       actually need to create a socket or named pipe, so there is a race
-       condition here.  It doesn't matter, since pathrun isn't world-writable
-       (conceivably two processes could end up using the same temporary name
-       at the same time, but the worst that will happen is that one process
-       will delete the other's temporary socket). */
-    if (ICCsockname == NULL)
-       ICCsockname = concatpath(innconf->pathrun, _PATH_TEMPSOCK);
-    fd = mkstemp(ICCsockname);
-    if (fd < 0) {
-        ICCfailure = "mkstemp";
-        return -1;
-    }
-    close(fd);
-    if (unlink(ICCsockname) < 0 && errno != ENOENT) {
-       ICCfailure = "unlink";
-       return -1;
-    }
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-
-    /* Make a socket and give it the name. */
-    if ((ICCfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
-       ICCfailure = "socket";
-       return -1;
-    }
-
-    /* Adjust the socket buffer size to accomodate large responses.  Ignore
-       failure; the message may fit anyway, and if not, we'll fail below. */
-    setsockopt(ICCfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-
-    memset(&ICCclient, 0, sizeof ICCclient);
-    ICCclient.sun_family = AF_UNIX;
-    strlcpy(ICCclient.sun_path, ICCsockname, sizeof(ICCclient.sun_path));
-    mask = umask(0);
-    if (bind(ICCfd, (struct sockaddr *) &ICCclient, SUN_LEN(&ICCclient)) < 0) {
-       oerrno = errno;
-       umask(mask);
-       errno = oerrno;
-       ICCfailure = "bind";
-       return -1;
-    }
-    umask(mask);
-
-    /* Name the server's socket. */
-    memset(&ICCserv, 0, sizeof ICCserv);
-    ICCserv.sun_family = AF_UNIX;
-    strlcpy(ICCserv.sun_path, innconf->pathrun, sizeof(ICCserv.sun_path));
-    strlcat(ICCserv.sun_path, "/", sizeof(ICCserv.sun_path));
-    strlcat(ICCserv.sun_path, _PATH_NEWSCONTROL, sizeof(ICCserv.sun_path));
-
-#else /* !HAVE_UNIX_DOMAIN_SOCKETS */
-
-    /* Make a named pipe and open it. */
-    mask = umask(0);
-    if (mkfifo(ICCsockname, 0666) < 0) {
-       oerrno = errno;
-       umask(mask);
-       errno = oerrno;
-       ICCfailure = "mkfifo";
-       return -1;
-    }
-    umask(mask);
-    if ((ICCfd = open(ICCsockname, O_RDWR)) < 0) {
-       ICCfailure = "open";
-       return -1;
-    }
-#endif /* !HAVE_UNIX_DOMAIN_SOCKETS */
-
-    ICCfailure = NULL;
-    return 0;
-}
-
-
-/*
-**  Close down.
-*/
-int
-ICCclose(void)
-{
-    int                i;
-
-    ICCfailure = NULL;
-    i = 0;
-    if (close(ICCfd) < 0) {
-       ICCfailure = "close";
-       i = -1;
-    }
-    if (unlink(ICCsockname) < 0 && errno != ENOENT) {
-       ICCfailure = "unlink";
-       i = -1;
-    }
-    return i;
-}
-
-
-/*
-**  Get the server's pid.
-*/
-static pid_t
-ICCserverpid(void)
-{
-    pid_t              pid;
-    FILE               *F;
-    char                *path;
-    char               buff[SMBUF];
-
-    pid = 1;
-    path = concatpath(innconf->pathrun, _PATH_SERVERPID);
-    F = fopen(path, "r");
-    free(path);
-    if (F != NULL) {
-       if (fgets(buff, sizeof buff, F) != NULL)
-           pid = atol(buff);
-       fclose(F);
-    }
-    return pid;
-}
-
-
-/*
-**  See if the server is still there.  When in doubt, assume yes.  Cache the
-**  PID since a rebooted server won't know about our pending message.
-*/
-static bool
-ICCserveralive(pid_t pid)
-{
-    if (kill(pid, 0) > 0 || errno != ESRCH)
-       return true;
-    return false;
-}
-
-
-/*
-**  Send an arbitrary command to the server.
-**  
-**  There is a protocol version (one-byte) on the front of the message,
-**  followed by a two byte length count.  The length includes the protocol
-**  byte and the length itself.  This differs from the protocol in much
-**  earlier versions of INN.
-*/
-int
-ICCcommand(char cmd, const char *argv[], char **replyp)
-{
-    char               *buff;
-    char               *p;
-    const char         *q;
-    char               save;
-    int                        i ;
-#ifndef HAVE_UNIX_DOMAIN_SOCKETS
-    int                        fd;
-    char                *path;
-#endif
-    int                        len;
-    fd_set             Rmask;
-    struct timeval     T;
-    pid_t              pid;
-    ICC_MSGLENTYPE      rlen;
-    ICC_PROTOCOLTYPE    protocol;
-    size_t bufsiz = 64 * 1024 - 1;
-
-    /* Is server there? */
-    pid = ICCserverpid();
-    if (!ICCserveralive(pid)) {
-       ICCfailure = "dead server";
-       return -1;
-    }
-
-    /* Get the length of the buffer. */
-    buff = xmalloc(bufsiz);
-    if (replyp)
-       *replyp = NULL;
-
-    /* Advance to leave space for length + protocol version info. */
-    buff += HEADER_SIZE;
-    bufsiz -= HEADER_SIZE;
-
-    /* Format the message. */
-    snprintf(buff, bufsiz, "%s%c%c", ICCsockname, SC_SEP, cmd);
-    for (p = buff + strlen(buff), i = 0; (q = argv[i]) != NULL; i++) {
-       *p++ = SC_SEP;
-        *p = '\0';
-        strlcat(buff, q, bufsiz);
-        p += strlen(q);
-    }
-
-    /* Send message. */
-    ICCfailure = NULL;
-    len = p - buff + HEADER_SIZE;
-    rlen = htons(len);
-
-    /* now stick in the protocol version and the length. */
-    buff -= HEADER_SIZE;
-    bufsiz += HEADER_SIZE;
-    protocol = ICC_PROTOCOL_1;
-    memcpy(buff, &protocol, sizeof(protocol));
-    memcpy(buff + sizeof(protocol), &rlen, sizeof(rlen));
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    if (sendto(ICCfd, buff, len, 0,(struct sockaddr *) &ICCserv,
-               SUN_LEN(&ICCserv)) < 0) {
-       free(buff);
-       ICCfailure = "sendto";
-       return -1;
-    }
-#else /* !HAVE_UNIX_DOMAIN_SOCKETS */
-    path = concatpath(innconf->pathrun, _PATH_NEWSCONTROL);
-    fd = open(path, O_WRONLY);
-    free(path);
-    if (fd < 0) {
-       free(buff);
-       ICCfailure = "open";
-       return -1;
-    }
-    if (write(fd, buff, len) != len) {
-       i = errno;
-       free(buff);
-       close(fd);
-       errno = i;
-       ICCfailure = "write";
-       return -1;
-    }
-    close(fd);
-#endif /* !HAVE_UNIX_DOMAIN_SOCKETS */
-
-    /* Possibly get a reply. */
-    switch (cmd) {
-    default:
-       if (ICCtimeout >= 0)
-           break;
-       /* FALLTHROUGH */
-    case SC_SHUTDOWN:
-    case SC_XABORT:
-    case SC_XEXEC:
-       free(buff);
-       return 0;
-    }
-
-    /* Wait for the reply. */
-    for ( ; ; ) {
-       FD_ZERO(&Rmask);
-       FD_SET(ICCfd, &Rmask);
-       T.tv_sec = ICCtimeout ? ICCtimeout : 120;
-       T.tv_usec = 0;
-       i = select(ICCfd + 1, &Rmask, NULL, NULL, &T);
-       if (i < 0) {
-           free(buff);
-           ICCfailure = "select";
-           return -1;
-       }
-       if (i > 0 && FD_ISSET(ICCfd, &Rmask))
-           /* Server reply is there; go handle it. */
-           break;
-
-       /* No data -- if we timed out, return. */
-       if (ICCtimeout) {
-           free(buff);
-           errno = ETIMEDOUT;
-           ICCfailure = "timeout";
-           return -1;
-       }
-
-       if (!ICCserveralive(pid)) {
-           free(buff);
-           ICCfailure = "dead server";
-           return -1;
-       }
-    }
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    
-    /* Read the reply. */
-    i = RECVorREAD(ICCfd, buff, bufsiz);
-    if ((unsigned int) i < HEADER_SIZE) {
-        free(buff);
-        ICCfailure = "read";
-        return -1;
-    }
-    memcpy(&protocol, buff, sizeof(protocol));
-    memcpy(&rlen, buff + sizeof(protocol), sizeof(rlen));
-    rlen = ntohs(rlen);
-
-    if (i != rlen) {
-        free(buff);
-        ICCfailure = "short read";
-        return -1;
-    }
-
-    if (protocol != ICC_PROTOCOL_1) {
-        free(buff);
-        ICCfailure = "protocol mismatch";
-        return -1;
-    }
-
-    memmove(buff, buff + HEADER_SIZE, rlen - HEADER_SIZE);
-    i -= HEADER_SIZE;
-
-    buff[i] = '\0';
-
-#else /* !HAVE_UNIX_DOMAIN_SOCKETS */
-
-    i = RECVorREAD(ICCfd, buff, HEADER_SIZE);
-    if (i != HEADER_SIZE)
-       return -1;
-
-    memcpy(&protocol, buff, sizeof(protocol));
-    memcpy(&rlen, buff + sizeof(protocol), sizeof(rlen));
-    rlen = ntohs(rlen) - HEADER_SIZE;
-    if (rlen > bufsiz) {
-        ICCfailure = "bad length";
-        return -1;
-    }
-    
-    i = RECVorREAD(ICCfd, buff, rlen);
-    if (i != rlen) {
-        ICCfailure = "short read";
-       return -1;
-    }
-
-    buff[i] = '\0';
-
-    if (protocol != ICC_PROTOCOL_1) {
-        ICCfailure = "protocol mismatch";
-        return -1;
-    }
-
-#endif /* !HAVE_UNIX_DOMAIN_SOCKETS */
-    
-    /* Parse the rest of the reply; expected to be like
-       <exitcode><space><text>" */
-    i = 0;
-    if (CTYPE(isdigit, buff[0])) {
-       for (p = buff; *p && CTYPE(isdigit, *p); p++)
-           continue;
-       if (*p) {
-           save = *p;
-           *p = '\0';
-           i = atoi(buff);
-           *p = save;
-       }
-    }
-    if (replyp)
-       *replyp = buff;
-    else
-       free(buff);
-
-    return i;
-}
-
-
-/*
-**  Send a "cancel" command.
-*/
-int
-ICCcancel(const char *msgid)
-{
-    const char *args[2];
-
-    args[0] = msgid;
-    args[1] = NULL;
-    return ICCcommand(SC_CANCEL, args, NULL);
-}
-
-
-/*
-**  Send a "go" command.
-*/
-int
-ICCgo(const char *why)
-{
-    const char *args[2];
-
-    args[0] = why;
-    args[1] = NULL;
-    return ICCcommand(SC_GO, args, NULL);
-}
-
-
-/*
-**  Send a "pause" command.
-*/
-int
-ICCpause(const char *why)
-{
-    const char *args[2];
-
-    args[0] = why;
-    args[1] = NULL;
-    return ICCcommand(SC_PAUSE, args, NULL);
-}
-
-
-/*
-**  Send a "reserve" command.
-*/
-int
-ICCreserve(const char *why)
-{
-    const char *args[2];
-
-    args[0] = why;
-    args[1] = NULL;
-    return ICCcommand(SC_RESERVE, args, NULL);
-}
diff --git a/lib/list.c b/lib/list.c
deleted file mode 100644 (file)
index a127abc..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*  $Id: list.c 6168 2003-01-21 06:27:32Z alexk $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/list.h"
-
-void
-list_new(struct list *list)
-{
-    list->head = (struct node *)&list->tail;
-    list->tailpred = (struct node *)&list->head;
-    list->tail = NULL;
-}
-
-struct node *
-list_addhead(struct list *list, struct node *node)
-{
-    node->succ = list->head;
-    node->pred = (struct node *)&list->head;
-    list->head->pred = node;
-    list->head = node;
-    return node;
-}
-
-struct node *
-list_addtail(struct list *list, struct node *node)
-{
-    node->succ = (struct node *)&list->tail;
-    node->pred = list->tailpred;
-    list->tailpred->succ = node;
-    list->tailpred = node;
-    return node;
-}
-
-struct node *
-list_remhead(struct list *list)
-{
-    struct node *node;
-
-    node = list->head->succ;
-    if (node) {
-       node->pred = (struct node *)&list->head;
-        node = list->head;
-        list->head = node->succ;
-    }
-    return node;
-}
-
-struct node *
-list_head(struct list *list)
-{
-    if (list->head->succ)
-       return list->head;
-    return NULL;
-}
-
-struct node *
-list_tail(struct list *list)
-{
-    if (list->tailpred->pred)
-       return list->tailpred;
-    return NULL;
-}
-
-struct node *
-list_succ(struct node *node)
-{
-    if (node->succ->succ)
-       return node->succ;
-    return NULL;
-}
-
-struct node *
-list_pred(struct node *node)
-{
-    if (node->pred->pred)
-       return node->pred;
-    return NULL;
-}
-
-struct node *
-list_remove(struct node *node)
-{
-    node->pred->succ = node->succ;
-    node->succ->pred = node->pred;
-    return node;
-}
-
-struct node *
-list_remtail(struct list *list)
-{
-    struct node *node;
-
-    node = list_tail(list);
-    if (node)
-       list_remove(node);
-    return node;
-}
-
-bool
-list_isempty(struct list *list)
-{
-    return list->tailpred == (struct node *)list;
-}
-
-struct node *
-list_insert(struct list *list, struct node *node, struct node *pred)
-{
-    if (pred) {
-       if (pred->succ) {
-           node->succ = pred->succ;
-           node->pred = pred;
-           pred->succ->pred = node;
-           pred->succ = node;
-       } else {
-           list_addtail(list, node);
-       }
-    } else {
-       list_addhead(list, node);
-    }
-    return node;
-}
diff --git a/lib/localopen.c b/lib/localopen.c
deleted file mode 100644 (file)
index 8460e32..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*  $Id: localopen.c 6155 2003-01-19 19:58:25Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/socket.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-#if HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-
-/*
-**  Open a connection to the local InterNetNews NNTP server and optionally
-**  create stdio FILE's for talking to it.  Return -1 on error.
-*/
-int
-NNTPlocalopen(FILE **FromServerp, FILE **ToServerp, char *errbuff)
-{
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-    int                        i;
-    int                        j;
-    int                        oerrno;
-    struct sockaddr_un server;
-    FILE               *F;
-    char               mybuff[NNTP_STRLEN + 2];
-    char               *buff;
-
-    buff = errbuff ? errbuff : mybuff;
-    *buff = '\0';
-
-    /* Create a socket. */
-    if ((i = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-       return -1;
-
-    /* Connect to the server. */
-    memset(&server, 0, sizeof server);
-    server.sun_family = AF_UNIX;
-    strlcpy(server.sun_path, innconf->pathrun, sizeof(server.sun_path));
-    strlcat(server.sun_path, "/", sizeof(server.sun_path));
-    strlcat(server.sun_path, _PATH_NNTPCONNECT, sizeof(server.sun_path));
-    if (connect(i, (struct sockaddr *)&server, SUN_LEN(&server)) < 0) {
-       oerrno = errno;
-       close(i);
-       errno = oerrno;
-       return -1;
-    }
-
-    /* Connected -- now make sure we can post. */
-    if ((F = fdopen(i, "r")) == NULL) {
-       oerrno = errno;
-       close(i);
-       errno = oerrno;
-       return -1;
-    }
-    if (fgets(buff, sizeof mybuff, F) == NULL) {
-       oerrno = errno;
-       fclose(F);
-       errno = oerrno;
-       return -1;
-    }
-    j = atoi(buff);
-    if (j != NNTP_POSTOK_VAL && j != NNTP_NOPOSTOK_VAL) {
-       fclose(F);
-       /* This seems like a reasonable error code to use... */
-       errno = EPERM;
-       return -1;
-    }
-
-    *FromServerp = F;
-    if ((*ToServerp = fdopen(dup(i), "w")) == NULL) {
-       oerrno = errno;
-       fclose(F);
-       errno = oerrno;
-       return -1;
-    }
-    return 0;
-#else
-    return NNTPconnect("127.0.0.1", innconf->port, FromServerp, ToServerp,
-                       errbuff);
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-}
diff --git a/lib/lockfile.c b/lib/lockfile.c
deleted file mode 100644 (file)
index 185b3e1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*  $Id: lockfile.c 6020 2002-12-20 00:19:58Z rra $
-**
-**  Lock a file or a range in a file.
-**
-**  Provides inn_lock_file and inn_lock_range functions to lock or unlock a
-**  file or ranges within a file with a more convenient syntax than fcntl.
-**  Assume that fcntl is available.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-
-#include "libinn.h"
-
-bool
-inn_lock_file(int fd, enum inn_locktype type, bool block)
-{
-    return inn_lock_range(fd, type, block, 0, 0);
-}
-
-bool
-inn_lock_range(int fd, enum inn_locktype type, bool block, off_t offset,
-               off_t size)
-{
-    struct flock fl;
-    int status;
-
-    switch (type) {
-        case INN_LOCK_READ:     fl.l_type = F_RDLCK;    break;
-        case INN_LOCK_WRITE:    fl.l_type = F_WRLCK;    break;
-        default:
-        case INN_LOCK_UNLOCK:   fl.l_type = F_UNLCK;    break;
-    }
-
-    do {
-       fl.l_whence = SEEK_SET;
-       fl.l_start = offset;
-       fl.l_len = size;
-
-       status = fcntl(fd, block ? F_SETLKW : F_SETLK, &fl);
-    } while (status == -1 && errno == EINTR);
-    return (status != -1);
-}
diff --git a/lib/makedir.c b/lib/makedir.c
deleted file mode 100644 (file)
index 737aeb5..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "libinn.h"
-
-/*
-**  Try to make one directory.  Return false on error.
-*/
-static bool MakeDir(char *Name)
-{
-    struct stat                Sb;
-
-    if (mkdir(Name, GROUPDIR_MODE) >= 0) {
-       return true;
-    }
-
-    /* See if it failed because it already exists. */
-    if (stat(Name, &Sb) >= 0 && S_ISDIR(Sb.st_mode)) {
-       errno = 0;
-       return true;
-    }
-    return false;
-}
-
-
-/*
-**  Given a directory, comp/foo/bar, create that directory and all
-**  intermediate directories needed.  Return true if ok, else false.
-*/
-bool MakeDirectory(char *Name, bool Recurse)
-{
-    char               *p;
-    bool               made;
-
-    /* Optimize common case -- parent almost always exists. */
-    if (MakeDir(Name))
-       return true;
-
-    if (!Recurse)
-       return false;
-
-    /* Try to make each of comp and comp/foo in turn. */
-    for (p = (Name[0] == '/') ? &Name[1] : Name; *p; p++)
-       if (*p == '/') {
-           *p = '\0';
-           made = MakeDir(Name);
-           *p = '/';
-           if (!made)
-               return false;
-       }
-
-    return MakeDir(Name);
-}
diff --git a/lib/md5.c b/lib/md5.c
deleted file mode 100644 (file)
index 6abbee9..0000000
--- a/lib/md5.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*  $Id: md5.c 4154 2000-10-31 16:28:53Z kondou $
-**
-**  RSA Data Security, Inc. MD5 Message-Digest Algorithm
-**
-**  The standard MD5 message digest routines, from RSA Data Security, Inc.
-**  by way of Landon Curt Noll, modified and integrated into INN by Clayton
-**  O'Neill and then simplified somewhat, converted to INN coding style,
-**  and commented by Russ Allbery.
-**
-**  To form the message digest for a message M:
-**    (1) Initialize a context buffer md5_context using md5_init
-**    (2) Call md5_update on md5_context and M
-**    (3) Call md5_final on md5_context
-**  The message digest is now in md5_context->digest[0...15].
-**
-**  Alternately, just call md5_hash on M, passing it a buffer of at least
-**  16 bytes into which to put the digest.  md5_hash does the above
-**  internally for you and is the most convenient interface; the interface
-**  described above, however, is better when all of the data to hash isn't
-**  available neatly in a single buffer (such as hashing data aquired a
-**  block at a time).
-**
-**  For information about MD5, see RFC 1321.
-**
-**  LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-**  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
-**  EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-**  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-**  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-**  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-**  PERFORMANCE OF THIS SOFTWARE.
-**
-**  Copyright (C) 1990, RSA Data Security, Inc.  All rights reserved.
-**
-**  License to copy and use this software is granted provided that it is
-**  identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
-**  in all material mentioning or referencing this software or this
-**  function.
-**
-**  License is also granted to make and use derivative works provided that
-**  such works are identified as "derived from the RSA Data Security,
-**  Inc. MD5 Message-Digest Algorithm" in all material mentioning or
-**  referencing the derived work.
-**
-**  RSA Data Security, Inc. makes no representations concerning either the
-**  merchantability of this software or the suitability of this software for
-**  any particular purpose.  It is provided "as is" without express or
-**  implied warranty of any kind.
-**
-**  These notices must be retained in any copies of any part of this
-**  documentation and/or software.
-*/
-
-/*
-**  The actual mathematics and cryptography are at the bottom of this file,
-**  as those parts should be fully debugged and very infrequently changed.
-**  The core of actual work is done by md5_transform.  The beginning of this
-**  file contains the infrastructure around the mathematics.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "inn/md5.h"
-
-/* Rotate a 32-bit value left, used by both the MD5 mathematics and by the
-   routine below to byteswap data on big-endian machines. */
-#define ROT(X, n)       (((X) << (n)) | ((X) >> (32 - (n))))
-
-/* Almost zero fill padding, used by md5_final.  The 0x80 is part of the MD5
-   hash algorithm, from RFC 1321 section 3.1:
-
-     Padding is performed as follows: a single "1" bit is appended to the
-     message, and then "0" bits are appended so that the length in bits of
-     the padded message becomes congruent to 448, modulo 512.  In all, at
-     least one bit and at most 512 bits are appended.
-
-   Let the compiler zero the remainder of the array for us, guaranteed by
-   ISO C99 6.7.8 paragraph 21.  */
-static const unsigned char padding[MD5_CHUNKSIZE] = { 0x80, 0 /* 0, ... */ };
-
-/* Internal prototypes. */
-static void md5_transform(uint32_t *, const uint32_t *);
-static void md5_update_block(struct md5_context *, const unsigned char *,
-                             size_t);
-
-/* MD5 requires that input data be treated as words in little-endian byte
-   order.  From RFC 1321 section 2:
-
-     Similarly, a sequence of bytes can be interpreted as a sequence of
-     32-bit words, where each consecutive group of four bytes is interpreted
-     as a word with the low-order (least significant) byte given first.
-
-   Input data must therefore be byteswapped on big-endian machines, as must
-   the 16-byte result digest.  Since we have to make a copy of the incoming
-   data anyway to ensure alignment for 4-byte access, we can byteswap it in
-   place. */
-#if !WORDS_BIGENDIAN
-# define decode(data)           /* empty */
-# define encode(data, out)      memcpy((out), (data), MD5_DIGESTSIZE)
-#else
-
-/* The obvious way to do this is to pull single bytes at a time out of the
-   input array and build words from them; this requires three shifts and
-   three Boolean or operations, but it requires four memory reads per word
-   unless the compiler is really smart.  Since we can assume four-byte
-   alignment for the input data, use this optimized routine from J. Touch,
-   USC/ISI.  This requires four shifts, two ands, and two ors, but only one
-   memory read per word. */
-#define swap(word)              \
-    do {                        \
-        htmp = ROT((word), 16); \
-        ltmp = htmp >> 8;       \
-        htmp &= 0x00ff00ff;     \
-        ltmp &= 0x00ff00ff;     \
-        htmp <<= 8;             \
-        (word) = htmp | ltmp;   \
-    } while (0)
-
-/* We process 16 words of data (one MD5 block) of data at a time, completely
-   unrolling the loop manually since it should allow the compiler to take
-   advantage of pipelining and parallel arithmetic units. */
-static void
-decode(uint32_t *data)
-{
-    uint32_t ltmp, htmp;
-
-    swap(data[ 0]); swap(data[ 1]); swap(data[ 2]); swap(data[ 3]);
-    swap(data[ 4]); swap(data[ 5]); swap(data[ 6]); swap(data[ 7]);
-    swap(data[ 8]); swap(data[ 9]); swap(data[10]); swap(data[11]);
-    swap(data[12]); swap(data[13]); swap(data[14]); swap(data[15]);
-}
-
-/* Used by md5_final to generate the final digest.  The digest is not
-   guaranteed to be aligned for 4-byte access but we are allowed to be
-   destructive, so byteswap first and then copy the result over. */
-static void
-encode(uint32_t *data, unsigned char *out)
-{
-    uint32_t ltmp, htmp;
-
-    swap(data[0]);
-    swap(data[1]);
-    swap(data[2]);
-    swap(data[3]);
-    memcpy(out, data, MD5_DIGESTSIZE);
-}
-
-#endif /* WORDS_BIGENDIAN */
-
-
-/*
-**  That takes care of the preliminaries; now the real fun begins.  The
-**  initialization function for a struct md5_context; set lengths to zero
-**  and initialize our working buffer with the magic constants (c.f. RFC
-**  1321 section 3.3).
-*/
-void
-md5_init(struct md5_context *context)
-{
-    context->buf[0] = 0x67452301U;
-    context->buf[1] = 0xefcdab89U;
-    context->buf[2] = 0x98badcfeU;
-    context->buf[3] = 0x10325476U;
-
-    context->count[0] = 0;
-    context->count[1] = 0;
-    context->datalen  = 0;
-}
-
-
-/*
-**  The workhorse function, called for each chunk of data.  Update the
-**  message-digest context to account for the presence of each of the
-**  characters data[0 .. count - 1] in the message whose digest is being
-**  computed.  Accepts any length of data; all whole blocks are processed
-**  and the remaining data is buffered for later processing by either
-**  another call to md5_update or by md5_final.
-*/
-void
-md5_update(struct md5_context *context, const unsigned char *data,
-           size_t count)
-{
-    unsigned int datalen = context->datalen;
-    unsigned int left;
-    size_t high_count, low_count, used;
-
-    /* Update the count of hashed bytes.  The machinations here are to do
-       the right thing on a platform where size_t > 32 bits without causing
-       compiler warnings on platforms where it's 32 bits.  RFC 1321 section
-       3.2 says:
-
-         A 64-bit representation of b (the length of the message before the
-         padding bits were added) is appended to the result of the previous
-         step.  In the unlikely event that b is greater than 2^64, then only
-         the low-order 64 bits of b are used.
-
-       so we can just ignore the higher bits of count if size_t is larger
-       than 64 bits.  (Think ahead!)  If size_t is only 32 bits, the
-       compiler should kill the whole if statement as dead code. */
-    if (sizeof(count) > 4) {
-        high_count = count >> 31;
-        context->count[1] += (high_count >> 1) & 0xffffffffU;
-    }
-
-    /* Now deal with count[0].  Add in the low 32 bits of count and
-       increment count[1] if count[0] wraps.  Isn't unsigned arithmetic
-       cool? */
-    low_count = count & 0xffffffffU;
-    context->count[0] += low_count;
-    if (context->count[0] < low_count)
-        context->count[1]++;
-
-    /* See if we already have some data queued.  If so, try to complete a
-       block and then deal with it first.  If the new data still doesn't
-       fill the buffer, add it to the buffer and return.  Otherwise,
-       transform that block and update data and count to account for the
-       data we've already used. */
-    if (datalen > 0) {
-        left = MD5_CHUNKSIZE - datalen;
-        if (left > count) {
-            memcpy(context->in.byte + datalen, data, count);
-            context->datalen += count;
-            return;
-        } else {
-            memcpy(context->in.byte + datalen, data, left);
-            decode(context->in.word);
-            md5_transform(context->buf, context->in.word);
-            data += left;
-            count -= left;
-            context->datalen = 0;
-        }
-    }
-
-    /* If we have a block of data or more left, pass the rest off to
-       md5_update_block to deal with all of the full blocks available. */
-    if (count >= MD5_CHUNKSIZE) {
-        md5_update_block(context, data, count);
-        used = (count / MD5_CHUNKSIZE) * MD5_CHUNKSIZE;
-        data += used;
-        count -= used;
-    }
-
-    /* If there's anything left, buffer it until we can complete a block or
-       for md5_final to deal with. */
-    if (count > 0) {
-        memcpy(context->in.byte, data, count);
-        context->datalen = count;
-    }
-}
-
-
-/*
-**  Update the message-digest context to account for the presence of each of
-**  the characters data[0 .. count - 1] in the message whose digest is being
-**  computed, except that we only deal with full blocks of data.  The data
-**  is processed one block at a time, and partial blocks at the end are
-**  ignored (they're dealt with by md5_update, which calls this routine.
-**
-**  Note that we always make a copy of the input data into an array of
-**  4-byte values.  If our input data were guaranteed to be aligned for
-**  4-byte access, we could just use the input buffer directly on
-**  little-endian machines, and in fact this implementation used to do that.
-**  However, a requirement to align isn't always easily detectable, even by
-**  configure (an Alpha running Tru64 will appear to allow unaligned
-**  accesses, but will spew errors to the terminal if you do it).  On top of
-**  that, even when it's allowed, unaligned access is quite frequently
-**  slower; we're about to do four reads of each word of the input data for
-**  the calculations, so doing one additional copy of the data up-front is
-**  probably worth it.
-*/
-static void
-md5_update_block(struct md5_context *context, const unsigned char *data,
-                 size_t count)
-{
-    uint32_t in[MD5_CHUNKWORDS];
-
-    /* Process data in MD5_CHUNKSIZE blocks. */
-    while (count >= MD5_CHUNKSIZE) {
-        memcpy(in, data, MD5_CHUNKSIZE);
-        decode(in);
-        md5_transform(context->buf, in);
-        data += MD5_CHUNKSIZE;
-        count -= MD5_CHUNKSIZE;
-    }
-}
-
-
-/*
-**  Terminates the message-digest computation, accounting for any final
-**  trailing data and adding the message length to the hashed data, and ends
-**  with the desired message digest in context->digest[0...15].
-*/
-void
-md5_final(struct md5_context *context)
-{
-    unsigned int pad_needed, left;
-    uint32_t count[2];
-    uint32_t *countloc;
-
-    /* Save the count before appending the padding. */
-    count[0] = context->count[0];
-    count[1] = context->count[1];
-
-    /* Pad the final block of data.  RFC 1321 section 3.1:
-
-         The message is "padded" (extended) so that its length (in bits) is
-         congruent to 448, modulo 512.  That is, the message is extended so
-         that it is just 64 bits shy of being a multiple of 512 bits long.
-         Padding is always performed, even if the length of the message is
-         already congruent to 448, modulo 512.
-
-       The 64 bits (two words) left are for the 64-bit count of bits
-       hashed.  We'll need at most 64 bytes of padding; lucky that the
-       padding array is exactly that size! */
-    left = context->datalen;
-    pad_needed = (left < 64 - 8) ? (64 - 8 - left) : (128 - 8 - left);
-    md5_update(context, padding, pad_needed);
-
-    /* Append length in bits and transform.  Note that we cheat slightly
-       here to save a few operations on big-endian machines; the algorithm
-       says that we should add the length, in little-endian byte order, to
-       the last block of data.  We'd then transform it into big-endian order
-       on a big-endian machine.  But the count is *already* in big-endian
-       order on a big-endian machine, so effectively we'd be byteswapping it
-       twice.  Instead, add it to the block after doing byte swapping on the
-       rest.
-
-       Note that we've been counting *bytes*, but the algorithm demands the
-       length in *bits*, so shift things around a bit. */
-    decode(context->in.word);
-    countloc = &context->in.word[MD5_CHUNKWORDS - 2];
-    countloc[0] = count[0] << 3;
-    countloc[1] = (count[1] << 3) | (count[0] >> 29);
-    md5_transform(context->buf, context->in.word);
-
-    /* Recover the final digest.  Whoo-hoo, we're done! */
-    encode(context->buf, context->digest);
-}
-
-
-/*
-**  A convenience wrapper around md5_init, md5_update, and md5_final.  Takes
-**  a pointer to a buffer of data, the length of the data, and a pointer to
-**  a buffer of at least 16 bytes into which to write the message digest.
-*/
-void
-md5_hash(const unsigned char *data, size_t length, unsigned char *digest)
-{
-    struct md5_context context;
-
-    md5_init(&context);
-    md5_update(&context, data, length);
-    md5_final(&context);
-    memcpy(digest, context.digest, MD5_DIGESTSIZE);
-}
-
-
-/*
-**  Look out, here comes the math.
-**
-**  There are no user-serviceable parts below this point unless you know
-**  quite a bit about MD5 or optimization of integer math.  The only
-**  function remaining, down below, is md5_transform; the rest of this is
-**  setting up macros to make that function more readable.
-**
-**  The F, G, H and I are basic MD5 functions.  The following identity saves
-**  one boolean operation.
-**
-**  F: (((x) & (y)) | (~(x) & (z))) == ((z) ^ ((x) & ((y) ^ (z))))
-**  G: (((x) & (z)) | ((y) & ~(z))) == ((y) ^ ((z) & ((x) ^ (y))))
-*/
-#define F(x, y, z)      ((z) ^ ((x) & ((y) ^ (z))))
-#define G(x, y, z)      ((y) ^ ((z) & ((x) ^ (y))))
-#define H(x, y, z)      ((x) ^ (y) ^ (z))
-#define I(x, y, z)      ((y) ^ ((x) | (~z)))
-
-/*
-**  FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.  Rotation
-**  is separate from addition to prevent recomputation.  S?? are the shift
-**  values for each round.
-*/
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define FF(a, b, c, d, x, s, ac)                                \
-    {                                                           \
-        (a) += F((b), (c), (d)) + (x) + (uint32_t) (ac);        \
-        (a) = ROT((a), (s));                                    \
-        (a) += (b);                                             \
-    }
-
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define GG(a, b, c, d, x, s, ac)                                \
-    {                                                           \
-        (a) += G((b), (c), (d)) + (x) + (uint32_t) (ac);        \
-        (a) = ROT((a), (s));                                    \
-        (a) += (b);                                             \
-    }
-
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define HH(a, b, c, d, x, s, ac)                                \
-    {                                                           \
-        (a) += H((b), (c), (d)) + (x) + (uint32_t) (ac);        \
-        (a) = ROT((a), (s));                                    \
-        (a) += (b);                                             \
-    }
-
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-#define II(a, b, c, d, x, s, ac)                                \
-    {                                                           \
-        (a) += I((b), (c), (d)) + (x) + (uint32_t) (ac);        \
-        (a) = ROT((a), (s));                                    \
-        (a) += (b);                                             \
-    }
-
-/*
-**  Basic MD5 step.  Transforms buf based on in.
-*/
-static void
-md5_transform(uint32_t *buf, const uint32_t *in)
-{
-    uint32_t a = buf[0];
-    uint32_t b = buf[1];
-    uint32_t c = buf[2];
-    uint32_t d = buf[3];
-
-    /* Round 1 */
-    FF(a, b, c, d, in[ 0], S11, 3614090360UL); /*  1 */
-    FF(d, a, b, c, in[ 1], S12, 3905402710UL); /*  2 */
-    FF(c, d, a, b, in[ 2], S13,  606105819UL); /*  3 */
-    FF(b, c, d, a, in[ 3], S14, 3250441966UL); /*  4 */
-    FF(a, b, c, d, in[ 4], S11, 4118548399UL); /*  5 */
-    FF(d, a, b, c, in[ 5], S12, 1200080426UL); /*  6 */
-    FF(c, d, a, b, in[ 6], S13, 2821735955UL); /*  7 */
-    FF(b, c, d, a, in[ 7], S14, 4249261313UL); /*  8 */
-    FF(a, b, c, d, in[ 8], S11, 1770035416UL); /*  9 */
-    FF(d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
-    FF(c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
-    FF(b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
-    FF(a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
-    FF(d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
-    FF(c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
-    FF(b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
-
-    /* Round 2 */
-    GG(a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
-    GG(d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
-    GG(c, d, a, b, in[11], S23,  643717713UL); /* 19 */
-    GG(b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
-    GG(a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
-    GG(d, a, b, c, in[10], S22,   38016083UL); /* 22 */
-    GG(c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
-    GG(b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
-    GG(a, b, c, d, in[ 9], S21,  568446438UL); /* 25 */
-    GG(d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
-    GG(c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
-    GG(b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
-    GG(a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
-    GG(d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
-    GG(c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
-    GG(b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
-
-    /* Round 3 */
-    HH(a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
-    HH(d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
-    HH(c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
-    HH(b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
-    HH(a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
-    HH(d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
-    HH(c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
-    HH(b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
-    HH(a, b, c, d, in[13], S31,  681279174UL); /* 41 */
-    HH(d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
-    HH(c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
-    HH(b, c, d, a, in[ 6], S34,   76029189UL); /* 44 */
-    HH(a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
-    HH(d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
-    HH(c, d, a, b, in[15], S33,  530742520UL); /* 47 */
-    HH(b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
-
-    /* Round 4 */
-    II(a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
-    II(d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
-    II(c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
-    II(b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
-    II(a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
-    II(d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
-    II(c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
-    II(b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
-    II(a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
-    II(d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
-    II(c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
-    II(b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
-    II(a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
-    II(d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
-    II(c, d, a, b, in[ 2], S43,  718787259UL); /* 63 */
-    II(b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
-
-    buf[0] += a;
-    buf[1] += b;
-    buf[2] += c;
-    buf[3] += d;
-}
diff --git a/lib/memcmp.c b/lib/memcmp.c
deleted file mode 100644 (file)
index b89b875..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*  $Id: memcmp.c 5049 2001-12-12 09:06:00Z rra $
-**
-**  Replacement for a missing or broken memcmp.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine memcmp
-**  for those platforms that don't have it or where it doesn't work right
-**  (such as on SunOS where it can't deal with eight-bit characters).
-*/
-
-#include "config.h"
-#include <sys/types.h>
-
-/* If we're running the test suite, rename memcmp to avoid conflicts with
-   the system version. */
-#if TESTING
-# define memcmp test_memcmp
-int test_memcmp(const void *, const void *, size_t);
-#endif
-
-int
-memcmp(const void *s1, const void *s2, size_t n)
-{
-    size_t i;
-    const unsigned char *p1, *p2;
-
-    /* It's technically illegal to call memcmp with NULL pointers, but we
-       may as well check anyway. */
-    if (!s1)
-        return !s2 ? 0 : -1;
-    if (!s2)
-        return 1;
-
-    p1 = (const unsigned char *) s1;
-    p2 = (const unsigned char *) s2;
-    for (i = 0; i < n; i++, p1++, p2++)
-        if (*p1 != *p2)
-           return (int) *p1 - (int) *p2;
-    return 0;
-}
diff --git a/lib/messages.c b/lib/messages.c
deleted file mode 100644 (file)
index 62e6f04..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/* $Id: messages.c 5496 2002-06-07 13:59:06Z alexk $
-**
-**  Message and error reporting (possibly fatal).
-**
-**  Usage:
-**
-**      extern int cleanup(void);
-**      extern void log(int, const char *, va_list, int);
-**
-**      message_fatal_cleanup = cleanup;
-**      message_program_name = argv[0];
-**
-**      warn("Something horrible happened at %lu", time);
-**      syswarn("Couldn't unlink temporary file %s", tmpfile);
-**
-**      die("Something fatal happened at %lu", time);
-**      sysdie("open of %s failed", filename);
-**
-**      debug("Some debugging message about %s", string);
-**      trace(TRACE_PROGRAM, "Program trace output");
-**      notice("Informational notices");
-**
-**      message_handlers_warn(1, log);
-**      warn("This now goes through our log function");
-**
-**  These functions implement message reporting through user-configurable
-**  handler functions.  debug() only does something if DEBUG is defined,
-**  trace() supports sending trace messages in one of a number of configurable
-**  classes of traces so that they can be turned on or off independently, and
-**  notice() and warn() just output messages as configured.  die() similarly
-**  outputs a message but then exits, normally with a status of 1.
-**
-**  The sys* versions do the same, but append a colon, a space, and the
-**  results of strerror(errno) to the end of the message.  All functions
-**  accept printf-style formatting strings and arguments.
-**
-**  If message_fatal_cleanup is non-NULL, it is called before exit by die and
-**  sysdie and its return value is used as the argument to exit.  It is a
-**  pointer to a function taking no arguments and returning an int, and can be
-**  used to call cleanup functions or to exit in some alternate fashion (such
-**  as by calling _exit).
-**
-**  If message_program_name is non-NULL, the string it points to, followed by
-**  a colon and a space, is prepended to all error messages logged through the
-**  message_log_stdout and message_log_stderr message handlers (the former is
-**  the default for notice, and the latter is the default for warn and die).
-**
-**  Honoring error_program_name and printing to stderr is just the default
-**  handler; with message_handlers_* the handlers for any message function can
-**  be changed.  By default, notice prints to stdout, warn and die print to
-**  stderr, and the others don't do anything at all.  These functions take a
-**  count of handlers and then that many function pointers, each one to a
-**  function that takes a message length (the number of characters snprintf
-**  generates given the format and arguments), a format, an argument list as a
-**  va_list, and the applicable errno value (if any).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <syslog.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-/* The default handler lists. */
-static message_handler_func stdout_handlers[2] = {
-    message_log_stdout, NULL
-};
-static message_handler_func stderr_handlers[2] = {
-    message_log_stderr, NULL
-};
-
-/* The list of logging functions currently in effect. */
-static message_handler_func *debug_handlers  = NULL;
-static message_handler_func *trace_handlers  = NULL;
-static message_handler_func *notice_handlers = stdout_handlers;
-static message_handler_func *warn_handlers   = stderr_handlers;
-static message_handler_func *die_handlers    = stderr_handlers;
-
-/* If non-NULL, called before exit and its return value passed to exit. */
-int (*message_fatal_cleanup)(void) = NULL;
-
-/* If non-NULL, prepended (followed by ": ") to messages. */
-const char *message_program_name = NULL;
-
-/* Whether or not we're currently outputting a particular type of trace. */
-static bool tracing[TRACE_ALL] = { false /* false, ... */ };
-
-
-/*
-**  Set the handlers for a particular message function.  Takes a pointer to
-**  the handler list, the count of handlers, and the argument list.
-*/
-static void
-message_handlers(message_handler_func **list, int count, va_list args)
-{
-    int i;
-
-    if (*list != stdout_handlers && *list != stderr_handlers)
-        free(*list);
-    *list = xmalloc(sizeof(message_handler_func) * (count + 1));
-    for (i = 0; i < count; i++)
-        (*list)[i] = (message_handler_func) va_arg(args, message_handler_func);
-    (*list)[count] = NULL;
-}
-
-
-/*
-**  There's no good way of writing these handlers without a bunch of code
-**  duplication since we can't assume variadic macros, but I can at least make
-**  it easier to write and keep them consistent.
-*/
-#define HANDLER_FUNCTION(type)                                  \
-    void                                                        \
-    message_handlers_ ## type(int count, ...)                   \
-    {                                                           \
-        va_list args;                                           \
-                                                                \
-        va_start(args, count);                                  \
-        message_handlers(& type ## _handlers, count, args);     \
-        va_end(args);                                           \
-    }
-HANDLER_FUNCTION(debug)
-HANDLER_FUNCTION(trace)
-HANDLER_FUNCTION(notice)
-HANDLER_FUNCTION(warn)
-HANDLER_FUNCTION(die)
-
-
-/*
-**  Print a message to stdout, supporting message_program_name.
-*/
-void
-message_log_stdout(int len UNUSED, const char *fmt, va_list args, int err)
-{
-    if (message_program_name != NULL)
-        fprintf(stdout, "%s: ", message_program_name);
-    vfprintf(stdout, fmt, args);
-    if (err)
-        fprintf(stdout, ": %s", strerror(err));
-    fprintf(stdout, "\n");
-}
-
-
-/*
-**  Print a message to stderr, supporting message_program_name.  Also flush
-**  stdout so that errors and regular output occur in the right order.
-*/
-void
-message_log_stderr(int len UNUSED, const char *fmt, va_list args, int err)
-{
-    fflush(stdout);
-    if (message_program_name != NULL)
-        fprintf(stderr, "%s: ", message_program_name);
-    vfprintf(stderr, fmt, args);
-    if (err)
-        fprintf(stderr, ": %s", strerror(err));
-    fprintf(stderr, "\n");
-}
-
-
-/*
-**  Log a message to syslog.  This is a helper function used to implement all
-**  of the syslog message log handlers.  It takes the same arguments as a
-**  regular message handler function but with an additional priority
-**  argument.
-*/
-static void
-message_log_syslog(int pri, int len, const char *fmt, va_list args, int err)
-{
-    char *buffer;
-
-    buffer = malloc(len + 1);
-    if (buffer == NULL) {
-        fprintf(stderr, "failed to malloc %u bytes at %s line %d: %s",
-                len + 1, __FILE__, __LINE__, strerror(errno));
-        exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
-    }
-    vsnprintf(buffer, len + 1, fmt, args);
-    syslog(pri, err ? "%s: %m" : "%s", buffer);
-    free(buffer);
-}
-
-
-/*
-**  Do the same sort of wrapper to generate all of the separate syslog logging
-**  functions.
-*/
-#define SYSLOG_FUNCTION(name, type)                                     \
-    void                                                                \
-    message_log_syslog_ ## name(int l, const char *f, va_list a, int e) \
-    {                                                                   \
-        message_log_syslog(LOG_ ## type, l, f, a, e);                   \
-    }
-SYSLOG_FUNCTION(debug,   DEBUG)
-SYSLOG_FUNCTION(info,    INFO)
-SYSLOG_FUNCTION(notice,  NOTICE)
-SYSLOG_FUNCTION(warning, WARNING)
-SYSLOG_FUNCTION(err,     ERR)
-SYSLOG_FUNCTION(crit,    CRIT)
-
-
-/*
-**  Enable or disable tracing for particular classes of messages.
-*/
-void
-message_trace_enable(enum message_trace type, bool enable)
-{
-    if (type > TRACE_ALL)
-        return;
-    if (type == TRACE_ALL) {
-        int i;
-
-        for (i = 0; i < TRACE_ALL; i++)
-            tracing[i] = enable;
-    } else {
-        tracing[type] = enable;
-    }
-}
-
-
-/*
-**  All of the message handlers.  There's a lot of code duplication here too,
-**  but each one is still *slightly* different and va_start has to be called
-**  multiple times, so it's hard to get rid of the duplication.
-*/
-
-#ifdef DEBUG
-void
-debug(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-
-    if (debug_handlers == NULL)
-        return;
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = debug_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, 0);
-        va_end(args);
-    }
-}
-#elif !INN_HAVE_C99_VAMACROS && !INN_HAVE_GNU_VAMACROS
-void debug(const char *format UNUSED, ...) { }
-#endif
-
-void
-trace(enum message_trace type, const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-
-    if (trace_handlers == NULL || !tracing[type])
-        return;
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = trace_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, 0);
-        va_end(args);
-    }
-}
-
-void
-notice(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = notice_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, 0);
-        va_end(args);
-    }
-}
-
-void
-sysnotice(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-    int error = errno;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = notice_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, error);
-        va_end(args);
-    }
-}
-
-void
-warn(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = warn_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, 0);
-        va_end(args);
-    }
-}
-
-void
-syswarn(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-    int error = errno;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length < 0)
-        return;
-    for (log = warn_handlers; *log != NULL; log++) {
-        va_start(args, format);
-        (**log)(length, format, args, error);
-        va_end(args);
-    }
-}
-
-void
-die(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length >= 0)
-        for (log = die_handlers; *log != NULL; log++) {
-            va_start(args, format);
-            (**log)(length, format, args, 0);
-            va_end(args);
-        }
-    exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
-}
-
-void
-sysdie(const char *format, ...)
-{
-    va_list args;
-    message_handler_func *log;
-    int length;
-    int error = errno;
-
-    va_start(args, format);
-    length = vsnprintf(NULL, 0, format, args);
-    va_end(args);
-    if (length >= 0)
-        for (log = die_handlers; *log != NULL; log++) {
-            va_start(args, format);
-            (**log)(length, format, args, error);
-            va_end(args);
-        }
-    exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
-}
diff --git a/lib/mkstemp.c b/lib/mkstemp.c
deleted file mode 100644 (file)
index fe4f385..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*  $Id: mkstemp.c 5329 2002-03-17 07:39:14Z rra $
-**
-**  Replacement for a missing mkstemp.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the library function mkstemp for those
-**  systems that don't have it.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <errno.h>
-#include <fcntl.h>
-
-/* If we're running the test suite, rename mkstemp to avoid conflicts with the
-   system version.  #undef it first because some systems may define it to
-   another name. */
-#if TESTING
-# undef mkstemp
-# define mkstemp test_mkstemp
-int test_mkstemp(char *);
-#endif
-
-/* Pick the longest available integer type. */
-#if HAVE_LONG_LONG
-typedef unsigned long long long_int_type;
-#else
-typedef unsigned long long_int_type;
-#endif
-
-int
-mkstemp(char *template)
-{
-    static const char letters[] =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-    size_t length;
-    char *XXXXXX;
-    struct timeval tv;
-    long_int_type randnum, working;
-    int i, tries, fd;
-
-    /* Make sure we have a valid template and initialize p to point at the
-       beginning of the template portion of the string. */
-    length = strlen(template);
-    if (length < 6) {
-        errno = EINVAL;
-        return -1;
-    }
-    XXXXXX = template + length - 6;
-    if (strcmp(XXXXXX, "XXXXXX") != 0) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    /* Get some more-or-less random information. */
-    gettimeofday(&tv, NULL);
-    randnum = ((long_int_type) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid();
-
-    /* Now, try to find a working file name.  We try no more than TMP_MAX file
-       names. */
-    for (tries = 0; tries < TMP_MAX; tries++) {
-        for (working = randnum, i = 0; i < 6; i++) {
-            XXXXXX[i] = letters[working % 62];
-            working /= 62;
-        }
-        fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
-        if (fd >= 0 || errno != EEXIST)
-            return fd;
-
-        /* This is a relatively random increment.  Cut off the tail end of
-           tv_usec since it's often predictable. */
-        randnum += (tv.tv_usec >> 10) & 0xfff;
-    }
-    errno = EEXIST;
-    return -1;
-}
diff --git a/lib/mmap.c b/lib/mmap.c
deleted file mode 100644 (file)
index 3eaacc6..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*  $Id: mmap.c 7598 2007-02-09 02:40:51Z eagle $
-**
-**  MMap manipulation routines
-**
-**  Written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  These routines work with mmap()ed memory
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-
-#include "inn/messages.h"
-#include "inn/mmap.h"
-
-/*
-**  Figure out what page an address is in and flush those pages
-*/
-void
-inn__mapcntl(void *p, size_t length, int flags)
-{
-    int pagesize;
-
-    pagesize = getpagesize();
-    if (pagesize == -1)
-        syswarn("getpagesize failed");
-    else {
-       char *start, *end;
-
-       start = (char *)((size_t)p & ~(size_t)(pagesize - 1));
-       end = (char *)((size_t)((char *)p + length + pagesize) &
-                      ~(size_t)(pagesize - 1));
-       msync(start, end - start, flags);
-    }
-}
diff --git a/lib/parsedate.y b/lib/parsedate.y
deleted file mode 100644 (file)
index 1cad6f8..0000000
+++ /dev/null
@@ -1,861 +0,0 @@
-%{
-/*  $Id: parsedate.y 6372 2003-05-31 19:48:28Z rra $
-**
-**  Originally written by Steven M. Bellovin <smb@research.att.com> while
-**  at the University of North Carolina at Chapel Hill.  Later tweaked by
-**  a couple of people on Usenet.  Completely overhauled by Rich $alz
-**  <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990.
-**  Further revised (removed obsolete constructs and cleaned up timezone
-**  names) in August, 1991, by Rich.  Paul Eggert <eggert@twinsun.com>
-**  helped in September, 1992.
-**
-**  This grammar has six shift/reduce conflicts.
-**
-**  This code is in the public domain and has no copyright.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#if defined(_HPUX_SOURCE)
-# include <alloca.h>
-#endif
-
-#ifdef TM_IN_SYS_TIME
-# include <sys/time.h>
-#else
-# include <time.h>
-#endif
-
-#include "libinn.h"
-
-
-#define yylhs          date_yylhs
-#define yylen          date_yylen
-#define yydefred       date_yydefred
-#define yydgoto                date_yydgoto
-#define yysindex       date_yysindex
-#define yyrindex       date_yyrindex
-#define yygindex       date_yygindex
-#define yytable                date_yytable
-#define yycheck                date_yycheck
-#define yyparse                date_parse
-#define yylex          date_lex
-#define yyerror                date_error
-#define yymaxdepth     date_yymaxdepth
-
-
-static int date_lex(void);
-
-int yyparse(void);
-
-    /* See the LeapYears table in Convert. */
-#define EPOCH          1970
-#define END_OF_TIME    2038
-    /* Constants for general time calculations. */
-#define DST_OFFSET     1
-#define SECSPERDAY     (24L * 60L * 60L)
-    /* Readability for TABLE stuff. */
-#define HOUR(x)                (x * 60)
-
-#define LPAREN         '('
-#define RPAREN         ')'
-#define IS7BIT(x)      ((unsigned int)(x) < 0200)
-
-
-/*
-**  An entry in the lexical lookup table.
-*/
-typedef struct _TABLE {
-    const char * name;
-    int          type;
-    time_t       value;
-} TABLE;
-
-/*
-**  Daylight-savings mode:  on, off, or not yet known.
-*/
-typedef enum _DSTMODE {
-    DSTon, DSToff, DSTmaybe
-} DSTMODE;
-
-/*
-**  Meridian:  am, pm, or 24-hour style.
-*/
-typedef enum _MERIDIAN {
-    MERam, MERpm, MER24
-} MERIDIAN;
-
-
-/*
-**  Global variables.  We could get rid of most of them by using a yacc
-**  union, but this is more efficient.  (This routine predates the
-**  yacc %union construct.)
-*/
-static char    *yyInput;
-static DSTMODE yyDSTmode;
-static int     yyHaveDate;
-static int     yyHaveRel;
-static int     yyHaveTime;
-static time_t  yyTimezone;
-static time_t  yyDay;
-static time_t  yyHour;
-static time_t  yyMinutes;
-static time_t  yyMonth;
-static time_t  yySeconds;
-static time_t  yyYear;
-static MERIDIAN        yyMeridian;
-static time_t  yyRelMonth;
-static time_t  yyRelSeconds;
-
-
-/* extern struct tm    *localtime(); */
-
-static void            date_error(const char *s);
-%}
-
-%union {
-    time_t             Number;
-    enum _MERIDIAN     Meridian;
-}
-
-%token tDAY tDAYZONE tMERIDIAN tMONTH tMONTH_UNIT tSEC_UNIT tSNUMBER
-%token tUNUMBER tZONE
-
-%type  <Number>        tDAYZONE tMONTH tMONTH_UNIT tSEC_UNIT
-%type  <Number>        tSNUMBER tUNUMBER tZONE numzone zone
-%type  <Meridian>      tMERIDIAN o_merid
-
-%%
-
-spec   : /* NULL */
-       | spec item
-       ;
-
-item   : time {
-           yyHaveTime++;
-#if    defined(lint)
-           /* I am compulsive about lint natterings... */
-           if (yyHaveTime == -1) {
-               YYERROR;
-           }
-#endif /* defined(lint) */
-       }
-       | time zone {
-           yyHaveTime++;
-           yyTimezone = $2;
-       }
-       | date {
-           yyHaveDate++;
-       }
-       | rel {
-           yyHaveRel = 1;
-       }
-       ;
-
-time   : tUNUMBER o_merid {
-           if ($1 < 100) {
-               yyHour = $1;
-               yyMinutes = 0;
-           }
-           else {
-               yyHour = $1 / 100;
-               yyMinutes = $1 % 100;
-           }
-           yySeconds = 0;
-           yyMeridian = $2;
-       }
-       | tUNUMBER ':' tUNUMBER o_merid {
-           yyHour = $1;
-           yyMinutes = $3;
-           yySeconds = 0;
-           yyMeridian = $4;
-       }
-       | tUNUMBER ':' tUNUMBER numzone {
-           yyHour = $1;
-           yyMinutes = $3;
-           yyTimezone = $4;
-           yyMeridian = MER24;
-           yyDSTmode = DSToff;
-       }
-       | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
-           yyHour = $1;
-           yyMinutes = $3;
-           yySeconds = $5;
-           yyMeridian = $6;
-       }
-       | tUNUMBER ':' tUNUMBER ':' tUNUMBER numzone {
-           yyHour = $1;
-           yyMinutes = $3;
-           yySeconds = $5;
-           yyTimezone = $6;
-           yyMeridian = MER24;
-           yyDSTmode = DSToff;
-       }
-       ;
-
-zone   : tZONE {
-           $$ = $1;
-           yyDSTmode = DSToff;
-       }
-       | tDAYZONE {
-           $$ = $1;
-           yyDSTmode = DSTon;
-       }
-       | tZONE numzone {
-           /* Only allow "GMT+300" and "GMT-0800" */
-           if ($1 != 0) {
-               YYABORT;
-           }
-           $$ = $2;
-           yyDSTmode = DSToff;
-       }
-       | numzone {
-           $$ = $1;
-           yyDSTmode = DSToff;
-       }
-       ;
-
-numzone        : tSNUMBER {
-           int         i;
-
-           /* Unix and GMT and numeric timezones -- a little confusing. */
-           if ($1 < 0) {
-               /* Don't work with negative modulus. */
-               $1 = -$1;
-               if ($1 > 9999 || (i = $1 % 100) >= 60) {
-                   YYABORT;
-               }
-               $$ = ($1 / 100) * 60 + i;
-           }
-           else {
-               if ($1 > 9999 || (i = $1 % 100) >= 60) {
-                   YYABORT;
-               }
-               $$ = -(($1 / 100) * 60 + i);
-           }
-       }
-       ;
-
-date   : tUNUMBER '/' tUNUMBER {
-           yyMonth = $1;
-           yyDay = $3;
-       }
-       | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
-           if ($1 > 100) {
-               /* assume YYYY/MM/DD format, so need not to add 1900 */
-               if ($1 > 999) {
-                   yyYear = $1;
-               } else {
-                   yyYear = 1900 + $1;
-               }
-               yyMonth = $3;
-               yyDay = $5;
-           }
-           else {
-               /* assume MM/DD/YY* format */
-               yyMonth = $1;
-               yyDay = $3;
-               if ($5 > 999) {
-                   /* assume year is YYYY format, so need not to add 1900 */
-                   yyYear = $5;
-               } else if ($5 < 100) {
-                   /* assume year is YY format, so need to add 1900 */
-                   yyYear = $5 + (yyYear / 100 + (yyYear % 100 - $5) / 50) * 100;
-               } else {
-                   yyYear = 1900 + $5;
-               }
-           }
-       }
-       | tMONTH tUNUMBER {
-           yyMonth = $1;
-           yyDay = $2;
-       }
-       | tMONTH tUNUMBER ',' tUNUMBER {
-           yyMonth = $1;
-           yyDay = $2;
-           if ($4 > 999) {
-               /* assume year is YYYY format, so need not to add 1900 */
-               yyYear = $4;
-           } else if ($4 < 100) {
-               /* assume year is YY format, so need to add 1900 */
-               yyYear = $4 + (yyYear / 100 + (yyYear % 100 - $4) / 50) * 100;
-           } else {
-               yyYear = 1900 + $4;
-           }
-       }
-       | tUNUMBER tMONTH {
-           yyDay = $1;
-           yyMonth = $2;
-       }
-       | tUNUMBER tMONTH tUNUMBER {
-           yyDay = $1;
-           yyMonth = $2;
-           if ($3 > 999) {
-               /* assume year is YYYY format, so need not to add 1900 */
-               yyYear = $3;
-           } else if ($3 < 100) {
-               /* assume year is YY format, so need to add 1900 */
-               yyYear = $3 + (yyYear / 100 + (yyYear % 100 - $3) / 50) * 100;
-           } else {
-               yyYear = 1900 + $3;
-           }
-       }
-       | tDAY ',' tUNUMBER tMONTH tUNUMBER {
-           yyDay = $3;
-           yyMonth = $4;
-           if ($5 > 999) {
-               /* assume year is YYYY format, so need not to add 1900 */
-               yyYear = $5;
-           } else if ($5 < 100) {
-               /* assume year is YY format, so need to add 1900 */
-               yyYear = $5 + (yyYear / 100 + (yyYear % 100 - $5) / 50) * 100;
-           } else {
-               yyYear = 1900 + $5;
-           }
-       }
-       ;
-
-rel    : tSNUMBER tSEC_UNIT {
-           yyRelSeconds += $1 * $2;
-       }
-       | tUNUMBER tSEC_UNIT {
-           yyRelSeconds += $1 * $2;
-       }
-       | tSNUMBER tMONTH_UNIT {
-           yyRelMonth += $1 * $2;
-       }
-       | tUNUMBER tMONTH_UNIT {
-           yyRelMonth += $1 * $2;
-       }
-       ;
-
-o_merid        : /* NULL */ {
-           $$ = MER24;
-       }
-       | tMERIDIAN {
-           $$ = $1;
-       }
-       ;
-
-%%
-
-/* Month and day table. */
-static TABLE   MonthDayTable[] = {
-    { "january",       tMONTH,  1 },
-    { "february",      tMONTH,  2 },
-    { "march",         tMONTH,  3 },
-    { "april",         tMONTH,  4 },
-    { "may",           tMONTH,  5 },
-    { "june",          tMONTH,  6 },
-    { "july",          tMONTH,  7 },
-    { "august",                tMONTH,  8 },
-    { "september",     tMONTH,  9 },
-    { "october",       tMONTH, 10 },
-    { "november",      tMONTH, 11 },
-    { "december",      tMONTH, 12 },
-       /* The value of the day isn't used... */
-    { "sunday",                tDAY, 0 },
-    { "monday",                tDAY, 0 },
-    { "tuesday",       tDAY, 0 },
-    { "wednesday",     tDAY, 0 },
-    { "thursday",      tDAY, 0 },
-    { "friday",                tDAY, 0 },
-    { "saturday",      tDAY, 0 },
-};
-
-/* Time units table. */
-static TABLE   UnitsTable[] = {
-    { "year",          tMONTH_UNIT,    12 },
-    { "month",         tMONTH_UNIT,    1 },
-    { "week",          tSEC_UNIT,      7 * 24 * 60 * 60 },
-    { "day",           tSEC_UNIT,      1 * 24 * 60 * 60 },
-    { "hour",          tSEC_UNIT,      60 * 60 },
-    { "minute",                tSEC_UNIT,      60 },
-    { "min",           tSEC_UNIT,      60 },
-    { "second",                tSEC_UNIT,      1 },
-    { "sec",           tSEC_UNIT,      1 },
-};
-
-/* Timezone table. */
-static TABLE   TimezoneTable[] = {
-    { "gmt",   tZONE,     HOUR( 0) },  /* Greenwich Mean */
-    { "ut",    tZONE,     HOUR( 0) },  /* Universal */
-    { "utc",   tZONE,     HOUR( 0) },  /* Universal Coordinated */
-    { "cut",   tZONE,     HOUR( 0) },  /* Coordinated Universal */
-    { "z",     tZONE,     HOUR( 0) },  /* Greenwich Mean */
-    { "wet",   tZONE,     HOUR( 0) },  /* Western European */
-    { "bst",   tDAYZONE,  HOUR( 0) },  /* British Summer */
-    { "nst",   tZONE,     HOUR(3)+30 }, /* Newfoundland Standard */
-    { "ndt",   tDAYZONE,  HOUR(3)+30 }, /* Newfoundland Daylight */
-    { "ast",   tZONE,     HOUR( 4) },  /* Atlantic Standard */
-    { "adt",   tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
-    { "est",   tZONE,     HOUR( 5) },  /* Eastern Standard */
-    { "edt",   tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
-    { "cst",   tZONE,     HOUR( 6) },  /* Central Standard */
-    { "cdt",   tDAYZONE,  HOUR( 6) },  /* Central Daylight */
-    { "mst",   tZONE,     HOUR( 7) },  /* Mountain Standard */
-    { "mdt",   tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
-    { "pst",   tZONE,     HOUR( 8) },  /* Pacific Standard */
-    { "pdt",   tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
-    { "yst",   tZONE,     HOUR( 9) },  /* Yukon Standard */
-    { "ydt",   tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
-    { "akst",  tZONE,     HOUR( 9) },  /* Alaska Standard */
-    { "akdt",  tDAYZONE,  HOUR( 9) },  /* Alaska Daylight */
-    { "hst",   tZONE,     HOUR(10) },  /* Hawaii Standard */
-    { "hast",  tZONE,     HOUR(10) },  /* Hawaii-Aleutian Standard */
-    { "hadt",  tDAYZONE,  HOUR(10) },  /* Hawaii-Aleutian Daylight */
-    { "ces",   tDAYZONE,  -HOUR(1) },  /* Central European Summer */
-    { "cest",  tDAYZONE,  -HOUR(1) },  /* Central European Summer */
-    { "mez",   tZONE,     -HOUR(1) },  /* Middle European */
-    { "mezt",  tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
-    { "cet",   tZONE,     -HOUR(1) },  /* Central European */
-    { "met",   tZONE,     -HOUR(1) },  /* Middle European */
-    { "eet",   tZONE,     -HOUR(2) },  /* Eastern Europe */
-    { "msk",   tZONE,     -HOUR(3) },  /* Moscow Winter */
-    { "msd",   tDAYZONE,  -HOUR(3) },  /* Moscow Summer */
-    { "wast",  tZONE,     -HOUR(8) },  /* West Australian Standard */
-    { "wadt",  tDAYZONE,  -HOUR(8) },  /* West Australian Daylight */
-    { "hkt",   tZONE,     -HOUR(8) },  /* Hong Kong */
-    { "cct",   tZONE,     -HOUR(8) },  /* China Coast */
-    { "jst",   tZONE,     -HOUR(9) },  /* Japan Standard */
-    { "kst",   tZONE,     -HOUR(9) },  /* Korean Standard */
-    { "kdt",   tZONE,     -HOUR(9) },  /* Korean Daylight */
-    { "cast",  tZONE,     -(HOUR(9)+30) }, /* Central Australian Standard */
-    { "cadt",  tDAYZONE,  -(HOUR(9)+30) }, /* Central Australian Daylight */
-    { "east",  tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
-    { "eadt",  tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
-    { "nzst",  tZONE,     -HOUR(12) }, /* New Zealand Standard */
-    { "nzdt",  tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
-
-    /* For completeness we include the following entries. */
-#if    0
-
-    /* Duplicate names.  Either they conflict with a zone listed above
-     * (which is either more likely to be seen or just been in circulation
-     * longer), or they conflict with another zone in this section and
-     * we could not reasonably choose one over the other. */
-    { "fst",   tZONE,     HOUR( 2) },  /* Fernando De Noronha Standard */
-    { "fdt",   tDAYZONE,  HOUR( 2) },  /* Fernando De Noronha Daylight */
-    { "bst",   tZONE,     HOUR( 3) },  /* Brazil Standard */
-    { "est",   tZONE,     HOUR( 3) },  /* Eastern Standard (Brazil) */
-    { "edt",   tDAYZONE,  HOUR( 3) },  /* Eastern Daylight (Brazil) */
-    { "wst",   tZONE,     HOUR( 4) },  /* Western Standard (Brazil) */
-    { "wdt",   tDAYZONE,  HOUR( 4) },  /* Western Daylight (Brazil) */
-    { "cst",   tZONE,     HOUR( 5) },  /* Chile Standard */
-    { "cdt",   tDAYZONE,  HOUR( 5) },  /* Chile Daylight */
-    { "ast",   tZONE,     HOUR( 5) },  /* Acre Standard */
-    { "adt",   tDAYZONE,  HOUR( 5) },  /* Acre Daylight */
-    { "cst",   tZONE,     HOUR( 5) },  /* Cuba Standard */
-    { "cdt",   tDAYZONE,  HOUR( 5) },  /* Cuba Daylight */
-    { "est",   tZONE,     HOUR( 6) },  /* Easter Island Standard */
-    { "edt",   tDAYZONE,  HOUR( 6) },  /* Easter Island Daylight */
-    { "sst",   tZONE,     HOUR(11) },  /* Samoa Standard */
-    { "ist",   tZONE,     -HOUR(2) },  /* Israel Standard */
-    { "idt",   tDAYZONE,  -HOUR(2) },  /* Israel Daylight */
-    { "idt",   tDAYZONE,  -(HOUR(3)+30) }, /* Iran Daylight */
-    { "ist",   tZONE,     -(HOUR(3)+30) }, /* Iran Standard */
-    { "cst",    tZONE,     -HOUR(8) }, /* China Standard */
-    { "cdt",    tDAYZONE,  -HOUR(8) }, /* China Daylight */
-    { "sst",    tZONE,     -HOUR(8) }, /* Singapore Standard */
-
-    /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
-    { "gst",   tZONE,     HOUR( 3) },  /* Greenland Standard */
-    { "wat",   tZONE,     -HOUR(1) },  /* West Africa */
-    { "at",    tZONE,     HOUR( 2) },  /* Azores */
-    { "gst",   tZONE,     -HOUR(10) }, /* Guam Standard */
-    { "nft",   tZONE,     HOUR(3)+30 }, /* Newfoundland */
-    { "idlw",  tZONE,     HOUR(12) },  /* International Date Line West */
-    { "mewt",  tZONE,     -HOUR(1) },  /* Middle European Winter */
-    { "mest",  tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
-    { "swt",   tZONE,     -HOUR(1) },  /* Swedish Winter */
-    { "sst",   tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
-    { "fwt",   tZONE,     -HOUR(1) },  /* French Winter */
-    { "fst",   tDAYZONE,  -HOUR(1) },  /* French Summer */
-    { "bt",    tZONE,     -HOUR(3) },  /* Baghdad */
-    { "it",    tZONE,     -(HOUR(3)+30) }, /* Iran */
-    { "zp4",   tZONE,     -HOUR(4) },  /* USSR Zone 3 */
-    { "zp5",   tZONE,     -HOUR(5) },  /* USSR Zone 4 */
-    { "ist",   tZONE,     -(HOUR(5)+30) }, /* Indian Standard */
-    { "zp6",   tZONE,     -HOUR(6) },  /* USSR Zone 5 */
-    { "nst",   tZONE,     -HOUR(7) },  /* North Sumatra */
-    { "sst",   tZONE,     -HOUR(7) },  /* South Sumatra */
-    { "jt",    tZONE,     -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
-    { "nzt",   tZONE,     -HOUR(12) }, /* New Zealand */
-    { "idle",  tZONE,     -HOUR(12) }, /* International Date Line East */
-    { "cat",   tZONE,     HOUR(10) },  /* -- expired 1967 */
-    { "nt",    tZONE,     HOUR(11) },  /* -- expired 1967 */
-    { "ahst",  tZONE,     HOUR(10) },  /* -- expired 1983 */
-    { "hdt",   tDAYZONE,  HOUR(10) },  /* -- expired 1986 */
-#endif /* 0 */
-};
-
-\f
-
-static void
-date_error(const char *s)
-{
-    s = s;                     /* ARGSUSED */
-    /* NOTREACHED */
-}
-
-
-static time_t
-ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
-{
-    if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
-       return -1;
-    if (Meridian == MER24) {
-       if (Hours < 0 || Hours > 23)
-           return -1;
-    }
-    else {
-       if (Hours < 1 || Hours > 12)
-           return -1;
-       if (Hours == 12)
-           Hours = 0;
-       if (Meridian == MERpm)
-           Hours += 12;
-    }
-    return (Hours * 60L + Minutes) * 60L + Seconds;
-}
-
-
-static time_t
-Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes,
-       time_t Seconds, MERIDIAN Meridian, DSTMODE dst)
-{
-    static int DaysNormal[13] = {
-       0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-    };
-    static int DaysLeap[13] = {
-       0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-    };
-    static int LeapYears[] = {
-       1972, 1976, 1980, 1984, 1988, 1992, 1996,
-       2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
-    };
-    int                        *yp;
-    int                        *mp;
-    time_t             Julian;
-    int                        i;
-    time_t             tod;
-
-    /* Year should not be passed as a relative value, but absolute one.
-       so this should not happen, but just ensure it */
-    if (Year < 0)
-       Year = -Year;
-    if (Year < 100) {
-       Year += 1900;
-       if (Year < EPOCH)
-           Year += 100;
-    }
-    for (mp = DaysNormal, yp = LeapYears; yp < ARRAY_END(LeapYears); yp++)
-       if (Year == *yp) {
-           mp = DaysLeap;
-           break;
-       }
-    if (Year < EPOCH || Year > END_OF_TIME
-     || Month < 1 || Month > 12
-     /* NOSTRICT *//* conversion from long may lose accuracy */
-     || Day < 1 || Day > mp[(int)Month])
-       return -1;
-
-    Julian = Day - 1 + (Year - EPOCH) * 365;
-    for (yp = LeapYears; yp < ARRAY_END(LeapYears); yp++, Julian++)
-       if (Year <= *yp)
-           break;
-    for (i = 1; i < Month; i++)
-       Julian += *++mp;
-    Julian *= SECSPERDAY;
-    Julian += yyTimezone * 60L;
-    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
-       return -1;
-    Julian += tod;
-    tod = Julian;
-    if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
-       Julian -= DST_OFFSET * 60 * 60;
-    return Julian;
-}
-
-
-static time_t
-DSTcorrect(time_t Start, time_t Future)
-{
-    time_t     StartDay;
-    time_t     FutureDay;
-
-    StartDay = (localtime(&Start)->tm_hour + 1) % 24;
-    FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
-    return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60 * 60;
-}
-
-
-static time_t
-RelativeMonth(time_t Start, time_t RelMonth)
-{
-    struct tm  *tm;
-    time_t     Month;
-    time_t     Year;
-
-    tm = localtime(&Start);
-    Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
-    Year = Month / 12;
-    Year += 1900;
-    Month = Month % 12 + 1;
-    return DSTcorrect(Start,
-           Convert(Month, (time_t)tm->tm_mday, Year,
-               (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
-               MER24, DSTmaybe));
-}
-
-
-static int
-LookupWord(char *buff, int length)
-{
-    char *p;
-    const char *q;
-    TABLE *tp;
-    int        c;
-
-    p = buff;
-    c = p[0];
-
-    /* See if we have an abbreviation for a month. */
-    if (length == 3 || (length == 4 && p[3] == '.'))
-       for (tp = MonthDayTable; tp < ARRAY_END(MonthDayTable); tp++) {
-           q = tp->name;
-           if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
-               yylval.Number = tp->value;
-               return tp->type;
-           }
-       }
-    else
-       for (tp = MonthDayTable; tp < ARRAY_END(MonthDayTable); tp++)
-           if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
-               yylval.Number = tp->value;
-               return tp->type;
-           }
-
-    /* Try for a timezone. */
-    for (tp = TimezoneTable; tp < ARRAY_END(TimezoneTable); tp++)
-       if (c == tp->name[0] && p[1] == tp->name[1]
-        && strcmp(p, tp->name) == 0) {
-           yylval.Number = tp->value;
-           return tp->type;
-       }
-
-    /* Try the units table. */
-    for (tp = UnitsTable; tp < ARRAY_END(UnitsTable); tp++)
-       if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
-           yylval.Number = tp->value;
-           return tp->type;
-       }
-
-    /* Strip off any plural and try the units table again. */
-    if (--length > 0 && p[length] == 's') {
-       p[length] = '\0';
-       for (tp = UnitsTable; tp < ARRAY_END(UnitsTable); tp++)
-           if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
-               p[length] = 's';
-               yylval.Number = tp->value;
-               return tp->type;
-           }
-       p[length] = 's';
-    }
-    length++;
-
-    /* Drop out any periods. */
-    for (p = buff, q = buff; *q; q++)
-       if (*q != '.')
-           *p++ = *q;
-    *p = '\0';
-
-    /* Try the meridians. */
-    if (buff[1] == 'm' && buff[2] == '\0') {
-       if (buff[0] == 'a') {
-           yylval.Meridian = MERam;
-           return tMERIDIAN;
-       }
-       if (buff[0] == 'p') {
-           yylval.Meridian = MERpm;
-           return tMERIDIAN;
-       }
-    }
-
-    /* If we saw any periods, try the timezones again. */
-    if (p - buff != length) {
-       c = buff[0];
-       for (p = buff, tp = TimezoneTable; tp < ARRAY_END(TimezoneTable); tp++)
-           if (c == tp->name[0] && p[1] == tp->name[1]
-           && strcmp(p, tp->name) == 0) {
-               yylval.Number = tp->value;
-               return tp->type;
-           }
-    }
-
-    /* Unknown word -- assume GMT timezone. */
-    yylval.Number = 0;
-    return tZONE;
-}
-
-
-static int
-date_lex(void)
-{
-    char               c;
-    char               *p;
-    char               buff[20];
-    int                        sign;
-    int                        i;
-    int                        nesting;
-
-    for ( ; ; ) {
-       /* Get first character after the whitespace. */
-       for ( ; ; ) {
-           while (CTYPE(isspace, (int)*yyInput))
-               yyInput++;
-           c = *yyInput;
-
-           /* Ignore RFC 822 comments, typically time zone names. */
-           if (c != LPAREN)
-               break;
-           for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
-               if (c == LPAREN)
-                   nesting++;
-               else if (!IS7BIT(c) || c == '\0' || c == '\r'
-                    || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
-                   /* Lexical error: bad comment. */
-                   return '?';
-           yyInput++;
-       }
-
-       /* A number? */
-       if (CTYPE(isdigit, (int)c) || c == '-' || c == '+') {
-           if (c == '-' || c == '+') {
-               sign = c == '-' ? -1 : 1;
-               yyInput++;
-               if (!CTYPE(isdigit, (int)*yyInput))
-                   /* Skip the plus or minus sign. */
-                   continue;
-           }
-           else
-               sign = 0;
-           for (i = 0; (c = *yyInput++) != '\0' && CTYPE(isdigit, (int)c); )
-               i = 10 * i + c - '0';
-           yyInput--;
-           yylval.Number = sign < 0 ? -i : i;
-           return sign ? tSNUMBER : tUNUMBER;
-       }
-
-       /* A word? */
-       if (CTYPE(isalpha, (int)c)) {
-           for (p = buff; (c = *yyInput++) == '.' || CTYPE(isalpha, (int)c); )
-               if (p < &buff[sizeof buff - 1])
-                   *p++ = CTYPE(isupper, (int)c) ? tolower(c) : c;
-           *p = '\0';
-           yyInput--;
-           return LookupWord(buff, p - buff);
-       }
-
-       return *yyInput++;
-    }
-}
-
-
-time_t
-parsedate(char *p, TIMEINFO *now)
-{
-    struct tm          *tm;
-    TIMEINFO           ti;
-    time_t             Start;
-
-    yyInput = p;
-    if (now == NULL) {
-       now = &ti;
-       GetTimeInfo(&ti);
-    }
-
-    tm = localtime(&now->time);
-    yyYear = tm->tm_year + 1900;
-    yyMonth = tm->tm_mon + 1;
-    yyDay = tm->tm_mday;
-    yyTimezone = now->tzone;
-    yyDSTmode = DSTmaybe;
-    yyHour = 0;
-    yyMinutes = 0;
-    yySeconds = 0;
-    yyMeridian = MER24;
-    yyRelSeconds = 0;
-    yyRelMonth = 0;
-    yyHaveDate = 0;
-    yyHaveRel = 0;
-    yyHaveTime = 0;
-
-    if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
-       return -1;
-
-    if (yyHaveDate || yyHaveTime) {
-       Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
-                   yyMeridian, yyDSTmode);
-       if (Start < 0)
-           return -1;
-    }
-    else {
-       Start = now->time;
-       if (!yyHaveRel)
-           Start -= (tm->tm_hour * 60L + tm->tm_min) * 60L + tm->tm_sec;
-    }
-
-    Start += yyRelSeconds;
-    if (yyRelMonth)
-       Start += RelativeMonth(Start, yyRelMonth);
-
-    /* Have to do *something* with a legitimate -1 so it's distinguishable
-     * from the error return value.  (Alternately could set errno on error.) */
-    return Start == -1 ? 0 : Start;
-}
-
-
-#if    defined(TEST)
-
-#if    YYDEBUG
-extern int     yydebug;
-#endif /* YYDEBUG */
-
-/* ARGSUSED */
-int
-main(int ac, char *av[])
-{
-    char       buff[128];
-    time_t     d;
-
-#if    YYDEBUG
-    yydebug = 1;
-#endif /* YYDEBUG */
-
-    printf("Enter date, or blank line to exit.\n\t> ");
-    for ( ; ; ) {
-       printf("\t> ");
-       fflush(stdout);
-       if (gets(buff) == NULL || buff[0] == '\n')
-           break;
-#if    YYDEBUG
-       if (strcmp(buff, "yydebug") == 0) {
-           yydebug = !yydebug;
-           printf("yydebug = %s\n", yydebug ? "on" : "off");
-           continue;
-       }
-#endif /* YYDEBUG */
-       d = parsedate(buff, (TIMEINFO *)NULL);
-       if (d == -1)
-           printf("Bad format - couldn't convert.\n");
-       else
-           printf("%s", ctime(&d));
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
-#endif /* defined(TEST) */
diff --git a/lib/perl.c b/lib/perl.c
deleted file mode 100644 (file)
index fe26ce4..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*  $Id: perl.c 7929 2008-06-29 17:55:04Z iulius $
-**
-**  Embedded Perl support for INN.
-**
-**  Originally written by Christophe Wolfhugel <wolf@pasteur.fr> (although
-**  he wouldn't recongize it any more, so don't blame him) and modified,
-**  expanded, and tweaked by James Brister, Dave Hayes, and Russ Allbery
-**  among others.
-**
-**  This file contains the Perl linkage shared by both nnrpd and innd.  It
-**  assumes Perl 5.004 or later.
-*/
-
-#include "config.h"
-
-/* Skip this entire file if DO_PERL (./configure --with-perl) isn't set. */
-#if DO_PERL
-
-#include "clibrary.h"
-#include <fcntl.h>
-#include <syslog.h>
-
-#include "libinn.h"
-
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-#include "ppport.h"
-
-#include "innperl.h"
-
-/* Provided by DynaLoader but not declared in Perl's header files. */
-extern void boot_DynaLoader(CV *cv);
-
-/* Forward declarations. */
-void    PerlSilence(void);
-void    PerlUnSilence(void);
-void    xs_init(void);
-
-/* Whether Perl filtering is currently active. */
-bool PerlFilterActive = false;
-
-/* The filter sub called (filter_art or filter_post). */
-CV *perl_filter_cv;
-
-/* The embedded Perl interpretor. */
-static PerlInterpreter *PerlCode;
-
-
-static void LogPerl(void)
-{
-   syslog(L_NOTICE, "SERVER perl filtering %s", PerlFilterActive ? "enabled" : "disabled");
-}
-
-
-/*
-**  Enable or disable the Perl filter.  Takes the desired state of the filter
-**  as an argument and returns success or failure.  Failure to enable
-**  indicates that the filter is not defined.
-*/
-bool
-PerlFilter(bool value)
-{
-    dSP;
-    char *argv[] = { NULL };
-
-    if (value == PerlFilterActive)
-        return true;
-
-    if (!value) {
-        /* Execute an end function, if one is defined. */
-        if (perl_get_cv("filter_end", false) != NULL) {
-            ENTER;
-            SAVETMPS;
-            perl_call_argv("filter_end", G_EVAL | G_DISCARD | G_NOARGS, argv);
-            if (SvTRUE(ERRSV)) {
-                syslog (L_ERROR, "SERVER perl function filter_end died: %s",
-                        SvPV(ERRSV, PL_na));
-                (void) POPs;
-            }
-            FREETMPS;
-            LEAVE;
-        }
-        PerlFilterActive = value;
-        LogPerl();
-        return true;
-    } else {
-        if (perl_filter_cv == NULL) {
-            syslog (L_ERROR, "SERVER perl filter not defined");
-            return false;
-        } else {
-            PerlFilterActive = value;
-            LogPerl();
-            return true;
-        }
-    }
-}
-
-
-
-/*
-** Loads a setup Perl module.  startupfile is the name of the file loaded
-** one-time at startup.  filterfile is the file containing the filter
-** functions which is loaded at startup and at each reload.  function is a
-** function name that must be defined after the filterfile file is loaded for
-** filtering to be turned on to start with.
-*/
-void PERLsetup (char *startupfile, char *filterfile, const char *function)
-{
-    if (PerlCode == NULL) {
-        /* Perl waits on standard input if not called with '-e'. */
-        int argc = 3;
-        const char *argv[] = { "innd", "-e", "0", NULL };
-        char *env[]  = { NULL };
-#ifdef PERL_SYS_INIT3
-        PERL_SYS_INIT3(&argc, &argv, &env);
-#endif
-        PerlCode = perl_alloc();
-        perl_construct(PerlCode);
-        perl_parse(PerlCode, xs_init, argc, (char **)argv, env) ;
-    }
-    
-    if (startupfile != NULL && filterfile != NULL) {
-        char *evalfile = NULL;
-        size_t length;
-        dSP;
-    
-        ENTER ;
-        SAVETMPS ;
-
-        /* The Perl expression which will be evaluated. */
-        length = strlen("do '%s'") + strlen(startupfile);
-        evalfile = xmalloc(length);
-        snprintf(evalfile, length, "do '%s'", startupfile);
-
-        PerlSilence();
-        perl_eval_pv(evalfile, TRUE);
-        PerlUnSilence();
-        
-        SPAGAIN ;
-        
-        if (SvTRUE(ERRSV))     /* check $@ */ {
-            syslog(L_ERROR,"SERVER perl loading %s failed: %s",
-                  startupfile, SvPV(ERRSV, PL_na)) ;
-            PerlFilter (false) ;
-    
-        } else {
-            PERLreadfilter (filterfile,function) ;
-        }
-
-        FREETMPS ;
-        LEAVE ;
-    } else {
-        PERLreadfilter (filterfile,function) ;
-    }
-}
-
-
-/* Load the perl file FILTERFILE. After it is load check that the give
-   function is defined. If yes filtering is turned on. If not it is turned
-   off. We remember whether the filter function was defined properly so
-   that we can catch when the use tries to turn filtering on without the
-   the funciton there. */
-int PERLreadfilter(char *filterfile, const char *function)
-{
-    dSP ;
-    char *argv[] = { NULL };
-    char *evalfile = NULL;
-    size_t length;
-
-    ENTER ;
-    SAVETMPS ;
-    
-    if (perl_get_cv("filter_before_reload", false) != NULL)    {
-        perl_call_argv("filter_before_reload", G_EVAL|G_DISCARD|G_NOARGS, argv);
-        if (SvTRUE(ERRSV))     /* check $@ */ {
-            syslog (L_ERROR,"SERVER perl function filter_before_reload died: %s",
-                    SvPV(ERRSV, PL_na)) ;
-            (void)POPs ;
-            PerlFilter (false) ;
-        }
-    }
-
-    /* The Perl expression which will be evaluated. */
-    length = strlen("do '%s'") + strlen(filterfile);
-    evalfile = xmalloc(length);
-    snprintf(evalfile, length, "do '%s'", filterfile);
-
-    PerlSilence();
-    perl_eval_pv(evalfile, TRUE);
-    PerlUnSilence();
-
-    free(evalfile);
-    evalfile = NULL;
-
-    if (SvTRUE(ERRSV))     /* check $@ */ {
-        syslog (L_ERROR,"SERVER perl loading %s failed: %s",
-                filterfile, SvPV(ERRSV, PL_na)) ;
-        PerlFilter (false) ;
-        
-        /* If the reload failed we don't want the old definition hanging
-           around. */
-        length = strlen("undef &%s") + strlen(function);
-        evalfile = xmalloc(length);
-        snprintf(evalfile, length, "undef &%s", function);
-        perl_eval_pv(evalfile, TRUE);
-
-        if (SvTRUE(ERRSV))     /* check $@ */ {
-            syslog (L_ERROR,"SERVER perl undef &%s failed: %s",
-                    function, SvPV(ERRSV, PL_na)) ;
-        }
-    } else if ((perl_filter_cv = perl_get_cv(function, false)) == NULL) {
-        PerlFilter (false) ;
-    }
-    
-    if (perl_get_cv("filter_after_reload", false) != NULL) {
-        perl_call_argv("filter_after_reload", G_EVAL|G_DISCARD|G_NOARGS, argv);
-        if (SvTRUE(ERRSV))     /* check $@ */ {
-            syslog (L_ERROR,"SERVER perl function filter_after_reload died: %s",
-                    SvPV(ERRSV, PL_na)) ;
-            (void)POPs ;
-            PerlFilter (false) ;
-        }
-    }
-
-    FREETMPS ;
-    LEAVE ;
-
-    return (perl_filter_cv != NULL) ;
-}
-
-
-/*
-**  Stops using the Perl filter
-*/
-void PerlClose(void)
-{
-   perl_destruct(PerlCode);
-   perl_free(PerlCode);
-#ifdef PERL_SYS_TERM
-   PERL_SYS_TERM();
-#endif
-   PerlFilterActive = false;
-}
-
-/*
-**  Redirects STDOUT/STDERR briefly (otherwise PERL complains to the net
-**  connection for NNRPD and that just won't do) -- dave@jetcafe.org
-*/
-static int savestdout = 0;
-static int savestderr = 0;
-void PerlSilence(void)
-{
-  int newfd;
-
-  /* Save the descriptors */
-  if ( (savestdout = dup(1)) < 0) {
-    syslog(L_ERROR,"SERVER perl silence cant redirect stdout: %m");
-    savestdout = 0;
-    return;
-  }
-  if ( (savestderr = dup(2)) < 0) {
-    syslog(L_ERROR,"SERVER perl silence cant redirect stderr: %m");
-    savestdout = 0;
-    savestderr = 0;
-    return;
-  }
-
-  /* Open /dev/null */
-  if ((newfd = open("/dev/null",O_WRONLY)) < 0) {
-    syslog(L_ERROR,"SERVER perl silence cant open /dev/null: %m");
-    savestdout = 0;
-    savestderr = 0;
-    return;
-  }
-
-  /* Redirect descriptors */
-  if (dup2(newfd,1) < 0) {
-    syslog(L_ERROR,"SERVER perl silence cant redirect stdout: %m");
-    savestdout = 0;
-    return;
-  }
-    
-  if (dup2(newfd,2) < 0) {
-    syslog(L_ERROR,"SERVER perl silence cant redirect stderr: %m");
-    savestderr = 0;
-    return;
-  }
-  close(newfd);
-}
-
-void PerlUnSilence(void) {
-  if (savestdout != 0) {
-    if (dup2(savestdout,1) < 0) {
-      syslog(L_ERROR,"SERVER perl silence cant restore stdout: %m");
-    }
-    close(savestdout);
-    savestdout = 0;
-  }
-
-  if (savestderr != 0) {
-    if (dup2(savestderr,2) < 0) {
-      syslog(L_ERROR,"SERVER perl silence cant restore stderr: %m");
-    }
-    close(savestderr);
-    savestderr = 0;
-  }
-}
-
-/*
-**  The remainder of this file consists of XS callbacks usable by either
-**  innd or nnrpd and initialized automatically when the Perl filter is
-**  initialized, as well as the function that initializes them.
-*/
-
-/*
-**  Log a message via syslog.  Only the first letter of the priority
-**  matters, and this function assumes that the controlling program has
-**  already done an openlog().  The argument must be a complete message, not
-**  a printf-style format.
-*/
-XS(XS_INN_syslog)
-{
-    dXSARGS;
-    const char *loglevel;
-    const char *logmsg;
-    int priority;
-
-    if (items != 2)
-        croak("Usage: INN::syslog(level, message)");
-
-    loglevel = (const char *) SvPV(ST(0), PL_na);
-    logmsg = (const char *) SvPV(ST(1), PL_na);
-
-    switch (*loglevel) {
-        default:                priority = LOG_NOTICE;
-        case 'a': case 'A':     priority = LOG_ALERT;           break;
-        case 'c': case 'C':     priority = LOG_CRIT;            break;
-        case 'e': case 'E':     priority = LOG_ERR;             break;
-        case 'w': case 'W':     priority = LOG_WARNING;         break;
-        case 'n': case 'N':     priority = LOG_NOTICE;          break;
-        case 'i': case 'I':     priority = LOG_INFO;            break;
-        case 'd': case 'D':     priority = LOG_DEBUG;           break;
-    }
-    syslog(priority, "filter: %s", logmsg);
-    XSRETURN_UNDEF;
-}
-
-extern void
-xs_init()
-{
-    dXSUB_SYS;
-    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, "perl.c");
-    newXS("INN::syslog", XS_INN_syslog, "perl.c");
-}
-
-#endif /* defined(DO_PERL) */
diff --git a/lib/pread.c b/lib/pread.c
deleted file mode 100644 (file)
index 4aafa9d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*  $Id: pread.c 5049 2001-12-12 09:06:00Z rra $
-**
-**  Replacement for a missing pread.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine pread
-**  for those platforms that don't have it.  Note that pread requires that
-**  the file pointer not move and without the library function, we can't
-**  copy that behavior; instead, we approximate it by moving the file
-**  pointer and then moving it back.  This may break threaded programs.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-/* If we're running the test suite, rename pread to avoid conflicts with the
-   system version.  #undef first because large file support may define a
-   macro pread (pointing to pread64) on some platforms (e.g. Solaris). */
-#if TESTING
-# undef pread
-# define pread test_pread
-ssize_t test_pread(int, void *, size_t, off_t);
-#endif
-
-ssize_t
-pread(int fd, void *buf, size_t nbyte, off_t offset)
-{
-    off_t current;
-    ssize_t nread;
-    int oerrno;
-
-    current = lseek(fd, 0, SEEK_CUR);
-    if (current == (off_t) -1 || lseek(fd, offset, SEEK_SET) == (off_t) -1)
-        return -1;
-
-    nread = read(fd, buf, nbyte);
-
-    /* Ignore errors in restoring the file position; this isn't ideal, but
-       reporting a failed read when the read succeeded is worse.  Make sure
-       that errno, if set, is set by read and not lseek. */
-    oerrno = errno;
-    lseek(fd, current, SEEK_SET);
-    errno = oerrno;
-    return nread;
-}
diff --git a/lib/pwrite.c b/lib/pwrite.c
deleted file mode 100644 (file)
index ee4ccc5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*  $Id: pwrite.c 5049 2001-12-12 09:06:00Z rra $
-**
-**  Replacement for a missing pwrite.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine pwrite
-**  for those platforms that don't have it.  Note that pwrite requires that
-**  the file pointer not move and without the library function, we can't
-**  copy that behavior; instead, we approximate it by moving the file
-**  pointer and then moving it back.  This may break threaded programs.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-/* If we're running the test suite, rename pread to avoid conflicts with the
-   system version.  #undef first because large file support may define a
-   macro pwrite (pointing to pwrite64) on some platforms (e.g. Solaris). */
-#if TESTING
-# undef pwrite
-# define pwrite test_pwrite
-ssize_t test_pwrite(int, const void *, size_t, off_t);
-#endif
-
-ssize_t
-pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
-{
-    off_t current;
-    ssize_t nwritten;
-    int oerrno;
-
-    current = lseek(fd, 0, SEEK_CUR);
-    if (current == (off_t) -1 || lseek(fd, offset, SEEK_SET) == (off_t) -1)
-        return -1;
-
-    nwritten = write(fd, buf, nbyte);
-
-    /* Ignore errors in restoring the file position; this isn't ideal, but
-       reporting a failed write when the write succeeded is worse.  Make
-       sure that errno, if set, is set by write and not lseek. */
-    oerrno = errno;
-    lseek(fd, current, SEEK_SET);
-    errno = oerrno;
-    return nwritten;
-}
diff --git a/lib/qio.c b/lib/qio.c
deleted file mode 100644 (file)
index 8a52f87..0000000
--- a/lib/qio.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*  $Id: qio.c 6943 2004-06-10 22:20:24Z hkehoe $
-**
-**  Quick I/O package.
-**
-**  A set of routines optimized for reading through files line by line.
-**  This package uses internal buffering like stdio, but is even more
-**  aggressive about its buffering.  The basic read call reads a single line
-**  and returns the whole line, provided that it can fit in the buffer.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/qio.h"
-#include "libinn.h"
-
-/* A reasonable default buffer size to use. */
-#define QIO_BUFFERSIZE  8192
-
-/*
-**  Given a file descriptor, return a reasonable buffer size to use for that
-**  file.  Uses st_blksize if available and reasonable, QIO_BUFFERSIZE
-**  otherwise.
-*/
-static size_t
-buffer_size(int fd)
-{
-    size_t size = QIO_BUFFERSIZE;
-
-#if HAVE_ST_BLKSIZE
-    struct stat st;
-
-    /* The Solaris 2.6 man page says that st_blksize is not defined for
-       block or character special devices (and could contain garbage), so
-       only use this value for regular files. */
-    if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
-        size = st.st_blksize;
-        if (size > (4 * QIO_BUFFERSIZE) || size == 0)
-            size = QIO_BUFFERSIZE;
-       else
-           while(size < QIO_BUFFERSIZE)
-               size += st.st_blksize;
-    }
-#endif /* HAVE_ST_BLKSIZE */
-
-    return size;
-}
-
-
-/*
-**  Open a quick file from a descriptor.
-*/
-QIOSTATE *
-QIOfdopen(const int fd)
-{
-    QIOSTATE *qp;
-
-    qp = xmalloc(sizeof(*qp));
-    qp->_fd = fd;
-    qp->_length = 0;
-    qp->_size = buffer_size(fd);
-    qp->_buffer = xmalloc(qp->_size);
-    qp->_start = qp->_buffer;
-    qp->_end = qp->_buffer;
-    qp->_count = 0;
-    qp->_flag = QIO_ok;
-
-    return qp;
-}
-
-
-/*
-**  Open a quick file from a file name.
-*/
-QIOSTATE *
-QIOopen(const char *name)
-{
-    int fd;
-
-    fd = open(name, O_RDONLY);
-    if (fd < 0)
-        return NULL;
-    return QIOfdopen(fd);
-}
-
-
-/*
-**  Close an open quick file.
-*/
-void
-QIOclose(QIOSTATE *qp)
-{
-    close(qp->_fd);
-    free(qp->_buffer);
-    free(qp);
-}
-
-
-/*
-**  Rewind a quick file.  Reads the first buffer full of data automatically,
-**  anticipating the first read from the file.  Returns -1 on error, 0 on
-**  success.
-*/
-int
-QIOrewind(QIOSTATE *qp)
-{
-    ssize_t nread;
-
-    if (lseek(qp->_fd, 0, SEEK_SET) < 0)
-        return -1;
-    nread = read(qp->_fd, qp->_buffer, qp->_size);
-    if (nread < 0)
-        return nread;
-    qp->_count = nread;
-    qp->_start = qp->_buffer;
-    qp->_end = qp->_buffer + nread;
-    return 0;
-}
-
-
-/*
-**  Get the next newline-terminated line from a quick file, replacing the
-**  newline with a nul.  Returns a pointer to that line on success and NULL
-**  on failure or end of file, with _flag set appropriately.
-*/
-char *
-QIOread(QIOSTATE *qp)
-{
-    char *p, *line;
-    ssize_t nread;
-    size_t nleft;
-
-    /* Loop until we get a result or fill the buffer. */
-    qp->_flag = QIO_ok;
-    while (1) {
-        nleft = qp->_end - qp->_start;
-
-        /* If nleft <= 0, the buffer currently contains no data that hasn't
-           previously been returned by QIOread, so we can overwrite the
-           buffer with new data.  Otherwise, first check the existing data
-           to see if we have a full line. */
-        if (nleft <= 0) {
-            qp->_start = qp->_buffer;
-            qp->_end = qp->_buffer;
-        } else {
-            p = memchr(qp->_start, '\n', nleft);
-            if (p != NULL) {
-                *p = '\0';
-                qp->_length = p - qp->_start;
-                line = qp->_start;
-                qp->_start = p + 1;
-                return (qp->_flag == QIO_long) ? NULL : line;
-            }
-
-            /* Not there.  See if our buffer is full.  If so, tag as having
-               seen too long of a line.  This will cause us to keep reading
-               as normal until we finally see the end of a line and then
-               return NULL. */
-            if (nleft >= qp->_size) {
-                qp->_flag = QIO_long;
-                qp->_start = qp->_end;
-                nleft = 0;
-            }
-
-            /* We need to read more data.  If there's read data in buffer,
-               then move the unread data down to the beginning of the buffer
-               first. */
-            if (qp->_start > qp->_buffer) {
-                if (nleft > 0)
-                    memmove(qp->_buffer, qp->_start, nleft);
-                qp->_start = qp->_buffer;
-                qp->_end = qp->_buffer + nleft;
-            }
-        }
-
-        /* Read in some more data, and then let the loop try to find the
-           newline again or discover that the line is too long. */
-        do {
-            nread = read(qp->_fd, qp->_end, qp->_size - nleft);
-        } while (nread == -1 && errno == EINTR);
-        if (nread <= 0) {
-            if (nread < 0)
-                qp->_flag = QIO_error;
-            return NULL;
-        }
-        qp->_count += nread;
-        qp->_end += nread;
-    }
-}
diff --git a/lib/radix32.c b/lib/radix32.c
deleted file mode 100644 (file)
index 7a7e503..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*  $Id: radix32.c 6118 2003-01-13 06:44:24Z rra $
-**
-**  Radix-32 strings divide a number into five-bit nibbles and use the
-**  alphabet 0..9a..v to represent 0..32.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <time.h>
-
-#include "libinn.h"
-
-
-static char    ALPHABET[] =
-    "0123456789abcdefghijklmnopqrstuv";
-
-
-/*
-**  Turn a number into a Radix-32 string.  Assume the number fits into
-**  32 bits.
-*/
-void Radix32(unsigned long l, char *buff)
-{
-    char                       *p;
-    int                                i;
-    char                       temp[10];
-
-    /* Simple sanity checks. */
-    if ((l &= 0xFFFFFFFFL) == 0) {
-       *buff++ = ALPHABET[0];
-       *buff = '\0';
-       return;
-    }
-
-    /* Format the string, in reverse. */
-    for (p = temp; l; l >>= 5)
-       *p++ = ALPHABET[(int)(l & 037)];
-
-    /* Reverse it. */
-    for (i = p - temp; --i >= 0; )
-       *buff++ = *--p;
-    *buff = '\0';
-}
-
-
-#if    0
-/*
-**  Return a Radix-32 string as a number, or ~0 on error.
-*/
-unsigned long
-Decode32(p)
-    char               *p;
-{
-    unsigned long      l;
-    char               *cp;
-
-    for (l = 0; *p; p++) {
-       if ((cp = strchr(ALPHABET, *p)) == NULL)
-           return ~0;
-       l = (l << 6) + cp - ALPHABET;
-    }
-    return l;
-}
-#endif /* 0 */
diff --git a/lib/readin.c b/lib/readin.c
deleted file mode 100644 (file)
index fc63313..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*  $Id: readin.c 6394 2003-07-12 19:13:14Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "libinn.h"
-
-
-/*
-**  Read a big amount, looping until it is all done.  Return true if
-**  successful.
-*/
-int xread(int fd, char *p, off_t i)
-{
-    int                        count;
-
-    for ( ; i; p += count, i -= count) {
-        do {
-            count = read(fd, p, i);
-        } while (count == -1 && errno == EINTR);
-        if (count <= 0)
-            return -1;
-    }
-    return 0;
-}
-
-
-/*
-**  Read an already-open file into memory.
-*/
-char *ReadInDescriptor(int fd, struct stat *Sbp)
-{
-    struct stat        mystat;
-    char       *p;
-    int                oerrno;
-
-    if (Sbp == NULL)
-       Sbp = &mystat;
-
-    /* Get the size, and enough memory. */
-    if (fstat(fd, Sbp) < 0) {
-       oerrno = errno;
-       close(fd);
-       errno = oerrno;
-       return NULL;
-    }
-    p = xmalloc(Sbp->st_size + 1);
-
-    /* Slurp, slurp. */
-    if (xread(fd, p, Sbp->st_size) < 0) {
-       oerrno = errno;
-       free(p);
-       close(fd);
-       errno = oerrno;
-       return NULL;
-    }
-
-    /* Terminate the string; terminate the routine. */
-    p[Sbp->st_size] = '\0';
-    return p;
-}
-
-
-/*
-**  Read a file into allocated memory.  Optionally fill in the stat(2) data.
-**  Return a pointer to the file contents, or NULL on error.
-*/
-char *ReadInFile(const char *name, struct stat *Sbp)
-{
-    char       *p;
-    int                fd;
-
-    if ((fd = open(name, O_RDONLY)) < 0)
-       return NULL;
-
-    p = ReadInDescriptor(fd, Sbp);
-    close(fd);
-    return p;
-}
diff --git a/lib/reservedfd.c b/lib/reservedfd.c
deleted file mode 100644 (file)
index c4639d5..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*  $Id: reservedfd.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <fcntl.h>
-
-#include "libinn.h"
-
-
-static FILE **Reserved_fd = NULL;
-static int Maxfd = -1;
-
-bool
-fdreserve(int fdnum)
-{
-    static int allocated = 0;
-    int i, start = allocated;
-
-    if (fdnum <= 0) {
-       if (Reserved_fd != NULL) {
-           for (i = 0 ; i < Maxfd ; i++) {
-               fclose(Reserved_fd[i]);
-           }
-           free(Reserved_fd);
-           Reserved_fd = NULL;
-       }
-       Maxfd = -1;
-       allocated = 0;
-       return true;
-    }
-    if (Reserved_fd == NULL) {
-       Reserved_fd = xmalloc(fdnum * sizeof(FILE *));
-       allocated = fdnum;
-    } else {
-       if (allocated < fdnum) {
-            Reserved_fd = xrealloc(Reserved_fd, fdnum * sizeof(FILE *));
-           allocated = fdnum;
-       } else if (Maxfd > fdnum) {
-           for (i = fdnum ; i < Maxfd ; i++) {
-               fclose(Reserved_fd[i]);
-           }
-       }
-    }
-    for (i = start ; i < fdnum ; i++) {
-       if (((Reserved_fd[i] = fopen("/dev/null", "r")) == NULL)){
-           for (--i ; i >= 0 ; i--)
-               fclose(Reserved_fd[i]);
-           free(Reserved_fd);
-           Reserved_fd = NULL;
-           allocated = 0;
-           Maxfd = -1;
-           return false;
-       }
-    }
-    Maxfd = fdnum;
-    return true;
-}
-
-FILE *
-Fopen(const char *p, const char *type, int xindex)
-{
-    FILE *nfp;
-    if (p == NULL || *p == '\0')
-       return NULL;
-    if (xindex < 0 || xindex > Maxfd || Reserved_fd[xindex] == NULL)
-       return fopen(p, type);
-    if ((nfp = freopen(p, type, Reserved_fd[xindex])) == NULL) {
-       Reserved_fd[xindex] = freopen("/dev/null", "r", Reserved_fd[xindex]);
-       return NULL;
-    }
-    return (Reserved_fd[xindex] = nfp);
-}
-
-int
-Fclose(FILE *fp)
-{
-    int        i;
-
-    if (fp == NULL)
-       return 0;
-    for (i = 0 ; i < Maxfd ; i++) {
-       if (Reserved_fd[i] == fp)
-           break;
-    }
-    if (i >= Maxfd)
-       return fclose(fp);
-    Reserved_fd[i] = freopen("/dev/null", "r", Reserved_fd[i]);
-    return 0;
-}
diff --git a/lib/resource.c b/lib/resource.c
deleted file mode 100644 (file)
index 0603daa..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  $Id: resource.c 6135 2003-01-19 01:15:40Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-
-#ifdef HAVE_GETRUSAGE
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#define TIMEVALasDOUBLE(t)     \
-    ((double)(t).tv_sec + ((double)(t).tv_usec) / 1000000.0)
-
-int getrusage(int who, struct rusage *rusage);
-
-int GetResourceUsage(double *usertime, double *systime)
-{
-    struct rusage      R;
-
-    if (getrusage(RUSAGE_SELF, &R) < 0)
-       return -1;
-    *usertime = TIMEVALasDOUBLE(R.ru_utime);
-    *systime = TIMEVALasDOUBLE(R.ru_stime);
-    return 0;
-}
-
-#else /* HAVE_GETRUSAGE */
-
-#include <sys/param.h>
-#include <sys/times.h>
-
-#if    !defined(HZ)
-#define HZ     60
-#endif /* !defined(HZ) */
-
-#define CPUTIMEasDOUBLE(t1, t2)                ((double)(t1 + t2) / (double)HZ)
-
-int GetResourceUsage(double *usertime, double *systime)
-{
-    struct tms T;
-
-    if (times(&T) == -1)
-       return -1;
-    *usertime = CPUTIMEasDOUBLE(T.tms_utime, T.tms_cutime);
-    *systime = CPUTIMEasDOUBLE(T.tms_stime, T.tms_cstime);
-    return 0;
-}
-
-#endif /* !HAVE_GETRUSAGE */
diff --git a/lib/sendarticle.c b/lib/sendarticle.c
deleted file mode 100644 (file)
index 4e514fb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*  $Id: sendarticle.c 4076 2000-10-05 00:36:52Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-#include "nntp.h"
-
-
-/*
-**  Send a string of one or more lines down a stdio FILE using RFC977
-**  conventions.  Return -1 on error.
-*/
-int NNTPsendarticle(char *p, FILE *F, bool Terminate)
-{
-    char *next;
-
-    for (; p && *p; next[-1] = '\n', p = next) {
-       /* Get pointer to next line.  Truncate long lines. */
-       if ((next = strchr(p, '\n')) != NULL)
-           *next++ = '\0';
-
-       /* Write line. */
-       if (*p == '.' && putc('.', F) == EOF)
-           return -1;
-       if (fprintf(F, "%s\r\n", p) == EOF)
-           return -1;
-
-       /* Done? */
-       if (next == NULL)
-           break;
-    }
-
-    if (Terminate && fprintf(F, ".\r\n") == EOF)
-       return -1;
-
-    return fflush(F) == EOF || ferror(F) ? -1 : 0;
-}
diff --git a/lib/sendpass.c b/lib/sendpass.c
deleted file mode 100644 (file)
index a229f8c..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*  $Id: sendpass.c 7145 2005-04-10 03:28:01Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-
-
-/*
-**  Send authentication information to an NNTP server.
-*/
-int NNTPsendpassword(char *server, FILE *FromServer, FILE *ToServer)
-{
-    FILE               *F;
-    char               *p;
-    char                *path;
-    char               buff[SMBUF];
-    char               input[SMBUF];
-    char               *user;
-    char               *pass;
-    char               *style;
-    int                        oerrno;
-
-    /* Default to innconf->server.  If that's not set either, error out.  Fake
-       errno since some of our callers rely on it. */
-    if (server == NULL)
-        server = innconf->server;
-    if (server == NULL) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    /* Open the password file; coarse check on errno, but good enough. */
-    path = concatpath(innconf->pathetc, _PATH_NNTPPASS);
-    F = fopen(path, "r");
-    free(path);
-    if (F == NULL)
-       return errno == EPERM ? -1 : 0;
-
-    /* Scan the file, skipping blank and comment lines. */
-    while (fgets(buff, sizeof buff, F) != NULL) {
-       if ((p = strchr(buff, '\n')) != NULL)
-           *p = '\0';
-       if (buff[0] == '\0' || buff[0] == '#')
-           continue;
-
-       /* Parse the line. */
-       if ((user = strchr(buff, ':')) == NULL)
-           continue;
-       *user++ = '\0';
-       if ((pass = strchr(user, ':')) == NULL)
-           continue;
-       *pass++ = '\0';
-       if ((style = strchr(pass, ':')) != NULL) {
-           *style++ = '\0';
-           if (strcmp(style, "authinfo") != 0) {
-               errno = EDOM;
-               break;
-           }
-       }
-
-       if (strcasecmp(server, buff) != 0)
-           continue;
-
-       if (*user) {
-           /* Send the first part of the command, get a reply. */
-           fprintf(ToServer, "authinfo user %s\r\n", user);
-           if (fflush(ToServer) == EOF || ferror(ToServer))
-               break;
-           if (fgets(input, sizeof input, FromServer) == NULL
-            || atoi(input) != NNTP_AUTH_NEXT_VAL)
-               break;
-       }
-
-       if (*pass) {
-           /* Send the second part of the command, get a reply. */
-           fprintf(ToServer, "authinfo pass %s\r\n", pass);
-           if (fflush(ToServer) == EOF || ferror(ToServer))
-               break;
-           if (fgets(input, sizeof input, FromServer) == NULL
-            || atoi(input) != NNTP_AUTH_OK_VAL)
-               break;
-       }
-
-       /* Authenticated. */
-       fclose(F);
-       return 0;
-    }
-
-    /* End of file without finding a password, that's okay. */
-    if (feof(F)) {
-       fclose(F);
-       return 0;
-    }
-
-    /* Save errno, close the file, fail. */
-    oerrno = errno;
-    fclose(F);
-    errno = oerrno;
-    return -1;
-}
diff --git a/lib/sequence.c b/lib/sequence.c
deleted file mode 100644 (file)
index 7e25876..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*  $Id: sequence.c 4871 2001-07-09 08:09:58Z alexk $
-**
-**  Sequence space arithmetic routines.
-**
-**  This is a set of routines for implementing so called sequence
-**  space arithmetic (typically used for DNS serial numbers). The
-**  implementation here is taken from RFC 1982.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <limits.h>
-#include "inn/sequence.h"
-
-
-/*
-**  compare two unsigned long numbers using sequence space arithmetic
-**
-**    returns:
-**     0 - i1 = i2
-**    -1 - i1 < i2
-**     1 - i1 > i2
-**     INT_MAX - undefined
-*/
-int
-seq_lcompare(unsigned long i1, unsigned long i2)
-{
-    if (i1 == i2)
-       return 0;
-    else if ((i1 < i2 && i2 - i1 < (1 + ULONG_MAX / 2)) ||
-            (i1 > i2 && i1 - i2 > (1 + ULONG_MAX / 2)))
-       return -1;
-    else if ((i1 < i2 && i2 - i1 > (1 + ULONG_MAX / 2)) ||
-            (i1 > i2 && i1 - i2 < (1 + ULONG_MAX / 2)))
-       return 1;
-    return INT_MAX;
-}
diff --git a/lib/setenv.c b/lib/setenv.c
deleted file mode 100644 (file)
index 51ca761..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  $Id: setenv.c 5713 2002-09-01 03:04:10Z rra $
-**
-**  Replacement for a missing setenv.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine setenv
-**  for those platforms that don't have it.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-/* If we're running the test suite, rename setenv to avoid conflicts with
-   the system version. */
-#if TESTING
-# define setenv test_setenv
-int test_setenv(const char *, const char *, int);
-#endif
-
-int
-setenv(const char *name, const char *value, int overwrite)
-{
-    char *envstring;
-
-    if (!overwrite && getenv(name) != NULL)
-        return 0;
-
-    /* Allocate memory for the environment string.  We intentionally don't
-       use concat here, or the xmalloc family of allocation routines, since
-       the intention is to provide a replacement for the standard library
-       function which sets errno and returns in the event of a memory
-       allocation failure. */
-    envstring = malloc(strlen(name) + 1 + strlen(value) + 1);
-    if (envstring == NULL)
-        return -1;
-
-    /* Build the environment string and add it to the environment using
-       putenv.  Systems without putenv lose, but XPG4 requires it. */
-    strcpy(envstring, name);
-    strcat(envstring, "=");
-    strcat(envstring, value);
-    return putenv(envstring);
-
-    /* Note that the memory allocated is not freed.  This is intentional;
-       many implementations of putenv assume that the string passed to
-       putenv will never be freed and don't make a copy of it.  Repeated use
-       of this function will therefore leak memory, since most
-       implementations of putenv also don't free strings removed from the
-       environment (due to being overwritten). */
-}
diff --git a/lib/seteuid.c b/lib/seteuid.c
deleted file mode 100644 (file)
index ade8b73..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*  $Id: seteuid.c 3839 2000-08-29 04:50:18Z rra $
-**
-**  Replacement for a missing seteuid.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Some systems don't have seteuid but do have setreuid.  setreuid with
-**  -1 given for the real UID is equivalent to seteuid on systems with
-**  POSIX saved UIDs.  On systems without POSIX saved UIDs, we'd lose our
-**  ability to regain privileges if we just set the effective UID, so
-**  instead fake a saved UID by setting the real UID to the current
-**  effective UID, using the real UID as the saved UID.
-**
-**  Note that swapping UIDs doesn't work on AIX, but AIX has saved UIDs.
-**  Note also that systems without setreuid lose, and that we assume that
-**  any system with seteuid has saved UIDs.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-int
-seteuid(uid_t euid)
-{
-    int ruid;
-
-#ifdef _POSIX_SAVED_IDS
-    ruid = -1;
-#else
-    ruid = geteuid();
-#endif
-    return setreuid(ruid, euid);
-}
diff --git a/lib/setproctitle.c b/lib/setproctitle.c
deleted file mode 100644 (file)
index cb72960..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*  $Id: setproctitle.c 5943 2002-12-08 02:28:06Z rra $
-**
-**  Replacement for a missing setproctitle.
-**
-**  Provides the same functionality as the BSD function setproctitle on hosts
-**  where modifying argv will produce those results, or on HP-UX (which has
-**  its own peculiar way of doing this).  This may be ineffective on some
-**  platforms.
-**
-**  Before calling setproctitle, it is *required* that setproctitle_init be
-**  called, passing it argc and argv as arguments.  setproctitle_init will be
-**  stubbed out on those platforms that don't need it.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/setproctitle.h"
-
-#include "inn/messages.h"
-
-#if HAVE_PSTAT
-
-#include <sys/param.h>
-#include <sys/pstat.h>
-
-void
-setproctitle(const char *format, ...)
-{
-    va_list args;
-    char title[BUFSIZ];
-    union pstun un;
-    ssize_t delta = 0;
-
-    if (message_program_name != NULL) {
-        delta = snprintf(title, sizeof(title), "%s: ", message_program_name);
-        if (delta < 0)
-            delta = 0;
-    }
-    va_start(args, format);
-    vsnprintf(title + delta, sizeof(title) - delta, format, args);
-    va_end(args);
-    un.pst_command = title;
-    pstat(PSTAT_SETCMD, un, strlen(title), 0, 0);
-}
-
-#else
-
-static char *title_start = NULL;
-static char *title_end = NULL;
-
-void
-setproctitle_init(int argc, char *argv[])
-{
-    title_start = argv[0];
-    title_end = argv[argc - 1] + strlen(argv[argc - 1]) - 1;
-}
-
-void
-setproctitle(const char *format, ...)
-{
-    va_list args;
-    size_t length;
-    ssize_t delta;
-    char *title;
-
-    if (title_start == NULL || title_end == NULL) {
-        warn("setproctitle called without setproctitle_init");
-        return;
-    }
-
-    /* setproctitle prepends the program name to its arguments.  Our emulation
-       should therefore do the same thing.  However, some operating systems
-       seem to do that automatically even when we completely overwrite argv,
-       so start our title with a - so that they'll instead put (nnrpd) at the
-       end, thinking we're swapped out. */
-    title = title_start;
-    *title++ = '-';
-    *title++ = ' ';
-    length = title_end - title_start - 2;
-
-    /* Now, put in the actual content.  Get the program name from
-       message_program_name if it's set. */
-    if (message_program_name != NULL) {
-        delta = snprintf(title, length, "%s: ", message_program_name);
-        if (delta < 0 || (size_t) delta > length)
-            return;
-        if (delta > 0) {
-            title += delta;
-            length -= delta;
-        }
-    }
-    va_start(args, format);
-    delta = vsnprintf(title, length, format, args);
-    va_end(args);
-    if (delta < 0 || (size_t) delta > length)
-        return;
-    if (delta > 0) {
-        title += delta;
-        length -= delta;
-    }
-    for (; length > 1; length--, title++)
-        *title = ' ';
-    *title = '\0';
-}
-
-#endif /* !HAVE_PSTAT */
diff --git a/lib/snprintf.c b/lib/snprintf.c
deleted file mode 100644 (file)
index 9d2f759..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-/*  $Id: snprintf.c 7230 2005-04-16 23:33:17Z rra $
-**
-**  Replacement for a missing snprintf or vsnprintf.
-**
-**  The following implementation of snprintf was taken mostly verbatim from
-**  <http://www.fiction.net/~blong/programs/>; it is the version of snprintf
-**  used in Mutt.
-**
-**  Please do not reformat or otherwise change this file more than
-**  necessary so that later merges with the original source are easy.
-**  Bug fixes and improvements should be sent back to the original author.
-*/
-
-/* If we're running the test suite, rename snprintf and vsnprintf to avoid
-   conflicts with the system version. */
-#if TESTING
-# define snprintf test_snprintf
-# define vsnprintf test_vsnprintf
-#endif
-
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell@astart.com)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
- */
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh.  This sort of thing is always nasty do deal with.  Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length.  This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
- *  This was ugly.  It is still ugly.  I opted out of floating point
- *  numbers, but the formatter understands just about everything
- *  from the normal C string format, at least as far as I can tell from
- *  the Solaris 2.5 printf(3S) man page.
- *
- *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
- *    Ok, added some minimal floating point support, which means this
- *    probably requires libm on most operating systems.  Don't yet
- *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
- *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
- *    to mutt conventions, and removed dead code left over from the
- *    original.  Also, there is now a builtin-test, just compile with:
- *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- *    and run snprintf for results.
- * 
- *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- *    The PGP code was using unsigned hexadecimal formats. 
- *    Unfortunately, unsigned formats simply didn't work.
- *
- *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
- *    The original code assumed that both snprintf() and vsnprintf() were
- *    missing.  Some systems only have snprintf() but not vsnprintf(), so
- *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- *  Andrew Tridgell (tridge@samba.org) Oct 1998
- *    fixed handling of %.0f
- *    added test for HAVE_LONG_DOUBLE
- *
- *  Russ Allbery <rra@stanford.edu> 2000-08-26
- *    fixed return value to comply with C99
- *    fixed handling of snprintf(NULL, ...)
- *
- *  Hrvoje Niksic <hniksic@arsdigita.com> 2000-11-04
- *    include <stdio.h> for NULL.
- *    added support for long long.
- *    don't declare argument types to (v)snprintf if stdarg is not used.
- *
- **************************************************************/
-
-#include "config.h"
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-
-#ifndef NULL
-# define NULL 0
-#endif
-
-/* varargs declarations: */
-
-#include <stdarg.h>
-#define HAVE_STDARGS    /* let's hope that works everywhere (mj) */
-#define VA_LOCAL_DECL   va_list ap
-#define VA_START(f)     va_start(ap, f)
-#define VA_SHIFT(v,t)  ;   /* no-op for ANSI */
-#define VA_END          va_end(ap)
-
-#ifdef HAVE_LONG_DOUBLE
-#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-
-#ifdef HAVE_LONG_LONG
-# define LLONG long long
-#else
-# define LLONG long
-#endif
-
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-
-static int dopr (char *buffer, size_t maxlen, const char *format, 
-                 va_list args);
-static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
-                  const char *value, int flags, int min, int max);
-static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
-                  LLONG value, int base, int min, int max, int flags);
-static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
-                 LDOUBLE fvalue, int min, int max, int flags);
-static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS   1
-#define DP_S_MIN     2
-#define DP_S_DOT     3
-#define DP_S_MAX     4
-#define DP_S_MOD     5
-#define DP_S_MOD_L   6
-#define DP_S_CONV    7
-#define DP_S_DONE    8
-
-/* format flags - Bits */
-#define DP_F_MINUS     (1 << 0)
-#define DP_F_PLUS      (1 << 1)
-#define DP_F_SPACE     (1 << 2)
-#define DP_F_NUM       (1 << 3)
-#define DP_F_ZERO      (1 << 4)
-#define DP_F_UP        (1 << 5)
-#define DP_F_UNSIGNED  (1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT   1
-#define DP_C_LONG    2
-#define DP_C_LLONG   3
-#define DP_C_LDOUBLE 4
-
-#define char_to_int(p) (p - '0')
-#define MAX(p,q) ((p >= q) ? p : q)
-#define MIN(p,q) ((p <= q) ? p : q)
-
-static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
-{
-  char ch;
-  LLONG value;
-  LDOUBLE fvalue;
-  char *strvalue;
-  int min;
-  int max;
-  int state;
-  int flags;
-  int cflags;
-  int total;
-  size_t currlen;
-  
-  state = DP_S_DEFAULT;
-  currlen = flags = cflags = min = 0;
-  max = -1;
-  ch = *format++;
-  total = 0;
-
-  while (state != DP_S_DONE)
-  {
-    if (ch == '\0')
-      state = DP_S_DONE;
-
-    switch(state) 
-    {
-    case DP_S_DEFAULT:
-      if (ch == '%') 
-       state = DP_S_FLAGS;
-      else 
-       total += dopr_outch (buffer, &currlen, maxlen, ch);
-      ch = *format++;
-      break;
-    case DP_S_FLAGS:
-      switch (ch) 
-      {
-      case '-':
-       flags |= DP_F_MINUS;
-        ch = *format++;
-       break;
-      case '+':
-       flags |= DP_F_PLUS;
-        ch = *format++;
-       break;
-      case ' ':
-       flags |= DP_F_SPACE;
-        ch = *format++;
-       break;
-      case '#':
-       flags |= DP_F_NUM;
-        ch = *format++;
-       break;
-      case '0':
-       flags |= DP_F_ZERO;
-        ch = *format++;
-       break;
-      default:
-       state = DP_S_MIN;
-       break;
-      }
-      break;
-    case DP_S_MIN:
-      if ('0' <= ch && ch <= '9') 
-      {
-       min = 10*min + char_to_int (ch);
-       ch = *format++;
-      } 
-      else if (ch == '*') 
-      {
-       min = va_arg (args, int);
-       ch = *format++;
-       state = DP_S_DOT;
-      } 
-      else 
-       state = DP_S_DOT;
-      break;
-    case DP_S_DOT:
-      if (ch == '.') 
-      {
-       state = DP_S_MAX;
-       ch = *format++;
-      } 
-      else 
-       state = DP_S_MOD;
-      break;
-    case DP_S_MAX:
-      if ('0' <= ch && ch <= '9')
-      {
-       if (max < 0)
-         max = 0;
-       max = 10*max + char_to_int (ch);
-       ch = *format++;
-      } 
-      else if (ch == '*') 
-      {
-       max = va_arg (args, int);
-       ch = *format++;
-       state = DP_S_MOD;
-      } 
-      else 
-       state = DP_S_MOD;
-      break;
-    case DP_S_MOD:
-      switch (ch) 
-      {
-      case 'h':
-       cflags = DP_C_SHORT;
-       ch = *format++;
-       break;
-      case 'l':
-       cflags = DP_C_LONG;
-       ch = *format++;
-       break;
-      case 'L':
-       cflags = DP_C_LDOUBLE;
-       ch = *format++;
-       break;
-      default:
-       break;
-      }
-      if (cflags != DP_C_LONG)
-        state = DP_S_CONV;
-      else
-        state = DP_S_MOD_L;
-      break;
-    case DP_S_MOD_L:
-      switch (ch)
-      {
-      case 'l':
-        cflags = DP_C_LLONG;
-        ch = *format++;
-        break;
-      default:
-        break;
-      }
-      state = DP_S_CONV;
-      break;
-    case DP_S_CONV:
-      switch (ch) 
-      {
-      case 'd':
-      case 'i':
-       if (cflags == DP_C_SHORT) 
-         value = (short int) va_arg (args, int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, long int);
-        else if (cflags == DP_C_LLONG)
-          value = va_arg (args, LLONG);
-       else
-         value = va_arg (args, int);
-       total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
-       break;
-      case 'o':
-       flags |= DP_F_UNSIGNED;
-       if (cflags == DP_C_SHORT)
-         value = (unsigned short int) va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-        else if (cflags == DP_C_LLONG)
-          value = va_arg (args, unsigned LLONG);
-       else
-         value = va_arg (args, unsigned int);
-       total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
-       break;
-      case 'u':
-       flags |= DP_F_UNSIGNED;
-       if (cflags == DP_C_SHORT)
-         value = (unsigned short int) va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-        else if (cflags == DP_C_LLONG)
-          value = va_arg (args, unsigned LLONG);
-       else
-         value = va_arg (args, unsigned int);
-       total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
-       break;
-      case 'X':
-       flags |= DP_F_UP;
-      case 'x':
-       flags |= DP_F_UNSIGNED;
-       if (cflags == DP_C_SHORT)
-         value = (unsigned short int) va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-        else if (cflags == DP_C_LLONG)
-          value = va_arg (args, unsigned LLONG);
-       else
-         value = va_arg (args, unsigned int);
-       total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
-       break;
-      case 'f':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, LDOUBLE);
-       else
-         fvalue = va_arg (args, double);
-       /* um, floating point? */
-       total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
-       break;
-      case 'E':
-       flags |= DP_F_UP;
-      case 'e':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, LDOUBLE);
-       else
-         fvalue = va_arg (args, double);
-       break;
-      case 'G':
-       flags |= DP_F_UP;
-      case 'g':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, LDOUBLE);
-       else
-         fvalue = va_arg (args, double);
-       break;
-      case 'c':
-       total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
-       break;
-      case 's':
-       strvalue = va_arg (args, char *);
-       total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
-       break;
-      case 'p':
-       strvalue = va_arg (args, void *);
-       total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
-                         max, flags);
-       break;
-      case 'n':
-       if (cflags == DP_C_SHORT) 
-       {
-         short int *num;
-         num = va_arg (args, short int *);
-         *num = currlen;
-        } 
-       else if (cflags == DP_C_LONG) 
-       {
-         long int *num;
-         num = va_arg (args, long int *);
-         *num = currlen;
-        }
-        else if (cflags == DP_C_LLONG) 
-        {
-          LLONG *num;
-          num = va_arg (args, LLONG *);
-          *num = currlen;
-        } 
-       else 
-       {
-         int *num;
-         num = va_arg (args, int *);
-         *num = currlen;
-        }
-       break;
-      case '%':
-       total += dopr_outch (buffer, &currlen, maxlen, ch);
-       break;
-      case 'w':
-       /* not supported yet, treat as next char */
-       ch = *format++;
-       break;
-      default:
-       /* Unknown, skip */
-       break;
-      }
-      ch = *format++;
-      state = DP_S_DEFAULT;
-      flags = cflags = min = 0;
-      max = -1;
-      break;
-    case DP_S_DONE:
-      break;
-    default:
-      /* hmm? */
-      break; /* some picky compilers need this */
-    }
-  }
-  if (buffer != NULL)
-  {
-    if (currlen < maxlen - 1) 
-      buffer[currlen] = '\0';
-    else 
-      buffer[maxlen - 1] = '\0';
-  }
-  return total;
-}
-
-static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
-                   const char *value, int flags, int min, int max)
-{
-  int padlen, strln;     /* amount to pad */
-  int cnt = 0;
-  int total = 0;
-  
-  if (value == 0)
-  {
-    value = "<NULL>";
-  }
-
-  for (strln = 0; value[strln]; ++strln); /* strlen */
-  if (max >= 0 && max < strln)
-    strln = max;
-  padlen = min - strln;
-  if (padlen < 0) 
-    padlen = 0;
-  if (flags & DP_F_MINUS) 
-    padlen = -padlen; /* Left Justify */
-
-  while (padlen > 0)
-  {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    --padlen;
-  }
-  while (*value && ((max < 0) || (cnt < max)))
-  {
-    total += dopr_outch (buffer, currlen, maxlen, *value++);
-    ++cnt;
-  }
-  while (padlen < 0)
-  {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    ++padlen;
-  }
-  return total;
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
-                  LLONG value, int base, int min, int max, int flags)
-{
-  int signvalue = 0;
-  unsigned LLONG uvalue;
-  char convert[24];
-  unsigned int place = 0;
-  int spadlen = 0; /* amount to space pad */
-  int zpadlen = 0; /* amount to zero pad */
-  const char *digits;
-  int total = 0;
-  
-  if (max < 0)
-    max = 0;
-
-  uvalue = value;
-
-  if(!(flags & DP_F_UNSIGNED))
-  {
-    if( value < 0 ) {
-      signvalue = '-';
-      uvalue = -value;
-    }
-    else
-      if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
-       signvalue = '+';
-    else
-      if (flags & DP_F_SPACE)
-       signvalue = ' ';
-  }
-  
-  if (flags & DP_F_UP)
-    /* Should characters be upper case? */
-    digits = "0123456789ABCDEF";
-  else
-    digits = "0123456789abcdef";
-
-  do {
-    convert[place++] = digits[uvalue % (unsigned)base];
-    uvalue = (uvalue / (unsigned)base );
-  } while(uvalue && (place < sizeof (convert)));
-  if (place == sizeof (convert)) place--;
-  convert[place] = 0;
-
-  zpadlen = max - place;
-  spadlen = min - MAX ((unsigned int)max, place) - (signvalue ? 1 : 0);
-  if (zpadlen < 0) zpadlen = 0;
-  if (spadlen < 0) spadlen = 0;
-  if (flags & DP_F_ZERO)
-  {
-    zpadlen = MAX(zpadlen, spadlen);
-    spadlen = 0;
-  }
-  if (flags & DP_F_MINUS) 
-    spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
-  dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
-      zpadlen, spadlen, min, max, place));
-#endif
-
-  /* Spaces */
-  while (spadlen > 0) 
-  {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    --spadlen;
-  }
-
-  /* Sign */
-  if (signvalue) 
-    total += dopr_outch (buffer, currlen, maxlen, signvalue);
-
-  /* Zeros */
-  if (zpadlen > 0) 
-  {
-    while (zpadlen > 0)
-    {
-      total += dopr_outch (buffer, currlen, maxlen, '0');
-      --zpadlen;
-    }
-  }
-
-  /* Digits */
-  while (place > 0) 
-    total += dopr_outch (buffer, currlen, maxlen, convert[--place]);
-  
-  /* Left Justified spaces */
-  while (spadlen < 0) {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    ++spadlen;
-  }
-
-  return total;
-}
-
-static LDOUBLE abs_val (LDOUBLE value)
-{
-  LDOUBLE result = value;
-
-  if (value < 0)
-    result = -value;
-
-  return result;
-}
-
-static LDOUBLE pow10 (int exp)
-{
-  LDOUBLE result = 1;
-
-  while (exp)
-  {
-    result *= 10;
-    exp--;
-  }
-  
-  return result;
-}
-
-static LLONG round (LDOUBLE value)
-{
-  LLONG intpart;
-
-  intpart = value;
-  value = value - intpart;
-  if (value >= 0.5)
-    intpart++;
-
-  return intpart;
-}
-
-static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
-                 LDOUBLE fvalue, int min, int max, int flags)
-{
-  int signvalue = 0;
-  LDOUBLE ufvalue;
-  char iconvert[20];
-  char fconvert[20];
-  int iplace = 0;
-  int fplace = 0;
-  int padlen = 0; /* amount to pad */
-  int zpadlen = 0; 
-  int caps = 0;
-  int total = 0;
-  LLONG intpart;
-  LLONG fracpart;
-  
-  /* 
-   * AIX manpage says the default is 0, but Solaris says the default
-   * is 6, and sprintf on AIX defaults to 6
-   */
-  if (max < 0)
-    max = 6;
-
-  ufvalue = abs_val (fvalue);
-
-  if (fvalue < 0)
-    signvalue = '-';
-  else
-    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
-      signvalue = '+';
-    else
-      if (flags & DP_F_SPACE)
-       signvalue = ' ';
-
-#if 0
-  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-#endif
-
-  intpart = ufvalue;
-
-  /* 
-   * Sorry, we only support 9 digits past the decimal because of our 
-   * conversion method
-   */
-  if (max > 9)
-    max = 9;
-
-  /* We "cheat" by converting the fractional part to integer by
-   * multiplying by a factor of 10
-   */
-  fracpart = round ((pow10 (max)) * (ufvalue - intpart));
-
-  if (fracpart >= pow10 (max))
-  {
-    intpart++;
-    fracpart -= pow10 (max);
-  }
-
-#ifdef DEBUG_SNPRINTF
-  dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
-#endif
-
-  /* Convert integer part */
-  do {
-    iconvert[iplace++] =
-      (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
-    intpart = (intpart / 10);
-  } while(intpart && (iplace < 20));
-  if (iplace == 20) iplace--;
-  iconvert[iplace] = 0;
-
-  /* Convert fractional part */
-  do {
-    fconvert[fplace++] =
-      (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
-    fracpart = (fracpart / 10);
-  } while(fracpart && (fplace < 20));
-  if (fplace == 20) fplace--;
-  fconvert[fplace] = 0;
-
-  /* -1 for decimal point, another -1 if we are printing a sign */
-  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
-  zpadlen = max - fplace;
-  if (zpadlen < 0)
-    zpadlen = 0;
-  if (padlen < 0) 
-    padlen = 0;
-  if (flags & DP_F_MINUS) 
-    padlen = -padlen; /* Left Justifty */
-
-  if ((flags & DP_F_ZERO) && (padlen > 0)) 
-  {
-    if (signvalue) 
-    {
-      total += dopr_outch (buffer, currlen, maxlen, signvalue);
-      --padlen;
-      signvalue = 0;
-    }
-    while (padlen > 0)
-    {
-      total += dopr_outch (buffer, currlen, maxlen, '0');
-      --padlen;
-    }
-  }
-  while (padlen > 0)
-  {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    --padlen;
-  }
-  if (signvalue) 
-    total += dopr_outch (buffer, currlen, maxlen, signvalue);
-
-  while (iplace > 0) 
-    total += dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
-
-  /*
-   * Decimal point.  This should probably use locale to find the correct
-   * char to print out.
-   */
-  if (max > 0)
-  {
-    total += dopr_outch (buffer, currlen, maxlen, '.');
-
-    while (fplace > 0) 
-      total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
-  }
-
-  while (zpadlen > 0)
-  {
-    total += dopr_outch (buffer, currlen, maxlen, '0');
-    --zpadlen;
-  }
-
-  while (padlen < 0) 
-  {
-    total += dopr_outch (buffer, currlen, maxlen, ' ');
-    ++padlen;
-  }
-
-  return total;
-}
-
-static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
-{
-  if (*currlen + 1 < maxlen)
-    buffer[(*currlen)++] = c;
-  return 1;
-}
-
-int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
-{
-  if (str != NULL)
-    str[0] = 0;
-  return dopr(str, count, fmt, args);
-}
-
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
-  char *str;
-  size_t count;
-  char *fmt;
-#endif
-  VA_LOCAL_DECL;
-  int total;
-    
-  VA_START (fmt);
-  VA_SHIFT (str, char *);
-  VA_SHIFT (count, size_t );
-  VA_SHIFT (fmt, char *);
-  total = vsnprintf(str, count, fmt, ap);
-  VA_END;
-  return total;
-}
-
-#ifdef TEST_SNPRINTF
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
-int main (void)
-{
-  char buf1[LONG_STRING];
-  char buf2[LONG_STRING];
-  char *fp_fmt[] = {
-    "%-1.5f",
-    "%1.5f",
-    "%123.9f",
-    "%10.5f",
-    "% 10.5f",
-    "%+22.9f",
-    "%+4.9f",
-    "%01.3f",
-    "%4f",
-    "%3.1f",
-    "%3.2f",
-    "%.0f",
-    "%.1f",
-    NULL
-  };
-  double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
-    0.9996, 1.996, 4.136, 0};
-  char *int_fmt[] = {
-    "%-1.5d",
-    "%1.5d",
-    "%123.9d",
-    "%5.5d",
-    "%10.5d",
-    "% 10.5d",
-    "%+22.33d",
-    "%01.3d",
-    "%4d",
-    NULL
-  };
-  long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
-  int x, y;
-  int fail = 0;
-  int num = 0;
-
-  printf ("Testing snprintf format codes against system sprintf...\n");
-
-  for (x = 0; fp_fmt[x] != NULL ; x++)
-    for (y = 0; fp_nums[y] != 0 ; y++)
-    {
-      snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
-      sprintf (buf2, fp_fmt[x], fp_nums[y]);
-      if (strcmp (buf1, buf2))
-      {
-       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
-           fp_fmt[x], buf1, buf2);
-       fail++;
-      }
-      num++;
-    }
-
-  for (x = 0; int_fmt[x] != NULL ; x++)
-    for (y = 0; int_nums[y] != 0 ; y++)
-    {
-      snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
-      sprintf (buf2, int_fmt[x], int_nums[y]);
-      if (strcmp (buf1, buf2))
-      {
-       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
-           int_fmt[x], buf1, buf2);
-       fail++;
-      }
-      num++;
-    }
-  printf ("%d tests failed out of %d.\n", fail, num);
-}
-#endif /* SNPRINTF_TEST */
diff --git a/lib/sockaddr.c b/lib/sockaddr.c
deleted file mode 100644 (file)
index 4e5872a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*  $Id: sockaddr.c 5381 2002-03-31 22:35:47Z rra $
-**
-**  Routines for manipulating sockaddr structs
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include <netdb.h>
-
-#include "libinn.h"
-
-char *sprint_sockaddr(const struct sockaddr *sa)
-{
-#ifdef HAVE_INET6
-    static char buff[256];
-    const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) sa;
-
-    *buff = '\0';
-    if (sa->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
-       struct sockaddr_in sin;
-       memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr + 12,
-               sizeof sin.sin_addr);
-       sin.sin_port = sin6->sin6_port;
-       sin.sin_family = AF_INET;
-#ifdef HAVE_SOCKADDR_LEN
-       sin.sin_len = sizeof(struct sockaddr_in);
-#endif
-       return inet_ntoa(sin.sin_addr);
-    }
-    getnameinfo(sa, SA_LEN(sa), buff, sizeof buff, NULL, 0, NI_NUMERICHOST);
-
-    return buff;
-#else
-    return inet_ntoa(((const struct sockaddr_in *)sa)->sin_addr);
-#endif
-}
-
-void make_sin(struct sockaddr_in *s, const struct in_addr *src)
-{
-    memset(s, 0, sizeof( struct sockaddr_in ));
-    s->sin_family = AF_INET;
-#ifdef HAVE_SOCKADDR_LEN
-    s->sin_len = sizeof( struct sockaddr_in );
-#endif
-    s->sin_addr = *src;
-}
diff --git a/lib/strcasecmp.c b/lib/strcasecmp.c
deleted file mode 100644 (file)
index 75a43df..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "config.h"
-#include "clibrary.h"
-
-
-/*  $Revision: 6118 $
- *
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static const char sccsid[] = "@(#)strcasecmp.c 5.9 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-typedef unsigned char u_char;
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison.  The mappings are
- * based upon ascii character sequences.
- */
-static const u_char charmap[] = {
-       '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-       '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-       '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-       '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-       '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-       '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-       '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-       '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-       '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-       '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-       '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-       '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-       '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-       '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
-       '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
-       '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
-       '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
-       '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
-       '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
-       '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
-       '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
-       '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
-       '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
-       '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
-       '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
-       '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
-       '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-       '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-       '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-       '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-int
-strcasecmp(s1, s2)
-       const char *s1, *s2;
-{
-       const u_char *cm = charmap,
-                       *us1 = (const u_char *)s1,
-                       *us2 = (const u_char *)s2;
-
-       while (cm[*us1] == cm[*us2++])
-               if (*us1++ == '\0')
-                       return (0);
-       return (cm[*us1] - cm[*--us2]);
-}
-
-int
-strncasecmp(s1, s2, n)
-       const char *s1, *s2;
-       size_t n;
-{
-       if (n != 0) {
-               const u_char *cm = charmap,
-                               *us1 = (const u_char *)s1,
-                               *us2 = (const u_char *)s2;
-
-               do {
-                       if (cm[*us1] != cm[*us2++])
-                               return (cm[*us1] - cm[*--us2]);
-                       if (*us1++ == '\0')
-                               break;
-               } while (--n != 0);
-       }
-       return (0);
-}
diff --git a/lib/strerror.c b/lib/strerror.c
deleted file mode 100644 (file)
index 7b4a472..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*  $Id: strerror.c 6127 2003-01-18 22:25:37Z rra $
-**
-**  Replacement for a missing strerror.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the standard library routine strerror
-**  for those platforms that don't have it (e.g. Ultrix).  Assume that we
-**  have sys_nerr and sys_errlist available to use instead.  Calling
-**  strerror should be thread-safe unless it is called for an unknown errno.
-*/
-
-#include "config.h"
-
-/* Our declarations of sys_nerr and sys_errlist may conflict with the ones
-   provided by stdio.h from glibc.  This trick hides the declarations in the
-   system header from the compiler while we test.  (The conflicts are just
-   whether or not to const, so there are no negative effects from using our
-   declarations.) */
-#if TESTING
-# define sys_nerr       hidden_sys_nerr
-# define sys_errlist    hidden_sys_errlist
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-
-#if TESTING
-# undef sys_nerr
-# undef sys_errlist
-#endif
-
-extern const int sys_nerr;
-extern const char *sys_errlist[];
-
-/* If we're running the test suite, rename strerror to avoid conflicts with
-   the system version. */
-#if TESTING
-# define strerror test_strerror
-const char *test_strerror(int);
-int snprintf(char *, size_t, const char *, ...);
-#endif
-
-const char *
-strerror(int error)
-{
-    static char buff[32];
-    int oerrno;
-
-    if (error >= 0 && error < sys_nerr)
-        return sys_errlist[error];
-    oerrno = errno;
-    snprintf(buff, sizeof(buff), "Error code %d", error);
-    errno = oerrno;
-    return buff;
-}
diff --git a/lib/strlcat.c b/lib/strlcat.c
deleted file mode 100644 (file)
index 2d00583..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*  $Id: strlcat.c 5681 2002-08-29 04:07:50Z rra $
-**
-**  Replacement for a missing strlcat.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the *BSD function strlcat, originally
-**  developed by Todd Miller and Theo de Raadt.  strlcat works similarly to
-**  strncat, except simpler.  The result is always nul-terminated even if the
-**  source string is longer than the space remaining in the destination
-**  string, and the total space required is returned.  The third argument is
-**  the total space available in the destination buffer, not just the amount
-**  of space remaining.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-/* If we're running the test suite, rename strlcat to avoid conflicts with
-   the system version. */
-#if TESTING
-# define strlcat test_strlcat
-size_t test_strlcat(char *, const char *, size_t);
-#endif
-
-size_t
-strlcat(char *dst, const char *src, size_t size)
-{
-    size_t used, length, copy;
-
-    used = strlen(dst);
-    length = strlen(src);
-    if (size > 0 && used < size - 1) {
-        copy = (length >= size - used) ? size - used - 1 : length;
-        memcpy(dst + used, src, copy);
-        dst[used + copy] = '\0';
-    }
-    return used + length;
-}
diff --git a/lib/strlcpy.c b/lib/strlcpy.c
deleted file mode 100644 (file)
index 6f6c214..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*  $Id: strlcpy.c 5681 2002-08-29 04:07:50Z rra $
-**
-**  Replacement for a missing strlcpy.
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  Provides the same functionality as the *BSD function strlcpy, originally
-**  developed by Todd Miller and Theo de Raadt.  strlcpy works similarly to
-**  strncpy, except saner and simpler.  The result is always nul-terminated
-**  even if the source string is longer than the destination string, and the
-**  total space required is returned.  The destination string is not
-**  nul-filled like strncpy does, just nul-terminated.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-/* If we're running the test suite, rename strlcpy to avoid conflicts with
-   the system version. */
-#if TESTING
-# define strlcpy test_strlcpy
-size_t test_strlcpy(char *, const char *, size_t);
-#endif
-
-size_t
-strlcpy(char *dst, const char *src, size_t size)
-{
-    size_t length, copy;
-
-    length = strlen(src);
-    if (size > 0) {
-        copy = (length >= size) ? size - 1 : length;
-        memcpy(dst, src, copy);
-        dst[copy] = '\0';
-    }
-    return length;
-}
diff --git a/lib/strspn.c b/lib/strspn.c
deleted file mode 100644 (file)
index 7337000..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*  $Id: strspn.c 6118 2003-01-13 06:44:24Z rra $
-**
-**  This file has been modified to get it to compile more easily
-**  on pre-4.4BSD systems.  Rich $alz, June 1991.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if 0
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strspn.c   5.7 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/stdc.h>
-#include <string.h>
-#endif
-
-/*
- * Span the string s2 (skip characters that are in s2).
- */
-size_t
-strspn(s1, s2)
-       const char *s1;
-       const char *s2;
-{
-       const char *p = s1, *spanp;
-       char c, sc;
-
-       /*
-        * Skip any characters in s2, excluding the terminating \0.
-        */
-cont:
-       c = *p++;
-       for (spanp = s2; (sc = *spanp++) != 0;)
-               if (sc == c)
-                       goto cont;
-       return (p - 1 - s1);
-}
diff --git a/lib/strtok.c b/lib/strtok.c
deleted file mode 100644 (file)
index 98470fe..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*  $Id: strtok.c 6118 2003-01-13 06:44:24Z rra $
-**
-**  This file has been modified to get it to compile more easily
-**  on pre-4.4BSD systems.  Rich $alz, June 1991.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if 0
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strtok.c   5.7 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stddef.h>
-#include <string.h>
-#endif
-
-char *
-strtok(s, delim)
-       char *s, *delim;
-{
-       char *spanp;
-       int c, sc;
-       char *tok;
-       static char *last;
-
-
-       if (s == NULL && (s = last) == NULL)
-               return (NULL);
-
-       /*
-        * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
-        */
-cont:
-       c = *s++;
-       for (spanp = delim; (sc = *spanp++) != 0;) {
-               if (c == sc)
-                       goto cont;
-       }
-
-       if (c == 0) {           /* no non-delimiter characters */
-               last = NULL;
-               return (NULL);
-       }
-       tok = s - 1;
-
-       /*
-        * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
-        * Note that delim must have one NUL; we stop if we see that, too.
-        */
-       for (;;) {
-               c = *s++;
-               spanp = delim;
-               do {
-                       if ((sc = *spanp++) == c) {
-                               if (c == 0)
-                                       s = NULL;
-                               else
-                                       s[-1] = 0;
-                               last = s;
-                               return (tok);
-                       }
-               } while (sc != 0);
-       }
-       /* NOTREACHED */
-}
diff --git a/lib/timer.c b/lib/timer.c
deleted file mode 100644 (file)
index c1bdf61..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*  $Id: timer.c 6129 2003-01-19 00:39:49Z rra $
-**
-**  Timer functions, to gather profiling data.
-**
-**  These functions log profiling information about where the server spends
-**  its time.  While this doesn't provide as detailed of information as a
-**  profiling build would, it's much faster and simpler, and since it's fast
-**  enough to always leave on even on production servers, it can gather
-**  information *before* it's needed and show long-term trends.
-**
-**  Functions that should have their time monitored need to call TMRstart(n)
-**  at the beginning of the segment of code and TMRstop(n) at the end.  The
-**  time spent will be accumulated and added to the total for the counter n,
-**  where n should be one of the constants in timer.h or defined in your
-**  application.  If you add new timers in the library code, add them to
-**  timer.h and also add a description to TMRsummary; if you add them in
-**  your application add them to your own description array.  Also add them
-**  to innreport.
-**
-**  Calls are sanity-checked to some degree and errors reported via
-**  warn/die, so all callers should have the proper warn and die handlers
-**  set up, if appropriate.
-**
-**  Recursion is not allowed on a given timer.  Setting multiple timers
-**  at once is fine (i.e., you may have a timer for the total time to write
-**  an article, how long the disk write takes, how long the history update
-**  takes, etc. which are components of the total article write time).  If a
-**  timer is started while another timer is running, the new timer is
-**  considered to be a sub-timer of the running timer, and must be stopped
-**  before the parent timer is stopped.  Note that the same timer number can
-**  be a sub-timer of more than one timer or a timer without a parent, and
-**  each of those counts will be reported separately.
-**
-**  Note that this code is not thread-safe and in fact would need to be
-**  completely overhauled for a threaded server (since the idea of global
-**  timing statistics doesn't make as much sense when different tasks are
-**  done in different threads).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/time.h"
-#include <syslog.h>
-
-#include "inn/messages.h"
-#include "inn/timer.h"
-#include "libinn.h"
-
-/* Timer values are stored in a series of trees.  This allows use to use
-   nested timers.  Each nested timer node is linked to three of its
-   neighbours to make lookups easy and fast.  The current position in the
-   graph is given by timer_current.
-
-   As an optimization, since most timers aren't nested, timer_list holds an
-   array of pointers to non-nested timers that's filled in as TMRstart is
-   called so that the non-nested case remains O(1).  That array is stored in
-   timers.  This is the "top level" of the timer trees; if timer_current is
-   NULL, any timer that's started is found in this array.  If timer_current
-   isn't NULL, there's a running timer, and starting a new timer adds to
-   that tree.
-
-   Note that without the parent pointer, this is a tree.  id is the
-   identifier of the timer.  start stores the time (relative to the last
-   summary) at which TMRstart was last called for each timer.  total is
-   the total time accrued by that timer since the last summary.  count is
-   the number of times the timer has been stopped since the last summary. */
-struct timer {
-    unsigned int id;
-    unsigned long start;
-    unsigned long total;
-    unsigned long count;
-
-    struct timer *parent;
-    struct timer *brother;
-    struct timer *child;
-};
-static struct timer **timers = NULL;
-static struct timer *timer_current = NULL;
-unsigned int timer_count = 0;
-
-/* Names for all of the timers.  These must be given in the same order
-   as the definition of the enum in timer.h. */
-static const char *const timer_name[TMR_APPLICATION] = {
-    "hishave", "hisgrep", "hiswrite", "hissync",
-};
-
-
-/*
-**  Returns the current time as a double.  This is not used by any of the
-**  other timer code, but is used by various programs right now to keep track
-**  of elapsed time.
-*/
-double
-TMRnow_double(void)
-{
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec + tv.tv_usec * 1.0e-6);
-}
-
-
-/*
-**  Returns the number of milliseconds since the base time.  This gives
-**  better resolution than time, but the return value is a lot easier to
-**  work with than a struct timeval.  If the argument is true, also reset
-**  the base time.
-*/
-static unsigned long
-TMRgettime(bool reset)
-{
-    unsigned long now;
-    struct timeval tv;
-
-    /* The time of the last summary, used as a base for times returned by
-       TMRnow.  Formerly, times were relative to the last call to TMRinit,
-       which was only called once when innd was starting up; with that
-       approach, times may overflow a 32-bit unsigned long about 50 days
-       after the server starts up.  While this may still work due to unsigned 
-       arithmetic, this approach is less confusing to follow. */
-    static struct timeval base;
-
-    gettimeofday(&tv, NULL);
-    now = (tv.tv_sec - base.tv_sec) * 1000;
-    now += (tv.tv_usec - base.tv_usec) / 1000;
-    if (reset)
-        base = tv;
-    return now;
-}
-
-
-/*
-**  Initialize the timer.  Zero out even variables that would initially be
-**  zero so that this function can be called multiple times if wanted.
-*/
-void
-TMRinit(unsigned int count)
-{
-    unsigned int i;
-
-    /* TMRinit(0) disables all timers. */
-    TMRfree();
-    if (count != 0) {
-        timers = xmalloc(count * sizeof(struct timer *));
-        for (i = 0; i < count; i++)
-            timers[i] = NULL;
-        TMRgettime(true);
-    }
-    timer_count = count;
-}
-
-
-/*
-**  Recursively destroy a timer node.
-*/
-static void
-TMRfreeone(struct timer *timer)
-{
-    if (timer == NULL)
-        return;
-    if (timer->child != NULL)
-        TMRfreeone(timer->child);
-    if (timer->brother != NULL)
-        TMRfreeone(timer->brother);
-    free(timer);
-}
-
-
-/*
-**  Free all timers and the resources devoted to them.
-*/
-void
-TMRfree(void)
-{
-    unsigned int i;
-
-    if (timers != NULL)
-        for (i = 0; i < timer_count; i++)
-            TMRfreeone(timers[i]);
-    free(timers);
-    timers = NULL;
-    timer_count = 0;
-}
-
-
-/*
-**  Allocate a new timer node.  Takes the id and the parent pointer.
-*/
-static struct timer *
-TMRnew(unsigned int id, struct timer *parent)
-{
-    struct timer *timer;
-
-    timer = xmalloc(sizeof(struct timer));
-    timer->parent = parent;
-    timer->brother = NULL;
-    timer->child = NULL;
-    timer->id = id;
-    timer->start = 0;
-    timer->total = 0;
-    timer->count = 0;
-    return timer;
-}
-
-
-/*
-**  Start a particular timer.  If no timer is currently running, start one
-**  of the top-level timers in the timers array (creating a new one if
-**  needed).  Otherwise, search for the timer among the children of the
-**  currently running timer, again creating a new timer if necessary.
-*/
-void
-TMRstart(unsigned int timer)
-{
-    struct timer *search;
-
-    if (timer_count == 0) {
-        /* this should happen if innconf->timer == 0 */
-        return;
-    }
-    if (timer >= timer_count) {
-        warn("timer %u is larger than the maximum timer %u, ignored",
-             timer, timer_count - 1);
-        return;
-    }
-
-    /* timers will be non-NULL if timer_count > 0. */
-    if (timer_current == NULL) {
-        if (timers[timer] == NULL)
-            timers[timer] = TMRnew(timer, NULL);
-        timer_current = timers[timer];
-    } else {
-        search = timer_current;
-
-        /* Go to the "child" level and look for the good "brother"; the
-           "brothers" are a simple linked list. */
-        if (search->child == NULL) {
-            search->child = TMRnew(timer, search);
-            timer_current = search->child;
-        } else {
-            search = search->child;
-            while (search->id != timer && search->brother != NULL)
-                search = search->brother;
-            if (search->id != timer) {
-                search->brother = TMRnew(timer, search->parent);
-                timer_current = search->brother;
-            } else {
-                timer_current = search;
-            }
-        }
-    }
-    timer_current->start = TMRgettime(false);
-}
-
-
-/*
-**  Stop a particular timer, adding the total time to total and incrementing
-**  the count of times that timer has been invoked.
-*/
-void
-TMRstop(unsigned int timer)
-{
-    if (timer_count == 0) {
-        /* this should happen if innconf->timer == 0 */
-        return;
-    }
-    if (timer_current == NULL)
-        warn("timer %u stopped when no timer was running", timer);
-    else if (timer != timer_current->id)
-        warn("timer %u stopped doesn't match running timer %u", timer,
-             timer_current->id);
-    else {
-        timer_current->total += TMRgettime(false) - timer_current->start;
-        timer_current->count++;
-        timer_current = timer_current->parent;
-    }
-}
-
-
-/*
-**  Return the current time in milliseconds since the last summary or the
-**  initialization of the timer.  This is intended for use by the caller to
-**  determine when next to call TMRsummary.
-*/
-unsigned long
-TMRnow(void)
-{
-    return TMRgettime(false);
-}
-
-
-/*
-**  Return the label associated with timer number id.  Used internally
-**  to do the right thing when fetching from the timer_name or labels
-**  arrays
-*/
-static const char *
-TMRlabel(const char *const *labels, unsigned int id)
-{
-    if (id >= TMR_APPLICATION)
-        return labels[id - TMR_APPLICATION];
-    else
-        return timer_name[id];
-}
-
-
-
-/*
-**  Recursively summarize a single timer tree into the supplied buffer,
-**  returning the number of characters added to the buffer.
-*/
-static size_t
-TMRsumone(const char *const *labels, struct timer *timer, char *buf,
-          size_t len)
-{
-    struct timer *node;
-    size_t off = 0;
-
-    /* This results in "child/parent nn(nn)" instead of the arguably more
-       intuitive "parent/child" but it's easy.  Since we ensure sane snprintf 
-       semantics, it's safe to defer checking for overflow until after
-       formatting all of the timer data. */
-    for (node = timer; node != NULL; node = node->parent)
-        off += snprintf(buf + off, len - off, "%s/",
-                        TMRlabel(labels, node->id));
-    off--;
-    off += snprintf(buf + off, len - off, " %lu(%lu) ", timer->total,
-                    timer->count);
-    if (off == len) {
-        warn("timer log too long while processing %s",
-             TMRlabel(labels, timer->id));
-        return 0;
-    }
-
-    timer->total = 0;
-    timer->count = 0;
-    if (timer->child != NULL)
-        off += TMRsumone(labels, timer->child, buf + off, len - off);
-    if (timer->brother != NULL)
-        off += TMRsumone(labels, timer->brother, buf + off, len - off);
-    return off;
-}
-
-
-/*
-**  Summarize the current timer statistics, report them to syslog, and then
-**  reset them for the next polling interval.
-*/
-void
-TMRsummary(const char *prefix, const char *const *labels)
-{
-    char *buf;
-    unsigned int i;
-    size_t len, off;
-
-    /* To find the needed buffer size, note that a 64-bit unsigned number can 
-       be up to 20 digits long, so each timer can be 52 characters.  We also
-       allow another 27 characters for the introductory timestamp, plus some
-       for the prefix.  We may have timers recurring at multiple points in
-       the structure, so this may not be long enough, but this is over-sized
-       enough that it shouldn't be a problem.  We use snprintf, so if the
-       buffer isn't large enough it will just result in logged errors. */
-    len = 52 * timer_count + 27 + (prefix == NULL ? 0 : strlen(prefix)) + 1;
-    buf = xmalloc(len);
-    if (prefix == NULL)
-        off = 0;
-    else
-        off = snprintf(buf, len, "%s ", prefix);
-    off += snprintf(buf + off, len - off, "time %ld ", TMRgettime(true));
-    for (i = 0; i < timer_count; i++)
-        if (timers[i] != NULL)
-            off += TMRsumone(labels, timers[i], buf + off, len - off);
-    syslog(LOG_NOTICE, "%s", buf);
-    free(buf);
-}
diff --git a/lib/tst.c b/lib/tst.c
deleted file mode 100644 (file)
index 15a4356..0000000
--- a/lib/tst.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*  $Id: tst.c 6083 2002-12-27 07:24:36Z rra $
-**
-**  Ternary search trie implementation.
-**
-**  A ternary search trie stores key/value pairs where the key is a
-**  nul-terminated string and the value is an arbitrary pointer.  It uses a
-**  data structure designed for fast lookups, where each level of the trie
-**  represents a character in the string being searched for.
-**
-**  This implementation is based on the implementation by Peter A. Friend
-**  (version 1.3), but has been assimilated into INN and modified to use INN
-**  formatting conventions.  If new versions are released, examine the
-**  differences between that version and version 1.3 (which was checked into
-**  INN as individual files in case it's no longer available) and then apply
-**  the changes to this file.
-**
-**  Copyright (c) 2002, Peter A. Friend
-**  All rights reserved.
-**
-**  Redistribution and use in source and binary forms, with or without
-**  modification, are permitted provided that the following conditions are
-**  met:
-**
-**  Redistributions of source code must retain the above copyright notice,
-**  this list of conditions and the following disclaimer.
-**
-**  Redistributions in binary form must reproduce the above copyright notice,
-**  this list of conditions and the following disclaimer in the documentation
-**  and/or other materials provided with the distribution.
-**
-**  Neither the name of Peter A. Friend nor the names of his contributors may
-**  be used to endorse or promote products derived from this software without
-**  specific prior written permission.
-**
-**  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-**  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-**  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-**  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-**  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-**  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-**  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-**  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-**  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-**  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/tst.h"
-#include "libinn.h"
-
-
-/* A single node in the ternary search trie.  Stores a character, which is
-   part of the string formed by walking the tree from its root down to the
-   node, and left, right, and middle pointers to child nodes.  If value is
-   non-zero (not a nul), middle is the pointer to follow if the desired
-   string's character matches value.  left is used if it's less than value and
-   right is used if it's greater than value.  If value is zero, this is a
-   terminal node, and middle holds a pointer to the data associated with the
-   string that ends at this point. */
-struct node {
-    unsigned char value;
-    struct node *left;
-    struct node *middle;
-    struct node *right;
-};
-
-/* The search trie structure.  node_line_width is the number of nodes that are
-   allocated at a time, and node_lines holds a linked list of groups of nodes.
-   The free_list is a linked list (through the middle pointers) of available
-   nodes to use, and head holds pointers to the first nodes for each possible
-   first letter of the string. */
-struct tst {
-    int node_line_width;
-    struct node_lines *node_lines;
-    struct node *free_list;
-    struct node *head[256];
-};
-
-/* A simple linked list structure used to hold all the groups of nodes. */
-struct node_lines {
-    struct node *node_line;
-    struct node_lines *next;
-};
-
-
-/*
-**  Given a node and a character, decide whether a new node for that character
-**  should be placed as the left child of that node.  (If false, it should be
-**  placed as the right child.)
-*/
-#define LEFTP(n, c) (((n)->value == 0) ? ((c) < 64) : ((c) < (n)->value))
-
-
-/*
-**  Allocate new nodes for the free list, called when the free list is empty.
-*/
-static void
-tst_grow_node_free_list(struct tst *tst)
-{
-    struct node *current_node;
-    struct node_lines *new_line;
-    int i;
-
-    new_line = xmalloc(sizeof(struct node_lines));
-    new_line->node_line = xcalloc(tst->node_line_width, sizeof(struct node));
-    new_line->next = tst->node_lines;
-    tst->node_lines = new_line;
-
-    current_node = tst->node_lines->node_line;
-    tst->free_list = current_node;
-    for (i = 1; i < tst->node_line_width; i++) {
-        current_node->middle = &(tst->node_lines->node_line[i]);
-        current_node = current_node->middle;
-    }
-    current_node->middle = NULL;
-}
-
-
-/*
-**  Grab a node from the free list and initialize it with the given value.
-*/
-static struct node *
-tst_get_free_node(struct tst *tst, unsigned char value)
-{
-    struct node *free_node;
-
-    if (tst->free_list == NULL)
-        tst_grow_node_free_list(tst);
-    free_node = tst->free_list;
-    tst->free_list = tst->free_list->middle;
-    free_node->middle = NULL;
-    free_node->value = value;
-    return free_node;
-}
-
-
-/*
-**  tst_init allocates memory for members of struct tst, and allocates the
-**  first node_line_width nodes.  The value for width must be chosen very
-**  carefully.  One node is required for every character in the tree.  If you
-**  choose a value that is too small, your application will spend too much
-**  time calling malloc and your node space will be too spread out.  Too large
-**  a value is just a waste of space.
-*/
-struct tst *
-tst_init(int width)
-{
-    struct tst *tst;
-
-    tst = xcalloc(1, sizeof(struct tst));
-    tst->node_lines = NULL;
-    tst->node_line_width = width;
-    tst_grow_node_free_list(tst);
-    return tst;
-}
-
-
-/*
-**  tst_insert inserts the string key into the tree.  Behavior when a
-**  duplicate key is inserted is controlled by option.  If key is already in
-**  the tree then TST_DUPLICATE_KEY is returned, and the data pointer for the
-**  existing key is placed in exist_ptr.  If option is set to TST_REPLACE then
-**  the existing data pointer for the existing key is replaced by data.  The
-**  old data pointer will still be placed in exist_ptr.
-**
-**  If a duplicate key is encountered and option is not set to TST_REPLACE
-**  then TST_DUPLICATE_KEY is returned.  If key is zero-length, then
-**  TST_NULL_KEY is returned.  A successful insert or replace returns TST_OK.
-**
-**  The data argument may not be NULL; if it is, TST_NULL_DATA is returned.
-**  If you just want a simple existence tree, use the tst pointer as the data
-**  pointer.
-*/
-int
-tst_insert(struct tst *tst, const unsigned char *key, void *data, int option,
-           void **exist_ptr)
-{
-    struct node *current_node = NULL;
-    struct node **root_node = NULL;
-    int key_index;
-
-    if (data == NULL)
-        return TST_NULL_DATA;
-
-    if (key == NULL || *key == '\0')
-        return TST_NULL_KEY;
-
-    key_index = 1;
-    if (tst->head[*key] == NULL)
-        root_node = &tst->head[*key];
-    else
-        current_node = tst->head[*key];
-
-    while (root_node == NULL) {
-        if (key[key_index] == current_node->value) {
-            if (key[key_index] == '\0') {
-                if (exist_ptr != NULL)
-                    *exist_ptr = current_node->middle;
-                if (option == TST_REPLACE) {
-                    current_node->middle = data;
-                    return TST_OK;
-                } else
-                    return TST_DUPLICATE_KEY;
-            }
-            if (current_node->middle == NULL)
-                root_node = &current_node->middle;
-            else {
-                current_node = current_node->middle;
-                key_index++;
-            }
-        } else if (LEFTP(current_node, key[key_index])) {
-            if (current_node->left == NULL)
-                root_node = &current_node->left;
-            else
-                current_node = current_node->left;
-        } else {
-            if (current_node->right == NULL)
-                root_node = &current_node->right;
-            else
-                current_node = current_node->right;
-        }
-
-    }
-
-    *root_node = tst_get_free_node(tst, key[key_index]);
-    current_node = *root_node;
-
-    while (key[key_index] != '\0') {
-        key_index++;
-        current_node->middle = tst_get_free_node(tst, key[key_index]);
-        current_node = current_node->middle;
-    }
-
-    current_node->middle = data;
-    return TST_OK;
-}
-
-
-/*
-**  tst_search finds the string key in the tree if it exists and returns the
-**  data pointer associated with that key or NULL if it's not found.
-*/
-void *
-tst_search(struct tst *tst, const unsigned char *key)
-{
-    struct node *current_node;
-    int key_index;
-
-    if (key == NULL || *key == '\0')
-        return NULL;
-
-    if (tst->head[*key] == NULL)
-        return NULL;
-
-    current_node = tst->head[*key];
-    key_index = 1;
-    while (current_node != NULL) {
-        if (key[key_index] == current_node->value) {
-            if (current_node->value == '\0')
-                return current_node->middle;
-            else {
-                current_node = current_node->middle;
-                key_index++;
-                continue;
-            }
-        } else if (LEFTP(current_node, key[key_index]))
-            current_node = current_node->left;
-        else
-            current_node = current_node->right;
-    }
-    return NULL;
-}
-
-
-/*
-**  tst_delete deletes the string key from the tree if it exists and returns
-**  the data pointer assocaited with that key, or NULL if it wasn't found.
-*/
-void *
-tst_delete(struct tst *tst, const unsigned char *key)
-{
-    struct node *current_node;
-    struct node *current_node_parent;
-    struct node *last_branch;
-    struct node *last_branch_parent;
-    struct node *next_node;
-    struct node *last_branch_replacement;
-    struct node *last_branch_dangling_child;
-    int key_index;
-
-    if (key == NULL || *key == '\0')
-        return NULL;
-
-    if (tst->head[*key] == NULL)
-        return NULL;
-
-    last_branch = NULL;
-    last_branch_parent = NULL;
-    current_node = tst->head[*key];
-    current_node_parent = NULL;
-    key_index = 1;
-    while (current_node != NULL) {
-        if (key[key_index] == current_node->value) {
-            if (current_node->left != NULL || current_node->right != NULL) {
-                last_branch = current_node;
-                last_branch_parent = current_node_parent;
-            }
-            if (key[key_index] == '\0')
-                break;
-            else {
-                current_node_parent = current_node;
-                current_node = current_node->middle;
-                key_index++;
-            }
-        } else if (LEFTP(current_node, key[key_index])) {
-            last_branch_parent = current_node;
-            current_node_parent = current_node;
-            current_node = current_node->left;
-            last_branch = current_node;
-        } else {
-            last_branch_parent = current_node;
-            current_node_parent = current_node;
-            current_node = current_node->right;
-            last_branch = current_node;
-        }
-    }
-    if (current_node == NULL)
-        return NULL;
-
-    if (last_branch == NULL) {
-        next_node = tst->head[*key];
-        tst->head[*key] = NULL;
-    } else if (last_branch->left == NULL && last_branch->right == NULL) {
-        if (last_branch_parent->left == last_branch)
-            last_branch_parent->left = NULL;
-        else
-            last_branch_parent->right = NULL;
-        next_node = last_branch;
-    } else {
-        if (last_branch->left != NULL && last_branch->right != NULL) {
-            last_branch_replacement = last_branch->right;
-            last_branch_dangling_child = last_branch->left;
-        } else if (last_branch->right != NULL) {
-            last_branch_replacement = last_branch->right;
-            last_branch_dangling_child = NULL;
-        } else {
-            last_branch_replacement = last_branch->left;
-            last_branch_dangling_child = NULL;
-        }
-
-        if (last_branch_parent == NULL)
-            tst->head[*key] = last_branch_replacement;
-        else {
-            if (last_branch_parent->left == last_branch)
-                last_branch_parent->left = last_branch_replacement;
-            else if (last_branch_parent->right == last_branch)
-                last_branch_parent->right = last_branch_replacement;
-            else
-                last_branch_parent->middle = last_branch_replacement;
-        }
-
-        if (last_branch_dangling_child != NULL) {
-            current_node = last_branch_replacement;
-            while (current_node->left != NULL)
-                current_node = current_node->left;
-            current_node->left = last_branch_dangling_child;
-        }
-
-        next_node = last_branch;
-    }
-
-    do {
-        current_node = next_node;
-        next_node = current_node->middle;
-
-        current_node->left = NULL;
-        current_node->right = NULL;
-        current_node->middle = tst->free_list;
-        tst->free_list = current_node;
-    } while (current_node->value != 0);
-
-    return next_node;
-}
-
-
-/*
-**  tst_cleanup frees all memory allocated to nodes, internal structures,
-**  as well as tst itself.
-*/
-void
-tst_cleanup(struct tst *tst)
-{
-    struct node_lines *current_line;
-    struct node_lines *next_line;
-
-    next_line = tst->node_lines;
-    do {
-        current_line = next_line;
-        next_line = current_line->next;
-        free(current_line->node_line);
-        free(current_line);
-    } while (next_line != NULL);
-
-    free(tst);
-}
diff --git a/lib/uwildmat.c b/lib/uwildmat.c
deleted file mode 100644 (file)
index 55c159b..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/*  $Id: uwildmat.c 6779 2004-05-17 07:25:28Z rra $
-**
-**  wildmat pattern matching with Unicode UTF-8 extensions.
-**
-**  Do shell-style pattern matching for ?, \, [], and * characters.  Might not
-**  be robust in face of malformed patterns; e.g., "foo[a-" could cause a
-**  segmentation violation.  It is 8-bit clean.  (Robustness hopefully fixed
-**  July 2000; all malformed patterns should now just fail to match anything.)
-**
-**  Original by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
-**  Rich $alz is now <rsalz@osf.org>.
-**
-**  April, 1991:  Replaced mutually-recursive calls with in-line code for the
-**  star character.
-**
-**  Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
-**  This can greatly speed up failing wildcard patterns.  For example:
-**
-**     pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
-**     text 1:  -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
-**     text 2:  -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
-**
-**  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
-**  the ABORT code, it takes 22310 calls to fail.  Ugh.  The following
-**  explanation is from Lars:
-**
-**  The precondition that must be fulfilled is that DoMatch will consume at
-**  least one character in text.  This is true if *p is neither '*' nor '\0'.)
-**  The last return has ABORT instead of false to avoid quadratic behaviour in
-**  cases like pattern "*a*b*c*d" with text "abcxxxxx".  With false, each
-**  star-loop has to run to the end of the text; with ABORT only the last one
-**  does.
-**
-**  Once the control of one instance of DoMatch enters the star-loop, that
-**  instance will return either true or ABORT, and any calling instance will
-**  therefore return immediately after (without calling recursively again).
-**  In effect, only one star-loop is ever active.  It would be possible to
-**  modify the code to maintain this context explicitly, eliminating all
-**  recursive calls at the cost of some complication and loss of clarity (and
-**  the ABORT stuff seems to be unclear enough by itself).  I think it would
-**  be unwise to try to get this into a released version unless you have a
-**  good test data base to try it out on.
-**
-**  June, 1991:  Robert Elz <kre@munnari.oz.au> added minus and close bracket
-**  handling for character sets.
-**
-**  July, 2000:  Largely rewritten by Russ Allbery <rra@stanford.edu> to add
-**  support for ',', '!', and optionally '@' to the core wildmat routine.
-**  Broke the character class matching into a separate function for clarity
-**  since it's infrequently used in practice, and added some simple lookahead
-**  to significantly decrease the recursive calls in the '*' matching code.
-**  Added support for UTF-8 as the default character set for any high-bit
-**  characters.
-**
-**  For more information on UTF-8, see RFC 2279.
-**
-**  Please note that this file is intentionally written so that conditionally
-**  executed expressions are on separate lines from the condition to
-**  facilitate analysis of the coverage of the test suite using purecov.
-**  Please preserve this.  As of March 11, 2001, purecov reports that the
-**  accompanying test suite achieves 100% coverage of this file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-
-#define ABORT -1
-
-/* Whether or not an octet looks like the start of a UTF-8 character. */
-#define ISUTF8(c)       (((c) & 0xc0) == 0xc0)
-
-
-/*
-**  Determine the length of a non-ASCII character in octets (for advancing
-**  pointers when skipping over characters).  Takes a pointer to the start of
-**  the character and to the last octet of the string.  If end is NULL, expect
-**  the string pointed to by start to be nul-terminated.  If the character is
-**  malformed UTF-8, return 1 to treat it like an eight-bit local character.
-*/
-static int
-utf8_length(const unsigned char *start, const unsigned char *end)
-{
-    unsigned char mask = 0x80;
-    const unsigned char *p;
-    int length = 0;
-    int left;
-
-    for (; mask > 0 && (*start & mask) == mask; mask >>= 1)
-        length++;
-    if (length < 2 || length > 6)
-        return 1;
-    if (end != NULL && (end - start + 1) < length)
-        return 1;
-    left = length - 1;
-    p = start + 1;
-    for (p = start + 1; left > 0 && (*p & 0xc0) == 0x80; p++)
-        left--;
-    return (left == 0) ? length : 1;
-}
-
-
-/*
-**  Convert a UTF-8 character to UCS-4.  Takes a pointer to the start of the
-**  character and to the last octet of the string, and to a uint32_t into
-**  which to put the decoded UCS-4 value.  If end is NULL, expect the string
-**  pointed to by start to be nul-terminated.  Returns the number of octets in
-**  the UTF-8 encoding.  If the UTF-8 character is malformed, set result to
-**  the decimal value of the first octet; this is wrong, but it will generally
-**  cause the rest of the wildmat matching to do the right thing for non-UTF-8
-**  input.
-*/
-static int
-utf8_decode(const unsigned char *start, const unsigned char *end,
-            uint32_t *result)
-{
-    uint32_t value = 0;
-    int length, i;
-    const unsigned char *p = start;
-    unsigned char mask;
-
-    length = utf8_length(start, end);
-    if (length < 2) {
-        *result = *start;
-        return 1;
-    }
-    mask = (1 << (7 - length)) - 1;
-    value = *p & mask;
-    p++;
-    for (i = length - 1; i > 0; i--) {
-        value = (value << 6) | (*p & 0x3f);
-        p++;
-    }
-    *result = value;
-    return length;
-}
-
-
-/*
-**  Match a character class against text, a UCS-4 character.  start is a
-**  pointer to the first character of the character class, end a pointer to
-**  the last.  Returns whether the class matches that character.
-*/
-static bool
-match_class(uint32_t text, const unsigned char *start,
-            const unsigned char *end)
-{
-    bool reversed, allowrange;
-    const unsigned char *p = start;
-    uint32_t first, last;
-
-    /* Check for an inverted character class (starting with ^).  If the
-       character matches the character class, we return !reversed; that way,
-       we return true if it's a regular character class and false if it's a
-       reversed one.  If the character doesn't match, we return reversed. */
-    reversed = (*p == '^');
-    if (reversed)
-        p++;
-
-    /* Walk through the character class until we reach the end or find a
-       match, handling character ranges as we go.  Only permit a range to
-       start when allowrange is true; this allows - to be treated like a
-       normal character as the first character of the class and catches
-       malformed ranges like a-e-n.  We treat the character at the beginning
-       of a range as both a regular member of the class and the beginning of
-       the range; this is harmless (although it means that malformed ranges
-       like m-a will match m and nothing else). */
-    allowrange = false;
-    while (p <= end) {
-        if (allowrange && *p == '-' && p < end) {
-            p++;
-            p += utf8_decode(p, end, &last);
-            if (text >= first && text <= last)
-                return !reversed;
-            allowrange = false;
-        } else {
-            p += utf8_decode(p, end, &first);
-            if (text == first)
-                return !reversed;
-            allowrange = true;
-        }
-    }
-    return reversed;
-}
-
-
-/*
-**  Match the text against the pattern between start and end.  This is a
-**  single pattern; a leading ! or @ must already be taken care of, and
-**  commas must be dealt with outside of this routine.
-*/
-static int
-match_pattern(const unsigned char *text, const unsigned char *start,
-              const unsigned char *end)
-{
-    const unsigned char *q, *endclass;
-    const unsigned char *p = start;
-    bool ismeta;
-    int matched, width;
-    uint32_t c;
-
-    for (; p <= end; p++) {
-        if (!*text && *p != '*')
-            return ABORT;
-
-        switch (*p) {
-        case '\\':
-            if (!*++p)
-                return ABORT;
-            /* Fall through. */
-
-        default:
-            if (*text++ != *p)
-                return false;
-            break;
-
-        case '?':
-            text += ISUTF8(*text) ? utf8_length(text, NULL) : 1;
-            break;
-
-        case '*':
-            /* Consecutive stars are equivalent to one.  Advance pattern to
-               the character after the star. */
-            for (++p; *p == '*'; p++)
-                ;
-
-            /* A trailing star will match anything. */
-            if (p > end)
-                return true;
-
-            /* Basic algorithm: Recurse at each point where the * could
-               possibly match.  If the match succeeds or aborts, return
-               immediately; otherwise, try the next position.
-
-               Optimization: If the character after the * in the pattern
-               isn't a metacharacter (the common case), then the * has to
-               consume characters at least up to the next occurance of that
-               character in the text.  Scan forward for those points rather
-               than recursing at every possible point to save the extra
-               function call overhead. */
-            ismeta = (*p == '[' || *p == '?' || *p == '\\');
-            while (*text) {
-                width = ISUTF8(*text) ? utf8_length(text, NULL) : 1;
-                if (ismeta) {
-                    matched = match_pattern(text, p, end);
-                    text += width;
-                } else {
-                    while (*text && *text != *p) {
-                        text += width;
-                        width = ISUTF8(*text) ? utf8_length(text, NULL) : 1;
-                    }
-                    if (!*text)
-                        return ABORT;
-                    matched = match_pattern(++text, p + 1, end);
-                }
-                if (matched != false)
-                    return matched;
-            }
-            return ABORT;
-
-        case '[':
-            /* Find the end of the character class, making sure not to pick
-               up a close bracket at the beginning of the class. */
-            p++;
-            q = p + (*p == '^') + 1;
-            if (q > end)
-                return ABORT;
-            endclass = memchr(q, ']', (size_t) (end - q + 1));
-            if (!endclass)
-                return ABORT;
-
-            /* Do the heavy lifting in another function for clarity, since
-               character classes are an uncommon case. */
-            text += utf8_decode(text, NULL, &c);
-            if (!match_class(c, p, endclass - 1))
-                return false;
-            p = endclass;
-            break;
-        }
-    }
-
-    return (*text == '\0');
-}
-
-
-/*
-**  Takes text and a wildmat expression; a wildmat expression is a
-**  comma-separated list of wildmat patterns, optionally preceeded by ! to
-**  invert the sense of the expression.  Returns WILDMAT_MATCH if that
-**  expression matches the text, WILDMAT_FAIL otherwise.  If allowpoison is
-**  set, allow @ to introduce a poison expression (the same as !, but if it
-**  triggers the failed match the routine returns WILDMAT_POISON instead).
-*/
-static enum uwildmat
-match_expression(const unsigned char *text, const unsigned char *start,
-                 bool allowpoison)
-{
-    const unsigned char *end, *split;
-    const unsigned char *p = start;
-    bool reverse, escaped;
-    bool match = false;
-    bool poison = false;
-    bool poisoned = false;
-
-    /* Handle the empty expression separately, since otherwise end will be
-       set to an invalid pointer. */
-    if (!*p)
-        return !*text ? UWILDMAT_MATCH : UWILDMAT_FAIL;
-    end = start + strlen((const char *) start) - 1;
-
-    /* Main match loop.  Find each comma that separates patterns, and attempt 
-       to match the text with each pattern in order.  The last matching
-       pattern determines whether the whole expression matches. */
-    for (; p <= end + 1; p = split + 1) {
-        if (allowpoison)
-            poison = (*p == '@');
-        reverse = (*p == '!') || poison;
-        if (reverse)
-            p++;
-
-        /* Find the first unescaped comma, if any.  If there is none, split
-           will be one greater than end and point at the nul at the end of
-           the string. */
-        for (escaped = false, split = p; split <= end; split++) {
-            if (*split == '[') {
-                split++;
-                if (*split == ']')
-                    split++;
-                while (split <= end && *split != ']')
-                    split++;
-            }
-            if (*split == ',' && !escaped)
-                break;
-            escaped = (*split == '\\') ? !escaped : false;
-        }
-
-        /* Optimization: If match == !reverse and poison == poisoned, this
-           pattern can't change the result, so don't do any work. */
-        if (match == !reverse && poison == poisoned)
-            continue;
-        if (match_pattern(text, p, split - 1) == true) {
-            poisoned = poison;
-            match = !reverse;
-        }
-    }
-    if (poisoned)
-        return UWILDMAT_POISON;
-    return match ? UWILDMAT_MATCH : UWILDMAT_FAIL;
-}
-
-
-/*
-**  User-level routine used for wildmats where @ should be treated as a
-**  regular character.
-*/
-bool
-uwildmat(const char *text, const char *pat)
-{
-    const unsigned char *utext = (const unsigned char *) text;
-    const unsigned char *upat = (const unsigned char *) pat;
-
-    if (upat[0] == '*' && upat[1] == '\0')
-        return true;
-    else
-        return (match_expression(utext, upat, false) == UWILDMAT_MATCH);
-}
-
-
-/*
-**  User-level routine used for wildmats that support poison matches.
-*/
-enum uwildmat
-uwildmat_poison(const char *text, const char *pat)
-{
-    const unsigned char *utext = (const unsigned char *) text;
-    const unsigned char *upat = (const unsigned char *) pat;
-
-    if (upat[0] == '*' && upat[1] == '\0')
-        return UWILDMAT_MATCH;
-    else
-        return match_expression(utext, upat, true);
-}
-
-
-/*
-**  User-level routine for simple expressions (neither , nor ! are special).
-*/
-bool
-uwildmat_simple(const char *text, const char *pat)
-{
-    const unsigned char *utext = (const unsigned char *) text;
-    const unsigned char *upat = (const unsigned char *) pat;
-    size_t length;
-
-    if (upat[0] == '*' && upat[1] == '\0')
-        return true;
-    else {
-        length = strlen(pat);
-        return (match_pattern(utext, upat, upat + length - 1) == true);
-    }
-}
diff --git a/lib/vector.c b/lib/vector.c
deleted file mode 100644 (file)
index 7efecf2..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-/*  $Id: vector.c 6699 2004-04-07 06:47:44Z rra $
-**
-**  Vector handling (counted lists of char *'s).
-**
-**  Written by Russ Allbery <rra@stanford.edu>
-**  This work is hereby placed in the public domain by its author.
-**
-**  A vector is a table for handling a list of strings with less overhead than
-**  linked list.  The intention is for vectors, once allocated, to be reused;
-**  this saves on memory allocations once the array of char *'s reaches a
-**  stable size.
-**
-**  There are two types of vectors.  Standard vectors copy strings when
-**  they're inserted into the vector, whereas cvectors just accept pointers
-**  to external strings to store.  There are therefore two entry points for
-**  every vector function, one for vectors and one for cvectors.
-**
-**  There's a whole bunch of code duplication here.  This would be a lot
-**  cleaner with C++ features (either inheritance or templates would
-**  probably help).  One could probably in some places just cast a cvector
-**  to a vector and perform the same operations, but I'm leery of doing that
-**  as I'm not sure if it's a violation of the C type aliasing rules.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#include "inn/vector.h"
-#include "libinn.h"
-
-/*
-**  Allocate a new, empty vector.
-*/
-struct vector *
-vector_new(void)
-{
-    struct vector *vector;
-
-    vector = xmalloc(sizeof(struct vector));
-    vector->count = 0;
-    vector->allocated = 0;
-    vector->strings = NULL;
-    return vector;
-}
-
-struct cvector *
-cvector_new(void)
-{
-    struct cvector *vector;
-
-    vector = xmalloc(sizeof(struct cvector));
-    vector->count = 0;
-    vector->allocated = 0;
-    vector->strings = NULL;
-    return vector;
-}
-
-
-/*
-**  Resize a vector (using realloc to resize the table).
-*/
-void
-vector_resize(struct vector *vector, size_t size)
-{
-    size_t i;
-
-    if (vector->count > size) {
-        for (i = size; i < vector->count; i++)
-            free(vector->strings[i]);
-        vector->count = size;
-    }
-    if (size == 0) {
-        free(vector->strings);
-        vector->strings = NULL;
-    } else {
-        vector->strings = xrealloc(vector->strings, size * sizeof(char *));
-    }
-    vector->allocated = size;
-}
-
-void
-cvector_resize(struct cvector *vector, size_t size)
-{
-    if (vector->count > size)
-        vector->count = size;
-    if (size == 0) {
-        free(vector->strings);
-        vector->strings = NULL;
-    } else {
-        vector->strings =
-            xrealloc(vector->strings, size * sizeof(const char *));
-    }
-    vector->allocated = size;
-}
-
-
-/*
-**  Add a new string to the vector, resizing the vector as necessary.  The
-**  vector is resized an element at a time; if a lot of resizes are expected,
-**  vector_resize should be called explicitly with a more suitable size.
-*/
-void
-vector_add(struct vector *vector, const char *string)
-{
-    size_t next = vector->count;
-
-    if (vector->count == vector->allocated)
-        vector_resize(vector, vector->allocated + 1);
-    vector->strings[next] = xstrdup(string);
-    vector->count++;
-}
-
-void
-cvector_add(struct cvector *vector, const char *string)
-{
-    size_t next = vector->count;
-
-    if (vector->count == vector->allocated)
-        cvector_resize(vector, vector->allocated + 1);
-    vector->strings[next] = string;
-    vector->count++;
-}
-
-
-/*
-**  Empty a vector but keep the allocated memory for the pointer table.
-*/
-void
-vector_clear(struct vector *vector)
-{
-    size_t i;
-
-    for (i = 0; i < vector->count; i++)
-        free(vector->strings[i]);
-    vector->count = 0;
-}
-
-void
-cvector_clear(struct cvector *vector)
-{
-    vector->count = 0;
-}
-
-
-/*
-**  Free a vector completely.
-*/
-void
-vector_free(struct vector *vector)
-{
-    vector_clear(vector);
-    free(vector->strings);
-    free(vector);
-}
-
-void
-cvector_free(struct cvector *vector)
-{
-    cvector_clear(vector);
-    free(vector->strings);
-    free(vector);
-}
-
-
-/*
-**  Given a vector that we may be reusing, clear it out.  If the first
-**  argument is NULL, allocate a new vector.  Used by vector_split*.
-*/
-static struct vector *
-vector_reuse(struct vector *vector)
-{
-    if (vector == NULL)
-        return vector_new();
-    else {
-        vector_clear(vector);
-        return vector;
-    }
-}
-
-static struct cvector *
-cvector_reuse(struct cvector *vector)
-{
-    if (vector == NULL)
-        return cvector_new();
-    else {
-        cvector_clear(vector);
-        return vector;
-    }
-}
-
-
-/*
-**  Given a string and a separator character, count the number of strings
-**  that it will split into.
-*/
-static size_t
-split_count(const char *string, char separator)
-{
-    const char *p;
-    size_t count;
-
-    if (*string == '\0')
-        return 1;
-    for (count = 1, p = string; *p; p++)
-        if (*p == separator)
-            count++;
-    return count;
-}
-
-
-/*
-**  Given a string and a separator character, form a vector by splitting the
-**  string at those separators.  Do a first pass to size the vector, and if
-**  the third argument isn't NULL, reuse it.  Otherwise, allocate a new one.
-*/
-struct vector *
-vector_split(const char *string, char separator, struct vector *vector)
-{
-    const char *p, *start;
-    size_t i, count;
-
-    vector = vector_reuse(vector);
-
-    count = split_count(string, separator);
-    if (vector->allocated < count)
-        vector_resize(vector, count);
-
-    for (start = string, p = string, i = 0; *p; p++)
-        if (*p == separator) {
-            vector->strings[i++] = xstrndup(start, p - start);
-            start = p + 1;
-        }
-    vector->strings[i++] = xstrndup(start, p - start);
-    vector->count = i;
-
-    return vector;
-}
-
-
-/*
-**  Given a modifiable string and a separator character, form a cvector by
-**  modifying the string in-place to add nuls at the separators and then
-**  building a vector of pointers into the string.  Do a first pass to size
-**  the vector, and if the third argument isn't NULL, reuse it.  Otherwise,
-**  allocate a new one.
-*/
-struct cvector *
-cvector_split(char *string, char separator, struct cvector *vector)
-{
-    char *p, *start;
-    size_t i, count;
-
-    vector = cvector_reuse(vector);
-
-    count = split_count(string, separator);
-    if (vector->allocated < count)
-        cvector_resize(vector, count);
-
-    for (start = string, p = string, i = 0; *p; p++)
-        if (*p == separator) {
-            *p = '\0';
-            vector->strings[i++] = start;
-            start = p + 1;
-        }
-    vector->strings[i++] = start;
-    vector->count = i;
-
-    return vector;
-}
-
-
-/*
-**  Given a string, count the number of strings that it will split into when
-**  splitting on whitespace.
-*/
-static size_t
-split_space_count(const char *string)
-{
-    const char *p;
-    size_t count;
-
-    if (*string == '\0')
-        return 0;
-    for (count = 1, p = string + 1; *p != '\0'; p++)
-        if ((*p == ' ' || *p == '\t') && !(p[-1] == ' ' || p[-1] == '\t'))
-            count++;
-
-    /* If the string ends in whitespace, we've overestimated the number of
-       strings by one. */
-    if (p[-1] == ' ' || p[-1] == '\t')
-        count--;
-    return count;
-}
-
-
-/*
-**  Given a string, split it at whitespace to form a vector, copying each
-**  string segment.  If the fourth argument isn't NULL, reuse that vector;
-**  otherwise, allocate a new one.  Any number of consecutive whitespace
-**  characters is considered a single separator.
-*/
-struct vector *
-vector_split_space(const char *string, struct vector *vector)
-{
-    const char *p, *start;
-    size_t i, count;
-
-    vector = vector_reuse(vector);
-
-    count = split_space_count(string);
-    if (vector->allocated < count)
-        vector_resize(vector, count);
-
-    for (start = string, p = string, i = 0; *p; p++)
-        if (*p == ' ' || *p == '\t') {
-            if (start != p)
-                vector->strings[i++] = xstrndup(start, p - start);
-            start = p + 1;
-        }
-    if (start != p)
-        vector->strings[i++] = xstrndup(start, p - start);
-    vector->count = i;
-
-    return vector;
-}
-
-
-/*
-**  Given a string, split it at whitespace to form a vector, destructively
-**  modifying the string to nul-terminate each segment.  If the fourth
-**  argument isn't NULL, reuse that vector; otherwise, allocate a new one.
-**  Any number of consecutive whitespace characters is considered a single
-**  separator.
-*/
-struct cvector *
-cvector_split_space(char *string, struct cvector *vector)
-{
-    char *p, *start;
-    size_t i, count;
-
-    vector = cvector_reuse(vector);
-
-    count = split_space_count(string);
-    if (vector->allocated < count)
-        cvector_resize(vector, count);
-
-    for (start = string, p = string, i = 0; *p; p++)
-        if (*p == ' ' || *p == '\t') {
-            if (start != p) {
-                *p = '\0';
-                vector->strings[i++] = start;
-            }
-            start = p + 1;
-        }
-    if (start != p)
-        vector->strings[i++] = start;
-    vector->count = i;
-
-    return vector;
-}
-
-
-/*
-**  Given a vector and a separator string, allocate and build a new string
-**  composed of all the strings in the vector separated from each other by the
-**  seperator string.  Caller is responsible for freeing.
-*/
-char *
-vector_join(const struct vector *vector, const char *seperator)
-{
-    char *string;
-    size_t i, size, seplen;
-
-    seplen = strlen(seperator);
-    for (size = 0, i = 0; i < vector->count; i++)
-        size += strlen(vector->strings[i]);
-    size += (vector->count - 1) * seplen + 1;
-
-    string = xmalloc(size);
-    strlcpy(string, vector->strings[0], size);
-    for (i = 1; i < vector->count; i++) {
-        strlcat(string, seperator, size);
-        strlcat(string, vector->strings[i], size);
-    }
-
-    return string;
-}
-
-char *
-cvector_join(const struct cvector *vector, const char *seperator)
-{
-    char *string;
-    size_t i, size, seplen;
-
-    seplen = strlen(seperator);
-    for (size = 0, i = 0; i < vector->count; i++)
-        size += strlen(vector->strings[i]);
-    size += (vector->count - 1) * seplen + 1;
-
-    string = xmalloc(size);
-    strlcpy(string, vector->strings[0], size);
-    for (i = 1; i < vector->count; i++) {
-        strlcat(string, seperator, size);
-        strlcat(string, vector->strings[i], size);
-    }
-
-    return string;
-}
diff --git a/lib/version.c b/lib/version.c
deleted file mode 100644 (file)
index 931280d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*  $Id: version.c 3989 2000-10-01 01:59:45Z rra $
-**
-**  INN compile-time version information.
-*/
-
-#include "config.h"
-#include "inn/version.h"
-
-const int inn_version[3] = {
-    INN_VERSION_MAJOR, INN_VERSION_MINOR, INN_VERSION_PATCH
-};
-const char inn_version_extra[]  = INN_VERSION_EXTRA;
-const char inn_version_string[] = INN_VERSION_STRING;
diff --git a/lib/wire.c b/lib/wire.c
deleted file mode 100644 (file)
index cae1071..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*  $Id: wire.c 7258 2005-06-06 03:14:45Z eagle $
-**
-**  Wire format article utilities.
-**
-**  Originally written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  These routines manipulate wire format articles; in particular, they should
-**  be safe in the presence of embedded NULs.  They assume wire format
-**  conventions (\r\n as a line ending, in particular) and will not work with
-**  articles in native format.
-**
-**  The functions in this file take const char * pointers and return char *
-**  pointers so that they can work on both const char * and char * article
-**  bodies without changing the const sense.  This unfortunately means that
-**  the routines in this file will produce warnings about const being cast
-**  away.  To avoid those, one would need to duplicate all the code in this
-**  file or use C++.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <assert.h>
-
-#include "inn/wire.h"
-#include "libinn.h"
-
-/*
-**  Given a pointer to the start of an article, locate the first octet of the
-**  body (which may be the octet beyond the end of the buffer if your article
-**  is bodiless).
-*/
-char *
-wire_findbody(const char *article, size_t length)
-{
-    char *p;
-    const char *end;
-
-    /* Handle the degenerate case of an article with no headers. */
-    if (length > 5 && article[0] == '\r' && article[1] == '\n')
-        return (char *) article + 2;
-
-    /* Jump from \r to \r and give up if we're too close to the end. */
-    end = article + length;
-    for (p = (char *) article; (p + 4) <= end; ++p) {
-        p = memchr(p, '\r', end - p - 3);
-        if (p == NULL)
-            break;
-        if (memcmp(p, "\r\n\r\n", 4) == 0) {
-            p += 4;
-            return p;
-        }
-    }
-    return NULL;
-}
-
-
-/*
-**  Given a pointer into an article and a pointer to the last octet of the
-**  article, find the next line ending and return a pointer to the first
-**  character after that line ending.  If no line ending is found in the
-**  article or if it is at the end of the article, return NULL.
-*/
-char *
-wire_nextline(const char *article, const char *end)
-{
-    char *p;
-
-    for (p = (char *) article; (p + 2) <= end; ++p) {
-        p = memchr(p, '\r', end - p - 2);
-        if (p == NULL)
-            break;
-        if (p[1] == '\n') {
-            p += 2;
-            return p;
-        }
-    }
-    return NULL;
-}
-
-
-/*
-**  Returns true if line is the beginning of a valid header for header, also
-**  taking the length of the header name as a third argument.  Assumes that
-**  there is at least length + 2 bytes of data at line, and that the header
-**  name doesn't contain nul.
-*/
-static bool
-isheader(const char *line, const char *header, size_t length)
-{
-    if (line[length] != ':' || !ISWHITE(line[length + 1]))
-        return false;
-    return strncasecmp(line, header, length) == 0;
-}
-
-
-/*
-**  Skip over folding whitespace, as defined by RFC 2822.  Takes a pointer to
-**  where to start skipping and a pointer to the end of the data, and will not
-**  return a pointer past the end pointer.  If skipping folding whitespace
-**  takes us past the end of data, return NULL.
-*/
-static char *
-skip_fws(char *text, const char *end)
-{
-    char *p;
-
-    for (p = text; p <= end; p++) {
-        if (p < end + 1 && p[0] == '\r' && p[1] == '\n' && ISWHITE(p[2]))
-            p += 2;
-        if (!ISWHITE(*p))
-            return p;
-    }
-    return NULL;
-}
-
-
-/*
-**  Given a pointer to the start of the article, the article length, and the
-**  header to look for, find the first occurance of that header in the
-**  article.  Skip over headers with no content, but allow for headers that
-**  are folded before the first text in the header.  If no matching headers
-**  with content other than spaces and tabs are found, return NULL.
-*/
-char *
-wire_findheader(const char *article, size_t length, const char *header)
-{
-    char *p;
-    const char *end;
-    ptrdiff_t headerlen;
-
-    headerlen = strlen(header);
-    end = article + length - 1;
-
-    /* There has to be enough space left in the article for at least the
-       header, the colon, whitespace, and one non-whitespace character, hence
-       3, minus 1 since the character pointed to by end is part of the
-       article. */
-    p = (char *) article;
-    while (p != NULL && end - p > headerlen + 2) {
-        if (p[0] == '\r' && p[1] == '\n')
-            return NULL;
-        else if (isheader(p, header, headerlen)) {
-            p = skip_fws(p + headerlen + 2, end);
-            if (p == NULL)
-                return NULL;
-            if (p >= end || p[0] != '\r' || p[1] != '\n')
-                return p;
-        }
-        p = wire_nextline(p, end);
-    }
-    return NULL;
-}
-
-
-/*
-**  Given a pointer to a header and a pointer to the last octet of the
-**  article, find the end of the header (a pointer to the final \n of the
-**  header value).  If the header contents don't end in \r\n, return NULL.
-*/
-char *
-wire_endheader(const char *header, const char *end)
-{
-    char *p;
-
-    p = wire_nextline(header, end);
-    while (p != NULL) {
-        if (!ISWHITE(*p))
-            return p - 1;
-        p = wire_nextline(p, end);
-    }
-    if (end - header >= 1 && *end == '\n' && *(end - 1) == '\r')
-        return (char *) end;
-    return NULL;
-}
diff --git a/lib/xfopena.c b/lib/xfopena.c
deleted file mode 100644 (file)
index 220927f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*  $Id: xfopena.c 5381 2002-03-31 22:35:47Z rra $
-**
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <fcntl.h>
-
-#include "libinn.h"
-
-/*
-**  Open a file in append mode.  Since not all fopen's set the O_APPEND
-**  flag, we do it by hand.
-*/
-FILE *xfopena(const char *p)
-{
-    int                fd;
-
-    /* We can't trust stdio to really use O_APPEND, so open, then fdopen. */
-    fd = open(p, O_WRONLY | O_APPEND | O_CREAT, 0666);
-    return fd >= 0 ? fdopen(fd, "a") : NULL;
-}
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
deleted file mode 100644 (file)
index 88a9545..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* $Id: xmalloc.c 5381 2002-03-31 22:35:47Z rra $
-**
-**  malloc routines with failure handling.
-**
-**  Usage:
-**
-**       extern xmalloc_handler_t memory_error;
-**       extern const char *string;
-**       char *buffer;
-**
-**       xmalloc_error_handler = memory_error;
-**       buffer = xmalloc(1024);
-**       xrealloc(buffer, 2048);
-**       free(buffer);
-**       buffer = xcalloc(1024);
-**       free(buffer);
-**       buffer = xstrdup(string);
-**       free(buffer);
-**       buffer = xstrndup(string, 25);
-**
-**  xmalloc, xcalloc, xrealloc, and xstrdup behave exactly like their C
-**  library counterparts without the leading x except that they will never
-**  return NULL.  Instead, on error, they call xmalloc_error_handler,
-**  passing it the name of the function whose memory allocation failed, the
-**  amount of the allocation, and the file and line number where the
-**  allocation function was invoked (from __FILE__ and __LINE__).  This
-**  function may do whatever it wishes, such as some action to free up
-**  memory or a call to sleep to hope that system resources return.  If the
-**  handler returns, the interrupted memory allocation function will try its
-**  allocation again (calling the handler again if it still fails).
-**
-**  xstrndup behaves like xstrdup but only copies the given number of
-**  characters.  It allocates an additional byte over its second argument and
-**  always nul-terminates the string.
-**
-**  The default error handler, if none is set by the caller, prints an error
-**  message to stderr and exits with exit status 1.  An error handler must
-**  take a const char * (function name), size_t (bytes allocated), const
-**  char * (file), and int (line).
-**
-**  xmalloc will return a pointer to a valid memory region on an xmalloc of 0
-**  bytes, ensuring this by allocating space for one character instead of 0
-**  bytes.
-**
-**  The functions defined here are actually x_malloc, x_realloc, etc.  The
-**  header file defines macros named xmalloc, etc. that pass the file name
-**  and line number to these functions.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-/* The default error handler. */
-void
-xmalloc_fail(const char *function, size_t size, const char *file, int line)
-{
-    sysdie("failed to %s %lu bytes at %s line %d", function,
-           (unsigned long) size, file, line);
-}
-
-/* Assign to this variable to choose a handler other than the default. */
-xmalloc_handler_t xmalloc_error_handler = xmalloc_fail;
-
-void *
-x_malloc(size_t size, const char *file, int line)
-{
-    void *p;
-    size_t real_size;
-
-    real_size = (size > 0) ? size : 1;
-    p = malloc(real_size);
-    while (p == NULL) {
-        (*xmalloc_error_handler)("malloc", size, file, line);
-        p = malloc(real_size);
-    }
-    return p;
-}
-
-void *
-x_calloc(size_t n, size_t size, const char *file, int line)
-{
-    void *p;
-
-    n = (n > 0) ? n : 1;
-    size = (size > 0) ? size : 1;
-    p = calloc(n, size);
-    while (p == NULL) {
-        (*xmalloc_error_handler)("calloc", n * size, file, line);
-        p = calloc(n, size);
-    }
-    return p;
-}
-
-void *
-x_realloc(void *p, size_t size, const char *file, int line)
-{
-    void *newp;
-
-    newp = realloc(p, size);
-    while (newp == NULL && size > 0) {
-        (*xmalloc_error_handler)("realloc", size, file, line);
-        newp = realloc(p, size);
-    }
-    return newp;
-}
-
-char *
-x_strdup(const char *s, const char *file, int line)
-{
-    char *p;
-    size_t len;
-
-    len = strlen(s) + 1;
-    p = malloc(len);
-    while (p == NULL) {
-        (*xmalloc_error_handler)("strdup", len, file, line);
-        p = malloc(len);
-    }
-    memcpy(p, s, len);
-    return p;
-}
-
-char *
-x_strndup(const char *s, size_t size, const char *file, int line)
-{
-    char *p;
-
-    p = malloc(size + 1);
-    while (p == NULL) {
-        (*xmalloc_error_handler)("strndup", size + 1, file, line);
-        p = malloc(size + 1);
-    }
-    memcpy(p, s, size);
-    p[size] = '\0';
-    return p;
-}
diff --git a/lib/xsignal.c b/lib/xsignal.c
deleted file mode 100644 (file)
index f2c1461..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*  $Id: xsignal.c 5610 2002-08-18 22:22:52Z rra $
-**
-**  A reliable implementation of signal for System V systems.
-**
-**  Two functions are provided, xsignal and xsignal_norestart.  The former
-**  attempts to set system calls to be restarted and the latter does not.
-**
-**  Be aware that there's weird declaration stuff going on here; a signal
-**  handler is a pointer to a function taking an int and returning void.
-**  We typedef this as sig_handler_type for clearer code.
-*/
-
-#include "config.h"
-#include "libinn.h"
-#include <signal.h>
-
-typedef void (*sig_handler_type)(int);
-
-#ifdef HAVE_SIGACTION
-
-sig_handler_type
-xsignal(int signum, sig_handler_type sigfunc)
-{
-    struct sigaction act, oact;
-
-    act.sa_handler = sigfunc;
-    sigemptyset(&act.sa_mask);
-
-    /* Try to restart system calls if possible. */
-#ifdef SA_RESTART
-    act.sa_flags = SA_RESTART;
-#else
-    act.sa_flags = 0;
-#endif
-
-    if (sigaction(signum, &act, &oact) < 0)
-        return SIG_ERR;
-    return oact.sa_handler;
-}
-
-sig_handler_type
-xsignal_norestart(int signum, sig_handler_type sigfunc)
-{
-    struct sigaction act, oact;
-
-    act.sa_handler = sigfunc;
-    sigemptyset(&act.sa_mask);
-
-    /* Try not to restart system calls. */
-#ifdef SA_INTERRUPT
-    act.sa_flags = SA_INTERRUPT;
-#else
-    act.sa_flags = 0;
-#endif
-
-    if (sigaction(signum, &act, &oact) < 0)
-        return SIG_ERR;
-    return oact.sa_handler;
-}
-
-#else /* !HAVE_SIGACTION */
-
-sig_handler_type
-xsignal(int signum, sig_handler_type sigfunc)
-{
-    return signal(signum, sigfunc);
-}
-
-sig_handler_type
-xsignal_norestart(int signum, sig_handler_type sigfunc)
-{
-    return signal(signum, sigfunc);
-}
-
-#endif /* !HAVE_SIGACTION */
diff --git a/lib/xwrite.c b/lib/xwrite.c
deleted file mode 100644 (file)
index 67c3d97..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*  $Id: xwrite.c 5771 2002-09-17 17:00:05Z alexk $
-**
-**  write and writev replacements to handle partial writes.
-**
-**  Usage:
-**
-**      ssize_t xwrite(int fildes, const void *buf, size_t nbyte);
-**      ssize_t xpwrite(int fildes, const void *buf, size_t nbyte,
-**                      off_t offset);
-**      ssize_t xwritev(int fildes, const struct iovec *iov, int iovcnt);
-**
-**  xwrite, xpwrite, and xwritev behave exactly like their C library
-**  counterparts except that, if write or writev succeeds but returns a number
-**  of bytes written less than the total bytes, the write is repeated picking
-**  up where it left off until the full amount of the data is written.  The
-**  write is also repeated if it failed with EINTR.  The write will be aborted
-**  after 10 successive writes with no forward progress.
-**
-**  Both functions return the number of bytes written on success or -1 on an
-**  error, and will leave errno set to whatever the underlying system call
-**  set it to.  Note that it is possible for a write to fail after some data
-**  was written, on the subsequent additional write; in that case, these
-**  functions will return -1 and the number of bytes actually written will
-**  be lost.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/uio.h>
-
-#include "libinn.h"
-
-/* If we're running the test suite, call testing versions of the write
-   functions.  #undef pwrite first because large file support may define a
-   macro pwrite (pointing to pwrite64) on some platforms (e.g. Solaris). */
-#if TESTING
-# undef pwrite
-# define pwrite fake_pwrite
-# define write  fake_write
-# define writev fake_writev
-ssize_t fake_pwrite(int, const void *, size_t, off_t);
-ssize_t fake_write(int, const void *, size_t);
-ssize_t fake_writev(int, const struct iovec *, int);
-#endif
-
-ssize_t
-xwrite(int fd, const void *buffer, size_t size)
-{
-    size_t total;
-    ssize_t status;
-    int count = 0;
-
-    if (size == 0)
-       return 0;
-
-    /* Abort the write if we try ten times with no forward progress. */
-    for (total = 0; total < size; total += status) {
-        if (++count > 10)
-            break;
-        status = write(fd, (const char *) buffer + total, size - total);
-        if (status > 0)
-            count = 0;
-        if (status < 0) {
-            if (errno != EINTR)
-                break;
-            status = 0;
-        }
-    }
-    return (total < size) ? -1 : (ssize_t) total;
-}
-
-ssize_t
-xpwrite(int fd, const void *buffer, size_t size, off_t offset)
-{
-    size_t total;
-    ssize_t status;
-    int count = 0;
-
-    if (size == 0)
-       return 0;
-
-    /* Abort the write if we try ten times with no forward progress. */
-    for (total = 0; total < size; total += status) {
-        if (++count > 10)
-            break;
-        status = pwrite(fd, (const char *) buffer + total, size - total,
-                        offset + total);
-        if (status > 0)
-            count = 0;
-        if (status < 0) {
-            if (errno != EINTR)
-                break;
-            status = 0;
-        }
-    }
-    return (total < size) ? -1 : (ssize_t) total;
-}
-
-ssize_t
-xwritev(int fd, const struct iovec iov[], int iovcnt)
-{
-    ssize_t total, status = 0;
-    size_t left, offset;
-    int iovleft, i, count;
-    struct iovec *tmpiov;
-
-    if (iovcnt == 0)
-       return 0;
-
-    /* Get a count of the total number of bytes in the iov array. */
-    for (total = 0, i = 0; i < iovcnt; i++)
-        total += iov[i].iov_len;
-
-    if (total == 0)
-       return 0;
-
-    /* First, try just writing it all out.  Most of the time this will
-       succeed and save us lots of work.  Abort the write if we try ten times 
-       with no forward progress. */
-    count = 0;
-    do {
-        if (++count > 10)
-            break;
-        status = writev(fd, iov, iovcnt);
-        if (status > 0)
-            count = 0;
-    } while (status < 0 && errno == EINTR);
-    if (status < 0)
-        return -1;
-    if (status == total)
-        return total;
-
-    /* If we fell through to here, the first write partially succeeded.
-       Figure out how far through the iov array we got, and then duplicate
-       the rest of it so that we can modify it to reflect how much we manage
-       to write on successive tries. */
-    offset = status;
-    left = total - offset;
-    for (i = 0; offset >= (size_t) iov[i].iov_len; i++)
-        offset -= iov[i].iov_len;
-    iovleft = iovcnt - i;
-    tmpiov = xmalloc(iovleft * sizeof(struct iovec));
-    memcpy(tmpiov, iov + i, iovleft * sizeof(struct iovec));
-
-    /* status now contains the offset into the first iovec struct in tmpiov.
-       Go into the write loop, trying to write out everything remaining at
-       each point.  At the top of the loop, status will contain a count of
-       bytes written out at the beginning of the set of iovec structs. */
-    i = 0;
-    do {
-        if (++count > 10)
-            break;
-
-        /* Skip any leading data that has been written out. */
-        for (; offset >= (size_t) tmpiov[i].iov_len && iovleft > 0; i++) {
-            offset -= tmpiov[i].iov_len;
-            iovleft--;
-        }
-        tmpiov[i].iov_base = (char *) tmpiov[i].iov_base + offset;
-        tmpiov[i].iov_len -= offset;
-
-        /* Write out what's left and return success if it's all written. */
-        status = writev(fd, tmpiov + i, iovleft);
-        if (status <= 0)
-            offset = 0;
-        else {
-            offset = status;
-            left -= offset;
-            count = 0;
-        }
-    } while (left > 0 && (status >= 0 || errno == EINTR));
-
-    /* We're either done or got an error; if we're done, left is now 0. */
-    free(tmpiov);
-    return (left == 0) ? total : -1;
-}
diff --git a/nnrpd/Makefile b/nnrpd/Makefile
deleted file mode 100644 (file)
index 1360933..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top            = ..
-CFLAGS         = $(GCFLAGS) $(SSLINC)
-
-ALL            = nnrpd
-
-SOURCES                = article.c cache.c group.c commands.c line.c list.c misc.c \
-                 newnews.c nnrpd.c perl.c perm.c post.c python.c \
-                 sasl_config.c tls.c track.c
-
-INCLUDES       = cache.h nnrpd.h post.h sasl_config.h tls.h
-
-OBJECTS                = $(SOURCES:.c=.o)
-
-INSTALLED      = $(D)$(PATHBIN)/nnrpd
-
-all: $(ALL)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPUB) nnrpd $D$(PATHBIN)/nnrpd
-
-clean:
-       rm -f *.o $(ALL) nnrpdp profiled
-       rm -rf .libs
-
-clobber distclean: clean
-       rm -f tags
-
-tags ctags: $(SOURCES) $(INCLUDES)
-       $(CTAGS) $(SOURCES) $(INCLUDES) ../lib/*.c ../include/*.h
-
-
-##  Compilation rules.
-
-NNRPDLIBS      = $(LIBHIST) $(LIBSTORAGE) $(LIBINN) $(EXTSTORAGELIBS) \
-                 $(PERLLIB) $(PYTHONLIB) $(SSLLIB) $(LIBS)
-
-perl.o:                perl.c          ; $(CC) $(CFLAGS) $(PERLINC) -c perl.c
-python.o:      python.c        ; $(CC) $(CFLAGS) $(PYTHONINC) -c python.c
-
-nnrpd: $(OBJECTS) $(LIBHIST) $(LIBSTORAGE) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(OBJECTS) $(NNRPDLIBS)
-
-$(LIBINN):     ; (cd ../lib ; $(MAKE))
-$(LIBSTORAGE): ; (cd ../storage ; $(MAKE))
-$(LIBHIST):    ; (cd ../history ; $(MAKE))
-
-
-##  Profiling.  These rules have not been checked for a while and may need
-##  some work.
-
-profiled:      nnrpdp
-       date >$@
-
-nnrpdp:                $(SOURCES)
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) nnrpd
-       mv nnrpd nnrpdp
-       rm -f $(OBJECTS)
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend:        $(SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS) $(PERLINC) $(PYTHONINC) $(TCLINC)' $(SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-article.o: article.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/wire.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h tls.h cache.h
-cache.o: cache.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/tst.h \
-  ../include/inn/list.h ../include/libinn.h ../include/storage.h cache.h
-group.o: group.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h
-commands.o: commands.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/wait.h ../include/config.h nnrpd.h \
-  ../include/portable/socket.h ../include/portable/time.h \
-  ../include/inn/qio.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ../include/inn/innconf.h \
-  ../include/inn/messages.h
-line.o: line.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/messages.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h
-list.o: list.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  nnrpd.h ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h \
-  ../include/inn/defines.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/inn/vector.h \
-  ../include/inn/timer.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../include/inn/innconf.h \
-  ../include/inn/messages.h
-misc.o: misc.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h sasl_config.h
-newnews.o: newnews.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/inn/wire.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h cache.h
-nnrpd.o: nnrpd.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/setproctitle.h ../include/config.h \
-  ../include/portable/wait.h ../include/inn/innconf.h \
-  ../include/inn/defines.h ../include/inn/messages.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h nnrpd.h \
-  ../include/portable/socket.h ../include/portable/time.h \
-  ../include/inn/qio.h ../include/nntp.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h sasl_config.h
-perl.o: perl.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h post.h
-perm.o: perm.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/wait.h ../include/config.h ../include/conffile.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/innperl.h \
-  nnrpd.h ../include/portable/socket.h ../include/portable/time.h \
-  ../include/inn/qio.h ../include/libinn.h ../include/nntp.h \
-  ../include/paths.h ../include/storage.h ../include/inn/vector.h \
-  ../include/inn/timer.h
-post.o: post.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h post.h
-python.o: python.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/hashtab.h
-sasl_config.o: sasl_config.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h sasl_config.h
-tls.o: tls.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h nnrpd.h ../include/portable/socket.h \
-  ../include/config.h ../include/portable/time.h ../include/inn/qio.h \
-  ../include/inn/defines.h ../include/libinn.h ../include/config.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h sasl_config.h
-track.o: track.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h nnrpd.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/qio.h ../include/libinn.h \
-  ../include/nntp.h ../include/paths.h ../include/storage.h \
-  ../include/inn/vector.h ../include/inn/timer.h
diff --git a/nnrpd/article.c b/nnrpd/article.c
deleted file mode 100644 (file)
index 5b9160e..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-/*  $Id: article.c 7538 2006-08-26 05:44:06Z eagle $
-**
-**  Article-related routines.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <assert.h>
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <sys/uio.h>
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/wire.h"
-#include "nnrpd.h"
-#include "ov.h"
-#include "tls.h"
-#include "cache.h"
-
-#ifdef HAVE_SSL
-extern SSL *tls_conn;
-#endif 
-
-/*
-**  Data structures for use in ARTICLE/HEAD/BODY/STAT common code.
-*/
-typedef enum _SENDTYPE {
-    STarticle,
-    SThead,
-    STbody,
-    STstat
-} SENDTYPE;
-
-typedef struct _SENDDATA {
-    SENDTYPE    Type;
-    int         ReplyCode;
-    const char *Item;
-} SENDDATA;
-
-static char            ARTnotingroup[] = NNTP_NOTINGROUP;
-static char            ARTnoartingroup[] = NNTP_NOARTINGRP;
-static char            ARTnocurrart[] = NNTP_NOCURRART;
-static ARTHANDLE        *ARThandle = NULL;
-static SENDDATA                SENDbody = {
-    STbody,    NNTP_BODY_FOLLOWS_VAL,          "body"
-};
-static SENDDATA                SENDarticle = {
-    STarticle, NNTP_ARTICLE_FOLLOWS_VAL,       "article"
-};
-static SENDDATA                SENDstat = {
-    STstat,    NNTP_NOTHING_FOLLOWS_VAL,       "status"
-};
-static SENDDATA                SENDhead = {
-    SThead,    NNTP_HEAD_FOLLOWS_VAL,          "head"
-};
-
-
-static struct iovec    iov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
-static int             queued_iov = 0;
-
-static void PushIOvHelper(struct iovec* vec, int* countp) {
-    int result;
-    TMRstart(TMR_NNTPWRITE);
-#ifdef HAVE_SSL
-    if (tls_conn) {
-Again:
-        result = SSL_writev(tls_conn, vec, *countp);
-        switch (SSL_get_error(tls_conn, result)) {
-        case SSL_ERROR_NONE:
-        case SSL_ERROR_SYSCALL:
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            goto Again;
-            break;
-        case SSL_ERROR_SSL:
-            SSL_shutdown(tls_conn);
-            tls_conn = NULL;
-            errno = ECONNRESET;
-            break;
-        case SSL_ERROR_ZERO_RETURN:
-            break;
-        }
-    } else {
-        result = xwritev(STDOUT_FILENO, vec, *countp);
-    }
-#else
-    result = xwritev(STDOUT_FILENO, vec, *countp);
-#endif
-    TMRstop(TMR_NNTPWRITE);
-    if (result == -1) {
-       /* we can't recover, since we can't resynchronise with our
-        * peer */
-       ExitWithStats(1, true);
-    }
-    *countp = 0;
-}
-
-static void
-PushIOvRateLimited(void) {
-    double              start, end, elapsed, target;
-    struct iovec        newiov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
-    int                 newiov_len;
-    int                 sentiov;
-    int                 i;
-    int                 bytesfound;
-    int                 chunkbittenoff;
-    struct timeval      waittime;
-
-    while (queued_iov) {
-       bytesfound = newiov_len = 0;
-       sentiov = 0;
-       for (i = 0; (i < queued_iov) && (bytesfound < MaxBytesPerSecond); i++) {
-           if ((signed)iov[i].iov_len + bytesfound > MaxBytesPerSecond) {
-               chunkbittenoff = MaxBytesPerSecond - bytesfound;
-               newiov[newiov_len].iov_base = iov[i].iov_base;
-               newiov[newiov_len++].iov_len = chunkbittenoff;
-               iov[i].iov_base = (char *)iov[i].iov_base + chunkbittenoff;
-               iov[i].iov_len -= chunkbittenoff;
-               bytesfound += chunkbittenoff;
-           } else {
-               newiov[newiov_len++] = iov[i];
-               sentiov++;
-               bytesfound += iov[i].iov_len;
-           }
-       }
-       assert(sentiov <= queued_iov);
-        start = TMRnow_double();
-       PushIOvHelper(newiov, &newiov_len);
-        end = TMRnow_double();
-        target = (double) bytesfound / MaxBytesPerSecond;
-        elapsed = end - start;
-        if (elapsed < 1 && elapsed < target) {
-            waittime.tv_sec = 0;
-            waittime.tv_usec = (target - elapsed) * 1e6;
-            start = TMRnow_double();
-           if (select(0, NULL, NULL, NULL, &waittime) != 0)
-                syswarn("%s: select in PushIOvRateLimit failed", ClientHost);
-            end = TMRnow_double();
-            IDLEtime += end - start;
-       }
-       memmove(iov, &iov[sentiov], (queued_iov - sentiov) * sizeof(struct iovec));
-       queued_iov -= sentiov;
-    }
-}
-
-static void
-PushIOv(void) {
-    TMRstart(TMR_NNTPWRITE);
-    fflush(stdout);
-    TMRstop(TMR_NNTPWRITE);
-    if (MaxBytesPerSecond != 0)
-       PushIOvRateLimited();
-    else
-       PushIOvHelper(iov, &queued_iov);
-}
-
-static void
-SendIOv(const char *p, int len) {
-    char                *q;
-
-    if (queued_iov) {
-       q = (char *)iov[queued_iov - 1].iov_base + iov[queued_iov - 1].iov_len;
-       if (p == q) {
-           iov[queued_iov - 1].iov_len += len;
-           return;
-       }
-    }
-    iov[queued_iov].iov_base = (char*)p;
-    iov[queued_iov++].iov_len = len;
-    if (queued_iov == IOV_MAX)
-       PushIOv();
-}
-
-static char            *_IO_buffer_ = NULL;
-static int             highwater = 0;
-
-static void
-PushIOb(void) {
-    TMRstart(TMR_NNTPWRITE);
-    fflush(stdout);
-#ifdef HAVE_SSL
-    if (tls_conn) {
-        int r;
-Again:
-        r = SSL_write(tls_conn, _IO_buffer_, highwater);
-        switch (SSL_get_error(tls_conn, r)) {
-        case SSL_ERROR_NONE:
-        case SSL_ERROR_SYSCALL:
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            goto Again;
-            break;
-        case SSL_ERROR_SSL:
-            SSL_shutdown(tls_conn);
-            tls_conn = NULL;
-            errno = ECONNRESET;
-            break;
-        case SSL_ERROR_ZERO_RETURN:
-            break;
-        }
-        if (r != highwater) {
-            TMRstop(TMR_NNTPWRITE);
-            highwater = 0;
-            return;
-        }
-    } else {
-      if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
-       TMRstop(TMR_NNTPWRITE);
-       highwater = 0;
-       return;
-      }
-    }
-#else
-    if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
-       TMRstop(TMR_NNTPWRITE);
-        highwater = 0;
-        return;
-    }
-#endif
-    TMRstop(TMR_NNTPWRITE);
-    highwater = 0;
-}
-
-static void
-SendIOb(const char *p, int len) {
-    int tocopy;
-    
-    if (_IO_buffer_ == NULL)
-        _IO_buffer_ = xmalloc(BIG_BUFFER);
-
-    while (len > 0) {
-        tocopy = (len > (BIG_BUFFER - highwater)) ? (BIG_BUFFER - highwater) : len;
-        memcpy(&_IO_buffer_[highwater], p, tocopy);
-        p += tocopy;
-        highwater += tocopy;
-        len -= tocopy;
-        if (highwater == BIG_BUFFER)
-            PushIOb();
-    }
-}
-
-
-/*
-**  If we have an article open, close it.
-*/
-void ARTclose(void)
-{
-    if (ARThandle) {
-       SMfreearticle(ARThandle);
-       ARThandle = NULL;
-    }
-}
-
-bool ARTinstorebytoken(TOKEN token)
-{
-    ARTHANDLE *art;
-    struct timeval     stv, etv;
-
-    if (PERMaccessconf->nnrpdoverstats) {
-       gettimeofday(&stv, NULL);
-    }
-    art = SMretrieve(token, RETR_STAT); /* XXX This isn't really overstats, is it? */
-    if (PERMaccessconf->nnrpdoverstats) {
-       gettimeofday(&etv, NULL);
-       OVERartcheck+=(etv.tv_sec - stv.tv_sec) * 1000;
-       OVERartcheck+=(etv.tv_usec - stv.tv_usec) / 1000;
-    }
-    if (art) {
-       SMfreearticle(art);
-       return true;
-    } 
-    return false;
-}
-
-/*
-**  If the article name is valid, open it and stuff in the ID.
-*/
-static bool ARTopen(ARTNUM artnum)
-{
-    static ARTNUM      save_artnum;
-    TOKEN              token;
-
-    /* Re-use article if it's the same one. */
-    if (save_artnum == artnum) {
-       if (ARThandle)
-           return true;
-    }
-    ARTclose();
-
-    if (!OVgetartinfo(GRPcur, artnum, &token))
-       return false;
-  
-    TMRstart(TMR_READART);
-    ARThandle = SMretrieve(token, RETR_ALL);
-    TMRstop(TMR_READART);
-    if (ARThandle == NULL) {
-       return false;
-    }
-
-    save_artnum = artnum;
-    return true;
-}
-
-
-/*
-**  Open the article for a given Message-ID.
-*/
-static bool
-ARTopenbyid(char *msg_id, ARTNUM *ap, bool final)
-{
-    TOKEN token;
-
-    *ap = 0;
-    token = cache_get(HashMessageID(msg_id), final);
-    if (token.type == TOKEN_EMPTY) {
-       if (History == NULL) {
-           time_t statinterval;
-
-           /* Do lazy opens of the history file - lots of clients
-            * will never ask for anything by message id, so put off
-            * doing the work until we have to */
-           History = HISopen(HISTORY, innconf->hismethod, HIS_RDONLY);
-           if (!History) {
-               syslog(L_NOTICE, "cant initialize history");
-               Reply("%d NNTP server unavailable. Try later.\r\n",
-                     NNTP_TEMPERR_VAL);
-               ExitWithStats(1, true);
-           }
-           statinterval = 30;
-           HISctl(History, HISCTLS_STATINTERVAL, &statinterval);
-       }
-       if (!HISlookup(History, msg_id, NULL, NULL, NULL, &token))
-           return false;
-    }
-    if (token.type == TOKEN_EMPTY)
-       return false;
-    TMRstart(TMR_READART);
-    ARThandle = SMretrieve(token, RETR_ALL);
-    TMRstop(TMR_READART);
-    if (ARThandle == NULL) {
-       return false;
-    }
-
-    return true;
-}
-
-/*
-**  Send a (part of) a file to stdout, doing newline and dot conversion.
-*/
-static void ARTsendmmap(SENDTYPE what)
-{
-    const char         *p, *q, *r;
-    const char         *s, *path, *xref, *endofpath;
-    long               bytecount;
-    char               lastchar;
-
-    ARTcount++;
-    GRParticles++;
-    bytecount = 0;
-    lastchar = -1;
-
-    /* Get the headers and detect if wire format. */
-    if (what == STarticle) {
-       q = ARThandle->data;
-       p = ARThandle->data + ARThandle->len;
-     } else {
-       for (q = p = ARThandle->data; p < (ARThandle->data + ARThandle->len); p++) {
-           if (*p == '\r')
-               continue;
-           if (*p == '\n') {
-               if (lastchar == '\n') {
-                   if (what == SThead) {
-                       if (*(p-1) == '\r')
-                           p--;
-                       break;
-                   } else {
-                       q = p + 1;
-                       p = ARThandle->data + ARThandle->len;
-                       break;
-                   }
-               }
-           }
-           lastchar = *p;
-       }
-    }
-
-    /* q points to the start of the article buffer, p to the end of it */
-    if (VirtualPathlen > 0 && (what != STbody)) {
-        path = wire_findheader(ARThandle->data, ARThandle->len, "Path");
-        if (path == NULL) {
-           SendIOv(".\r\n", 3);
-           ARTgetsize += 3;
-           PushIOv();
-           ARTget++;
-           return;
-       } else {
-            xref = wire_findheader(ARThandle->data, ARThandle->len, "Xref");
-            if (xref == NULL) {
-                SendIOv(".\r\n", 3);
-                ARTgetsize += 3;
-                PushIOv();
-                ARTget++;
-                return;
-            }
-        }
-        endofpath = wire_endheader(path, ARThandle->data + ARThandle->len - 1);
-        if (endofpath == NULL) {
-           SendIOv(".\r\n", 3);
-           ARTgetsize += 3;
-           PushIOv();
-           ARTget++;
-           return;
-       }
-       if ((r = memchr(xref, ' ', p - xref)) == NULL || r == p) {
-           SendIOv(".\r\n", 3);
-           ARTgetsize += 3;
-           PushIOv();
-           ARTget++;
-           return;
-       }
-       /* r points to the first space in the Xref header */
-       for (s = path, lastchar = '\0';
-           s + VirtualPathlen + 1 < endofpath;
-           lastchar = *s++) {
-           if ((lastchar != '\0' && lastchar != '!') || *s != *VirtualPath ||
-               strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
-               continue;
-           if (*(s + VirtualPathlen - 1) != '\0' &&
-               *(s + VirtualPathlen - 1) != '!')
-               continue;
-           break;
-       }
-       if (s + VirtualPathlen + 1 < endofpath) {
-           if (xref > path) {
-               SendIOv(q, path - q);
-               SendIOv(s, xref - s);
-               SendIOv(VirtualPath, VirtualPathlen - 1);
-               SendIOv(r, p - r);
-           } else {
-               SendIOv(q, xref - q);
-               SendIOv(VirtualPath, VirtualPathlen - 1);
-               SendIOv(r, path - r);
-               SendIOv(s, p - s);
-           }
-       } else {
-           if (xref > path) {
-               SendIOv(q, path - q);
-               SendIOv(VirtualPath, VirtualPathlen);
-               SendIOv(path, xref - path);
-               SendIOv(VirtualPath, VirtualPathlen - 1);
-               SendIOv(r, p - r);
-           } else {
-               SendIOv(q, xref - q);
-               SendIOv(VirtualPath, VirtualPathlen - 1);
-               SendIOv(r, path - r);
-               SendIOv(VirtualPath, VirtualPathlen);
-               SendIOv(path, p - path);
-           }
-       }
-    } else
-       SendIOv(q, p - q);
-    ARTgetsize += p - q;
-    if (what == SThead) {
-       SendIOv(".\r\n", 3);
-       ARTgetsize += 3;
-    } else if (memcmp((ARThandle->data + ARThandle->len - 5), "\r\n.\r\n", 5)) {
-       if (memcmp((ARThandle->data + ARThandle->len - 2), "\r\n", 2)) {
-           SendIOv("\r\n.\r\n", 5);
-           ARTgetsize += 5;
-       } else {
-           SendIOv(".\r\n", 3);
-           ARTgetsize += 3;
-       }
-    }
-    PushIOv();
-
-    ARTget++;
-}
-
-/*
-**  Return the header from the specified file, or NULL if not found.
-*/
-char *GetHeader(const char *header)
-{
-    const char         *p, *q, *r, *s, *t;
-    char               *w, prevchar;
-    /* Bogus value here to make sure that it isn't initialized to \n */
-    char               lastchar = ' ';
-    const char         *limit;
-    const char         *cmplimit;
-    static char                *retval = NULL;
-    static int         retlen = 0;
-    int                        headerlen;
-    bool               pathheader = false;
-    bool               xrefheader = false;
-
-    limit = ARThandle->data + ARThandle->len;
-    cmplimit = ARThandle->data + ARThandle->len - strlen(header) - 1;
-    for (p = ARThandle->data; p < cmplimit; p++) {
-       if (*p == '\r')
-           continue;
-       if ((lastchar == '\n') && (*p == '\n')) {
-           return NULL;
-       }
-       if ((lastchar == '\n') || (p == ARThandle->data)) {
-           headerlen = strlen(header);
-           if (strncasecmp(p, header, headerlen) == 0 && p[headerlen] == ':') {
-               for (; (p < limit) && !isspace((int)*p) ; p++);
-               for (; (p < limit) && isspace((int)*p) ; p++);
-               for (q = p; q < limit; q++) 
-                   if ((*q == '\r') || (*q == '\n')) {
-                       /* Check for continuation header lines */
-                       t = q + 1;
-                       if (t < limit) {
-                           if ((*q == '\r' && *t == '\n')) {
-                               t++;
-                               if (t == limit)
-                                   break;
-                           }
-                           if ((*t == '\t' || *t == ' ')) {
-                               for (; (t < limit) && isspace((int)*t) ; t++);
-                               q = t;
-                           } else {
-                               break;
-                           }
-                       } else {
-                           break;
-                       }
-                   }
-               if (q == limit)
-                   return NULL;
-               if (strncasecmp("Path", header, headerlen) == 0)
-                   pathheader = true;
-               else if (strncasecmp("Xref", header, headerlen) == 0)
-                   xrefheader = true;
-               if (retval == NULL) {
-                   retlen = q - p + VirtualPathlen + 1;
-                   retval = xmalloc(retlen);
-               } else {
-                   if ((q - p + VirtualPathlen + 1) > retlen) {
-                       retlen = q - p + VirtualPathlen + 1;
-                        retval = xrealloc(retval, retlen);
-                   }
-               }
-               if (pathheader && (VirtualPathlen > 0)) {
-                    const char *endofpath;
-                    const char *endofarticle;
-
-                    endofarticle = ARThandle->data + ARThandle->len - 1;
-                    endofpath = wire_endheader(p, endofarticle);
-                    if (endofpath == NULL)
-                        return NULL;
-                   for (s = p, prevchar = '\0';
-                       s + VirtualPathlen + 1 < endofpath;
-                       prevchar = *s++) {
-                       if ((prevchar != '\0' && prevchar != '!') ||
-                           *s != *VirtualPath ||
-                           strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
-                           continue;
-                       if (*(s + VirtualPathlen - 1) != '\0' &&
-                           *(s + VirtualPathlen - 1) != '!')
-                           continue;
-                       break;
-                   }
-                   if (s + VirtualPathlen + 1 < endofpath) {
-                       memcpy(retval, s, q - s);
-                       *(retval + (int)(q - s)) = '\0';
-                   } else {
-                       memcpy(retval, VirtualPath, VirtualPathlen);
-                       memcpy(retval + VirtualPathlen, p, q - p);
-                       *(retval + (int)(q - p) + VirtualPathlen) = '\0';
-                   }
-               } else if (xrefheader && (VirtualPathlen > 0)) {
-                   if ((r = memchr(p, ' ', q - p)) == NULL)
-                       return NULL;
-                   for (; (r < q) && isspace((int)*r) ; r++);
-                   if (r == q)
-                       return NULL;
-                   memcpy(retval, VirtualPath, VirtualPathlen - 1);
-                   memcpy(retval + VirtualPathlen - 1, r - 1, q - r + 1);
-                   *(retval + (int)(q - r) + VirtualPathlen) = '\0';
-               } else {
-                   memcpy(retval, p, q - p);
-                   *(retval + (int)(q - p)) = '\0';
-               }
-               for (w = retval; *w; w++)
-                   if (*w == '\n' || *w == '\r')
-                       *w = ' ';
-               return retval;
-           }
-       }
-       lastchar = *p;
-    }
-    return NULL;
-}
-
-/*
-**  Fetch part or all of an article and send it to the client.
-*/
-void CMDfetch(int ac, char *av[])
-{
-    char               buff[SMBUF];
-    SENDDATA           *what;
-    bool               ok;
-    ARTNUM             art;
-    char               *msgid;
-    ARTNUM             tart;
-    bool final = false;
-
-    /* Find what to send; get permissions. */
-    ok = PERMcanread;
-    switch (*av[0]) {
-    default:
-       what = &SENDbody;
-       final = true;
-       break;
-    case 'a': case 'A':
-       what = &SENDarticle;
-       final = true;
-       break;
-    case 's': case 'S':
-       what = &SENDstat;
-       break;
-    case 'h': case 'H':
-       what = &SENDhead;
-       /* Poster might do a "head" command to verify the article. */
-       ok = PERMcanread || PERMcanpost;
-       break;
-    }
-
-    if (!ok) {
-       Reply("%s\r\n", NOACCESS);
-       return;
-    }
-
-    /* Requesting by Message-ID? */
-    if (ac == 2 && av[1][0] == '<') {
-       if (!ARTopenbyid(av[1], &art, final)) {
-           Reply("%d No such article\r\n", NNTP_DONTHAVEIT_VAL);
-           return;
-       }
-       if (!PERMartok()) {
-           ARTclose();
-           Reply("%s\r\n", NOACCESS);
-           return;
-       }
-       tart=art;
-       Reply("%d %lu %s %s\r\n", what->ReplyCode, (unsigned long) art,
-              av[1], what->Item);
-       if (what->Type != STstat) {
-           ARTsendmmap(what->Type);
-       }
-       ARTclose();
-       return;
-    }
-
-    /* Trying to read. */
-    if (GRPcount == 0) {
-       Reply("%s\r\n", ARTnotingroup);
-       return;
-    }
-
-    /* Default is to get current article, or specified article. */
-    if (ac == 1) {
-       if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
-           Reply("%s\r\n", ARTnocurrart);
-           return;
-       }
-       snprintf(buff, sizeof(buff), "%d", ARTnumber);
-       tart=ARTnumber;
-    }
-    else {
-       if (strspn(av[1], "0123456789") != strlen(av[1])) {
-           Reply("%s\r\n", ARTnoartingroup);
-           return;
-       }
-       strlcpy(buff, av[1], sizeof(buff));
-       tart=(ARTNUM)atol(buff);
-    }
-
-    /* Open the article and send the reply. */
-    if (!ARTopen(atol(buff))) {
-        Reply("%s\r\n", ARTnoartingroup);
-        return;
-    }
-    if (ac > 1)
-       ARTnumber = tart;
-    if ((msgid = GetHeader("Message-ID")) == NULL) {
-        ARTclose();
-        Reply("%s\r\n", ARTnoartingroup);
-       return;
-    }
-    Reply("%d %s %.512s %s\r\n", what->ReplyCode, buff, msgid, what->Item); 
-    if (what->Type != STstat)
-       ARTsendmmap(what->Type);
-    ARTclose();
-}
-
-
-/*
-**  Go to the next or last (really previous) article in the group.
-*/
-void CMDnextlast(int ac UNUSED, char *av[])
-{
-    char *msgid;
-    int        save, delta, errcode;
-    bool next;
-    const char *message;
-
-    if (!PERMcanread) {
-       Reply("%s\r\n", NOACCESS);
-       return;
-    }
-    if (GRPcount == 0) {
-       Reply("%s\r\n", ARTnotingroup);
-       return;
-    }
-    if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
-       Reply("%s\r\n", ARTnocurrart);
-       return;
-    }
-
-    next = (av[0][0] == 'n' || av[0][0] == 'N');
-    if (next) {
-       delta = 1;
-       errcode = NNTP_NONEXT_VAL;
-       message = "next";
-    }
-    else {
-       delta = -1;
-       errcode = NNTP_NOPREV_VAL;
-       message = "previous";
-    }
-
-    save = ARTnumber;
-    msgid = NULL;
-    do {
-        ARTnumber += delta;
-        if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
-            Reply("%d No %s to retrieve.\r\n", errcode, message);
-            ARTnumber = save;
-            return;
-        }
-        if (!ARTopen(ARTnumber))
-            continue;
-        msgid = GetHeader("Message-ID");
-        ARTclose();
-    } while (msgid == NULL);
-
-    Reply("%d %d %s Article retrieved; request text separately.\r\n",
-          NNTP_NOTHING_FOLLOWS_VAL, ARTnumber, msgid);
-}
-
-
-static bool CMDgetrange(int ac, char *av[], ARTRANGE *rp, bool *DidReply)
-{
-    char               *p;
-
-    *DidReply = false;
-    if (GRPcount == 0) {
-       Reply("%s\r\n", ARTnotingroup);
-       *DidReply = true;
-       return false;
-    }
-
-    if (ac == 1) {
-       /* No argument, do only current article. */
-       if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
-           Reply("%s\r\n", ARTnocurrart);
-           *DidReply = true;
-           return false;
-       }
-       rp->High = rp->Low = ARTnumber;
-        return true;
-    }
-
-    /* Got just a single number? */
-    if ((p = strchr(av[1], '-')) == NULL) {
-       rp->Low = rp->High = atol(av[1]);
-        return true;
-    }
-
-    /* Parse range. */
-    *p++ = '\0';
-    rp->Low = atol(av[1]);
-       if (*p == '\0' || (rp->High = atol(p)) < rp->Low)
-           /* "XHDR 234-0 header" gives everything to the end. */
-       rp->High = ARThigh;
-    else if (rp->High > ARThigh)
-       rp->High = ARThigh;
-    if (rp->Low < ARTlow)
-       rp->Low = ARTlow;
-    p--;
-    *p = '-';
-
-    return true;
-}
-
-
-/*
-**  Apply virtual hosting to an Xref field.
-*/
-static char *
-vhost_xref(char *p)
-{
-    char *space;
-    size_t offset;
-    char *field = NULL;
-
-    space = strchr(p, ' ');
-    if (space == NULL) {
-       warn("malformed Xref `%s'", field);
-       goto fail;
-    }
-    offset = space + 1 - p;
-    space = strchr(p + offset, ' ');
-    if (space == NULL) {
-       warn("malformed Xref `%s'", field);
-       goto fail;
-    }
-    field = concat(PERMaccessconf->domain, space, NULL);
- fail:
-    free(p);
-    return field;
-}
-
-/*
-**  XOVER another extension.  Dump parts of the overview database.
-*/
-void CMDxover(int ac, char *av[])
-{
-    bool               DidReply;
-    ARTRANGE           range;
-    struct timeval     stv, etv;
-    ARTNUM             artnum;
-    void               *handle;
-    char               *data, *r;
-    const char         *p, *q;
-    int                        len, useIOb = 0;
-    TOKEN              token;
-    struct cvector *vector = NULL;
-
-    if (!PERMcanread) {
-       Printf("%s\r\n", NOACCESS);
-       return;
-    }
-
-    /* Trying to read. */
-    if (GRPcount == 0) {
-       Reply("%s\r\n", ARTnotingroup);
-       return;
-    }
-
-    /* Parse range. */
-    if (!CMDgetrange(ac, av, &range, &DidReply)) {
-       if (DidReply) {
-           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) {
-               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/nnrpd/cache.c b/nnrpd/cache.c
deleted file mode 100644 (file)
index 8ad2874..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*  $Id: cache.c 6169 2003-01-21 06:31:40Z alexk $
-**
-**  MessageID to storage token cache
-**
-**  Written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  Implementation of a message ID to storage token cache which can be
-**  built during XOVER/XHDR/NEWNEWS.  If we hit in the cache when
-**  retrieving articles the (relatively) expensive cost of a trip
-**  through the history database is saved.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/tst.h"
-#include "inn/list.h"
-#include "libinn.h"
-#include "storage.h"
-
-#include "cache.h"
-
-/*
-**  Pointer to the message ID to storage token ternary search tree
-*/
-static struct tst *msgidcache;
-
-/*
-**  Count of message IDs in the cache so that someone doing GROUP,
-**  XOVER, GROUP, XOVER etc. for example doesn't blow up with out of
-**  memory
-*/
-static int msgcachecount;
-
-struct cache_entry {
-    struct node node;
-    HASH hash;
-    TOKEN token;
-};
-
-static struct list unused, used;
-
-/*
-**  Add a translation from HASH, h, to TOKEN, t, to the message ID
-**  cache
-*/
-void
-cache_add(const HASH h, const TOKEN t)
-{
-    if (innconf->msgidcachesize != 0) {
-       struct cache_entry *entry;
-       const unsigned char *p;
-       struct cache_entry *exist;
-
-       if (!msgidcache) {
-           msgidcache = tst_init((innconf->msgidcachesize + 9) / 10);
-           list_new(&unused);
-           list_new(&used);
-       }
-
-       entry = xmalloc(sizeof *entry);
-       entry->hash = h;
-       entry->token = t;
-       p = (unsigned char *) HashToText(h);
-       if (tst_insert(msgidcache, p, entry,
-                      0, (void **)&exist) == TST_DUPLICATE_KEY) {
-           free(entry);
-           list_remove(&exist->node);
-           list_addtail(&unused, &exist->node);
-       } else {
-           list_addtail(&unused, &entry->node);
-           ++msgcachecount;
-       }
-       if (msgcachecount >= innconf->msgidcachesize) {
-           /* need to throw away a node */
-           entry = (struct cache_entry *)list_remhead(&used);
-           if (entry == NULL)
-               entry = (struct cache_entry *)list_remhead(&unused);
-           if (entry != NULL) {
-               tst_delete(msgidcache,
-                          (unsigned char *) HashToText(entry->hash));
-               free(entry);
-           }
-       }
-    }
-}
-
-
-/*
-**  Lookup (and remove if found) a MessageID to TOKEN mapping. If this
-**  is a final lookup (ARTICLE or BODY) we remove it if we find it
-**  since this matches the observed behaviour of most clients, but
-**  cache it just in case we can reuse it if they issue multiple
-**  commands against the same message ID (e.g. HEAD, BODY).
-*/
-TOKEN
-cache_get(const HASH h, bool final)
-{
-    static HASH last_hash;
-    static TOKEN last_token;
-    static const TOKEN empty_token = { TOKEN_EMPTY, 0, "" };
-
-    if (HashCompare(&h, &last_hash) == 0 && !HashEmpty(last_hash))
-       return last_token;
-
-    if (msgidcache) {
-       struct cache_entry *entry;
-
-       entry = tst_search(msgidcache, (unsigned char *) HashToText(h));
-       if (entry != NULL) {
-           list_remove(&entry->node);
-           if (!final)
-               list_addtail(&unused, &entry->node);
-           else
-               list_addtail(&used, &entry->node);
-           last_hash = entry->hash;
-           last_token = entry->token;
-           return last_token;
-       }
-    }
-    return empty_token;
-}
diff --git a/nnrpd/cache.h b/nnrpd/cache.h
deleted file mode 100644 (file)
index 6c561cd..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef CACHE_H
-#define CACHE_H
-
-#include "libinn.h"
-#include "storage.h"
-
-BEGIN_DECLS
-
-void cache_add(const HASH, const TOKEN);
-TOKEN cache_get(const HASH, bool final);
-
-END_DECLS
-
-#endif /* CACHE_H */
diff --git a/nnrpd/commands.c b/nnrpd/commands.c
deleted file mode 100644 (file)
index 72fea77..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-/*  $Id: commands.c 7542 2006-08-26 05:57:11Z eagle $
-**
-**  Miscellaneous commands.
-*/
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-
-#include "nnrpd.h"
-#include "ov.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-
-typedef struct {
-    char                *name;
-    int                 high;
-    int                 low;
-    int                 count;
-} GROUPDATA;
-
-
-extern const char *NNRPinstance;
-
-/* returns:
-       -1 for problem (such as no such authenticator etc.)
-       0 for authentication succeeded
-       1 for authentication failed
- */
-
-static char *PERMauthstring;
-
-static int
-PERMgeneric(char *av[], char *accesslist)
-{
-    char path[BIG_BUFFER], *fields[6], *p;
-    int i, pan[2], status;
-    pid_t pid;
-    struct stat stb;
-
-    av += 2;
-
-    PERMcanread = false;
-    PERMcanpost = false;
-    PERMaccessconf->locpost = false;
-    PERMaccessconf->allowapproved = false;
-
-    if (!*av) {
-       Reply("%d no authenticator\r\n", NNTP_SYNTAX_VAL);
-       return(-1);
-    }
-
-    /* check for ../.  I'd use strstr, but there doesn't appear to
-       be any other references for it, and I don't want to break
-       portability */
-    for (p = av[0]; *p; p++)
-       if (strncmp(p, "../", 3) == 0) {
-           Reply("%d ../ in authenticator %s\r\n", NNTP_SYNTAX_VAL, av[0]);
-           return(-1);
-       }
-
-    if (strchr(_PATH_AUTHDIR,'/') == NULL)
-       snprintf(path, sizeof(path), "%s/%s/%s/%s", innconf->pathbin,
-                 _PATH_AUTHDIR, _PATH_AUTHDIR_GENERIC, av[0]);
-    else
-       snprintf(path, sizeof(path), "%s/%s/%s", _PATH_AUTHDIR,
-                 _PATH_AUTHDIR_GENERIC, av[0]);
-
-#if !defined(S_IXUSR) && defined(_S_IXUSR)
-#define S_IXUSR _S_IXUSR
-#endif /* !defined(S_IXUSR) && defined(_S_IXUSR) */
-    
-#if !defined(S_IXUSR) && defined(S_IEXEC)
-#define S_IXUSR S_IEXEC
-#endif  /* !defined(S_IXUSR) && defined(S_IEXEC) */
-
-    if (stat(path, &stb) || !(stb.st_mode&S_IXUSR)) {
-       Reply("%d No such authenticator %s\r\n", NNTP_TEMPERR_VAL, av[0]);
-       return -1;
-    }
-       
-
-    /* Create a pipe. */
-    if (pipe(pan) < 0) {
-       syslog(L_FATAL, "cant pipe for %s %m", av[0]);
-       return -1;
-    }
-
-    for (i = 0; (pid = fork()) < 0; i++) {
-       if (i == innconf->maxforks) {
-           Reply("%d Can't fork %s\r\n", NNTP_TEMPERR_VAL,
-               strerror(errno));
-           syslog(L_FATAL, "cant fork %s %m", av[0]);
-           return -1;
-       }
-       syslog(L_NOTICE, "cant fork %s -- waiting", av[0]);
-       sleep(5);
-    }
-
-    /* Run the child, with redirection. */
-    if (pid == 0) {
-       close(STDERR_FILENO);   /* Close existing stderr */
-       close(pan[PIPE_READ]);
-
-       /* stderr goes down the pipe. */
-       if (pan[PIPE_WRITE] != STDERR_FILENO) {
-           if ((i = dup2(pan[PIPE_WRITE], STDERR_FILENO)) != STDERR_FILENO) {
-               syslog(L_FATAL, "cant dup2 %d to %d got %d %m",
-                   pan[PIPE_WRITE], STDERR_FILENO, i);
-               _exit(1);
-           }
-           close(pan[PIPE_WRITE]);
-       }
-
-       close_on_exec(STDIN_FILENO, false);
-       close_on_exec(STDOUT_FILENO, false);
-       close_on_exec(STDERR_FILENO, false);
-
-       execv(path, av);
-       Reply("%s\r\n", NNTP_BAD_COMMAND);
-
-       syslog(L_FATAL, "cant execv %s %m", path);
-       _exit(1);
-    }
-
-    close(pan[PIPE_WRITE]);
-    i = read(pan[PIPE_READ], path, sizeof(path));
-
-    waitpid(pid, &status, 0);
-    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
-        return 1;
-
-    if ((p = strchr(path, '\n')) != NULL)
-       *p = '\0';
-
-    if (PERMauthstring)
-       free(PERMauthstring);
-
-    PERMauthstring = xstrdup(path);
-
-    /*syslog(L_NOTICE, "%s (%ld) returned: %d %s %d\n", av[0], (long) pid, i, path, status);*/
-    /* Split "host:permissions:user:pass:groups" into fields. */
-    for (fields[0] = path, i = 0, p = path; *p; p++)
-       if (*p == ':') {
-           *p = '\0';
-           fields[++i] = p + 1;
-       }
-
-    PERMcanread = strchr(fields[1], 'R') != NULL;
-    PERMcanpost = strchr(fields[1], 'P') != NULL;
-    PERMaccessconf->allowapproved = strchr(fields[1], 'A') != NULL;
-    PERMaccessconf->locpost = strchr(fields[1], 'L') != NULL;
-    PERMaccessconf->allowihave = strchr(fields[1], 'I') != NULL;
-    if (strchr(fields[1], 'N') != NULL) PERMaccessconf->allownewnews = true;
-    snprintf(PERMuser, sizeof(PERMuser), "%s@%s", fields[2], fields[0]);
-    strlcpy(PERMpass, fields[3], sizeof(PERMpass));
-    strcpy(accesslist, fields[4]);
-    /*strcpy(writeaccess, fields[5]); future work? */
-
-    /*for (i = 0; fields[i] && i < 6; i++)
-       printf("fields[%d] = %s\n", i, fields[i]);*/
-
-    return 0;
-}
-
-/* ARGSUSED */
-void
-CMDauthinfo(ac, av)
-    int                ac;
-    char       *av[];
-{
-    static char        User[SMBUF];
-    static char        Password[SMBUF];
-    char       accesslist[BIG_BUFFER];
-    char        errorstr[BIG_BUFFER];
-
-    if (strcasecmp(av[1], "generic") == 0) {
-       char *logrec = Glom(av);
-
-       strlcpy(PERMuser, "<none>", sizeof(PERMuser));
-
-       switch (PERMgeneric(av, accesslist)) {
-           case 1:
-               PERMspecified = NGgetlist(&PERMreadlist, accesslist);
-               PERMpostlist = PERMreadlist;
-               syslog(L_NOTICE, "%s auth %s (%s -> %s)", ClientHost, PERMuser,
-                       logrec, PERMauthstring? PERMauthstring: "" );
-               Reply("%d Authentication succeeded\r\n", NNTP_AUTH_OK_VAL);
-               PERMneedauth = false;
-               PERMauthorized = true;
-               free(logrec);
-               return;
-           case 0:
-               syslog(L_NOTICE, "%s bad_auth %s (%s)", ClientHost, PERMuser,
-                       logrec);
-               Reply("%d Authentication failed\r\n", NNTP_ACCESS_VAL);
-               free(logrec);
-               ExitWithStats(1, false);
-           default:
-               /* lower level has issued Reply */
-               return;
-       }
-
-    } else {
-
-       if (strcasecmp(av[1], "simple") == 0) {
-           if (ac != 4) {
-               Reply("%d AUTHINFO SIMPLE <USER> <PASS>\r\n", NNTP_BAD_COMMAND_VAL);
-               return;
-           }
-           strlcpy(User, av[2], sizeof(User));
-           strlcpy(Password, av[3], sizeof(Password));
-       } else {
-           if (strcasecmp(av[1], "user") == 0) {
-               strlcpy(User, av[2], sizeof(User));
-               Reply("%d PASS required\r\n", NNTP_AUTH_NEXT_VAL);
-               return;
-           }
-
-           if (strcasecmp(av[1], "pass") != 0) {
-               Reply("%d bad authinfo param\r\n", NNTP_BAD_COMMAND_VAL);
-               return;
-           }
-           if (User[0] == '\0') {
-               Reply("%d USER required\r\n", NNTP_AUTH_REJECT_VAL);
-               return;
-           }
-
-           strlcpy(Password, av[2], sizeof(Password));
-       }
-
-        if (strcmp(User, PERMuser) == 0 && strcmp(Password, PERMpass) == 0) {
-            syslog(L_NOTICE, "%s user %s", ClientHost, PERMuser);
-            if (LLOGenable) {
-                fprintf(locallog, "%s user (%s):%s\n", ClientHost, Username, PERMuser);
-                fflush(locallog);
-            }
-            Reply("%d Ok\r\n", NNTP_AUTH_OK_VAL);
-            PERMneedauth = false;
-            PERMauthorized = true;
-            return;
-        }
-        
-        errorstr[0] = '\0';
-        
-        PERMlogin(User, Password, errorstr);
-        PERMgetpermissions();
-        if (!PERMneedauth) {
-            syslog(L_NOTICE, "%s user %s", ClientHost, PERMuser);
-            if (LLOGenable) {
-                fprintf(locallog, "%s user (%s):%s\n", ClientHost, Username, PERMuser);
-                fflush(locallog);
-            }
-            Reply("%d Ok\r\n", NNTP_AUTH_OK_VAL);
-            PERMneedauth = false;
-            PERMauthorized = true;
-            return;
-        }
-
-       syslog(L_NOTICE, "%s bad_auth", ClientHost);
-        if (errorstr[0] != '\0') {
-            syslog(L_NOTICE, "%s script error str: %s", ClientHost, errorstr);
-            Reply("%d %s\r\n", NNTP_ACCESS_VAL, errorstr);
-        } else {
-            Reply("%d Authentication error\r\n", NNTP_ACCESS_VAL);
-        }
-       ExitWithStats(1, false);
-    }
-
-}
-
-
-/*
-**  The "DATE" command.  Part of NNTPv2.
-*/
-/* ARGSUSED0 */
-void
-CMDdate(ac, av)
-    int                ac UNUSED;
-    char       *av[] UNUSED;
-{
-    TIMEINFO   t;
-    struct tm  *gmt;
-
-    if (GetTimeInfo(&t) < 0 || (gmt = gmtime(&t.time)) == NULL) {
-       Reply("%d Can't get time, %s\r\n", NNTP_TEMPERR_VAL, strerror(errno));
-       return;
-    }
-    Reply("%d %04.4d%02.2d%02.2d%02.2d%02.2d%02.2d\r\n",
-       NNTP_DATE_FOLLOWS_VAL,
-       gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
-       gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
-}
-
-
-/*
-**  Handle the "mode" command.
-*/
-/* ARGSUSED */
-void
-CMDmode(ac, av)
-    int                ac UNUSED;
-    char       *av[];
-{
-    if (strcasecmp(av[1], "reader") == 0)
-       Reply("%d %s InterNetNews NNRP server %s ready (%s).\r\n",
-              PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL,
-               PERMaccessconf->pathhost, inn_version_string,
-              PERMcanpost ? "posting ok" : "no posting");
-    else
-       Reply("%d What?\r\n", NNTP_SYNTAX_VAL);
-}
-
-static int GroupCompare(const void *a1, const void* b1) {
-    const GROUPDATA     *a = a1;
-    const GROUPDATA     *b = b1;
-
-    return strcmp(a->name, b->name);
-}
-
-/*
-**  Display new newsgroups since a given date and time for specified
-**  <distributions>.
-*/
-void CMDnewgroups(int ac, char *av[])
-{
-    char               *p;
-    char               *q;
-    QIOSTATE           *qp;
-    time_t             date;
-    char               *grplist[2];
-    int                 hi, lo, count, flag;
-    GROUPDATA           *grouplist = NULL;
-    GROUPDATA           key;
-    GROUPDATA           *gd;
-    int                 listsize = 0;
-    int                 numgroups = 0;
-    int                 numfound = 0;
-    int                 i;
-    bool                local;
-
-    /* Parse the date. */
-    local = !(ac > 3 && strcasecmp(av[3], "GMT") == 0);
-    date = parsedate_nntp(av[1], av[2], local);
-    if (date == (time_t) -1) {
-        Reply("%d Bad date\r\n", NNTP_SYNTAX_VAL);
-        return;
-    }
-
-    /* Log an error if active.times doesn't exist, but don't return an error
-       to the client.  The most likely cause of this is a new server
-       installation that's yet to have any new groups created, and returning
-       an error was causing needless confusion.  Just return the empty list
-       of groups. */
-    if ((qp = QIOopen(ACTIVETIMES)) == NULL) {
-       syslog(L_ERROR, "%s cant fopen %s %m", ClientHost, ACTIVETIMES);
-       Reply("%d New newsgroups follow.\r\n", NNTP_NEWGROUPS_FOLLOWS_VAL);
-        Printf(".\r\n");
-       return;
-    }
-
-    /* Read the file, ignoring long lines. */
-    while ((p = QIOread(qp)) != NULL) {
-       if ((q = strchr(p, ' ')) == NULL)
-           continue;
-       *q++ = '\0';
-        if ((time_t) atol(q) < date)
-            continue;
-       if (!OVgroupstats(p, &lo, &hi, &count, &flag))
-           continue;
-
-       if (PERMspecified) {
-           grplist[0] = p;
-           grplist[1] = NULL;
-           if (!PERMmatch(PERMreadlist, grplist))
-               continue;
-       }
-       else 
-           continue;
-
-       if (grouplist == NULL) {
-           grouplist = xmalloc(1000 * sizeof(GROUPDATA));
-           listsize = 1000;
-       }
-       if (listsize <= numgroups) {
-           listsize += 1000;
-            grouplist = xrealloc(grouplist, listsize * sizeof(GROUPDATA));
-       }
-
-       grouplist[numgroups].high = hi;
-       grouplist[numgroups].low = lo;
-       grouplist[numgroups].count = count;
-       grouplist[numgroups].name = xstrdup(p);
-       numgroups++;
-    }
-    QIOclose(qp);
-
-    if ((qp = QIOopen(ACTIVE)) == NULL) {
-       syslog(L_ERROR, "%s cant fopen %s %m", ClientHost, ACTIVE);
-       Reply("%d Cannot open active file.\r\n", NNTP_TEMPERR_VAL);
-       return;
-    }
-    qsort(grouplist, numgroups, sizeof(GROUPDATA), GroupCompare);
-    Reply("%d New newsgroups follow.\r\n", NNTP_NEWGROUPS_FOLLOWS_VAL);
-    for (numfound = numgroups; (p = QIOread(qp)) && numfound;) {
-       if ((q = strchr(p, ' ')) == NULL)
-           continue;
-       *q++ = '\0';
-       if ((q = strchr(q, ' ')) == NULL)
-           continue;
-       q++;
-       if ((q = strchr(q, ' ')) == NULL)
-           continue;
-       q++;
-       key.name = p;
-       if ((gd = bsearch(&key, grouplist, numgroups, sizeof(GROUPDATA), GroupCompare)) == NULL)
-           continue;
-       Printf("%s %u %u %s\r\n", p, gd->high, gd->low, q);
-       numfound--;
-    }
-    for (i = 0; i < numgroups; i++) {
-       free(grouplist[i].name);
-    }
-    free(grouplist);
-    QIOclose(qp);
-    Printf(".\r\n");
-}
-
-
-/*
-**  Post an article.
-*/
-/* ARGSUSED */
-void
-CMDpost(int ac UNUSED, char *av[] UNUSED)
-{
-    static char        *article;
-    static int size;
-    char       *p, *q;
-    char       *end;
-    int                longline;
-    READTYPE   r;
-    int                i;
-    long       l;
-    long       sleeptime;
-    char       *path;
-    const char *response;
-    char       idbuff[SMBUF];
-    static int backoff_inited = false;
-    bool       ihave, permanent;
-
-    ihave = (strcasecmp(av[0], "ihave") == 0);
-    if (ihave && (!PERMaccessconf->allowihave || !PERMcanpost)) {
-       syslog(L_NOTICE, "%s noperm ihave without permission", ClientHost);
-       Reply("%s\r\n", NNTP_ACCESS);
-       return;
-    }
-    if (!ihave && !PERMcanpost) {
-       syslog(L_NOTICE, "%s noperm post without permission", ClientHost);
-       Reply("%s\r\n", NNTP_CANTPOST);
-       return;
-    }
-
-    if (!backoff_inited) {
-       /* Exponential posting backoff */
-       InitBackoffConstants();
-       backoff_inited = true;
-    }
-
-    /* Dave's posting limiter - Limit postings to a certain rate
-     * And now we support multiprocess rate limits. Questions?
-     * Email dave@jetcafe.org.
-     */
-    if (BACKOFFenabled) {
-
-      /* Acquire lock (this could be in RateLimit but that would
-       * invoke the spaghetti factor). 
-       */
-      if ((path = (char *) PostRecFilename(ClientIpString,PERMuser)) == NULL) {
-        Reply("%s\r\n", NNTP_CANTPOST);
-        return;
-      }
-      
-      if (LockPostRec(path) == 0) {
-        syslog(L_ERROR, "%s Error write locking '%s'",
-               ClientHost, path);
-        Reply("%s\r\n", NNTP_CANTPOST);
-        return;
-      }
-      
-      if (!RateLimit(&sleeptime,path)) {
-       syslog(L_ERROR, "%s can't check rate limit info", ClientHost);
-       Reply("%s\r\n", NNTP_CANTPOST);
-        UnlockPostRec(path);
-       return;
-      } else if (sleeptime != 0L) {
-        syslog(L_NOTICE,"%s post sleep time is now %ld", ClientHost, sleeptime);
-        sleep(sleeptime);
-      }
-      
-      /* Remove the lock here so that only one nnrpd process does the
-       * backoff sleep at once. Other procs are sleeping for the lock.
-       */
-      UnlockPostRec(path);
-
-    } /* end backoff code */
-
-    /* Start at beginning of buffer. */
-    if (article == NULL) {
-       size = 4096;
-       article = xmalloc(size);
-    }
-    idbuff[0] = 0;
-    if (ihave) {
-       Reply(NNTP_SENDIT "\r\n");
-    } else {
-       if ((p = GenerateMessageID(PERMaccessconf->domain)) != NULL) {
-           if (VirtualPathlen > 0) {
-               q = p;
-               if ((p = strchr(p, '@')) != NULL) {
-                   *p = '\0';
-                   snprintf(idbuff, sizeof(idbuff), "%s%s@%s>", q,
-                             NNRPinstance, PERMaccessconf->domain);
-               }
-           } else {
-               strlcpy(idbuff, p, sizeof(idbuff));
-           }
-       }
-       Reply("%d Ok, recommended ID %s\r\n", NNTP_START_POST_VAL, idbuff);
-    }
-    fflush(stdout);
-
-    p = article;
-    end = &article[size];
-
-    longline = 0;
-    for (l = 1; ; l++) {
-       size_t len;
-       const char *line;
-
-       r = line_read(&NNTPline, PERMaccessconf->clienttimeout, &line, &len);
-       switch (r) {
-       default:
-           warn("%s internal %d in post", ClientHost, r);
-           /* FALLTHROUGH */
-       case RTtimeout:
-           warn("%s timeout in post", ClientHost);
-           ExitWithStats(1, false);
-           /* NOTREACHED */
-       case RTeof:
-           warn("%s eof in post", ClientHost);
-           ExitWithStats(1, false);
-           /* NOTREACHED */
-       case RTlong:
-           if (longline == 0)
-               longline = l;
-           continue;
-       case RTok:
-           break;
-       }
-
-       /* if its the terminator, break out */
-       if (strcmp(line, ".") == 0) {
-           break;
-       }
-
-       /* if they broke our line length limit, there's little point
-        * in processing any more of their input */
-       if (longline != 0) {
-           continue;
-       }
-
-       /* +2 because of the \n\0 we append; note we don't add the 2
-        * when increasing the size of the buffer as ART_LINE_MALLOC
-        * will always be larger than 2 bytes */
-       if ((len + 2) > (size_t)(end - p)) {
-           i = p - article;
-           size += len + ART_LINE_MALLOC;
-            article = xrealloc(article, size);
-           end = &article[size];
-           p = i + article;
-       }
-
-       /* reverse any byte-stuffing */
-       if (*line == '.') {
-           ++line;
-           --len;
-       }
-       memcpy(p, line, len);
-       p += len;
-       *p++ = '\n';
-       *p = '\0';
-    }
-
-    if (longline) {
-       warn("%s toolong in post", ClientHost);
-       Printf("%d Line %d too long\r\n", 
-              ihave ? NNTP_REJECTIT_VAL : NNTP_POSTFAIL_VAL, longline);
-       POSTrejected++;
-       return;
-    }
-
-    /* Send the article to the server. */
-    response = ARTpost(article, idbuff, ihave, &permanent);
-    if (response == NULL) {
-       notice("%s post ok %s", ClientHost, idbuff);
-       Reply("%s %s\r\n", ihave ? NNTP_TOOKIT : NNTP_POSTEDOK, idbuff);
-       POSTreceived++;
-    }
-    else {
-       if ((p = strchr(response, '\r')) != NULL)
-           *p = '\0';
-       if ((p = strchr(response, '\n')) != NULL)
-           *p = '\0';
-       notice("%s post failed %s", ClientHost, response);
-       if (!ihave || permanent) {
-           /* for permanent errors reject the message */
-           Reply("%d %s\r\n", ihave ? NNTP_REJECTIT_VAL : NNTP_POSTFAIL_VAL,
-                 response);
-       } else {
-           /* non-permanent errors only have relevance to ihave, for
-            * these we have the error status from the upstream
-            * server to report */
-           Reply("%s\r\n", response);
-       }
-       POSTrejected++;
-    }
-}
-
-/*
-**  The "xpath" command.  An uncommon extension.
-*/
-/* ARGSUSED */
-void
-CMDxpath(ac, av)
-    int                ac UNUSED;
-    char       *av[] UNUSED;
-{
-    Reply("%d Syntax error or bad command\r\n", NNTP_BAD_COMMAND_VAL);
-}
diff --git a/nnrpd/group.c b/nnrpd/group.c
deleted file mode 100644 (file)
index 9429245..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*  $Id: group.c 7538 2006-08-26 05:44:06Z eagle $
-**
-**  Newsgroups and the active file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "ov.h"
-
-/*
-**  Change to or list the specified newsgroup.  If invalid, stay in the old
-**  group.
-*/
-void CMDgroup(int ac, char *av[])
-{
-    static char                NOSUCHGROUP[] = NNTP_NOSUCHGROUP;
-    ARTNUM              i;
-    char               *grplist[2];
-    char               *group;
-    void                *handle;
-    TOKEN               token;
-    int                 count;
-    bool               boolval;
-    bool                hookpresent = false;
-
-#ifdef DO_PYTHON
-    hookpresent = PY_use_dynamic;
-#endif /* DO_PYTHON */
-
-    if (!hookpresent && !PERMcanread) {
-        if (PERMspecified)
-           Reply("%d Permission denied\r\n", NNTP_ACCESS_VAL);
-        else
-            Reply("%d Authentication required\r\n", NNTP_AUTH_NEEDED_VAL);
-       return;
-    }
-
-    /* Parse arguments. */
-    if (ac == 1) {
-       if (GRPcur == NULL) {
-           Printf("%d No group specified\r\n", NNTP_XGTITLE_BAD);
-           return;
-       } else {
-           group = xstrdup(GRPcur);
-       }
-    } else {
-       group = xstrdup(av[1]);
-    }
-    
-    if (!OVgroupstats(group, &ARTlow, &ARThigh, &count, NULL)) {
-       Reply("%s %s\r\n", NOSUCHGROUP, group);
-       free(group);
-       return;
-    }
-
-#ifdef DO_PYTHON
-    if (PY_use_dynamic) {
-        char    *reply;
-
-       /* Authorize user using Python module method dynamic*/
-       if (PY_dynamic(PERMuser, group, 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, group, reply);
-               Reply("%d %s\r\n", NNTP_ACCESS_VAL, reply);
-               free(group);
-                free(reply);
-               return;
-           }
-       }
-    }
-#endif /* DO_PYTHON */
-
-    if (!hookpresent) {
-        if (PERMspecified) {
-            grplist[0] = group;
-            grplist[1] = NULL;
-            if (!PERMmatch(PERMreadlist, grplist)) {
-                Reply("%d Permission denied\r\n", NNTP_ACCESS_VAL);
-                free(group);
-                return;
-            }
-        } else {
-            Reply("%d Authentication required\r\n", NNTP_AUTH_NEEDED_VAL);
-            free(group);
-            return;
-        }
-    }
-
-    /* Close out any existing article, report group stats. */
-    ARTclose();
-    GRPreport();
-
-    /* Doing a "group" command? */
-    if (strcasecmp(av[0], "group") == 0) {
-       if (count == 0)
-           Reply("%d 0 0 0 %s\r\n", NNTP_GROUPOK_VAL, group);
-       else {
-           /* if we're an NFS reader, check the last nfsreaderdelay
-            * articles in the group to see if they arrived in the
-            * last nfsreaderdelay (default 60) seconds. If they did,
-            * don't report them as we don't want them to appear too
-            * soon */
-           if (innconf->nfsreader) {
-               ARTNUM low, prev;
-               time_t now, arrived;
-
-               time(&now);
-               if (ARTlow + innconf->nfsreaderdelay > ARThigh)
-                   low = ARTlow;
-               else
-                   low = ARThigh - innconf->nfsreaderdelay;
-               handle = OVopensearch(group, low, ARThigh);
-               if (!handle) {
-                   Reply("%d group disappeared\r\n", NNTP_TEMPERR_VAL);
-                   free(group);
-                   return;
-               }
-               prev = low;
-               while (OVsearch(handle, &i, NULL, NULL, NULL, &arrived)) {
-                   if (arrived + innconf->nfsreaderdelay > now) {
-                       ARThigh = prev;
-                       break;
-                   }
-                   prev = i;
-               }
-               OVclosesearch(handle);
-           }
-           Reply("%d %d %lu %lu %s\r\n", NNTP_GROUPOK_VAL, count,
-                  (unsigned long) ARTlow, (unsigned long) ARThigh, group);
-       }
-       GRPcount++;
-       ARTnumber = ARTlow;
-       if (GRPcur) {
-           if (strcmp(GRPcur, group) != 0) {
-               OVctl(OVCACHEFREE, &boolval);
-               free(GRPcur);
-               GRPcur = xstrdup(group);
-           }
-       } else
-           GRPcur = xstrdup(group);
-    } else {
-       /* Must be doing a "listgroup" command.  We used to just return
-           something bland here ("Article list follows"), but reference NNTP
-           returns the same data as GROUP does and since we have it all
-           available it shouldn't hurt to return the same thing. */
-        if (count == 0) {
-            Reply("%d 0 0 0 %s\r\n", NNTP_GROUPOK_VAL, group);
-            Printf(".\r\n");
-        } else if ((handle = OVopensearch(group, ARTlow, ARThigh)) != NULL) {
-            Reply("%d %d %lu %lu %s\r\n", NNTP_GROUPOK_VAL, count,
-                  (unsigned long) ARTlow, (unsigned long) ARThigh, group);
-           while (OVsearch(handle, &i, NULL, NULL, &token, NULL)) {
-               if (PERMaccessconf->nnrpdcheckart && !ARTinstorebytoken(token))
-                   continue;
-               Printf("%lu\r\n", (unsigned long) i);
-           }
-           OVclosesearch(handle);
-           Printf(".\r\n");
-           GRPcount++;
-           ARTnumber = ARTlow;
-           if (GRPcur) {
-               if (strcmp(GRPcur, group) != 0) {
-                   OVctl(OVCACHEFREE, &boolval);
-                   free(GRPcur);
-                   GRPcur = xstrdup(group);
-               }
-           } else
-               GRPcur = xstrdup(group);
-       } else {
-           Reply("%s %s\r\n", NOSUCHGROUP, group);
-       }
-    }
-    free(group);
-}
-
-
-/*
-**  Report on the number of articles read in the group, and clear the count.
-*/
-void
-GRPreport()
-{
-    char               buff[SPOOLNAMEBUFF];
-    char               repbuff[1024];
-
-    if (GRPcur) {
-       strlcpy(buff, GRPcur, sizeof(buff));
-       syslog(L_NOTICE, "%s group %s %lu", ClientHost, buff,
-               (unsigned long) GRParticles);
-       GRParticles = 0;
-       repbuff[0]='\0';
-    }
-}
-
-
-/*
-**  Used by ANU-News clients.
-*/
-void
-CMDxgtitle(ac, av)
-    int                        ac;
-    char               *av[];
-{
-    QIOSTATE   *qp;
-    char       *line;
-    char       *p;
-    char       *q;
-    char               *grplist[2];
-    char               save;
-
-    /* Parse the arguments. */
-    if (ac == 1) {
-       if (GRPcount == 0) {
-           Printf("%d No group specified\r\n", NNTP_XGTITLE_BAD);
-           return;
-       }
-       p = GRPcur;
-    }
-    else
-       p = av[1];
-
-    if (!PERMspecified) {
-       Printf("%d list follows\r\n", NNTP_XGTITLE_OK);
-       Printf(".\r\n");
-       return;
-    }
-
-    /* Open the file, get ready to scan. */
-    if ((qp = QIOopen(NEWSGROUPS)) == NULL) {
-       syslog(L_ERROR, "%s cant open %s %m", ClientHost, NEWSGROUPS);
-       Printf("%d Can't open %s\r\n", NNTP_XGTITLE_BAD, NEWSGROUPS);
-       return;
-    }
-    Printf("%d list follows\r\n", NNTP_XGTITLE_OK);
-
-    /* Print all lines with matching newsgroup name. */
-    while ((line = QIOread(qp)) != NULL) {
-       for (q = line; *q && !ISWHITE(*q); q++)
-           continue;
-       save = *q;
-       *q = '\0';
-       if (uwildmat(line, p)) {
-           if (PERMspecified) {
-               grplist[0] = line;
-               grplist[1] = NULL;
-               if (!PERMmatch(PERMreadlist, grplist))
-                   continue;
-           }
-           *q = save;
-           Printf("%s\r\n", line);
-       }
-    }
-
-    /* Done. */
-    QIOclose(qp);
-    Printf(".\r\n");
-}
diff --git a/nnrpd/line.c b/nnrpd/line.c
deleted file mode 100644 (file)
index 67f210f..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*  $Id: line.c 7837 2008-05-19 17:14:15Z iulius $
-**
-**  Line by line reading support from sockets/pipes
-**
-**  Written by Alex Kiernan (alex.kiernan@thus.net)
-**
-**  This code implements a infinitely (well size_t) long single line
-**  read routine, to protect against eating all available memory it
-**  actually starts discarding characters if you try to send more than
-**  the maximum article size in a single line.
-** 
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <assert.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/messages.h"
-#include "nnrpd.h"
-
-#ifdef HAVE_SSL
-#include <openssl/ssl.h>
-#include <signal.h>
-extern SSL *tls_conn;
-#endif
-
-/*
-**  free a previously allocated line structure
-*/
-void
-line_free(struct line *line)
-{
-    static const struct line nullline = {0, 0, 0, 0};
-
-    if (line && line->start) {
-       free(line->start);
-       *line = nullline;
-    }
-}
-
-#ifdef HAVE_SSL
-/*
-**  Alarm signal handler for client timeout.
-*/
-static void
-alarmHandler(int s)
-{
-    SSL_shutdown(tls_conn);
-    tls_conn = NULL;
-    errno = ECONNRESET;
-}
-#endif
-  
-/*
-**  initialise a new line structure
-*/
-void
-line_init(struct line *line)
-{
-    assert(line);
-    line->allocated = NNTP_STRLEN;
-    line->where = line->start = xmalloc(line->allocated);
-    line->remaining = 0;
-}
-
-static ssize_t
-line_doread(void *p, size_t len, int timeout)
-{
-    ssize_t n;
-
-#ifdef HAVE_SSL
-    if (tls_conn) {
-       int err;
-        xsignal(SIGALRM, alarmHandler);
-       do {
-            alarm(timeout);
-            n = SSL_read(tls_conn, p, len);
-            alarm(0);
-            if (tls_conn == NULL) {
-                break;
-        }
-           err = SSL_get_error(tls_conn, n);
-           switch (err) {
-           case SSL_ERROR_SYSCALL:
-               break;
-
-           case SSL_ERROR_SSL:
-               SSL_shutdown(tls_conn);
-               tls_conn = NULL;
-               errno = ECONNRESET;
-               break;
-           }
-       } while (err == SSL_ERROR_WANT_READ);
-        xsignal(SIGALRM, SIG_DFL);
-    } else {
-#endif
-       do {
-           n = read(STDIN_FILENO, p, len);
-       } while (n == -1 && errno == EINTR);
-#ifdef HAVE_SSL
-    }
-#endif
-    return n;
-}
-
-READTYPE
-line_read(struct line *line, int timeout, const char **p, size_t *len)
-{
-    char *where;
-    char *lf = NULL;
-    READTYPE r = RTok;
-
-    assert(line != NULL);
-    assert(line->start != NULL);
-    /* shuffle any trailing portion not yet processed to the start of
-     * the buffer */
-    if (line->remaining != 0) {
-       if (line->start != line->where) {
-           memmove(line->start, line->where, line->remaining);
-       }
-       lf = memchr(line->start, '\n', line->remaining);
-    }
-    where = line->start + line->remaining;
-
-    /* if we found a line terminator in the data we have we don't need
-     * to ask for any more */
-    if (lf == NULL) {
-       do {
-           fd_set rmask;
-           int i;
-           ssize_t count;
-
-           /* if we've filled the line buffer, double the size,
-            * reallocate the buffer and try again */
-           if (where == line->start + line->allocated) {
-               size_t newsize = line->allocated * 2;
-           
-               /* don't grow the buffer bigger than the maximum
-                * article size we'll accept */
-                if (PERMaccessconf->localmaxartsize > NNTP_STRLEN)
-                    if (newsize > (unsigned)PERMaccessconf->localmaxartsize)
-                        newsize = PERMaccessconf->localmaxartsize;
-
-               /* if we're trying to grow from the same size, to the
-                * same size, we must have hit the localmaxartsize
-                * buffer for a second (or subsequent) time - the user
-                * is likely trying to DOS us, so don't double the
-                * size any more, just overwrite characters until they
-                * stop, then discard the whole thing */
-               if (newsize == line->allocated) {
-                   warn("%s overflowed our line buffer (%ld), "
-                        "discarding further input", ClientHost,
-                        PERMaccessconf->localmaxartsize);
-                   where = line->start;
-                   r = RTlong;
-               } else {
-                   line->start = xrealloc(line->start, newsize);
-                   where = line->start + line->allocated;
-                   line->allocated = newsize;
-               }
-           }
-
-#ifdef HAVE_SSL
-            /* It seems that the SSL_read cannot be mixed with select()
-             * as in the current code.  SSL communicates in its own data
-             * blocks and hand shaking.  The do_readline using SSL_read
-             * could return, but still with a partial line in the SSL_read
-             * buffer.  Then the server SSL routine would sit there waiting
-             * for completion of that data block while nnrpd sat at the
-             * select() routine waiting for more data from the server.
-             *
-             * Here, we decide to just bypass the select() wait.  Unlike
-             * innd with multiple threads, the select on nnrpd is just
-             * waiting on a single file descriptor, so it is not really
-             * essential with blocked read like SSL_read.  Using an alarm
-             * signal around SSL_read for non active timeout, SSL works
-             * without dead locks.  However, without the select() wait,
-             * the IDLE timer stat won't be collected...
-             */
-            if (tls_conn == NULL) {
-#endif
-                /* Wait for activity on stdin, updating timer stats as we
-                 * go. */
-                do {
-                    struct timeval t;
-
-                    FD_ZERO(&rmask);
-                    FD_SET(STDIN_FILENO, &rmask);
-                    t.tv_sec = timeout;
-                    t.tv_usec = 0;
-                    TMRstart(TMR_IDLE);
-                    i = select(STDIN_FILENO + 1, &rmask, NULL, NULL, &t);
-                    TMRstop(TMR_IDLE);
-                    if (i == -1 && errno != EINTR) {
-                        syswarn("%s can't select", ClientHost);
-                        return RTtimeout;
-                    }
-                } while (i == -1);
-
-                /* If stdin didn't select, we must have timed out. */
-                if (i == 0 || !FD_ISSET(STDIN_FILENO, &rmask))
-                    return RTtimeout;
-#ifdef HAVE_SSL
-            }
-#endif
-            count = line_doread(where,
-                                line->allocated - (where - line->start), 
-                                timeout);
-
-           /* give timeout for read errors */
-           if (count < 0) {
-               sysnotice("%s can't read", ClientHost);
-               return RTtimeout;
-           }
-           /* if we hit EOF, terminate the string and send it back */
-           if (count == 0) {
-               assert((where + count) < (line->start + line->allocated));
-               where[count] = '\0';
-               return RTeof;
-           }
-           /* search for `\n' in what we just read, if we find it we'll
-            * drop out and return the line for processing */
-           lf = memchr(where, '\n', count);
-           where += count;
-       } while (lf == NULL);
-    }
-
-    /* remember where we've processed up to so we can start off there
-     * next time */
-    line->where = lf + 1;
-    line->remaining = where - line->where;
-
-    if (r == RTok) {
-       /* if we see a full CRLF pair strip them both off before
-        * returning the line to our caller, if we just get an LF
-        * we'll accept that too */
-       if (lf > line->start && lf[-1] == '\r') {
-           --lf;
-       }
-       *lf = '\0';
-       *len = lf - line->start;
-       *p = line->start;
-    }
-    return r;
-}
diff --git a/nnrpd/list.c b/nnrpd/list.c
deleted file mode 100644 (file)
index d03fbbb..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/*  $Id: list.c 7731 2008-04-06 08:40:29Z iulius $
-**
-**  List commands.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "nnrpd.h"
-#include "ov.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-
-typedef struct _LISTINFO {
-    const char *method;
-    const char * File;
-    void (*impl)(struct _LISTINFO *);
-    bool         Required;
-    const char * Items;
-    const char * Format;
-} LISTINFO;
-
-static void cmd_list_schema(LISTINFO *lp);
-static void cmd_list_extensions(LISTINFO *lp);
-
-static LISTINFO                INFOactive = {
-    "active", _PATH_ACTIVE, NULL, true, "active newsgroups",
-    "Newsgroups in form \"group high low flags\""
-};
-static LISTINFO                INFOactivetimes = {
-    "active.times", _PATH_ACTIVETIMES, NULL, false, "creation times",
-    "Group creations in form \"name time who\""
-};
-static LISTINFO                INFOdistribs = {
-    "distributions", _PATH_NNRPDIST, NULL, false, "newsgroup distributions",
-    "Distributions in form \"area description\""
-};
-static LISTINFO               INFOsubs = {
-    "subscriptions", _PATH_NNRPSUBS, NULL, false, "automatic group subscriptions",
-    "Subscriptions in form \"group\""
-};
-static LISTINFO                INFOdistribpats = {
-    "distrib.pats", _PATH_DISTPATS, NULL, false, "distribution patterns",
-    "Default distributions in form \"weight:pattern:value\""
-};
-static LISTINFO                INFOextensions = {
-    "extensions", NULL, cmd_list_extensions, false, "supported extensions",
-    "Supported NNTP extensions"
-};
-static LISTINFO                INFOgroups = {
-    "newsgroups", _PATH_NEWSGROUPS, NULL, false, "newsgroup descriptions",
-    "Descriptions in form \"group description\""
-};
-static LISTINFO                INFOmoderators = {
-    "moderators", _PATH_MODERATORS, NULL, false, "moderator patterns",
-    "Newsgroup moderators in form \"group-pattern:mail-address-pattern\""
-};
-static LISTINFO                INFOschema = {
-    "overview.fmt", NULL, cmd_list_schema, true, "overview format",
-    "Order of fields in overview database"
-};
-static LISTINFO                INFOmotd = {
-    "motd", _PATH_MOTD, NULL, false, "motd",
-    "Message of the day text"
-};
-
-static LISTINFO *info[] = {
-    &INFOactive,
-    &INFOactivetimes,
-    &INFOdistribs,
-    &INFOsubs,
-    &INFOdistribpats,
-    &INFOextensions,
-    &INFOgroups,
-    &INFOmoderators,
-    &INFOschema,
-    &INFOmotd,
-};
-
-
-/*
-**  List the overview schema
-*/
-static void
-cmd_list_schema(LISTINFO *lp)
-{
-    const struct cvector *standard;
-    unsigned int i;
-
-    Reply("%d %s.\r\n", NNTP_LIST_FOLLOWS_VAL, lp->Format);
-    standard = overview_fields();
-    for (i = 0; i < standard->count; ++i) {
-       Printf("%s:\r\n", standard->strings[i]);
-    }
-    for (i = 0; i < OVextra->count; ++i) {
-       Printf("%s:full\r\n", OVextra->strings[i]);
-    }
-    Printf(".\r\n");
-}
-
-
-/*
-**  List supported extensions
-*/
-static void
-cmd_list_extensions(LISTINFO *lp)
-{
-    Reply("%d %s.\r\n", NNTP_SLAVEOK_VAL, lp->Format);
-    if (PERMauthorized != true)
-        Printf("AUTHINFO USER\r\n");
-    Printf("LISTGROUP\r\n");
-    Printf(".\r\n");
-}
-
-
-/*
-**  List a single newsgroup.  Called by LIST ACTIVE with a single argument.
-**  This is quicker than parsing the whole active file, but only works with
-**  single groups.  It also doesn't work for aliased groups, since overview
-**  doesn't know what group the group is aliased to (yet).  Returns whether we
-**  were able to answer the command.
-*/
-static bool
-CMD_list_single(char *group)
-{
-    char *grplist[2] = { NULL, NULL };
-    int lo, hi, flag;
-
-    if (PERMspecified) {
-        grplist[0] = group;
-        if (!PERMmatch(PERMreadlist, grplist))
-            return false;
-    }
-    if (OVgroupstats(group, &lo, &hi, NULL, &flag) && flag != '=') {
-        Reply("%d %s.\r\n", NNTP_LIST_FOLLOWS_VAL, INFOactive.Format);
-        Printf("%s %010u %010u %c\r\n.\r\n", group, hi, lo, flag);
-        return true;
-    }
-    return false;
-}
-
-
-/*
-**  List active newsgroups, newsgroup descriptions, and distributions.
-*/
-void
-CMDlist(int ac, char *av[])
-{
-    QIOSTATE   *qp;
-    char       *p;
-    char       *save;
-    char        *path;
-    char               *q;
-    char               *grplist[2];
-    LISTINFO           *lp;
-    char               *wildarg = NULL;
-    char               savec;
-    unsigned int i;
-
-    p = av[1];
-    if (p == NULL) {
-       lp = &INFOactive;
-    } else {
-       lp = NULL;
-       for (i = 0; i < ARRAY_SIZE(info); ++i) {
-           if (strcasecmp(p, info[i]->method) == 0) {
-               lp = info[i];
-               break;
-           }
-       }
-    }
-    if (lp == NULL) {
-       Reply("%s\r\n", NNTP_SYNTAX_USE);
-       return;
-    }
-    if (lp == &INFOactive) {
-       if (ac == 3) {
-           wildarg = av[2];
-            if (CMD_list_single(wildarg))
-               return;
-       }
-    } else if (lp == &INFOgroups || lp == &INFOactivetimes) {
-       if (ac == 3)
-           wildarg = av[2];
-    }
-
-    if (ac > 2 && !wildarg) {
-       Reply("%s\r\n", NNTP_SYNTAX_USE);
-       return;
-    }
-
-    if (lp->impl != NULL) {
-       lp->impl(lp);
-       return;
-    }
-
-    path = innconf->pathetc;
-    if ((strstr(lp->File, "active") != NULL) ||
-       (strstr(lp->File, "newsgroups") != NULL))
-       path = innconf->pathdb;
-    if (strchr(lp->File, '/') != NULL)
-       path = "";
-    path = concatpath(path, lp->File);
-    qp = QIOopen(path);
-    free(path);
-    if (qp == NULL) {
-        Reply("%d No list of %s available.\r\n",
-              NNTP_TEMPERR_VAL, lp->Items);
-           if (lp->Required || errno != ENOENT) {
-            syslog(L_ERROR, "%s cant fopen %s %m", ClientHost, lp->File);
-        }
-        return;
-    }
-
-    Reply("%d %s.\r\n", NNTP_LIST_FOLLOWS_VAL, lp->Format);
-    if (!PERMspecified) {
-       /* Optmize for unlikely case of no permissions and false default. */
-       QIOclose(qp);
-       Printf(".\r\n");
-       return;
-    }
-
-    /* Set up group list terminator. */
-    grplist[1] = NULL;
-
-    /* Read lines, ignore long ones. */
-    while ((p = QIOread(qp)) != NULL) {
-       if (lp == &INFOmotd) {
-           Printf("%s\r\n", p);
-           continue;
-       }
-       if (p[0] == '.' && p[1] == '\0') {
-           syslog(L_ERROR, "%s single dot in %s", ClientHost, lp->File);
-           continue;
-       }
-       /* matching patterns against patterns is not that
-          good but it's better than nothing ... */
-       if (lp == &INFOdistribpats) {
-           if (*p == '\0' || *p == '#' || *p == ';' || *p == ' ')
-               continue;
-           if (PERMspecified) {
-               if ((q = strchr(p, ':')) == NULL)
-                   continue;
-               q++;
-               if ((save = strchr(q, ':')) == NULL)
-                   continue;
-               *save = '\0';
-               grplist[0] = q;
-               if (!PERMmatch(PERMreadlist, grplist))
-                   continue;
-               *save = ':';
-           }
-           Printf("%s\r\n", p);
-           continue;
-       }
-       if (lp == &INFOdistribs || lp == &INFOmoderators) {
-           if (*p != '\0' && *p != '#' && *p != ';' && *p != ' ')
-               Printf("%s\r\n", p);
-           continue;
-       }
-       savec = '\0';
-       for (save = p; *save != '\0'; save++) {
-           if (*save == ' ' || *save == '\t') {
-               savec = *save;
-               *save = '\0';
-               break;
-           }
-       }
-             
-       if (PERMspecified) {
-           grplist[0] = p;
-           if (!PERMmatch(PERMreadlist, grplist))
-               continue;
-       }
-       if (wildarg && !uwildmat(p, wildarg))
-           continue;
-       if (savec != '\0')
-           *save = savec;
-       Printf("%s\r\n", p);
-    }
-    QIOclose(qp);
-
-    Printf(".\r\n");
-}
diff --git a/nnrpd/misc.c b/nnrpd/misc.c
deleted file mode 100644 (file)
index e4e0d4a..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-/*  $Id: misc.c 6535 2003-12-10 09:02:22Z rra $
-**
-**  Miscellaneous support routines.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "tls.h"
-#include "sasl_config.h"
-
-#ifdef HAVE_SSL
-extern SSL *tls_conn;
-extern int nnrpd_starttls_done;
-#endif 
-
-
-/*
-**  Parse a string into a NULL-terminated array of words; return number
-**  of words.  If argvp isn't NULL, it and what it points to will be freed.
-*/
-int
-Argify(line, argvp)
-    char               *line;
-    char               ***argvp;
-{
-    char       **argv;
-    char       *p;
-
-    if (*argvp != NULL) {
-       free(*argvp[0]);
-       free(*argvp);
-    }
-
-    /*  Copy the line, which we will split up. */
-    while (ISWHITE(*line))
-       line++;
-    p = xstrdup(line);
-
-    /* Allocate worst-case amount of space. */
-    for (*argvp = argv = xmalloc((strlen(p) + 2) * sizeof(char *)); *p; ) {
-       /* Mark start of this word, find its end. */
-       for (*argv++ = p; *p && !ISWHITE(*p); )
-           p++;
-       if (*p == '\0')
-           break;
-
-       /* Nip off word, skip whitespace. */
-       for (*p++ = '\0'; ISWHITE(*p); )
-           p++;
-    }
-    *argv = NULL;
-    return argv - *argvp;
-}
-
-
-/*
-**  Take a vector which Argify made and glue it back together with
-**  spaces between each element.  Returns a pointer to dynamic space.
-*/
-char *
-Glom(av)
-    char               **av;
-{
-    char       **v;
-    int        i;
-    char               *save;
-
-    /* Get space. */
-    for (i = 0, v = av; *v; v++)
-       i += strlen(*v) + 1;
-    i++;
-
-    save = xmalloc(i);
-    save[0] = '\0';
-    for (v = av; *v; v++) {
-       if (v > av)
-            strlcat(save, " ", i);
-        strlcat(save, *v, i);
-    }
-
-    return save;
-}
-
-
-/*
-**  Match a list of newsgroup specifiers against a list of newsgroups.
-**  func is called to see if there is a match.
-*/
-bool PERMmatch(char **Pats, char **list)
-{
-    int                        i;
-    char               *p;
-    int                 match = false;
-
-    if (Pats == NULL || Pats[0] == NULL)
-       return true;
-
-    for ( ; *list; list++) {
-       for (i = 0; (p = Pats[i]) != NULL; i++) {
-           if (p[0] == '!') {
-               if (uwildmat(*list, ++p))
-                   match = false;
-           }
-           else if (uwildmat(*list, p))
-               match = true;
-       }
-       if (match)
-           /* If we can read it in one group, we can read it, period. */
-           return true;
-    }
-
-    return false;
-}
-
-
-/*
-**  Check to see if user is allowed to see this article by matching
-**  Newsgroups line.
-*/
-bool
-PERMartok(void)
-{
-    static char                **grplist;
-    char               *p, **grp;
-
-    if (!PERMspecified)
-       return false;
-
-    if ((p = GetHeader("Xref")) == NULL) {
-       /* in case article does not include Xref */
-       if ((p = GetHeader("Newsgroups")) != NULL) {
-           if (!NGgetlist(&grplist, p))
-               /* No newgroups or null entry. */
-               return true;
-       } else {
-           return true;
-       }
-    } else {
-       /* skip path element */
-       if ((p = strchr(p, ' ')) == NULL)
-           return true;
-       for (p++ ; *p == ' ' ; p++);
-       if (*p == '\0')
-           return true;
-       if (!NGgetlist(&grplist, p))
-           /* No newgroups or null entry. */
-           return true;
-       /* chop ':' and article number */
-       for (grp = grplist ; *grp != NULL ; grp++) {
-           if ((p = strchr(*grp, ':')) == NULL)
-               return true;
-           *p = '\0';
-       }
-    }
-
-#ifdef DO_PYTHON
-    if (PY_use_dynamic) {
-        char    *reply;
-
-       /* Authorize user at a Python authorization module */
-       if (PY_dynamic(PERMuser, p, false, &reply) < 0) {
-           syslog(L_NOTICE, "PY_dynamic(): authorization skipped due to no Python dynamic method defined.");
-       } else {
-           if (reply != NULL) {
-               syslog(L_TRACE, "PY_dynamic() returned a refuse string for user %s at %s who wants to read %s: %s", PERMuser, ClientHost, p, reply);
-                free(reply);
-               return false;
-           }
-            return true;
-       }
-    }
-#endif /* DO_PYTHON */
-
-    return PERMmatch(PERMreadlist, grplist);
-}
-
-
-/*
-**  Parse a newsgroups line, return true if there were any.
-*/
-bool
-NGgetlist(argvp, list)
-    char               ***argvp;
-    char               *list;
-{
-    char       *p;
-
-    for (p = list; *p; p++)
-       if (*p == ',')
-           *p = ' ';
-
-    return Argify(list, argvp) != 0;
-}
-
-
-/*********************************************************************
- * POSTING RATE LIMITS - The following code implements posting rate
- * limits. News clients are indexed by IP number (or PERMuser, see
- * config file). After a relatively configurable number of posts, the nnrpd
- * process will sleep for a period of time before posting anything.
- * 
- * Each time that IP number posts a message, the time of
- * posting and the previous sleep time is stored. The new sleep time
- * is computed based on these values.
- *
- * To compute the new sleep time, the previous sleep time is, for most
- * cases multiplied by a factor (backoff_k). 
- *
- * See inn.conf(5) for how this code works
- *
- *********************************************************************/
-
-/* Defaults are pass through, i.e. not enabled 
- * NEW for INN 1.8 - Use the inn.conf file to specify the following:
- *
- * backoff_k: <integer>
- * backoff_postfast: <integer>
- * backoff_postslow: <integer>
- * backoff_trigger: <integer>
- * backoff_db: <path>
- * backoff_auth: <on|off> 
- *
- * You may also specify posting backoffs on a per user basis. To do this
- * turn on "backoff_auth"
- *
- * Now these are runtime constants. <grin>
- */
-static char postrec_dir[SMBUF];   /* Where is the post record directory? */
-
-void
-InitBackoffConstants()
-{
-  struct stat st;
-
-  /* Default is not to enable this code */
-  BACKOFFenabled = false;
-  
-  /* Read the runtime config file to get parameters */
-
-  if ((PERMaccessconf->backoff_db == NULL) ||
-    !(PERMaccessconf->backoff_k >= 0L && PERMaccessconf->backoff_postfast >= 0L && PERMaccessconf->backoff_postslow >= 1L))
-    return;
-
-  /* Need this database for backing off */
-  strlcpy(postrec_dir, PERMaccessconf->backoff_db, sizeof(postrec_dir));
-  if (stat(postrec_dir, &st) < 0) {
-    if (ENOENT == errno) {
-      if (!MakeDirectory(postrec_dir, true)) {
-       syslog(L_ERROR, "%s cannot create backoff_db '%s': %s",ClientHost,postrec_dir,strerror(errno));
-       return;
-      }
-    } else {
-      syslog(L_ERROR, "%s cannot stat backoff_db '%s': %s",ClientHost,postrec_dir,strerror(errno));
-      return;
-    }
-  }
-  if (!S_ISDIR(st.st_mode)) {
-    syslog(L_ERROR, "%s backoff_db '%s' is not a directory",ClientHost,postrec_dir);
-    return;
-  }
-
-  BACKOFFenabled = true;
-
-  return;
-}
-
-/*
- * PostRecs are stored in individual files. I didn't have a better
- * way offhand, don't want to touch DBZ, and the number of posters is
- * small compared to the number of readers. This is the filename corresponding
- * to an IP number.
- */
-char
-*PostRecFilename(ip,user) 
-     char                         *ip;
-     char                         *user;
-{
-     static char                   buff[SPOOLNAMEBUFF];
-     char                          dirbuff[SPOOLNAMEBUFF];
-     struct in_addr                inaddr;
-     unsigned long int             addr;
-     unsigned char                 quads[4];
-     unsigned int                  i;
-
-     if (PERMaccessconf->backoff_auth) {
-       snprintf(buff, sizeof(buff), "%s/%s", postrec_dir, user);
-       return(buff);
-     }
-
-     if (inet_aton(ip, &inaddr) < 1) {
-       /* If inet_aton() fails, we'll assume it's an IPv6 address.  We'll
-        * also assume for now that we're dealing with a limited number of
-        * IPv6 clients so we'll place their files all in the same 
-        * directory for simplicity.  Someday we'll need to change this to
-        * something more scalable such as DBZ when IPv6 clients become
-        * more popular. */
-       snprintf(buff, sizeof(buff), "%s/%s", postrec_dir, ip);
-       return(buff);
-     }
-     /* If it's an IPv4 address just fall through. */
-
-     addr = ntohl(inaddr.s_addr);
-     for (i=0; i<4; i++)
-       quads[i] = (unsigned char) (0xff & (addr>>(i*8)));
-
-     snprintf(dirbuff, sizeof(dirbuff), "%s/%03d%03d/%03d",
-         postrec_dir, quads[3], quads[2], quads[1]);
-     if (!MakeDirectory(dirbuff,true)) {
-       syslog(L_ERROR, "%s Unable to create postrec directories '%s': %s",
-               ClientHost, dirbuff, strerror(errno));
-       return NULL;
-     }
-     snprintf(buff, sizeof(buff), "%s/%03d", dirbuff, quads[0]);
-     return(buff);
-}
-
-/*
- * Lock the post rec file. Return 1 on lock, 0 on error
- */
-int
-LockPostRec(path)
-     char              *path;
-{
-  char lockname[SPOOLNAMEBUFF];  
-  char temp[SPOOLNAMEBUFF];
-  int statfailed = 0;
-  snprintf(lockname, sizeof(lockname), "%s.lock", path);
-
-  for (;; sleep(5)) {
-    int fd;
-    struct stat st;
-    time_t now;
-    fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT, 0600);
-    if (fd >= 0) {
-      /* We got the lock! */
-      snprintf(temp, sizeof(temp), "pid:%ld\n", (unsigned long) getpid());
-      write(fd, temp, strlen(temp));
-      close(fd);
-      return(1);
-    }
-
-    /* No lock. See if the file is there. */
-    if (stat(lockname, &st) < 0) {
-      syslog(L_ERROR, "%s cannot stat lock file %s", ClientHost, strerror(errno));
-      if (statfailed++ > 5) return(0);
-      continue;
-    }
-
-    /* If lockfile is older than the value of
-       PERMaccessconf->backoff_postslow, remove it */
-    statfailed = 0;
-    time(&now);
-    if (now < st.st_ctime + PERMaccessconf->backoff_postslow) continue;
-    syslog(L_ERROR, "%s removing stale lock file %s", ClientHost, lockname);
-    unlink(lockname);
-  }
-}
-
-void
-UnlockPostRec(path)
-     char              *path;
-{
-  char lockname[SPOOLNAMEBUFF];  
-
-  snprintf(lockname, sizeof(lockname), "%s.lock", path);
-  if (unlink(lockname) < 0) {
-    syslog(L_ERROR, "%s can't unlink lock file: %s", ClientHost,strerror(errno)) ;
-  }
-  return;
-}
-
-/* 
- * Get the stored postrecord for that IP 
- */
-static int
-GetPostRecord(char *path, long *lastpost, long *lastsleep, long *lastn)
-{
-     static char                   buff[SMBUF];
-     FILE                         *fp;
-     char                         *s;
-
-     fp = fopen(path,"r");
-     if (fp == NULL) { 
-       if (errno == ENOENT) {
-         return 1;
-       }
-       syslog(L_ERROR, "%s Error opening '%s': %s",
-              ClientHost, path, strerror(errno));
-       return 0;
-     }
-
-     if (fgets(buff,SMBUF,fp) == NULL) {
-       syslog(L_ERROR, "%s Error reading '%s': %s",
-              ClientHost, path, strerror(errno));
-       return 0;
-     }
-     *lastpost = atol(buff);
-
-     if ((s = strchr(buff,',')) == NULL) {
-       syslog(L_ERROR, "%s bad data in postrec file: '%s'",
-              ClientHost, buff);
-       return 0;
-     }
-     s++; *lastsleep = atol(s);
-
-     if ((s = strchr(s,',')) == NULL) {
-       syslog(L_ERROR, "%s bad data in postrec file: '%s'",
-              ClientHost, buff);
-       return 0;
-     }
-     s++; *lastn = atol(s);
-
-     fclose(fp);
-     return 1;
-}
-
-/* 
- * Store the postrecord for that IP 
- */
-static int
-StorePostRecord(char *path, time_t lastpost, long lastsleep, long lastn)
-{
-     FILE                         *fp;
-
-     fp = fopen(path,"w");
-     if (fp == NULL)                   {
-       syslog(L_ERROR, "%s Error opening '%s': %s",
-              ClientHost, path, strerror(errno));
-       return 0;
-     }
-
-     fprintf(fp,"%ld,%ld,%ld\n",(long) lastpost,lastsleep,lastn);
-     fclose(fp);
-     return 1;
-}
-
-/*
- * Return the proper sleeptime. Return false on error.
- */
-int
-RateLimit(sleeptime,path) 
-     long                         *sleeptime;
-     char                         *path;
-{
-     TIMEINFO                      Now;
-     long                          prevpost,prevsleep,prevn,n;
-
-     if (GetTimeInfo(&Now) < 0) 
-       return 0;
-     
-     prevpost = 0L; prevsleep = 0L; prevn = 0L; n = 0L;
-     if (!GetPostRecord(path,&prevpost,&prevsleep,&prevn)) {
-       syslog(L_ERROR, "%s can't get post record: %s",
-              ClientHost, strerror(errno));
-       return 0;
-     }
-     /*
-      * Just because yer paranoid doesn't mean they ain't out ta get ya
-      * This is called paranoid clipping
-      */
-     if (prevn < 0L) prevn = 0L;
-     if (prevsleep < 0L)  prevsleep = 0L;
-     if (prevsleep > PERMaccessconf->backoff_postfast)  prevsleep = PERMaccessconf->backoff_postfast;
-     
-      /*
-       * Compute the new sleep time
-       */
-     *sleeptime = 0L;  
-     if (prevpost <= 0L) {
-       prevpost = 0L;
-       prevn = 1L;
-     } else {
-       n = Now.time - prevpost;
-       if (n < 0L) {
-         syslog(L_NOTICE,"%s previous post was in the future (%ld sec)",
-                ClientHost,n);
-         n = 0L;
-       }
-       if (n < PERMaccessconf->backoff_postfast) {
-         if (prevn >= PERMaccessconf->backoff_trigger) {
-           *sleeptime = 1 + (prevsleep * PERMaccessconf->backoff_k);
-         } 
-       } else if (n < PERMaccessconf->backoff_postslow) {
-         if (prevn >= PERMaccessconf->backoff_trigger) {
-           *sleeptime = prevsleep;
-         }
-       } else {
-         prevn = 0L;
-       } 
-       prevn++;
-     }
-
-     *sleeptime = ((*sleeptime) > PERMaccessconf->backoff_postfast) ? PERMaccessconf->backoff_postfast : (*sleeptime);
-     /* This ought to trap this bogon */
-     if ((*sleeptime) < 0L) {
-       syslog(L_ERROR,"%s Negative sleeptime detected: %ld, prevsleep: %ld, N: %ld",ClientHost,*sleeptime,prevsleep,n);
-       *sleeptime = 0L;
-     }
-  
-     /* Store the postrecord */
-     if (!StorePostRecord(path,Now.time,*sleeptime,prevn)) {
-       syslog(L_ERROR, "%s can't store post record: %s", ClientHost, strerror(errno));
-       return 0;
-     }
-
-     return 1;
-}
-
-#ifdef HAVE_SSL
-/*
-**  The "STARTTLS" command.  RFC2595.
-*/
-/* ARGSUSED0 */
-
-void
-CMDstarttls(ac, av)
-    int                ac UNUSED;
-    char       *av[] UNUSED;
-{
-  int result;
-
-  tls_init();
-  if (nnrpd_starttls_done == 1) {
-      Reply("%d Already successfully executed STARTTLS\r\n",
-            NNTP_STARTTLS_DONE_VAL);
-      return;
-  }
-
-  Reply("%d Begin TLS negotiation now\r\n", NNTP_STARTTLS_NEXT_VAL);
-  fflush(stdout);
-
-  /* must flush our buffers before starting tls */
-  
-  result=tls_start_servertls(0, /* read */
-                            1); /* write */
-  if (result==-1) {
-    /* No reply because we have already sent NNTP_STARTTLS_NEXT_VAL. */
-    return;
-  }
-  nnrpd_starttls_done = 1;
-}
-#endif /* HAVE_SSL */
diff --git a/nnrpd/newnews.c b/nnrpd/newnews.c
deleted file mode 100644 (file)
index 0ab87d5..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*  $Revision: 6372 $
-**
-**  The newnews command.
-*/
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/wire.h"
-#include "nnrpd.h"
-#include "ov.h"
-#include "cache.h"
-
-#define GROUP_LIST_DELTA       10
-
-static bool FindHeader(ARTHANDLE *art, const char **pp, const char **qp,
-    const char* hdr, size_t hdrlen)
-{
-  const char *p, *p1, *q;
-  bool Nocr = true;
-
-  p = wire_findheader(art->data, art->len, hdr);
-  if (p == NULL)
-    return false;
-  q = p;
-  for (p1 = NULL; p < art->data + art->len; p++) {
-    if (p1 != NULL && *p1 == '\r' && *p == '\n') {
-      Nocr = false;
-      break;
-    }
-    if (*p == '\n') {
-      Nocr = true;
-      break;
-    }
-    p1 = p;
-  }
-  if (p >= art->data + art->len)
-    return false;
-  if (!Nocr)
-    p = p1;
-
-  *pp = p;
-  *qp = q;
-  return true;
-}
-
-/*
-**  get Xref header
-*/
-static char *GetXref(ARTHANDLE *art) {
-  const char   *p, *q;
-
-  if (!FindHeader(art, &p, &q, "xref", sizeof("xref")))
-    return NULL;
-  return xstrndup(q, p - q);
-}
-
-/*
-**  Split newsgroup list into array of newsgroups.  Return static pointer,
-**  or NULL if there are no newsgroup.
-*/
-static char **GetGroups(char *p) {
-  static int   size;
-  static char  **list;
-  int          i;
-  char         *q;
-  static char  *Xrefbuf = NULL;
-  char         *Xref = p;
-
-  if (size == 0) {
-    size = GROUP_LIST_DELTA;
-    list = xmalloc((size + 1) * sizeof(char *));
-  }
-  Xref = p;
-  for (Xref++; *Xref == ' '; Xref++);
-  if ((Xref = strchr(Xref, ' ')) == NULL)
-    return NULL;
-  for (Xref++; *Xref == ' '; Xref++);
-  if (!Xrefbuf)
-    Xrefbuf = xmalloc(BIG_BUFFER);
-  strlcpy(Xrefbuf, Xref, BIG_BUFFER);
-  if ((q = strchr(Xrefbuf, '\t')) != NULL)
-    *q = '\0';
-  p = Xrefbuf;
-
-  for (i = 0 ; ;i++) {
-    while (ISWHITE(*p))
-      p++;
-    if (*p == '\0' || *p == '\n')
-      break;
-
-    if (i >= size - 1) {
-      size += GROUP_LIST_DELTA;
-      list = xrealloc(list, (size + 1) * sizeof(char *));
-    }
-    for (list[i] = p; *p && *p != '\n' && !ISWHITE(*p); p++) {
-      if (*p == ':')
-       *p = '\0';
-    }
-    if (*p) *p++ = '\0';
-  }
-  list[i] = NULL;
-  return i ? list : NULL;
-}
-
-static bool HaveSeen(bool AllGroups, char *group, char **groups, char **xrefs) {
-  char *list[2];
-
-  list[1] = NULL;
-  for ( ; *xrefs; xrefs++) {
-    list[0] = *xrefs;
-    if ((!AllGroups && PERMmatch(groups, list)) && (!PERMspecified || (PERMspecified && PERMmatch(PERMreadlist, list)))) {
-      if (!strcmp(*xrefs, group))
-       return false;
-      else
-       return true;
-    }
-  }
-  return false;
-}
-
-static char **groups;
-
-static void
-process_newnews(char *group, bool AllGroups, time_t date)
-{
-    char **xrefs;
-    int count;
-    void *handle;
-    char *p;
-    time_t arrived;
-    ARTHANDLE *art = NULL;
-    TOKEN token;
-    char *data;
-    int len;
-    char *grplist[2];
-    time_t now;
-
-    grplist[0] = group;
-    grplist[1] = NULL;
-    if (PERMspecified && !PERMmatch(PERMreadlist, grplist))
-       return;
-    if (!AllGroups && !PERMmatch(groups, grplist))
-       return;
-    if (!OVgroupstats(group, &ARTlow, &ARThigh, &count, NULL))
-       return;
-    if ((handle = OVopensearch(group, ARTlow, ARThigh)) != NULL) {
-       ARTNUM artnum;
-       unsigned long artcount = 0;
-       struct cvector *vector = NULL;
-
-       if (innconf->nfsreader) {
-           time(&now);
-           /* move the start time back nfsreaderdelay seconds */
-           if (date >= innconf->nfsreaderdelay)
-               date -= innconf->nfsreaderdelay;
-       }
-       while (OVsearch(handle, &artnum, &data, &len, &token, &arrived)) {
-           if (innconf->nfsreader && arrived + innconf->nfsreaderdelay > now)
-               continue;
-           if (len == 0 || date > arrived)
-               continue;
-
-           vector = overview_split(data, len, NULL, vector);
-           if (overhdr_xref == -1) {
-               if ((art = SMretrieve(token, RETR_HEAD)) == NULL)
-                   continue;
-               p = GetXref(art);
-               SMfreearticle(art);
-           } else {
-               if (PERMaccessconf->nnrpdcheckart && 
-                   !ARTinstorebytoken(token))
-                   continue;
-               /* We only care about the newsgroup list here, virtual
-                * hosting isn't relevant */
-               p = overview_getheader(vector, overhdr_xref, OVextra);
-           }
-           if (p == NULL)
-               continue;
-           xrefs = GetGroups(p);
-           free(p);
-           if (xrefs == NULL)
-               continue;
-           if (HaveSeen(AllGroups, group, groups, xrefs))
-               continue;
-           p = overview_getheader(vector, OVERVIEW_MESSAGE_ID, OVextra);
-           if (p == NULL)
-               continue;
-
-           ++artcount;
-           cache_add(HashMessageID(p), token);
-           Printf("%s\r\n", p);
-           free(p);
-       }
-       OVclosesearch(handle);
-       notice("%s newnews %s %lu", ClientHost, group, artcount);
-       if (vector)
-           cvector_free(vector);
-    }
-}
-
-/*
-**  NEWNEWS newsgroups date time ["GMT"]
-**  Return the Message-ID of any articles after the specified date
-*/
-void CMDnewnews(int ac, char *av[]) {
-  char         *p, *q;
-  char          *path;
-  bool         AllGroups;
-  char         line[BIG_BUFFER];
-  time_t       date;
-  QIOSTATE     *qp;
-  int          i;
-  bool          local;
-
-  if (!PERMaccessconf->allownewnews) {
-      Reply("%d NEWNEWS command disabled by administrator\r\n", NNTP_ACCESS_VAL);
-      return;
-  }
-
-  if (!PERMcanread) {
-      Reply("%s\r\n", NNTP_ACCESS);
-      return;
-  }
-
-  /* Make other processes happier if someone uses NEWNEWS */
-  if (innconf->nicenewnews > 0) {
-      nice(innconf->nicenewnews);
-      innconf->nicenewnews = 0;
-  }
-
-  snprintf(line, sizeof(line), "%s %s %s %s", av[1], av[2], av[3],
-          (ac >= 5 && (*av[4] == 'G' || *av[4] == 'U')) ? "GMT" : "local");
-  notice("%s newnews %s", ClientHost, line);
-
-  TMRstart(TMR_NEWNEWS);
-  /* Optimization in case client asks for !* (no groups) */
-  if (strcmp(av[1], "!*") == 0) {
-      Reply("%s\r\n", NNTP_NEWNEWSOK);
-      Printf(".\r\n");
-      TMRstop(TMR_NEWNEWS);
-      return;
-  }
-
-  /* Parse the newsgroups. */
-  AllGroups = (strcmp(av[1], "*") == 0);
-  if (!AllGroups && !NGgetlist(&groups, av[1])) {
-      Reply("%d Bad newsgroup specifier %s\r\n", NNTP_SYNTAX_VAL, av[1]);
-      TMRstop(TMR_NEWNEWS);
-      return;
-  }
-
-  /* Parse the date. */
-  local = !(ac > 4 && strcasecmp(av[4], "GMT") == 0);
-  date = parsedate_nntp(av[2], av[3], local);
-  if (date == (time_t) -1) {
-      Reply("%d Bad date\r\n", NNTP_SYNTAX_VAL);
-      TMRstop(TMR_NEWNEWS);
-      return;
-  }
-
-  if (strcspn(av[1], "\\!*[?]") == strlen(av[1])) {
-      /* optimise case - don't need to scan the active file pattern
-       * matching */
-      Reply("%s\r\n", NNTP_NEWNEWSOK);
-      for (i = 0; groups[i]; ++i) {
-         process_newnews(groups[i], AllGroups, date);
-      }
-  } else {
-      path = concatpath(innconf->pathdb, _PATH_ACTIVE);
-      qp = QIOopen(path);
-      if (qp == NULL) {
-         if (errno == ENOENT) {
-             Reply("%d Can't open active\r\n", NNTP_TEMPERR_VAL);
-         } else {
-             syswarn("%s cant fopen %s", ClientHost, path);
-             Reply("%d Can't open active\r\n", NNTP_TEMPERR_VAL);
-         }
-         free(path);
-         TMRstop(TMR_NEWNEWS);
-         return;
-      }
-      free(path);
-
-      Reply("%s\r\n", NNTP_NEWNEWSOK);
-
-      while ((p = QIOread(qp)) != NULL) {
-         for (q = p; *q != '\0'; q++) {
-             if (*q == ' ' || *q == '\t') {
-                 *q = '\0';
-                 break;
-             }
-         }
-         process_newnews(p, AllGroups, date);
-      }
-      QIOclose(qp);
-  }
-  Printf(".\r\n");
-  TMRstop(TMR_NEWNEWS);
-}
diff --git a/nnrpd/nnrpd.c b/nnrpd/nnrpd.c
deleted file mode 100644 (file)
index 010aa66..0000000
+++ /dev/null
@@ -1,1362 +0,0 @@
-/*  $Id: nnrpd.c 7731 2008-04-06 08:40:29Z iulius $
-**
-**  NNTP server for readers (NNRP) for InterNetNews.
-**
-**  This server doesn't do any real load-limiting, except for what has
-**  proven empirically necesary (i.e., look at GRPscandir).
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/setproctitle.h"
-#include "portable/wait.h"
-#include <grp.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <signal.h>
-
-#if HAVE_GETSPNAM
-# include <shadow.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "ov.h"
-#define MAINLINE
-#include "nnrpd.h"
-
-#include "tls.h"
-#include "sasl_config.h"
-
-#ifdef HAVE_SSL
-extern SSL *tls_conn;
-int nnrpd_starttls_done = 0;
-#endif 
-
-#if NEED_HERRNO_DECLARATION
-extern int h_errno;
-#endif
-
-/* If we have getloadavg, include the appropriate header file.  Otherwise,
-   just assume that we always have a load of 0. */
-#if HAVE_GETLOADAVG
-# if HAVE_SYS_LOADAVG_H
-#  include <sys/loadavg.h>
-# endif
-#else
-static int
-getloadavg(double loadavg[], int nelem)
-{
-    int i;
-
-    for (i = 0; i < nelem && i < 3; i++)
-        loadavg[i] = 0;
-    return i;
-}
-#endif
-
-
-#define MAXPATTERNDEFINE       10
-
-#define CMDany         -1
-
-
-typedef struct _CMDENT {
-    const char *        Name;
-    void                (*Function)(int, char **);
-    bool                Needauth;
-    int                 Minac;
-    int                 Maxac;
-    const char *        Help;
-} CMDENT;
-
-
-char   NOACCESS[] = NNTP_ACCESS;
-char   *ACTIVE = NULL;
-char   *ACTIVETIMES = NULL;
-char   *HISTORY = NULL;
-char   *NEWSGROUPS = NULL;
-char   *NNRPACCESS = NULL;
-
-static char    *LocalLogFileName = NULL;
-static char    *LocalLogDirName;
-
-struct history *History;
-static double  STATstart;
-static double  STATfinish;
-static char    *PushedBack;
-static sig_atomic_t    ChangeTrace;
-bool   DaemonMode = false;
-bool   ForeGroundMode = false;
-#if HAVE_GETSPNAM
-static const char      *ShadowGroup;
-#endif
-static const char      *HostErrorStr;
-bool GetHostByAddr = true;      /* formerly DO_NNRP_GETHOSTBYADDR */
-const char *NNRPinstance = "";
-
-#ifdef DO_PERL
-bool   PerlLoaded = false;
-#endif /* DO_PERL */
-
-#ifdef DO_PYTHON
-bool PY_use_dynamic = false;
-#endif /* DO_PYTHON */
-
-static char    CMDfetchhelp[] = "[MessageID|Number]";
-
-static CMDENT  CMDtable[] = {
-    {  "authinfo",     CMDauthinfo,    false,  3,      CMDany,
-       "user Name|pass Password|generic <prog> <args>" },
-#ifdef HAVE_SSL
-    {  "starttls",     CMDstarttls,    false,  1,      1,
-       NULL },
-#endif
-    {  "article",      CMDfetch,       true,   1,      2,
-       CMDfetchhelp },
-    {  "body",         CMDfetch,       true,   1,      2,
-       CMDfetchhelp },
-    {  "date",         CMDdate,        false,  1,      1,
-       NULL },
-    {  "group",        CMDgroup,       true,   2,      2,
-       "newsgroup" },
-    {  "head",         CMDfetch,       true,   1,      2,
-       CMDfetchhelp },
-    {  "help",         CMDhelp,        false,  1,      CMDany,
-       NULL },
-    {  "ihave",        CMDpost,        true,   2,      2,
-       "MessageID" },
-    {  "last",         CMDnextlast,    true,   1,      1,
-       NULL },
-    {  "list",         CMDlist,        true,   1,      3,
-       "[active|active.times|distrib.pats|distributions|extensions|moderators|motd|newsgroups|overview.fmt|subscriptions]" },
-    {  "listgroup",    CMDgroup,       true,   1,      2,
-       "newsgroup" },
-    {  "mode",         CMDmode,        false,  2,      2,
-       "reader" },
-    {  "newgroups",    CMDnewgroups,   true,   3,      5,
-       "[YY]yymmdd hhmmss [\"GMT\"]" },
-    {  "newnews",      CMDnewnews,     true,   4,      5,
-       "newsgroups [YY]yymmdd hhmmss [\"GMT\"]" },
-    {  "next",         CMDnextlast,    true,   1,      1,
-       NULL },
-    {  "post",         CMDpost,        true,   1,      1,
-       NULL },
-    {  "slave",        CMD_unimp,      false,  1,      1,
-       NULL },
-    {  "stat",         CMDfetch,       true,   1,      2,
-       CMDfetchhelp },
-    {  "xgtitle",      CMDxgtitle,     true,   1,      2,
-       "[group_pattern]" },
-    {  "xhdr",         CMDpat,         true,   2,      3,
-       "header [range|MessageID]" },
-    {  "xover",        CMDxover,       true,   1,      2,
-       "[range]" },
-    {  "xpat",         CMDpat,         true,   4,      CMDany,
-       "header range|MessageID pat [morepat...]" },
-    {  "xpath",        CMDxpath,       true,   2,      2,
-       "MessageID" },
-    {  NULL,           CMD_unimp,      false,  0,      0,
-        NULL }
-};
-
-
-static const char *const timer_name[] = {
-    "idle",
-    "newnews",
-    "readart",
-    "checkart",
-    "nntpread",
-    "nntpwrite",
-};
-
-/*
-**  Log a summary status message and exit.
-*/
-void
-ExitWithStats(int x, bool readconf)
-{
-    double             usertime;
-    double             systime;
-
-    line_free(&NNTPline);
-    fflush(stdout);
-    STATfinish = TMRnow_double();
-    if (GetResourceUsage(&usertime, &systime) < 0) {
-       usertime = 0;
-       systime = 0;
-    }
-
-    GRPreport();
-    if (ARTcount)
-        syslog(L_NOTICE, "%s exit articles %ld groups %ld", 
-           ClientHost, ARTcount, GRPcount);
-    if (POSTreceived ||  POSTrejected)
-       syslog(L_NOTICE, "%s posts received %ld rejected %ld",
-          ClientHost, POSTreceived, POSTrejected);
-    syslog(L_NOTICE, "%s times user %.3f system %.3f idle %.3f elapsed %.3f",
-       ClientHost, usertime, systime, IDLEtime, STATfinish - STATstart);
-    /* Tracking code - Make entries in the logfile(s) to show that we have
-       finished with this session */
-    if (!readconf && PERMaccessconf &&  PERMaccessconf->readertrack) {
-       syslog(L_NOTICE, "%s Tracking Disabled (%s)", ClientHost, Username);
-       if (LLOGenable) {
-               fprintf(locallog, "%s Tracking Disabled (%s)\n", ClientHost, Username);
-               fclose(locallog);
-               syslog(L_NOTICE,"%s Local Logging ends (%s) %s",ClientHost, Username, LocalLogFileName);
-       }
-    }
-    if (ARTget)
-        syslog(L_NOTICE, "%s artstats get %ld time %ld size %ld", ClientHost,
-            ARTget, ARTgettime, ARTgetsize);
-    if (!readconf && PERMaccessconf && PERMaccessconf->nnrpdoverstats && OVERcount)
-        syslog(L_NOTICE, "%s overstats count %ld hit %ld miss %ld time %ld size %ld dbz %ld seek %ld get %ld artcheck %ld", ClientHost,
-            OVERcount, OVERhit, OVERmiss, OVERtime, OVERsize, OVERdbz, OVERseek, OVERget, OVERartcheck);
-
-#ifdef HAVE_SSL
-     if (tls_conn) {
-        SSL_shutdown(tls_conn);
-        SSL_free(tls_conn);
-        tls_conn = NULL;
-     } 
-#endif
-
-     if (DaemonMode) {
-       shutdown(STDIN_FILENO, 2);
-       shutdown(STDOUT_FILENO, 2);
-       shutdown(STDERR_FILENO, 2);
-       close(STDIN_FILENO);
-       close(STDOUT_FILENO);
-       close(STDERR_FILENO);
-     }
-    
-    OVclose();
-    SMshutdown();
-
-#ifdef DO_PYTHON
-        PY_close_python();
-#endif /* DO_PYTHON */
-
-    if (History)
-       HISclose(History);
-
-    if (innconf->timer != 0) {
-        TMRsummary(ClientHost, timer_name);
-        TMRfree();
-    }
-
-    if (LocalLogFileName != NULL)
-       free(LocalLogFileName);
-    closelog();
-    exit(x);
-}
-
-
-/*
-**  The "help" command.
-*/
-/* ARGSUSED0 */
-void
-CMDhelp(int ac UNUSED, char *av[] UNUSED)
-{
-    CMDENT     *cp;
-    char       *p, *q;
-    static const char *newsmaster = NEWSMASTER;
-
-    Reply("%s\r\n", NNTP_HELP_FOLLOWS);
-    for (cp = CMDtable; cp->Name; cp++)
-       if (cp->Help == NULL)
-           Printf("  %s\r\n", cp->Name);
-       else
-           Printf("  %s %s\r\n", cp->Name, cp->Help);
-    if (PERMaccessconf && (VirtualPathlen > 0)) {
-       if (PERMaccessconf->newsmaster) {
-           if (strchr(PERMaccessconf->newsmaster, '@') == NULL) {
-               Printf("Report problems to <%s@%s>\r\n",
-                   PERMaccessconf->newsmaster, PERMaccessconf->domain);
-           } else {
-               Printf("Report problems to <%s>\r\n",
-                   PERMaccessconf->newsmaster);
-           }
-       } else {
-           /* sigh, pickup from newsmaster anyway */
-           if ((p = strchr(newsmaster, '@')) == NULL)
-               Printf("Report problems to <%s@%s>\r\n",
-                   newsmaster, PERMaccessconf->domain);
-           else {
-                q = xstrndup(newsmaster, p - newsmaster);
-               Printf("Report problems to <%s@%s>\r\n",
-                   q, PERMaccessconf->domain);
-               free(q);
-           }
-       }
-    } else {
-       if (strchr(newsmaster, '@') == NULL)
-           Printf("Report problems to <%s@%s>\r\n",
-               newsmaster, innconf->fromhost);
-       else
-           Printf("Report problems to <%s>\r\n",
-               newsmaster);
-    }
-    Reply(".\r\n");
-}
-
-
-/*
-**  Unimplemented catch-all.
-*/
-/* ARGSUSED0 */
-void
-CMD_unimp(ac, av)
-    int                ac UNUSED;
-    char       *av[];
-{
-    if (strcasecmp(av[0], "slave") == 0)
-       /* Somebody sends us this?  I don't believe it! */
-       Reply("%d Unsupported\r\n", NNTP_SLAVEOK_VAL);
-    else
-       Reply("%d %s not implemented; try help\r\n",
-           NNTP_BAD_COMMAND_VAL, av[0]);
-}
-
-
-#ifndef        INADDR_LOOPBACK
-#define        INADDR_LOOPBACK 0x7f000001
-#endif /* INADDR_LOOPBACK */
-/*
-**  Convert an IP address to a hostname.  Don't trust the reverse lookup,
-**  since anyone can fake .in-addr.arpa entries.
-*/
-static bool
-Address2Name(INADDR *ap, char *hostname, int i)
-{
-    char               *p;
-    struct hostent     *hp;
-    static char                mismatch_error[] = "reverse lookup validation failed";
-    char               **pp;
-
-    /* Get the official hostname, store it away. */
-    if ((hp = gethostbyaddr((char *)ap, sizeof *ap, AF_INET)) == NULL) {
-       HostErrorStr = hstrerror(h_errno);
-       return false;
-    }
-    strlcpy(hostname, hp->h_name, i);
-
-    /* Get addresses for this host. */
-    if ((hp = gethostbyname(hostname)) == NULL) {
-       HostErrorStr = hstrerror(h_errno);
-       return false;
-    }
-
-    /* Make sure one of those addresses is the address we got. */
-    for (pp = hp->h_addr_list; *pp; pp++)
-       if (strncmp((const char *)&ap->s_addr, *pp, hp->h_length) == 0)
-           break;
-    if (*pp == NULL)
-    {
-       HostErrorStr = mismatch_error;
-       return false;
-    }
-
-    /* Only needed for misconfigured YP/NIS systems. */
-    if (ap->s_addr != INADDR_LOOPBACK && strchr(hostname, '.') == NULL
-     && (p = innconf->domain) != NULL) {
-       strlcat(hostname, ".", i);
-       strlcat(hostname, p, i);
-    }
-
-    /* Make all lowercase, for wildmat. */
-    for (p = hostname; *p; p++)
-       if (CTYPE(isupper, (int)*p))
-           *p = tolower(*p);
-    return true;
-}
-
-/*
-**  Convert an IPv6 address to a hostname.  Don't trust the reverse lookup,
-**  since anyone can fake .ip6.arpa entries.
-*/
-#ifdef HAVE_INET6
-static bool
-Address2Name6(struct sockaddr *sa, char *hostname, int i)
-{
-    static char                mismatch_error[] = "reverse lookup validation failed";
-    int ret;
-    bool valid = 0;
-    struct addrinfo hints, *res, *res0;
-    char *p;
-
-    /* Get the official hostname, store it away. */
-    ret = getnameinfo( sa, SA_LEN( sa ), hostname, i, NULL, 0, NI_NAMEREQD );
-    if( ret != 0 )
-    {
-       HostErrorStr = gai_strerror( ret );
-       return false;
-    }
-
-    /* Get addresses for this host. */
-    memset( &hints, 0, sizeof( hints ) );
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_family = AF_INET6;
-    if( ( ret = getaddrinfo( hostname, NULL, &hints, &res0 ) ) != 0 )
-    {
-       HostErrorStr = gai_strerror( ret );
-       return false;
-    }
-
-    /* Make sure one of those addresses is the address we got. */
-    for( res = res0; res; res = res->ai_next )
-    {
-#ifdef HAVE_BROKEN_IN6_ARE_ADDR_EQUAL
-       if( ! memcmp( &(((struct sockaddr_in6 *)sa)->sin6_addr),
-                   &(((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr),
-                   sizeof( struct in6_addr ) ) )
-#else
-       if( IN6_ARE_ADDR_EQUAL( &(((struct sockaddr_in6 *)sa)->sin6_addr),
-                   &(((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr) ) )
-#endif
-       {
-           valid = 1;
-           break;
-       }
-    }
-
-    freeaddrinfo( res0 );
-
-    if (valid) {
-        /* Make all lowercase for matching. */
-        for (p = hostname; *p != '\0'; p++)
-            if (CTYPE(isupper, *p))
-                *p = tolower(*p);
-        return true;
-    } else {
-       HostErrorStr = mismatch_error;
-       return false;
-    }
-}
-#endif
-
-
-static bool
-Sock2String( struct sockaddr *sa, char *string, int len, bool lookup )
-{
-    struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
-
-#ifdef HAVE_INET6
-    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-    struct sockaddr_in temp;
-
-    if( sa->sa_family == AF_INET6 )
-    {
-       if( ! IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) )
-       {
-           if( lookup )
-           {
-               return Address2Name6(sa, string, len);
-           } else {
-               strlcpy( string, sprint_sockaddr( sa ), len );
-               return true;
-           }
-       } else {
-           temp.sin_family = AF_INET;
-           memcpy( &temp.sin_addr, sin6->sin6_addr.s6_addr + 12, 4 );
-           temp.sin_port = sin6->sin6_port;
-           sin4 = &temp;
-           /* fall through to AF_INET case */
-       }
-    }
-#endif
-    if( lookup ) {
-       return Address2Name(&sin4->sin_addr, string, len);
-    } else {
-       strlcpy( string, inet_ntoa(sin4->sin_addr), len );
-       return true;
-    }
-}
-
-/*
-**  Determine access rights of the client.
-*/
-static void StartConnection(void)
-{
-    struct sockaddr_storage    ssc, sss;
-    socklen_t          length;
-    const char         *default_host_error = "unknown error";
-
-    ClientIpAddr = 0L;
-    ClientHost[0] = '\0';
-    ClientIpString[0] = '\0';
-    ClientPort = 0;
-    ServerHost[0] = '\0';
-    ServerIpString[0] = '\0';
-    ServerPort = 0;
-
-    /* Get the peer's name. */
-    length = sizeof ssc;
-    if (getpeername(STDIN_FILENO, (struct sockaddr *)&ssc, &length) < 0) {
-      if (!isatty(STDIN_FILENO)) {
-           syslog(L_TRACE, "%s cant getpeername %m", "?");
-             /* so stats generation looks correct. */
-            strlcpy(ClientHost, "?", sizeof(ClientHost));
-           Printf("%d I can't get your name.  Goodbye.\r\n", NNTP_ACCESS_VAL);
-           ExitWithStats(1, true);
-       }
-        strlcpy(ClientHost, "stdin", sizeof(ClientHost));
-    }
-
-    else {
-#ifdef HAVE_INET6
-       if ( ssc.ss_family != AF_INET && ssc.ss_family != AF_INET6) {
-#else
-       if ( ssc.ss_family != AF_INET ) {
-#endif
-           syslog(L_ERROR, "%s bad_address_family %ld",
-               "?", (long)ssc.ss_family);
-           Printf("%d Bad address family.  Goodbye.\r\n", NNTP_ACCESS_VAL);
-           ExitWithStats(1, true);
-       }
-
-       length = sizeof sss;
-       if (getsockname(STDIN_FILENO, (struct sockaddr *)&sss, &length) < 0) {
-           syslog(L_NOTICE, "%s can't getsockname %m", ClientHost);
-           Printf("%d Can't figure out where you connected to.  Goodbye\r\n", NNTP_ACCESS_VAL);
-           ExitWithStats(1, true);
-       }
-
-       /* figure out client's IP address/hostname */
-       HostErrorStr = default_host_error;
-       if( ! Sock2String( (struct sockaddr *)&ssc, ClientIpString,
-                               sizeof( ClientIpString ), false ) ) {
-            syslog(L_NOTICE, "? cant get client numeric address: %s", HostErrorStr);
-           ExitWithStats(1, true);
-       }
-       if(GetHostByAddr) {
-           HostErrorStr = default_host_error;
-           if( ! Sock2String( (struct sockaddr *)&ssc, ClientHost,
-                                   sizeof( ClientHost ), true ) ) {
-                syslog(L_NOTICE,
-                       "? reverse lookup for %s failed: %s -- using IP address for access",
-                       ClientIpString, HostErrorStr);
-               strlcpy(ClientHost, ClientIpString, sizeof(ClientHost));
-           }
-       } else {
-            strlcpy(ClientHost, ClientIpString, sizeof(ClientHost));
-        }
-
-       /* figure out server's IP address/hostname */
-       HostErrorStr = default_host_error;
-       if( ! Sock2String( (struct sockaddr *)&sss, ServerIpString,
-                               sizeof( ServerIpString ), false ) ) {
-            syslog(L_NOTICE, "? cant get server numeric address: %s", HostErrorStr);
-           ExitWithStats(1, true);
-       }
-       if(GetHostByAddr) {
-           HostErrorStr = default_host_error;
-           if( ! Sock2String( (struct sockaddr *)&sss, ServerHost,
-                                   sizeof( ServerHost ), true ) ) {
-                syslog(L_NOTICE,
-                       "? reverse lookup for %s failed: %s -- using IP address for access",
-                       ServerIpString, HostErrorStr);
-               strlcpy(ServerHost, ServerIpString, sizeof(ServerHost));
-           }
-       } else {
-            strlcpy(ServerHost, ServerIpString, sizeof(ServerHost));
-        }
-
-       /* get port numbers */
-       switch( ssc.ss_family ) {
-           case AF_INET:
-               ClientPort = ntohs( ((struct sockaddr_in *)&ssc)->sin_port );
-               ServerPort = ntohs( ((struct sockaddr_in *)&sss)->sin_port );
-               break;
-#ifdef HAVE_INET6
-           case AF_INET6:
-               ClientPort = ntohs( ((struct sockaddr_in6 *)&ssc)->sin6_port );
-               ServerPort = ntohs( ((struct sockaddr_in6 *)&sss)->sin6_port );
-               break;
-#endif
-       }
-    }
-
-    strlcpy(LogName, ClientHost, sizeof(LogName));
-
-    syslog(L_NOTICE, "%s (%s) connect", ClientHost, ClientIpString);
-
-    PERMgetaccess(NNRPACCESS);
-    PERMgetpermissions();
-}
-
-
-/*
-**  Send a reply, possibly with debugging output.
-*/
-void
-Reply(const char *fmt, ...)
-{
-    va_list     args;
-    int         oerrno;
-    char *      p;
-    char        buff[2048];
-
-#ifdef HAVE_SSL
-    if (tls_conn) {
-      int r;
-
-      va_start(args, fmt);
-      vsnprintf(buff, sizeof(buff), fmt, args);
-      va_end(args);
-      TMRstart(TMR_NNTPWRITE);
-Again:
-      r = SSL_write(tls_conn, buff, strlen(buff));
-      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;
-      }
-      TMRstop(TMR_NNTPWRITE);
-    } else {
-      va_start(args, fmt);
-      TMRstart(TMR_NNTPWRITE);
-      vprintf(fmt, args);
-      TMRstop(TMR_NNTPWRITE);
-      va_end(args);
-    }
-#else
-      va_start(args, fmt);
-      TMRstart(TMR_NNTPWRITE);
-      vprintf(fmt, args);
-      TMRstop(TMR_NNTPWRITE);
-      va_end(args);
-#endif
-    if (Tracing) {
-        oerrno = errno;
-        va_start(args, fmt);
-
-        /* Copy output, but strip trailing CR-LF.  Note we're assuming here
-           that no output line can ever be longer than 2045 characters. */
-        vsnprintf(buff, sizeof(buff), fmt, args);
-        va_end(args);
-        p = buff + strlen(buff) - 1;
-        while (p >= buff && (*p == '\n' || *p == '\r'))
-            *p-- = '\0';
-        syslog(L_TRACE, "%s > %s", ClientHost, buff);
-
-        errno = oerrno;
-    }
-}
-
-void
-Printf(const char *fmt, ...)
-{
-    va_list     args;
-
-#ifdef HAVE_SSL
-    if (tls_conn) {
-      int r;
-      char buff[2048];
-
-      va_start(args, fmt);
-      vsnprintf(buff, sizeof(buff), fmt, args);
-      va_end(args);
-      TMRstart(TMR_NNTPWRITE);
-Again:
-      r = SSL_write(tls_conn, buff, strlen(buff));
-      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;
-      }
-      TMRstop(TMR_NNTPWRITE);
-    } else {
-#endif /* HAVE_SSL */
-      va_start(args, fmt);
-      TMRstart(TMR_NNTPWRITE);
-      vprintf(fmt, args);
-      TMRstop(TMR_NNTPWRITE);
-      va_end(args);
-#ifdef HAVE_SSL
-    }
-#endif /* HAVE_SSL */
-}
-
-
-#ifdef HAVE_SIGACTION
-#define NO_SIGACTION_UNUSED UNUSED
-#else
-#define NO_SIGACTION_UNUSED
-#endif
-/*
-**  Got a signal; toggle tracing.
-*/
-static RETSIGTYPE
-ToggleTrace(int s NO_SIGACTION_UNUSED)
-{
-    ChangeTrace = true;
-#ifndef HAVE_SIGACTION
-    xsignal(s, ToggleTrace);
-#endif
-}
-
-/*
-** Got a SIGPIPE; exit cleanly
-*/
-static RETSIGTYPE
-CatchPipe(int s UNUSED)
-{
-    ExitWithStats(0, false);
-}
-
-/*
-**  Got a signal; wait for children.
-*/
-static RETSIGTYPE
-WaitChild(int s NO_SIGACTION_UNUSED)
-{
-    int pid;
-
-    for (;;) {
-       pid = waitpid(-1, NULL, WNOHANG);
-       if (pid <= 0)
-                   break;
-    }
-#ifndef HAVE_SIGACTION
-    xsignal(s, WaitChild);
-#endif
-}
-
-static void SetupDaemon(void) {
-    bool                val;
-
-    val = true;
-    if (SMsetup(SM_PREOPEN, (void *)&val) && !SMinit()) {
-       syslog(L_NOTICE, "cant initialize storage method, %s", SMerrorstr);
-       Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-       ExitWithStats(1, true);
-    }
-    OVextra = overview_extra_fields();
-    if (OVextra == NULL) {
-       /* overview_extra_fields should already have logged something
-        * useful */
-       Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-       ExitWithStats(1, true);
-    }
-    overhdr_xref = overview_index("Xref", OVextra);
-    if (!OVopen(OV_READ)) {
-       /* This shouldn't really happen. */
-       syslog(L_NOTICE, "cant open overview %m");
-       Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-       ExitWithStats(1, true);
-    }
-    if (!OVctl(OVCACHEKEEP, &val)) {
-       syslog(L_NOTICE, "cant enable overview cache %m");
-       Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-       ExitWithStats(1, true);
-    }
-}
-
-/*
-**  Print a usage message and exit.
-*/
-static void
-Usage(void)
-{
-    fprintf(stderr, "Usage error.\n");
-    exit(1);
-}
-
-
-/* ARGSUSED0 */
-int
-main(int argc, char *argv[])
-{
-    const char *name;
-    CMDENT             *cp;
-    char               buff[NNTP_STRLEN];
-    char               **av;
-    int                        ac;
-    READTYPE           r;
-    int                        i;
-    char               *Reject;
-    int                        timeout;
-    unsigned int       vid=0; 
-    int                count=123456789;
-    struct             timeval tv;
-    unsigned short     ListenPort = NNTP_PORT;
-#ifdef HAVE_INET6
-    char               ListenAddr[INET6_ADDRSTRLEN];
-#else
-    char               ListenAddr[16];
-#endif
-    int                        lfd, fd;
-    socklen_t          clen;
-#ifdef HAVE_INET6
-    struct sockaddr_storage ssa, csa;
-    struct sockaddr_in6        *ssa6 = (struct sockaddr_in6 *) &ssa;
-#else
-    struct sockaddr_in ssa, csa;
-#endif
-    struct sockaddr_in *ssa4 = (struct sockaddr_in *) &ssa;
-    struct stat                Sb;
-    pid_t              pid = -1;
-    gid_t               NewsGID;
-    uid_t               NewsUID;
-    int                 one = 1;
-    FILE                *pidfile;
-    struct passwd      *pwd;
-    int                        clienttimeout;
-    char               *ConfFile = NULL;
-    char                *path;
-#if HAVE_GETSPNAM
-    struct group       *grp;
-    gid_t              shadowgid;
-#endif /* HAVE_GETSPNAM */
-
-    int respawn = 0;
-
-    setproctitle_init(argc, argv);
-
-    /* Parse arguments.   Must xstrdup() optarg if used because setproctitle may
-       clobber it! */
-    Reject = NULL;
-    LLOGenable = false;
-    GRPcur = NULL;
-    MaxBytesPerSecond = 0;
-    strlcpy(Username, "unknown", sizeof(Username));
-
-    /* Set up the pathname, first thing, and teach our error handlers about
-       the name of the program. */
-    name = argv[0];
-    if (name == NULL || *name == '\0')
-       name = "nnrpd";
-    else {
-       const char *p;
-
-       p = strrchr(name, '/');
-       if (p != NULL)
-           name = p + 1;
-    }
-    message_program_name = xstrdup(name);
-    openlog(message_program_name, L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_handlers_die(1, message_log_syslog_crit);
-    message_handlers_warn(1, message_log_syslog_warning);
-    message_handlers_notice(1, message_log_syslog_notice);
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-#ifdef HAVE_SSL
-    while ((i = getopt(argc, argv, "c:b:Dfi:I:g:nop:P:r:s:tS")) != EOF)
-#else
-    while ((i = getopt(argc, argv, "c:b:Dfi:I:g:nop:P:r:s:t")) != EOF)
-#endif /* HAVE_SSL */
-       switch (i) {
-       default:
-           Usage();
-           /* NOTREACHED */
-       case 'c':               /* use alternate readers.conf */
-           ConfFile = concatpath(innconf->pathetc, optarg);
-           break;
-       case 'b':                       /* bind to a certain address in
-                                          daemon mode */
-           strlcpy(ListenAddr, optarg, sizeof(ListenAddr));
-           break;
-       case 'D':                       /* standalone daemon mode */
-           DaemonMode = true;
-           break;
-       case 'P':                       /* prespawn count in daemon mode */
-           respawn = atoi(optarg);
-           break;
-       case 'f':                       /* Don't fork on daemon mode */
-           ForeGroundMode = true;
-           break;
-#if HAVE_GETSPNAM
-       case 'g':
-           ShadowGroup = optarg;
-           break;
-#endif /* HAVE_GETSPNAM */
-       case 'i':                       /* Initial command */
-           PushedBack = xstrdup(optarg);
-           break;
-       case 'I':                       /* Instance */
-           NNRPinstance = xstrdup(optarg);
-           break;
-       case 'n':                       /* No DNS lookups */
-           GetHostByAddr = false;
-           break;
-       case 'o':
-           Offlinepost = true;         /* Offline posting only */
-           break;
-       case 'p':                       /* tcp port for daemon mode */
-           ListenPort = atoi(optarg);
-           break;
-       case 'r':                       /* Reject connection message */
-           Reject = xstrdup(optarg);
-           break;
-       case 's':                       /* Unused title string */
-           break;
-       case 't':                       /* Tracing */
-           Tracing = true;
-           break;
-#ifdef HAVE_SSL
-       case 'S':                       /* SSL negotiation as soon as connected */
-           initialSSL = true;
-           break;
-#endif /* HAVE_SSL */
-       }
-    argc -= optind;
-    if (argc)
-       Usage();
-
-    /*
-     * Make other processes happier if someone is reading
-     * This allows other processes like 'overchan' to keep up when
-     * there are lots of readers. Note that this is cumulative with
-     * 'nicekids'
-    */
-    if (innconf->nicennrpd > 0)
-       nice(innconf->nicennrpd);
-
-    HISTORY = concatpath(innconf->pathdb, _PATH_HISTORY);
-    ACTIVE = concatpath(innconf->pathdb, _PATH_ACTIVE);
-    ACTIVETIMES = concatpath(innconf->pathdb, _PATH_ACTIVETIMES);
-    NEWSGROUPS = concatpath(innconf->pathdb, _PATH_NEWSGROUPS);
-    if(ConfFile)
-        NNRPACCESS = ConfFile;
-    else
-        NNRPACCESS = concatpath(innconf->pathetc,_PATH_NNRPACCESS);
-    SPOOLlen = strlen(innconf->patharticles);
-
-    if (DaemonMode) {
-#ifdef HAVE_INET6
-       memset(&ssa, '\0', sizeof(struct sockaddr_in6));
-       ssa6->sin6_family = AF_INET6;
-       ssa6->sin6_port   = htons(ListenPort);
-       if (inet_pton(AF_INET6, ListenAddr, ssa6->sin6_addr.s6_addr) > 0) {
-           if ( (lfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
-               syslog(L_FATAL, "can't open socket (%m)");
-               exit(1);
-           }
-       }
-       else {
-#endif
-           memset(&ssa, '\0', sizeof(struct sockaddr_in));
-           ssa4->sin_family = AF_INET;
-           ssa4->sin_port   = htons(ListenPort);
-           if (inet_aton(ListenAddr, &ssa4->sin_addr) <= 0 )
-               ssa4->sin_addr.s_addr = htonl(INADDR_ANY);
-           if ( (lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-               syslog(L_FATAL, "can't open socket (%m)");
-               exit(1);
-           }
-#ifdef HAVE_INET6
-       }
-#endif
-
-       if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR,
-                      (char *)&one, sizeof(one)) < 0) {
-           syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
-           exit(1);
-       }
-
-       if (bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
-           fprintf(stderr, "%s: can't bind (%s)\n", argv[0], strerror(errno));
-           syslog(L_FATAL, "can't bind local address (%m)");
-           exit(1);
-       }
-
-       /* If started as root, switch to news uid */
-       if (getuid() == 0) {
-           if (stat(innconf->pathrun, &Sb) < 0 || !S_ISDIR(Sb.st_mode)) {
-               syslog(L_FATAL, "nnrpd cant stat %s %m", innconf->pathrun);
-               exit(1);
-           }
-           if (Sb.st_uid == 0) {
-               syslog(L_FATAL, "nnrpd %s must not be owned by root", innconf->pathrun);
-               exit(1);
-           }
-           pwd = getpwnam(NEWSUSER);
-           if (pwd == (struct passwd *)NULL) {
-               syslog(L_FATAL, "nnrpd getpwnam(%s): %s", NEWSUSER, strerror(errno));
-               exit(1);
-           } else if (pwd->pw_gid != Sb.st_gid) {
-               syslog(L_FATAL, "nnrpd %s must have group %s", innconf->pathrun, NEWSGRP);
-               exit(1);
-           } else if (pwd->pw_uid != Sb.st_uid) {
-               syslog(L_FATAL, "nnrpd %s must be owned by %s", innconf->pathrun, NEWSUSER);
-               exit(1);
-           }
-
-#if HAVE_GETSPNAM
-           shadowgid = (gid_t) -1;
-           /* Find shadowgroup gid if needed */
-           if (ShadowGroup != NULL) {
-               if ((grp = getgrnam(ShadowGroup)) == NULL)
-                   syslog(L_ERROR, "nnrpd cannot find group %s",
-                               ShadowGroup);
-               else
-                   shadowgid = grp->gr_gid;
-           } else if ((grp = getgrnam("shadow")) != NULL) {
-               /* found default group "shadow" */
-               shadowgid = grp->gr_gid;
-               ShadowGroup = "shadow";
-           }
-           /* If we have a shadowgid, try to set it as an extra group. */
-           if (shadowgid != (gid_t) -1) {
-               if (setgroups(1, &shadowgid) < 0)
-                  syslog(L_ERROR, "nnrpd cannot set supplementary group %s %m",
-                       ShadowGroup);
-               else
-                  syslog(L_NOTICE, "nnrpd added supplementary group %s",
-                       ShadowGroup);
-           }
-#endif /* HAVE_GETSPNAM */
-
-           NewsUID = Sb.st_uid;
-           NewsGID = Sb.st_gid;
-           setgid(NewsGID);
-           if (getgid() != NewsGID)
-               syslog(L_ERROR, "nnrpd cant setgid to %d %m", NewsGID);
-           setuid(NewsUID);
-           if (getuid() != NewsUID)
-               syslog(L_ERROR, "nnrpd cant setuid to %d %m", NewsUID);
-       }
-
-       /* Detach */
-       if (!ForeGroundMode) {
-           daemonize("/");
-       }
-
-       if (ListenPort == NNTP_PORT)
-           strlcpy(buff, "nnrpd.pid", sizeof(buff));
-       else
-           snprintf(buff, sizeof(buff), "nnrpd-%d.pid", ListenPort);
-        path = concatpath(innconf->pathrun, buff);
-        pidfile = fopen(path, "w");
-        free(path);
-       if (pidfile == NULL) {
-           syslog(L_ERROR, "cannot write %s %m", buff);
-            exit(1);
-       }
-       fprintf(pidfile,"%lu\n", (unsigned long) getpid());
-       fclose(pidfile);
-
-       /* Set signal handle to care for dead children */
-       if (!respawn)
-           xsignal(SIGCHLD, WaitChild);
-
-       /* Arrange to toggle tracing. */
-       xsignal(SIGHUP, ToggleTrace);
-       setproctitle("accepting connections");
-       
-       listen(lfd, 128);       
-
-       if (respawn) {
-           /* pre-forked mode */
-           for (;;) {
-               if (respawn > 0) {
-                   --respawn;
-                   pid = fork();
-                   if (pid == 0) {
-                       do {
-                           clen = sizeof(csa);
-                           fd = accept(lfd, (struct sockaddr *) &csa, &clen);
-                       } while (fd < 0);
-                       break;
-                   }
-               }
-               for (;;) {
-                   if (respawn == 0)
-                       pid = wait(NULL);
-                   else
-                       pid = waitpid(-1, NULL, WNOHANG);
-                   if (pid <= 0)
-                       break;
-                   ++respawn;
-               }
-           }
-       } else {
-           /* fork on demand */
-           do {
-               clen = sizeof(csa);
-               fd = accept(lfd, (struct sockaddr *) &csa, &clen);
-               if (fd < 0)
-                   continue;
-           
-               for (i = 0; i <= innconf->maxforks && (pid = fork()) < 0; i++) {
-                   if (i == innconf->maxforks) {
-                       syslog(L_FATAL, "cant fork (dropping connection): %m");
-                       continue;
-                   }
-                   syslog(L_NOTICE, "cant fork (waiting): %m");
-                   sleep(1);
-               }
-               if (ChangeTrace) {
-                   Tracing = Tracing ? false : true;
-                   syslog(L_TRACE, "trace %sabled", Tracing ? "en" : "dis");
-                   ChangeTrace = false;
-               }
-               if (pid != 0)
-                   close(fd);
-           } while (pid != 0);
-       }
-
-       /* child process starts here */
-       setproctitle("connected");
-       close(lfd);
-       dup2(fd, 0);
-       close(fd);
-       dup2(0, 1);
-       dup2(0, 2);
-        if (innconf->timer != 0)
-            TMRinit(TMR_MAX);
-        STATstart = TMRnow_double();
-       SetupDaemon();
-
-       /* if we are a daemon innd didn't make us nice, so be nice kids */
-       if (innconf->nicekids) {
-           if (nice(innconf->nicekids) < 0)
-               syslog(L_ERROR, "Could not nice child to %ld: %m", innconf->nicekids);
-       }
-
-       /* Only automatically reap children in the listening process */
-       xsignal(SIGCHLD, SIG_DFL);
-    } else {
-        if (innconf->timer)
-            TMRinit(TMR_MAX);
-        STATstart = TMRnow_double();
-       SetupDaemon();
-       /* Arrange to toggle tracing. */
-       xsignal(SIGHUP, ToggleTrace);
-    }/* DaemonMode */
-
-#ifdef HAVE_SSL
-    ClientSSL = false;
-    if (initialSSL) {
-        tls_init();
-        if (tls_start_servertls(0, 1) == -1) {
-            Reply("%d SSL connection failed\r\n", NNTP_STARTTLS_BAD_VAL);
-            ExitWithStats(1, false);
-        }
-        nnrpd_starttls_done = 1;
-        ClientSSL = true;
-    }
-#endif /* HAVE_SSL */
-
-    /* If requested, check the load average. */
-    if (innconf->nnrpdloadlimit > 0) {
-        double load[1];
-
-        if (getloadavg(load, 1) < 0)
-            warn("cannot obtain system load");
-        else {
-            if ((int)(load[0] + 0.5) > innconf->nnrpdloadlimit) {
-                syslog(L_NOTICE, "load %.2f > %ld", load[0], innconf->nnrpdloadlimit);
-                Reply("%d load at %.2f, try later\r\n", NNTP_GOODBYE_VAL,
-                      load[0]);
-                ExitWithStats(1, true);
-            }
-        }
-    }
-
-    strlcpy(LogName, "?", sizeof(LogName));
-
-    /* Catch SIGPIPE so that we can exit out of long write loops */
-    xsignal(SIGPIPE, CatchPipe);
-
-    /* Get permissions and see if we can talk to this client */
-    StartConnection();
-    if (!PERMcanread && !PERMcanpost && !PERMneedauth) {
-       syslog(L_NOTICE, "%s no_permission", ClientHost);
-       Printf("%d You have no permission to talk.  Goodbye.\r\n",
-              NNTP_ACCESS_VAL);
-       ExitWithStats(1, false);
-    }
-
-    /* Proceed with initialization. */
-    setproctitle("%s connect", ClientHost);
-
-    /* Were we told to reject connections? */
-    if (Reject) {
-       syslog(L_NOTICE, "%s rejected %s", ClientHost, Reject);
-       Reply("%s %s\r\n", NNTP_GOODBYE, Reject);
-       ExitWithStats(0, false);
-    }
-
-    if (PERMaccessconf) {
-       if (PERMaccessconf->readertrack)
-           PERMaccessconf->readertrack=TrackClient(ClientHost,Username);
-    } else {
-       if (innconf->readertrack)
-           innconf->readertrack=TrackClient(ClientHost,Username);
-    }
-
-    if ((PERMaccessconf && PERMaccessconf->readertrack)
-        || (!PERMaccessconf && innconf->readertrack)) {
-       int len;
-       syslog(L_NOTICE, "%s Tracking Enabled (%s)", ClientHost, Username);
-       pid=getpid();
-       gettimeofday(&tv,NULL);
-       count += pid;
-       vid = tv.tv_sec ^ tv.tv_usec ^ pid ^ count;
-       len = strlen("innconf->pathlog") + strlen("/tracklogs/log-") + BUFSIZ;
-       LocalLogFileName = xmalloc(len);
-       sprintf(LocalLogFileName, "%s/tracklogs/log-%d", innconf->pathlog, vid);
-       if ((locallog = fopen(LocalLogFileName, "w")) == NULL) {
-            LocalLogDirName = concatpath(innconf->pathlog, "tracklogs");
-           MakeDirectory(LocalLogDirName, false);
-           free(LocalLogDirName);
-       }
-       if (locallog == NULL && (locallog = fopen(LocalLogFileName, "w")) == NULL) {
-           syslog(L_ERROR, "%s Local Logging failed (%s) %s: %m", ClientHost, Username, LocalLogFileName);
-       } else {
-           syslog(L_NOTICE, "%s Local Logging begins (%s) %s",ClientHost, Username, LocalLogFileName);
-           fprintf(locallog, "%s Tracking Enabled (%s)\n", ClientHost, Username);
-           fflush(locallog);
-           LLOGenable = true;
-       }
-    }
-
-    if (PERMaccessconf) {
-        Reply("%d %s InterNetNews NNRP server %s ready (%s).\r\n",
-          PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL,
-           PERMaccessconf->pathhost, inn_version_string,
-          PERMcanpost ? "posting ok" : "no posting");
-       clienttimeout = PERMaccessconf->clienttimeout;
-    } else {
-        Reply("%d %s InterNetNews NNRP server %s ready (%s).\r\n",
-          PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL,
-           innconf->pathhost, inn_version_string,
-          PERMcanpost ? "posting ok" : "no posting");
-       clienttimeout = innconf->clienttimeout;
-    }
-
-    line_init(&NNTPline);
-
-    /* Main dispatch loop. */
-    for (timeout = innconf->initialtimeout, av = NULL, ac = 0; ;
-                       timeout = clienttimeout) {
-       TMRstart(TMR_NNTPWRITE);
-       fflush(stdout);
-       TMRstop(TMR_NNTPWRITE);
-       if (ChangeTrace) {
-           Tracing = Tracing ? false : true;
-           syslog(L_TRACE, "trace %sabled", Tracing ? "en" : "dis");
-           ChangeTrace = false;
-       }
-       if (PushedBack) {
-           if (PushedBack[0] == '\0')
-               continue;
-           if (Tracing)
-               syslog(L_TRACE, "%s < %s", ClientHost, PushedBack);
-           ac = Argify(PushedBack, &av);
-           r = RTok;
-       }
-       else {
-           size_t len;
-           const char *p;
-
-           r = line_read(&NNTPline, timeout, &p, &len);
-           switch (r) {
-           default:
-               syslog(L_ERROR, "%s internal %d in main", ClientHost, r);
-               /* FALLTHROUGH */
-           case RTtimeout:
-               if (timeout < clienttimeout)
-                   syslog(L_NOTICE, "%s timeout short", ClientHost);
-               else
-                   syslog(L_NOTICE, "%s timeout", ClientHost);
-               ExitWithStats(1, false);
-               break;
-           case RTok:
-               if (len < sizeof(buff)) {
-                   /* line_read guarantees null termination */
-                   memcpy(buff, p, len + 1);
-                   /* Do some input processing, check for blank line. */
-                   if (Tracing)
-                       syslog(L_TRACE, "%s < %s", ClientHost, buff);
-                   if (buff[0] == '\0')
-                       continue;
-                   ac = Argify(buff, &av);
-                   break;
-               }
-               /* FALLTHROUGH */               
-           case RTlong:
-               Reply("%d Line too long\r\n", NNTP_BAD_COMMAND_VAL);
-               continue;
-           case RTeof:
-               /* Handled below. */
-               break;
-           }
-       }
-       /* Client gone? */
-       if (r == RTeof)
-           break;
-       if (ac == 0 || strcasecmp(av[0], "quit") == 0)
-           break;
-
-       /* Find command. */
-       for (cp = CMDtable; cp->Name; cp++)
-           if (strcasecmp(cp->Name, av[0]) == 0)
-               break;
-       if (cp->Name == NULL) {
-           if ((int)strlen(buff) > 40)
-               syslog(L_NOTICE, "%s unrecognized %.40s...", ClientHost, buff);
-           else
-               syslog(L_NOTICE, "%s unrecognized %s", ClientHost, buff);
-           Reply("%d What?\r\n", NNTP_BAD_COMMAND_VAL);
-           continue;
-       }
-
-       /* Check usage. */
-       if ((cp->Minac != CMDany && ac < cp->Minac)
-        || (cp->Maxac != CMDany && ac > cp->Maxac)) {
-           Reply("%d %s\r\n",
-               NNTP_SYNTAX_VAL,  cp->Help ? cp->Help : "Usage error");
-           continue;
-       }
-
-       /* Check permissions and dispatch. */
-       if (cp->Needauth && PERMneedauth) {
-           Reply("%d Authentication required for command\r\n",
-               NNTP_AUTH_NEEDED_VAL);
-           continue;
-       }
-       setproctitle("%s %s", ClientHost, av[0]);
-       (*cp->Function)(ac, av);
-       if (PushedBack)
-           break;
-       if (PERMaccessconf)
-           clienttimeout = PERMaccessconf->clienttimeout;
-       else
-           clienttimeout = innconf->clienttimeout;
-    }
-
-    Reply("%s\r\n", NNTP_GOODBYE_ACK);
-
-    ExitWithStats(0, false);
-    /* NOTREACHED */
-    return 1;
-}
diff --git a/nnrpd/nnrpd.h b/nnrpd/nnrpd.h
deleted file mode 100644 (file)
index 1679513..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*  $Id: nnrpd.h 7343 2005-06-20 03:23:34Z eagle $
-**
-**  Net News Reading Protocol server.
-*/
-
-#include "config.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-#include "inn/qio.h"
-#include "libinn.h"
-#include "nntp.h"
-#include "paths.h"
-#include "storage.h"
-#include "inn/vector.h"
-#include "inn/timer.h"
-
-/*
-**  Maximum input line length, sigh.
-*/
-#define ART_LINE_LENGTH                1000
-#define ART_LINE_MALLOC                1024
-#define ART_MAX                        1024
-
-
-/*
-**  Some convenient shorthands.
-*/
-typedef struct in_addr INADDR;
-
-
-/*
-**  A range of article numbers.
-*/
-typedef struct _ARTRANGE {
-    int                Low;
-    int                High;
-} ARTRANGE;
-
-/*
-** access configuration for each readers
- */
-typedef struct _ACCESSGROUP {
-    char *name;
-    char *key;
-    char *read;
-    char *post;
-    char *users;
-    char *rejectwith;
-    int allownewnews;
-    bool allowihave;
-    int locpost;
-    int allowapproved;
-    int used;
-    int localtime;
-    int strippath;
-    int nnrpdperlfilter;
-    int nnrpdpythonfilter;
-    char *fromhost;
-    char *pathhost;
-    char *organization;
-    char *moderatormailer;
-    char *domain;
-    char *complaints;
-    int spoolfirst;
-    int checkincludedtext;
-    int clienttimeout;
-    long localmaxartsize;
-    int readertrack;
-    int strippostcc;
-    int addnntppostinghost;
-    int addnntppostingdate;
-    char *nnrpdposthost;
-    int nnrpdpostport;
-    int nnrpdoverstats;
-    int backoff_auth;
-    char *backoff_db;
-    long backoff_k;
-    long backoff_postfast;
-    long backoff_postslow;
-    long backoff_trigger;
-    int nnrpdcheckart;
-    int nnrpdauthsender;
-    int virtualhost;
-    char *newsmaster;
-    long maxbytespersecond;
-} ACCESSGROUP;
-
-/*
-**  What line_read returns.
-*/
-typedef enum _READTYPE {
-    RTeof,
-    RTok,
-    RTlong,
-    RTtimeout
-} READTYPE;
-
-
-/*
-** Structure used by line_read to keep track of what's been read
-*/
-struct line {
-    char *start;
-    char *where;
-    size_t remaining;
-    size_t allocated;
-};
-
-/*
-**  Information about the schema of the news overview files.
-*/
-typedef struct _ARTOVERFIELD {
-    char       *Header;
-    int                Length;
-    bool       NeedsHeader;
-} ARTOVERFIELD;
-
-/*
-**  Supported timers.  If you add new timers to this list, also add them to
-**  the list of tags in nnrpd.c.
-*/
-enum timer {
-    TMR_IDLE = TMR_APPLICATION, /* Server is completely idle. */
-    TMR_NEWNEWS,                /* Executing NEWNEWS command */
-    TMR_READART,                /* Reading an article (SMretrieve) */
-    TMR_CHECKART,               /* Checking an article (ARTinstorebytoken) */
-    TMR_NNTPREAD,               /* Reading from the peer */
-    TMR_NNTPWRITE,              /* Writing to the peer */
-    TMR_MAX
-};
-
-#if    defined(MAINLINE)
-#define EXTERN /* NULL */
-#else
-#define EXTERN extern
-#endif /* defined(MAINLINE) */
-
-EXTERN bool    PERMauthorized;
-EXTERN bool    PERMcanpost;
-EXTERN bool    PERMcanread;
-EXTERN bool    PERMneedauth;
-EXTERN bool    PERMspecified;
-EXTERN ACCESSGROUP     *PERMaccessconf;
-EXTERN bool    Tracing;
-EXTERN bool    Offlinepost;
-EXTERN bool    initialSSL;
-EXTERN char    **PERMreadlist;
-EXTERN char    **PERMpostlist;
-EXTERN char    ClientHost[SMBUF];
-EXTERN char     ServerHost[SMBUF];
-EXTERN char    Username[SMBUF];
-#ifdef HAVE_INET6
-EXTERN char     ClientIpString[INET6_ADDRSTRLEN];
-EXTERN char     ServerIpString[INET6_ADDRSTRLEN];
-#else
-EXTERN char     ClientIpString[20];
-EXTERN char     ServerIpString[20];
-#endif
-EXTERN int     ClientPort;
-EXTERN int     ServerPort;
-EXTERN char    LogName[256] ;
-#ifdef HAVE_SSL
-EXTERN bool    ClientSSL;
-#endif
-extern char    *ACTIVETIMES;
-extern char    *HISTORY;
-extern char    *ACTIVE;
-extern char    *NEWSGROUPS;
-extern char    *NNRPACCESS;
-extern char    NOACCESS[];
-EXTERN int     SPOOLlen;
-EXTERN char    PERMpass[SMBUF];
-EXTERN char    PERMuser[SMBUF];
-EXTERN FILE    *locallog;
-EXTERN int     ARTnumber;      /* Current article number */
-EXTERN int     ARThigh;        /* Current high number for group */
-EXTERN int     ARTlow;         /* Current low number for group */
-EXTERN long    ARTcount;       /* Current number of articles in group */
-EXTERN long    MaxBytesPerSecond; /* maximum bytes per sec a client can use, defaults to 0 */
-EXTERN long    ARTget;
-EXTERN long    ARTgettime;
-EXTERN long    ARTgetsize;
-EXTERN long    OVERcount;      /* number of XOVER commands */
-EXTERN long    OVERhit;        /* number of XOVER records found in .overview */
-EXTERN long    OVERmiss;       /* number of XOVER records found in articles */
-EXTERN long    OVERtime;       /* number of ms spent sending XOVER data */
-EXTERN long    OVERsize;       /* number of bytes of XOVER data sent   */
-EXTERN long    OVERdbz;        /* number of ms spent reading dbz data  */
-EXTERN long    OVERseek;       /* number of ms spent seeking history   */
-EXTERN long    OVERget;        /* number of ms spent reading history   */
-EXTERN long    OVERartcheck;   /* number of ms spent article check     */
-EXTERN double  IDLEtime;
-EXTERN long    GRParticles;
-EXTERN long    GRPcount;
-EXTERN char    *GRPcur;
-EXTERN long    POSTreceived;
-EXTERN long    POSTrejected;
-
-EXTERN bool     BACKOFFenabled;
-EXTERN long     ClientIpAddr;
-EXTERN char    *VirtualPath;
-EXTERN int     VirtualPathlen;
-EXTERN struct history *History;
-EXTERN struct line NNTPline;
-EXTERN struct vector *OVextra;
-EXTERN int     overhdr_xref;
-EXTERN bool    LLOGenable;
-
-extern const char      *ARTpost(char *article, char *idbuff, bool ihave,
-                                bool *permanent);
-extern void            ARTclose(void);
-extern int             TrimSpaces(char *line);
-extern char            *Glom(char **av);
-extern int             Argify(char *line, char ***argvp);
-extern void            InitBackoffConstants(void);
-extern char            *PostRecFilename(char *ip, char *user);
-extern int             LockPostRec(char *path);
-extern int             LockPostRec(char *path);
-extern void            UnlockPostRec(char *path);
-extern int             RateLimit(long *sleeptime, char *path);
-extern void            ExitWithStats(int x, bool readconf);
-extern char            *GetHeader(const char *header);
-extern void            GRPreport(void);
-extern bool            NGgetlist(char ***argvp, char *list);
-extern bool            PERMartok(void);
-extern void            PERMgetaccess(char *nnrpaccess);
-extern void            PERMgetpermissions(void);
-extern void            PERMlogin(char *uname, char *pass, char *errorstr);
-extern bool            PERMmatch(char **Pats, char **list);
-extern bool            ParseDistlist(char ***argvp, char *list);
-extern void            SetDefaultAccess(ACCESSGROUP*);
-extern void            Reply(const char *fmt, ...);
-extern void             Printf(const char *fmt, ...);
-
-extern void            CMDauthinfo  (int ac, char** av);
-extern void            CMDdate      (int ac, char** av);
-extern void            CMDfetch     (int ac, char** av);
-extern void            CMDgroup     (int ac, char** av);
-extern void            CMDhelp      (int ac, char** av);
-extern void            CMDlist      (int ac, char** av);
-extern void            CMDmode      (int ac, char** av);
-extern void            CMDnewgroups (int ac, char** av);
-extern void            CMDnewnews   (int ac, char** av);
-extern void            CMDnextlast  (int ac, char** av);
-extern void            CMDpost      (int ac, char** av);
-extern void            CMDxgtitle   (int ac, char** av);
-extern void            CMDxover     (int ac, char** av);
-extern void            CMDpat       (int ac, char** av);
-extern void            CMDxpath     (int ac, char** av);
-extern void            CMD_unimp    (int ac, char** av);
-#ifdef HAVE_SSL
-extern void            CMDstarttls  (int ac, char** av);
-#endif
-
-
-
-extern char *HandleHeaders(char *article);
-extern bool ARTinstorebytoken(TOKEN token);
-
-extern int TrackClient(char *client, char* user);
-
-#ifdef  DO_PERL
-extern void loadPerl(void);
-extern void perlAccess(char *user, struct vector *access_vec);
-extern int perlAuthenticate(char *user, char *passwd, char *errorstring, char*newUser);
-extern void perlAuthInit(void);
-#endif /* DO_PERL */
-
-#ifdef DO_PYTHON
-extern bool PY_use_dynamic;
-
-int PY_authenticate(char *path, char *Username, char *Password, char *errorstring, char *newUser);
-void PY_access(char* path, struct vector *access_vec, char *Username);
-int PY_dynamic(char *Username, char *NewsGroup, int PostFlag, char **reply_message);
-void PY_dynamic_init (char* file);
-#endif /* DO_PYTHON */
-
-void line_free(struct line *);
-void line_init(struct line *);
-READTYPE line_read(struct line *, int, const char **, size_t *);
diff --git a/nnrpd/perl.c b/nnrpd/perl.c
deleted file mode 100644 (file)
index 2d967dc..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/*  $Id: perl.c 7815 2008-05-05 08:43:58Z iulius $
-**
-**  Embedded Perl support for INN.
-**
-**  Originally written by Christophe Wolfhugel <wolf@pasteur.fr> (although
-**  he wouldn't recongize it any more, so don't blame him) and modified,
-**  expanded, and tweaked by James Brister, Dave Hayes, Andrew Gierth, and
-**  Russ Allbery among others.
-**
-**  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.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "paths.h"
-#include "post.h"
-
-#include "nntp.h"
-
-/* Skip this entire file if DO_PERL (./configure --with-perl) isn't set. */
-#ifdef DO_PERL
-
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-#include "ppport.h"
-
-#include "innperl.h"
-
-extern HEADER  Table[], *EndOfTable;
-extern char LogName[];
-extern char PERMuser[];
-
-extern char **OtherHeaders;
-extern int OtherCount;
-extern bool HeadersModified;
-
-extern bool PerlLoaded;
-
-/* #define DEBUG_MODIFY only if you want to see verbose outout */
-#ifdef DEBUG_MODIFY
-static FILE *flog;
-void dumpTable(char *msg);
-#endif /* DEBUG_MODIFY */
-
-char *HandleHeaders(char *article)
-{
-   dSP;
-   HEADER      *hp;
-   HV          *hdr;
-   SV           *body;
-   int         rc;
-   char                *p, *q;
-   static char buf[256];
-   int   i;
-   char *s,*t;
-   HE            *scan;
-   SV            *modswitch;
-   int            OtherSize;
-   char *argv[] = { NULL };
-
-   if(!PerlLoaded) {
-       loadPerl();
-   }
-
-   if (!PerlFilterActive)
-       return NULL; /* not really necessary */
-
-#ifdef DEBUG_MODIFY
-   if ((flog = fopen("/var/news/log/nnrpdperlerrror","a+")) == NULL) {
-     syslog(L_ERROR,"Whoops. Can't open error log: %m");
-   }
-#endif /* DEBUG_MODIFY */
-   
-   ENTER ;
-   SAVETMPS ;
-   
-   /* Create the Perl Hash */
-   hdr = perl_get_hv("hdr", true);
-   for (hp = Table; hp < EndOfTable; hp++) {
-      if (hp->Body)
-         hv_store(hdr, (char *) hp->Name, strlen(hp->Name), newSVpv(hp->Body, 0), 0);
-   }
-   
-   /* Also store other headers */
-   OtherSize = OtherCount;
-   for (i = 0; i < OtherCount; i++) {
-       p = OtherHeaders[i];
-        if (p == NULL) {
-          syslog (L_ERROR,"Null header number %d copying headers for Perl",i);
-          continue;
-        }
-        s = strchr(p,':');
-        if (s == NULL) {
-          syslog (L_ERROR,"Bad header copying headers for Perl: '%s'",p);
-          continue;
-        }
-        s++;
-        t = (*s == ' ' ? s + 1 : s);
-        hv_store(hdr, p, (s - p) - 1, newSVpv(t, 0), 0);
-   }
-   /* Store user */
-   sv_setpv(perl_get_sv("user",true), PERMuser);
-   
-   /* Store body */
-   body = perl_get_sv("body", true);
-   sv_setpv(body, article);
-
-   /* Call the filtering function */
-   rc = perl_call_argv("filter_post", G_EVAL|G_SCALAR, argv);
-
-   SPAGAIN;
-
-   /* Restore headers */
-   modswitch = perl_get_sv("modify_headers",false);
-   HeadersModified = false;
-   if (SvTRUE(modswitch)) {
-     HeadersModified = true;
-     i = 0;
-
-#ifdef DEBUG_MODIFY     
-     dumpTable("Before mod");
-#endif /* DEBUG_MODIFY */
-
-     hv_iterinit(hdr);
-     while ((scan = hv_iternext(hdr)) != NULL) {
-       /* Get the values */
-       p = HePV(scan, PL_na);  
-       s = SvPV(HeVAL(scan), PL_na);
-#ifdef DEBUG_MODIFY     
-       fprintf(flog,"Hash iter: '%s','%s'\n",p,s);
-#endif /* DEBUG_MODIFY */
-
-       /* See if it's a table header */
-       for (hp = Table; hp < EndOfTable; hp++) {
-         if (strncasecmp(p, hp->Name, hp->Size) == 0) {
-           char *copy = xstrdup(s);
-           HDR_SET(hp - Table, copy);
-           hp->Len = TrimSpaces(hp->Value);
-           for (q = hp->Value ; ISWHITE(*q) || *q == '\n' ; q++)
-             continue;
-           hp->Body = q;
-           if (hp->Len == 0) {
-             free(hp->Value);
-             hp->Value = hp->Body = NULL;
-           }
-           break;
-         }
-       }
-       if (hp != EndOfTable) continue;
-       
-       /* Add to other headers */
-       if (i >= OtherSize - 1) {
-         OtherSize += 20;
-         OtherHeaders = xrealloc(OtherHeaders, OtherSize * sizeof(char *));
-       }
-       t = concat(p, ": ", s, (char *) 0);
-       OtherHeaders[i++] = t;
-     }
-     OtherCount = i;
-#ifdef DEBUG_MODIFY
-     dumpTable("After Mod");
-#endif /* DEBUG_MODIFY */
-   }
-
-   hv_undef (hdr);
-   sv_setsv (body, &PL_sv_undef);
-
-   buf [0] = '\0' ;
-   
-   if (SvTRUE(ERRSV))     /* check $@ */ {
-       syslog (L_ERROR,"Perl function filter_post died: %s",
-               SvPV(ERRSV, PL_na)) ;
-       (void)POPs ;
-       PerlFilter (false) ;
-   } else if (rc == 1) {
-       p = POPp;
-       if (p != NULL && *p != '\0')
-           strlcpy(buf, p, sizeof(buf));
-   }
-
-   FREETMPS ;
-   LEAVE ;
-   
-   if (buf[0] != '\0') 
-      return buf ;
-   return NULL;
-}
-
-void loadPerl(void) {
-    char *path;
-
-    path = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_NNRPD);
-    PERLsetup(NULL, path, "filter_post");
-    free(path);
-    PerlFilter(true);
-    PerlLoaded = true;
-}
-
-void perlAccess(char *user, struct vector *access_vec) {
-  dSP;
-  HV              *attribs;
-  SV              *sv;
-  int             rc, i;
-  char            *key, *val, *buffer;
-
-  if (!PerlFilterActive)
-    return;
-
-  ENTER;
-  SAVETMPS;
-
-  attribs = perl_get_hv("attributes", true);
-  hv_store(attribs, "hostname", 8, newSVpv(ClientHost, 0), 0);
-  hv_store(attribs, "ipaddress", 9, newSVpv(ClientIpString, 0), 0);
-  hv_store(attribs, "port", 4, newSViv(ClientPort), 0);
-  hv_store(attribs, "interface", 9, newSVpv(ServerHost, 0), 0);
-  hv_store(attribs, "intipaddr", 9, newSVpv(ServerIpString, 0), 0);
-  hv_store(attribs, "intport", 7, newSViv(ServerPort), 0);
-  hv_store(attribs, "username", 8, newSVpv(user, 0), 0);
-
-  PUSHMARK(SP);
-
-  if (perl_get_cv("access", 0) == NULL) {
-    syslog(L_ERROR, "Perl function access not defined");
-    Reply("%d Internal Error (3).  Goodbye\r\n", NNTP_ACCESS_VAL);
-    ExitWithStats(1, true);
-  }
-
-  rc = perl_call_pv("access", G_EVAL|G_ARRAY);
-
-  SPAGAIN;
-
-  if (rc == 0 ) { /* Error occured, same as checking $@ */
-    syslog(L_ERROR, "Perl function access died: %s",
-           SvPV(ERRSV, PL_na));
-    Reply("%d Internal Error (1).  Goodbye\r\n", NNTP_ACCESS_VAL);
-    ExitWithStats(1, true);
-  }
-
-  if ((rc % 2) != 0) {
-    syslog(L_ERROR, "Perl function access returned an odd number of arguments: %i", rc);
-    Reply("%d Internal Error (2).  Goodbye\r\n", NNTP_ACCESS_VAL);
-    ExitWithStats(1, true);
-  }
-
-  vector_resize(access_vec, (rc / 2));
-
-  buffer = xmalloc(BIG_BUFFER);
-
-  for (i = (rc / 2); i >= 1; i--) {
-    sv = POPs;
-    val = SvPV(sv, PL_na);
-    sv = POPs;
-    key = SvPV(sv, PL_na);
-
-    strlcpy(buffer, key, BIG_BUFFER);
-    strlcat(buffer, ": \"", BIG_BUFFER);
-    strlcat(buffer, val, BIG_BUFFER);
-    strlcat(buffer, "\"\n", BIG_BUFFER);
-    vector_add(access_vec, xstrdup(buffer));
-  }
-
-  free(buffer);
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-
-}
-
-void perlAuthInit(void) {
-    dSP;
-    int             rc;
-    
-    if (!PerlFilterActive)
-       return;
-
-    ENTER;
-    SAVETMPS;
-    PUSHMARK(SP);
-    
-    if (perl_get_cv("auth_init", 0) == NULL) {
-      syslog(L_ERROR, "Perl function auth_init not defined");
-      Reply("%d Internal Error (3).  Goodbye\r\n", NNTP_ACCESS_VAL);
-      ExitWithStats(1, true);
-    }
-
-    rc = perl_call_pv("auth_init", G_EVAL|G_DISCARD);
-
-    SPAGAIN;
-
-
-    if (SvTRUE(ERRSV))     /* check $@ */ {
-       syslog(L_ERROR, "Perl function authenticate died: %s",
-              SvPV(ERRSV, PL_na));
-       Reply("%d Internal Error (1).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    }
-
-    while (rc--) {
-       (void)POPs;
-    }
-
-    PUTBACK;
-    FREETMPS;
-    LEAVE;
-    
-}
-
-int perlAuthenticate(char *user, char *passwd, char *errorstring, char *newUser) {
-    dSP;
-    HV              *attribs;
-    int             rc;
-    char            *p;
-    int             code;
-    
-    if (!PerlFilterActive)
-        return NNTP_ACCESS_VAL;
-
-    if (perl_get_cv("authenticate", 0) == NULL) {
-        syslog(L_ERROR, "Perl function authenticate not defined");
-        Reply("%d Internal Error (3).  Goodbye\r\n", NNTP_ACCESS_VAL);
-        ExitWithStats(1, true);
-    }
-
-    ENTER;
-    SAVETMPS;
-    attribs = perl_get_hv("attributes", true);
-    hv_store(attribs, "hostname", 8, newSVpv(ClientHost, 0), 0);
-    hv_store(attribs, "ipaddress", 9, newSVpv(ClientIpString, 0), 0);
-    hv_store(attribs, "port", 4, newSViv(ClientPort), 0);
-    hv_store(attribs, "interface", 9, newSVpv(ServerHost, 0), 0);
-    hv_store(attribs, "intipaddr", 9, newSVpv(ServerIpString, 0), 0);
-    hv_store(attribs, "intport", 7, newSViv(ServerPort), 0);
-    hv_store(attribs, "username", 8, newSVpv(user, 0), 0);
-    hv_store(attribs, "password", 8, newSVpv(passwd, 0), 0);
-    
-    PUSHMARK(SP);
-    rc = perl_call_pv("authenticate", G_EVAL|G_ARRAY);
-
-    SPAGAIN;
-
-    if (rc == 0 ) { /* Error occured, same as checking $@ */
-       syslog(L_ERROR, "Perl function authenticate died: %s",
-              SvPV(ERRSV, PL_na));
-       Reply("%d Internal Error (1).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, false);
-    }
-
-    if ((rc != 3) && (rc != 2)) {
-       syslog(L_ERROR, "Perl function authenticate returned wrong number of results: %d", rc);
-       Reply("%d Internal Error (2).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, false);
-    }
-
-    if (rc == 3) {
-      p = POPp;
-      strcpy(newUser, p);
-    } 
-
-    p = POPp;
-    strcpy(errorstring, p);
-
-    code = POPi;
-
-    if ((code == NNTP_POSTOK_VAL) || (code == NNTP_NOPOSTOK_VAL))
-       code = PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL;
-
-    if (code == NNTP_AUTH_NEEDED_VAL) 
-       PERMneedauth = true;
-
-    hv_undef(attribs);
-
-    PUTBACK;
-    FREETMPS;
-    LEAVE;
-    
-    return code;
-}
-
-#ifdef DEBUG_MODIFY
-void
-dumpTable (msg)
-char *msg;
-{
-      HEADER        *hp;
-      int   i;
-
-      fprintf(flog,"===BEGIN TABLE DUMP: %s\n",msg);
-      
-      for (hp = Table; hp < EndOfTable; hp++) {
-        fprintf(flog," Name: '%s'",hp->Name); fflush(flog);
-        fprintf(flog," Size: '%d'",hp->Size); fflush(flog);
-        fprintf(flog," Value: '%s'\n",((hp->Value == NULL) ? "(NULL)" : hp->Value)); fflush(flog);
-      }
-
-      for (i=0; i<OtherCount; i++) {
-        fprintf(flog,"Extra[%02d]: %s\n",i,OtherHeaders[i]);
-      }
-      fprintf(flog,"===END TABLE DUMP: %s\n",msg);
-}
-#endif /* DEBUG_MODIFY */
-
-#endif /* DO_PERL */
diff --git a/nnrpd/perm.c b/nnrpd/perm.c
deleted file mode 100644 (file)
index 50a04cc..0000000
+++ /dev/null
@@ -1,2362 +0,0 @@
-/*  $Id: perm.c 7426 2005-12-11 20:37:27Z eagle $
-**
-**  How to figure out where a user comes from, and what that user can do once
-**  we know who sie is.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-#include <netdb.h>
-#include <signal.h>
-
-#include "conffile.h"
-#include "inn/innconf.h"
-#include "innperl.h"
-#include "nnrpd.h"
-
-/* Needed on AIX 4.1 to get fd_set and friends. */
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-/* data types */
-typedef struct _CONFCHAIN {
-    CONFFILE *f;
-    struct _CONFCHAIN *parent;
-} CONFCHAIN;
-
-typedef struct _METHOD {
-    char *name;
-    char *program;
-    int  type;          /* type of auth (perl, python or external) */
-    char *users;       /* only used for auth_methods, not for res_methods. */
-    char **extra_headers;
-    char **extra_logs;
-} METHOD;
-
-typedef struct _AUTHGROUP {
-    char *name;
-    char *key;
-#ifdef HAVE_SSL
-    int require_ssl;
-#endif
-    char *hosts;
-    METHOD **res_methods;
-    METHOD **auth_methods;
-    char *default_user;
-    char *default_domain;
-    char *localaddress;
-    char *access_script;
-    int  access_type; /* type of access (perl or python) */
-    char *dynamic_script;
-    int  dynamic_type; /* type of dynamic authorization (python only) */
-} AUTHGROUP;
-
-typedef struct _GROUP {
-    char *name;
-    struct _GROUP *above;
-    AUTHGROUP *auth;
-    ACCESSGROUP *access;
-} GROUP;
-
-/* function declarations */
-static void PERMreadfile(char *filename);
-static void authdecl_parse(AUTHGROUP*, CONFFILE*, CONFTOKEN*);
-static void accessdecl_parse(ACCESSGROUP *curaccess, CONFFILE *f, CONFTOKEN *tok);
-static void method_parse(METHOD*, CONFFILE*, CONFTOKEN*, int);
-
-static void add_authgroup(AUTHGROUP*);
-static void add_accessgroup(ACCESSGROUP*);
-static void strip_accessgroups(void);
-
-static METHOD *copy_method(METHOD*);
-static void free_method(METHOD*);
-static AUTHGROUP *copy_authgroup(AUTHGROUP*);
-static void free_authgroup(AUTHGROUP*);
-static ACCESSGROUP *copy_accessgroup(ACCESSGROUP*);
-static void free_accessgroup(ACCESSGROUP*);
-
-static void CompressList(char*);
-static bool MatchHost(char*, char*, char*);
-static int MatchUser(char*, char*);
-static char *ResolveUser(AUTHGROUP*);
-static char *AuthenticateUser(AUTHGROUP*, char*, char*, char*);
-
-static void GrowArray(void***, void*);
-static void PERMvectortoaccess(ACCESSGROUP *acc, const char *name, struct vector *acccess_vec);
-
-/* global variables */
-static AUTHGROUP **auth_realms;
-static AUTHGROUP *success_auth;
-static ACCESSGROUP **access_realms;
-
-static char    *ConfigBit;
-static int     ConfigBitsize;
-
-extern bool PerlLoaded;
-
-#define PERMlbrace             1
-#define PERMrbrace             2
-#define PERMgroup              3
-#define PERMauth               4
-#define PERMaccess             5
-#define PERMhost               6
-#define PERMauthprog           7
-#define PERMresolv             8
-#define PERMresprog            9
-#define PERMdefuser            10
-#define PERMdefdomain          11
-#define PERMusers              12
-#define PERMnewsgroups         13
-#define PERMread               14
-#define PERMpost               15
-#define PERMaccessrp           16
-#define PERMheader             17
-#define PERMalsolog            18
-#define PERMprogram            19
-#define PERMinclude            20
-#define PERMkey                        21
-#define PERMlocaltime          22
-#define PERMstrippath          23
-#define PERMnnrpdperlfilter    24
-#define PERMnnrpdpythonfilter  25
-#define PERMfromhost           26
-#define PERMpathhost           27
-#define PERMorganization       28
-#define PERMmoderatormailer    29
-#define PERMdomain             30
-#define PERMcomplaints         31
-#define PERMspoolfirst         32
-#define PERMcheckincludedtext  33
-#define PERMclienttimeout      34
-#define PERMlocalmaxartsize    35
-#define PERMreadertrack                36
-#define PERMstrippostcc                37
-#define PERMaddnntppostinghost 38
-#define PERMaddnntppostingdate 39
-#define PERMnnrpdposthost      40
-#define PERMnnrpdpostport      41
-#define PERMnnrpdoverstats     42
-#define PERMbackoff_auth       43
-#define PERMbackoff_db         44
-#define PERMbackoff_k          45
-#define PERMbackoff_postfast   46
-#define PERMbackoff_postslow   47
-#define PERMbackoff_trigger    48
-#define PERMnnrpdcheckart      49
-#define PERMnnrpdauthsender    50
-#define PERMvirtualhost                51
-#define PERMnewsmaster         52
-#define PERMlocaladdress       53
-#define PERMrejectwith         54
-#define PERMmaxbytespersecond  55
-#define PERMperl_auth           56
-#define PERMpython_auth         57
-#define PERMperl_access         58
-#define PERMpython_access       59
-#define PERMpython_dynamic      60
-#ifdef HAVE_SSL
-#define PERMrequire_ssl                61
-#define PERMMAX                        62
-#else
-#define PERMMAX                        61
-#endif
-
-#define TEST_CONFIG(a, b) \
-    { \
-       int byte, offset; \
-       offset = a % 8; \
-       byte = (a - offset) / 8; \
-       b = ((ConfigBit[byte] & (1 << offset)) != 0) ? true : false; \
-    }
-#define SET_CONFIG(a) \
-    { \
-       int byte, offset; \
-       offset = a % 8; \
-       byte = (a - offset) / 8; \
-       ConfigBit[byte] |= (1 << offset); \
-    }
-#define CLEAR_CONFIG(a) \
-    { \
-       int byte, offset; \
-       offset = a % 8; \
-       byte = (a - offset) / 8; \
-       ConfigBit[byte] &= ~(1 << offset); \
-    }
-
-static CONFTOKEN PERMtoks[] = {
-  { PERMlbrace, "{" },
-  { PERMrbrace, "}" },
-  { PERMgroup, "group" },
-  { PERMauth, "auth" },
-  { PERMaccess, "access" },
-  { PERMhost, "hosts:" },
-  { PERMauthprog, "auth:" },
-  { PERMresolv, "res" },
-  { PERMresprog, "res:" },
-  { PERMdefuser, "default:" },
-  { PERMdefdomain, "default-domain:" },
-  { PERMusers, "users:" },
-  { PERMnewsgroups, "newsgroups:" },
-  { PERMread, "read:" },
-  { PERMpost, "post:" },
-  { PERMaccessrp, "access:" },
-  { PERMheader, "header:" },
-  { PERMalsolog, "log:" },
-  { PERMprogram, "program:" },
-  { PERMinclude, "include" },
-  { PERMkey, "key:" },
-  { PERMlocaltime, "localtime:" },
-  { PERMstrippath, "strippath:" },
-  { PERMnnrpdperlfilter, "perlfilter:" },
-  { PERMnnrpdpythonfilter, "pythonfilter:" },
-  { PERMfromhost, "fromhost:" },
-  { PERMpathhost, "pathhost:" },
-  { PERMorganization, "organization:" },
-  { PERMmoderatormailer, "moderatormailer:" },
-  { PERMdomain, "domain:" },
-  { PERMcomplaints, "complaints:" },
-  { PERMspoolfirst, "spoolfirst:" },
-  { PERMcheckincludedtext, "checkincludedtext:" },
-  { PERMclienttimeout, "clienttimeout:" },
-  { PERMlocalmaxartsize, "localmaxartsize:" },
-  { PERMreadertrack, "readertrack:" },
-  { PERMstrippostcc, "strippostcc:" },
-  { PERMaddnntppostinghost, "addnntppostinghost:" },
-  { PERMaddnntppostingdate, "addnntppostingdate:" },
-  { PERMnnrpdposthost, "nnrpdposthost:" },
-  { PERMnnrpdpostport, "nnrpdpostport:" },
-  { PERMnnrpdoverstats, "nnrpdoverstats:" },
-  { PERMbackoff_auth, "backoff_auth:" },
-  { PERMbackoff_db, "backoff_db:" },
-  { PERMbackoff_k, "backoff_k:" },
-  { PERMbackoff_postfast, "backoff_postfast:" },
-  { PERMbackoff_postslow, "backoff_postslow:" },
-  { PERMbackoff_trigger, "backoff_trigger:" },
-  { PERMnnrpdcheckart, "nnrpdcheckart:" },
-  { PERMnnrpdauthsender, "nnrpdauthsender:" },
-  { PERMvirtualhost, "virtualhost:" },
-  { PERMnewsmaster, "newsmaster:" },
-  { PERMlocaladdress, "localaddress:" },
-  { PERMrejectwith, "reject_with:" },
-  { PERMmaxbytespersecond, "max_rate:" },
-  { PERMperl_auth, "perl_auth:" },
-  { PERMpython_auth, "python_auth:" },
-  { PERMperl_access, "perl_access:" },
-  { PERMpython_access, "python_access:" },
-  { PERMpython_dynamic, "python_dynamic:" },
-#ifdef HAVE_SSL
-  { PERMrequire_ssl, "require_ssl:" },
-#endif
-  { 0, 0 }
-};
-
-/* function definitions */
-static void GrowArray(void ***array, void *el)
-{
-    int i;
-
-    if (!*array) {
-       *array = xmalloc(2 * sizeof(void *));
-       i = 0;
-    } else {
-       for (i = 0; (*array)[i]; i++)
-           ;
-       *array = xrealloc(*array, (i + 2) * sizeof(void *));
-    }
-    (*array)[i++] = el;
-    (*array)[i] = 0;
-}
-
-static METHOD *copy_method(METHOD *orig)
-{
-    METHOD *ret;
-    int i;
-
-    ret = xmalloc(sizeof(METHOD));
-    memset(ConfigBit, '\0', ConfigBitsize);
-
-    ret->name = xstrdup(orig->name);
-    ret->program = xstrdup(orig->program);
-    if (orig->users)
-       ret->users = xstrdup(orig->users);
-    else
-       ret->users = 0;
-
-    ret->extra_headers = 0;
-    if (orig->extra_headers) {
-       for (i = 0; orig->extra_headers[i]; i++)
-           GrowArray((void***) &ret->extra_headers,
-             (void*) xstrdup(orig->extra_headers[i]));
-    }
-
-    ret->extra_logs = 0;
-    if (orig->extra_logs) {
-       for (i = 0; orig->extra_logs[i]; i++)
-           GrowArray((void***) &ret->extra_logs,
-             (void*) xstrdup(orig->extra_logs[i]));
-    }
-
-    ret->type = orig->type;
-
-    return(ret);
-}
-
-static void free_method(METHOD *del)
-{
-    int j;
-
-    if (del->extra_headers) {
-       for (j = 0; del->extra_headers[j]; j++)
-           free(del->extra_headers[j]);
-       free(del->extra_headers);
-    }
-    if (del->extra_logs) {
-       for (j = 0; del->extra_logs[j]; j++)
-           free(del->extra_logs[j]);
-       free(del->extra_logs);
-    }
-    if (del->program)
-       free(del->program);
-    if (del->users)
-       free(del->users);
-    free(del->name);
-    free(del);
-}
-
-static AUTHGROUP *copy_authgroup(AUTHGROUP *orig)
-{
-    AUTHGROUP *ret;
-    int i;
-
-    if (!orig)
-       return(0);
-    ret = xmalloc(sizeof(AUTHGROUP));
-    memset(ConfigBit, '\0', ConfigBitsize);
-
-    if (orig->name)
-       ret->name = xstrdup(orig->name);
-    else
-       ret->name = 0;
-
-    if (orig->key)
-       ret->key = xstrdup(orig->key);
-    else
-       ret->key = 0;
-
-    if (orig->hosts)
-       ret->hosts = xstrdup(orig->hosts);
-    else
-       ret->hosts = 0;
-
-#ifdef HAVE_SSL
-    ret->require_ssl = orig->require_ssl;
-#endif
-
-    ret->res_methods = 0;
-    if (orig->res_methods) {
-       for (i = 0; orig->res_methods[i]; i++)
-           GrowArray((void***) &ret->res_methods,
-             (void*) copy_method(orig->res_methods[i]));;
-    }
-
-    ret->auth_methods = 0;
-    if (orig->auth_methods) {
-       for (i = 0; orig->auth_methods[i]; i++)
-           GrowArray((void***) &ret->auth_methods,
-             (void*) copy_method(orig->auth_methods[i]));
-    }
-
-    if (orig->default_user)
-       ret->default_user = xstrdup(orig->default_user);
-    else
-       ret->default_user = 0;
-
-    if (orig->default_domain)
-       ret->default_domain = xstrdup(orig->default_domain);
-    else
-       ret->default_domain = 0;
-
-    if (orig->localaddress)
-       ret->localaddress = xstrdup(orig->localaddress);
-    else
-       ret->localaddress = 0;
-
-    if (orig->access_script)
-        ret->access_script = xstrdup(orig->access_script);
-    else
-        ret->access_script = 0;
-
-    if (orig->access_type)
-        ret->access_type = orig->access_type;
-    else
-        ret->access_type = 0;
-
-    if (orig->dynamic_script)
-        ret->dynamic_script = xstrdup(orig->dynamic_script);
-    else
-        ret->dynamic_script = 0;
-
-    if (orig->dynamic_type)
-        ret->dynamic_type = orig->dynamic_type;
-    else
-        ret->dynamic_type = 0;
-
-    return(ret);
-}
-
-static ACCESSGROUP *copy_accessgroup(ACCESSGROUP *orig)
-{
-    ACCESSGROUP *ret;
-
-    if (!orig)
-       return(0);
-    ret = xmalloc(sizeof(ACCESSGROUP));
-    memset(ConfigBit, '\0', ConfigBitsize);
-    /* copy all anyway, and update for local strings */
-    *ret = *orig;
-
-    if (orig->name)
-       ret->name = xstrdup(orig->name);
-    if (orig->key)
-       ret->key = xstrdup(orig->key);
-    if (orig->read)
-       ret->read = xstrdup(orig->read);
-    if (orig->post)
-       ret->post = xstrdup(orig->post);
-    if (orig->users)
-       ret->users = xstrdup(orig->users);
-    if (orig->rejectwith)
-       ret->rejectwith = xstrdup(orig->rejectwith);
-    if (orig->fromhost)
-       ret->fromhost = xstrdup(orig->fromhost);
-    if (orig->pathhost)
-       ret->pathhost = xstrdup(orig->pathhost);
-    if (orig->organization)
-       ret->organization = xstrdup(orig->organization);
-    if (orig->moderatormailer)
-       ret->moderatormailer = xstrdup(orig->moderatormailer);
-    if (orig->domain)
-       ret->domain = xstrdup(orig->domain);
-    if (orig->complaints)
-       ret->complaints = xstrdup(orig->complaints);
-    if (orig->nnrpdposthost)
-       ret->nnrpdposthost = xstrdup(orig->nnrpdposthost);
-    if (orig->backoff_db)
-       ret->backoff_db = xstrdup(orig->backoff_db);
-    if (orig->newsmaster)
-       ret->newsmaster = xstrdup(orig->newsmaster);
-    return(ret);
-}
-
-static void SetDefaultAuth(AUTHGROUP *curauth UNUSED)
-{
-#ifdef HAVE_SSL
-        curauth->require_ssl = false;
-#endif
-}
-
-void SetDefaultAccess(ACCESSGROUP *curaccess)
-{
-    curaccess->allownewnews = innconf->allownewnews;;
-    curaccess->allowihave = false;
-    curaccess->locpost = false;
-    curaccess->allowapproved = false;
-    curaccess->localtime = false;
-    curaccess->strippath = false;
-    curaccess->nnrpdperlfilter = true;
-    curaccess->nnrpdpythonfilter = true;
-    curaccess->fromhost = NULL;
-    if (innconf->fromhost)
-       curaccess->fromhost = xstrdup(innconf->fromhost);
-    curaccess->pathhost = NULL;
-    if (innconf->pathhost)
-       curaccess->pathhost = xstrdup(innconf->pathhost);
-    curaccess->organization = NULL;
-    if (innconf->organization)
-       curaccess->organization = xstrdup(innconf->organization);
-    curaccess->moderatormailer = NULL;
-    if (innconf->moderatormailer)
-       curaccess->moderatormailer = xstrdup(innconf->moderatormailer);
-    curaccess->domain = NULL;
-    if (innconf->domain)
-       curaccess->domain = xstrdup(innconf->domain);
-    curaccess->complaints = NULL;
-    if (innconf->complaints)
-       curaccess->complaints = xstrdup(innconf->complaints);
-    curaccess->spoolfirst = innconf->spoolfirst;
-    curaccess->checkincludedtext = innconf->checkincludedtext;
-    curaccess->clienttimeout = innconf->clienttimeout;
-    curaccess->localmaxartsize = innconf->localmaxartsize;
-    curaccess->readertrack = innconf->readertrack;
-    curaccess->strippostcc = innconf->strippostcc;
-    curaccess->addnntppostinghost = innconf->addnntppostinghost;
-    curaccess->addnntppostingdate = innconf->addnntppostingdate;
-    curaccess->nnrpdposthost = innconf->nnrpdposthost;
-    curaccess->nnrpdpostport = innconf->nnrpdpostport;
-    curaccess->nnrpdoverstats = innconf->nnrpdoverstats;
-    curaccess->backoff_auth = innconf->backoffauth;
-    curaccess->backoff_db = NULL;
-    if (innconf->backoffdb && *innconf->backoffdb != '\0')
-       curaccess->backoff_db = xstrdup(innconf->backoffdb);
-    curaccess->backoff_k = innconf->backoffk;
-    curaccess->backoff_postfast = innconf->backoffpostfast;
-    curaccess->backoff_postslow = innconf->backoffpostslow;
-    curaccess->backoff_trigger = innconf->backofftrigger;
-    curaccess->nnrpdcheckart = innconf->nnrpdcheckart;
-    curaccess->nnrpdauthsender = innconf->nnrpdauthsender;
-    curaccess->virtualhost = false;
-    curaccess->newsmaster = NULL;
-    curaccess->maxbytespersecond = 0;
-}
-
-static void free_authgroup(AUTHGROUP *del)
-{
-    int i;
-
-    if (del->name)
-       free(del->name);
-    if (del->key)
-       free(del->key);
-    if (del->hosts)
-       free(del->hosts);
-    if (del->res_methods) {
-       for (i = 0; del->res_methods[i]; i++)
-           free_method(del->res_methods[i]);
-       free(del->res_methods);
-    }
-    if (del->auth_methods) {
-       for (i = 0; del->auth_methods[i]; i++)
-           free_method(del->auth_methods[i]);
-       free(del->auth_methods);
-    }
-    if (del->default_user)
-       free(del->default_user);
-    if (del->default_domain)
-       free(del->default_domain);
-    if (del->localaddress)
-       free(del->localaddress);
-    if (del->access_script)
-        free(del->access_script);
-    if (del->dynamic_script)
-        free(del->dynamic_script);
-    free(del);
-}
-
-static void free_accessgroup(ACCESSGROUP *del)
-{
-    if (del->name)
-       free(del->name);
-    if (del->key)
-       free(del->key);
-    if (del->read)
-       free(del->read);
-    if (del->post)
-       free(del->post);
-    if (del->users)
-       free(del->users);
-    if (del->rejectwith)
-       free(del->rejectwith);
-    if (del->fromhost)
-       free(del->fromhost);
-    if (del->pathhost)
-       free(del->pathhost);
-    if (del->organization)
-       free(del->organization);
-    if (del->moderatormailer)
-       free(del->moderatormailer);
-    if (del->domain)
-       free(del->domain);
-    if (del->complaints)
-       free(del->complaints);
-    if (del->nnrpdposthost)
-       free(del->nnrpdposthost);
-    if (del->backoff_db)
-       free(del->backoff_db);
-    if (del->newsmaster)
-       free(del->newsmaster);
-    free(del);
-}
-
-static void ReportError(CONFFILE *f, const char *err)
-{
-    syslog(L_ERROR, "%s syntax error in %s(%d), %s", ClientHost,
-      f->filename, f->lineno, err);
-    Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-    ExitWithStats(1, true);
-}
-
-static void method_parse(METHOD *method, CONFFILE *f, CONFTOKEN *tok, int auth)
-{
-    int oldtype;
-
-    oldtype = tok->type;
-    tok = CONFgettoken(0, f);
-
-    if (tok == NULL) {
-       ReportError(f, "Expected value.");
-    }
-
-    switch (oldtype) {
-      case PERMheader:
-       GrowArray((void***) &method->extra_headers, (void*) xstrdup(tok->name));
-       break;
-      case PERMalsolog:
-       GrowArray((void***) &method->extra_logs, (void*) xstrdup(tok->name));
-       break;
-      case PERMusers:
-
-       if (!auth) {
-           ReportError(f, "Unexpected users: directive in file.");
-       } else if (method->users) {
-           ReportError(f, "Multiple users: directive in file.");
-       }
-
-       method->users = xstrdup(tok->name);
-       break;
-      case PERMprogram:
-       if (method->program) {
-           ReportError(f, "Multiple program: directives in auth/res decl."); 
-       }
-
-       method->program = xstrdup(tok->name);
-       break;
-    }
-}
-
-static void authdecl_parse(AUTHGROUP *curauth, CONFFILE *f, CONFTOKEN *tok)
-{
-    int oldtype,boolval;
-    METHOD *m;
-    bool bit;
-    char buff[SMBUF], *oldname, *p;
-
-    oldtype = tok->type;
-    oldname = tok->name;
-
-    tok = CONFgettoken(PERMtoks, f);
-
-    if (tok == NULL) {
-       ReportError(f, "Expected value.");
-    }
-    TEST_CONFIG(oldtype, bit);
-    if (bit) {
-       snprintf(buff, sizeof(buff), "Duplicated '%s' field in authgroup.",
-                 oldname);
-       ReportError(f, buff);
-    }
-
-    if (strcasecmp(tok->name, "on") == 0
-        || strcasecmp(tok->name, "true") == 0
-        || strcasecmp(tok->name, "yes") == 0)
-       boolval = true;
-    else if (strcasecmp(tok->name, "off") == 0
-             || strcasecmp(tok->name, "false") == 0
-             || strcasecmp(tok->name, "no") == 0)
-       boolval = false;
-    else
-       boolval = -1;
-
-    switch (oldtype) {
-      case PERMkey:
-       curauth->key = xstrdup(tok->name);
-       SET_CONFIG(PERMkey);
-       break;
-#ifdef HAVE_SSL
-      case PERMrequire_ssl:
-        if (boolval != -1) curauth->require_ssl = boolval;
-        SET_CONFIG(PERMrequire_ssl);
-        break;
-#endif
-      case PERMhost:
-       curauth->hosts = xstrdup(tok->name);
-       CompressList(curauth->hosts);
-       SET_CONFIG(PERMhost);
-
-        /* nnrpd.c downcases the names of connecting hosts.  We should
-           therefore also downcase the wildmat patterns to make sure there
-           aren't any surprises.  DNS is case-insensitive. */
-        for (p = curauth->hosts; *p; p++)
-            if (CTYPE(isupper, (unsigned char) *p))
-                *p = tolower((unsigned char) *p);
-
-       break;
-      case PERMdefdomain:
-       curauth->default_domain = xstrdup(tok->name);
-       SET_CONFIG(PERMdefdomain);
-       break;
-      case PERMdefuser:
-       curauth->default_user = xstrdup(tok->name);
-       SET_CONFIG(PERMdefuser);
-       break;
-      case PERMresolv:
-      case PERMresprog:
-        m = xcalloc(1, sizeof(METHOD));
-       memset(ConfigBit, '\0', ConfigBitsize);
-       GrowArray((void***) &curauth->res_methods, (void*) m);
-
-       if (oldtype == PERMresprog)
-           m->program = xstrdup(tok->name);
-       else {
-           m->name = xstrdup(tok->name);
-           tok = CONFgettoken(PERMtoks, f);
-           if (tok == NULL || tok->type != PERMlbrace) {
-               ReportError(f, "Expected '{' after 'res'");
-           }
-
-           tok = CONFgettoken(PERMtoks, f);
-
-           while (tok != NULL && tok->type != PERMrbrace) {
-               method_parse(m, f, tok, 0);
-               tok = CONFgettoken(PERMtoks, f);
-           }
-
-           if (tok == NULL) {
-               ReportError(f, "Unexpected EOF.");
-           }
-       }
-       break;
-      case PERMauth:
-      case PERMperl_auth:
-      case PERMpython_auth:
-      case PERMauthprog:
-        m = xcalloc(1, sizeof(METHOD));
-       memset(ConfigBit, '\0', ConfigBitsize);
-       GrowArray((void***) &curauth->auth_methods, (void*) m);
-       if (oldtype == PERMauthprog) {
-            m->type = PERMauthprog;
-           m->program = xstrdup(tok->name);
-       } else if (oldtype == PERMperl_auth) {
-#ifdef DO_PERL
-            m->type = PERMperl_auth;
-           m->program = xstrdup(tok->name);
-#else
-            ReportError(f, "perl_auth can not be used in readers.conf: inn not compiled with perl support enabled.");
-#endif
-        } else if (oldtype == PERMpython_auth) {
-#ifdef DO_PYTHON
-            m->type = PERMpython_auth;
-            m->program = xstrdup(tok->name);
-#else
-            ReportError(f, "python_auth can not be used in readers.conf: inn not compiled with python support enabled.");
-#endif
-        } else {
-           m->name = xstrdup(tok->name);
-           tok = CONFgettoken(PERMtoks, f);
-
-           if (tok == NULL || tok->type != PERMlbrace) {
-               ReportError(f, "Expected '{' after 'auth'");
-           }
-
-           tok = CONFgettoken(PERMtoks, f);
-
-           while (tok != NULL && tok->type != PERMrbrace) {
-               method_parse(m, f, tok, 1);
-               tok = CONFgettoken(PERMtoks, f);
-           }
-
-           if (tok == NULL) {
-               ReportError(f, "Unexpected EOF.");
-           }
-       }
-       break;
-      case PERMperl_access:
-#ifdef DO_PERL
-        curauth->access_script = xstrdup(tok->name);
-        curauth->access_type = PERMperl_access;
-#else
-        ReportError(f, "perl_access can not be used in readers.conf: inn not compiled with perl support enabled.");
-#endif
-        break;
-      case PERMpython_access:
-#ifdef DO_PYTHON
-        curauth->access_script = xstrdup(tok->name);
-        curauth->access_type = PERMpython_access;
-#else
-        ReportError(f, "python_access can not be used in readers.conf: inn not compiled with python support enabled.");
-#endif
-        break;
-      case PERMpython_dynamic:
-#ifdef DO_PYTHON
-        curauth->dynamic_script = xstrdup(tok->name);
-        curauth->dynamic_type = PERMpython_dynamic;
-#else
-        ReportError(f, "python_dynamic can not be used in readers.conf: inn not compiled with python support enabled.");
-#endif
-       break;
-      case PERMlocaladdress:
-       curauth->localaddress = xstrdup(tok->name);
-       CompressList(curauth->localaddress);
-       SET_CONFIG(PERMlocaladdress);
-       break;
-      default:
-       snprintf(buff, sizeof(buff), "Unexpected token: %s", tok->name);
-       ReportError(f, buff);
-       break;
-    }
-}
-
-static void accessdecl_parse(ACCESSGROUP *curaccess, CONFFILE *f, CONFTOKEN *tok)
-{
-    int oldtype, boolval;
-    bool bit;
-    char buff[SMBUF], *oldname;
-
-    oldtype = tok->type;
-    oldname = tok->name;
-
-    tok = CONFgettoken(0, f);
-
-    if (tok == NULL) {
-       ReportError(f, "Expected value.");
-    }
-    TEST_CONFIG(oldtype, bit);
-    if (bit) {
-       snprintf(buff, sizeof(buff), "Duplicated '%s' field in accessgroup.",
-                 oldname);
-       ReportError(f, buff);
-    }
-    if (strcasecmp(tok->name, "on") == 0
-        || strcasecmp(tok->name, "true") == 0
-        || strcasecmp(tok->name, "yes") == 0)
-       boolval = true;
-    else if (strcasecmp(tok->name, "off") == 0
-             || strcasecmp(tok->name, "false") == 0
-             || strcasecmp(tok->name, "no") == 0)
-       boolval = false;
-    else
-       boolval = -1;
-
-    switch (oldtype) {
-      case PERMkey:
-       curaccess->key = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMusers:
-       curaccess->users = xstrdup(tok->name);
-       CompressList(curaccess->users);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMrejectwith:
-       curaccess->rejectwith = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnewsgroups:
-       TEST_CONFIG(PERMread, bit);
-       if (bit) {
-           /* syntax error..  can't set read: or post: _and_ use
-            * newsgroups: */
-           ReportError(f, "read: newsgroups already set.");
-       }
-       TEST_CONFIG(PERMpost, bit);
-       if (bit) {
-           /* syntax error..  can't set read: or post: _and_ use
-            * newsgroups: */
-           ReportError(f, "post: newsgroups already set.");
-       }
-
-       curaccess->read = xstrdup(tok->name);
-       CompressList(curaccess->read);
-       curaccess->post = xstrdup(tok->name);
-       CompressList(curaccess->post);
-       SET_CONFIG(oldtype);
-       SET_CONFIG(PERMread);
-       SET_CONFIG(PERMpost);
-       break;
-      case PERMread:
-       curaccess->read = xstrdup(tok->name);
-       CompressList(curaccess->read);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMpost:
-       curaccess->post = xstrdup(tok->name);
-       CompressList(curaccess->post);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMaccessrp:
-       TEST_CONFIG(PERMread, bit);
-       if (bit && strchr(tok->name, 'R') == NULL) {
-           free(curaccess->read);
-           curaccess->read = 0;
-           CLEAR_CONFIG(PERMread);
-       }
-       TEST_CONFIG(PERMpost, bit);
-       if (bit && strchr(tok->name, 'P') == NULL) {
-           free(curaccess->post);
-           curaccess->post = 0;
-           CLEAR_CONFIG(PERMpost);
-       }
-       curaccess->allowapproved = (strchr(tok->name, 'A') != NULL);
-       curaccess->allownewnews = (strchr(tok->name, 'N') != NULL);
-       curaccess->allowihave = (strchr(tok->name, 'I') != NULL);
-       curaccess->locpost = (strchr(tok->name, 'L') != NULL);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMlocaltime:
-       if (boolval != -1) curaccess->localtime = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMstrippath:
-       if (boolval != -1) curaccess->strippath = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdperlfilter:
-       if (boolval != -1) curaccess->nnrpdperlfilter = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdpythonfilter:
-       if (boolval != -1) curaccess->nnrpdpythonfilter = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMfromhost:
-       if (curaccess->fromhost)
-           free(curaccess->fromhost);
-       curaccess->fromhost = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMpathhost:
-       if (curaccess->pathhost)
-           free(curaccess->pathhost);
-       curaccess->pathhost = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMorganization:
-       if (curaccess->organization)
-           free(curaccess->organization);
-       curaccess->organization = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMmoderatormailer:
-       if (curaccess->moderatormailer)
-           free(curaccess->moderatormailer);
-       curaccess->moderatormailer = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMdomain:
-       if (curaccess->domain)
-           free(curaccess->domain);
-       curaccess->domain = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMcomplaints:
-       if (curaccess->complaints)
-           free(curaccess->complaints);
-       curaccess->complaints = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMspoolfirst:
-       if (boolval != -1) curaccess->spoolfirst = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMcheckincludedtext:
-       if (boolval != -1) curaccess->checkincludedtext = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMclienttimeout:
-       curaccess->clienttimeout = atoi(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMlocalmaxartsize:
-       curaccess->localmaxartsize = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMreadertrack:
-       if (boolval != -1) curaccess->readertrack = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMstrippostcc:
-       if (boolval != -1) curaccess->strippostcc = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMaddnntppostinghost:
-       if (boolval != -1) curaccess->addnntppostinghost = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMaddnntppostingdate:
-       if (boolval != -1) curaccess->addnntppostingdate = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdposthost:
-       if (curaccess->nnrpdposthost)
-           free(curaccess->nnrpdposthost);
-       curaccess->nnrpdposthost = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdpostport:
-       curaccess->nnrpdpostport = atoi(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdoverstats:
-       if (boolval != -1) curaccess->nnrpdoverstats = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_auth:
-       if (boolval != -1) curaccess->backoff_auth = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_db:
-       if (curaccess->backoff_db)
-           free(curaccess->backoff_db);
-       curaccess->backoff_db = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_k:
-       curaccess->backoff_k = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_postfast:
-       curaccess->backoff_postfast = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_postslow:
-       curaccess->backoff_postslow = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMbackoff_trigger:
-       curaccess->backoff_trigger = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdcheckart:
-       if (boolval != -1) curaccess->nnrpdcheckart = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnnrpdauthsender:
-       if (boolval != -1) curaccess->nnrpdauthsender = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMvirtualhost:
-       if (boolval != -1) curaccess->virtualhost = boolval;
-       SET_CONFIG(oldtype);
-       break;
-      case PERMnewsmaster:
-       if (curaccess->newsmaster)
-           free(curaccess->newsmaster);
-       curaccess->newsmaster = xstrdup(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      case PERMmaxbytespersecond:
-       curaccess->maxbytespersecond = atol(tok->name);
-       SET_CONFIG(oldtype);
-       break;
-      default:
-       snprintf(buff, sizeof(buff), "Unexpected token: %s", tok->name);
-       ReportError(f, buff);
-       break;
-    }
-}
-
-static void PERMvectortoaccess(ACCESSGROUP *acc, const char *name, struct vector *access_vec) {
-    CONFTOKEN  *tok        = NULL;
-    CONFFILE    *file;
-    char        *str;
-    unsigned int i;
-
-    file = xcalloc(1, sizeof(CONFFILE));
-    file->array = access_vec->strings;
-    file->array_len = access_vec->count;
-    memset(ConfigBit, '\0', ConfigBitsize);
-
-    SetDefaultAccess(acc);
-    str = xstrdup(name);
-    acc->name = str;
-
-    for (i = 0; i <= access_vec->count; i++) {
-      tok = CONFgettoken(PERMtoks, file);
-
-      if (tok != NULL) {
-        accessdecl_parse(acc, file, tok);
-      }
-    }
-    free(file);
-    return;       
-}
-
-static void PERMreadfile(char *filename)
-{
-    CONFCHAIN  *cf         = NULL,
-               *hold       = NULL;
-    CONFTOKEN  *tok        = NULL;
-    int                inwhat;
-    GROUP      *curgroup   = NULL,
-               *newgroup   = NULL;
-    ACCESSGROUP *curaccess  = NULL;
-    AUTHGROUP  *curauth    = NULL;
-    int                oldtype;
-    char       *str        = NULL;
-    char        *path       = NULL;
-    char buff[SMBUF];
-
-    if(filename != NULL) {
-       syslog(L_TRACE, "Reading access from %s", 
-              filename == NULL ? "(NULL)" : filename);
-    }
-
-    cf         = xmalloc(sizeof(CONFCHAIN));
-    if ((cf->f = CONFfopen(filename)) == NULL) {
-       syslog(L_ERROR, "%s cannot open %s: %m", ClientHost, filename);
-       Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-       ExitWithStats(1, true);
-    }
-    cf->parent = 0;
-
-    /* are we editing an AUTH or ACCESS group? */
-
-    inwhat     = 0;
-    newgroup   = curgroup = 0;
-
-    tok                = CONFgettoken(PERMtoks, cf->f);
-
-    while (tok != NULL) {
-       if (inwhat == 0) {
-           /* top-level parser */
-
-           switch (tok->type) {
-               /* include a child file */
-
-             case PERMinclude:
-               tok = CONFgettoken(0, cf->f);
-
-               if (tok == NULL) {
-                   ReportError(cf->f, "Expected filename after 'include'.");
-               }
-
-               hold            = xmalloc(sizeof(CONFCHAIN));
-               hold->parent    = cf;
-
-               /* unless the filename's path is fully qualified, open it
-                * relative to /news/etc */
-
-                path = concatpath(innconf->pathetc, tok->name);
-                hold->f = CONFfopen(path);
-                free(path);
-
-               if (hold->f == NULL) {
-                   ReportError(cf->f, "Couldn't open 'include' filename.");
-               }
-
-               cf = hold;
-               goto again;
-               break;
-
-               /* nested group declaration. */
-             case PERMgroup:
-               tok = CONFgettoken(PERMtoks, cf->f);
-
-               if (tok == NULL) {
-                   ReportError(cf->f, "Unexpected EOF at group name");
-               }
-
-               newgroup        = xmalloc(sizeof(GROUP));
-               newgroup->above = curgroup;
-               newgroup->name  = xstrdup(tok->name);
-               memset(ConfigBit, '\0', ConfigBitsize);
-
-               tok = CONFgettoken(PERMtoks, cf->f);
-
-               if (tok == NULL || tok->type != PERMlbrace) {
-                   ReportError(cf->f, "Expected '{' after group name");
-               }
-
-               /* nested group declaration */
-               if (curgroup) {
-                   newgroup->auth = copy_authgroup(curgroup->auth);
-                   newgroup->access = copy_accessgroup(curgroup->access);
-               } else {
-                   newgroup->auth = 0;
-                   newgroup->access = 0;
-               }
-
-               curgroup = newgroup;
-               break;
-
-               /* beginning of an auth or access group decl */
-             case PERMauth:
-             case PERMaccess:
-               oldtype = tok->type;
-
-               if ((tok = CONFgettoken(PERMtoks, cf->f)) == NULL) {
-                   ReportError(cf->f, "Expected identifier.");
-               }
-
-               str = xstrdup(tok->name);
-
-               tok = CONFgettoken(PERMtoks, cf->f);
-
-               if (tok == NULL || tok->type != PERMlbrace) {
-                   ReportError(cf->f, "Expected '{'");
-               }
-
-               switch (oldtype) {
-                 case PERMauth:
-                   if (curgroup && curgroup->auth)
-                       curauth = copy_authgroup(curgroup->auth);
-                   else {
-                       curauth = xcalloc(1, sizeof(AUTHGROUP));
-                       memset(ConfigBit, '\0', ConfigBitsize);
-                        SetDefaultAuth(curauth);
-                   }
-
-                   curauth->name = str;
-                   inwhat = 1;
-                   break;
-
-                 case PERMaccess:
-                   if (curgroup && curgroup->access)
-                       curaccess = copy_accessgroup(curgroup->access);
-                   else {
-                       curaccess = xcalloc(1, sizeof(ACCESSGROUP));
-                       memset(ConfigBit, '\0', ConfigBitsize);
-                       SetDefaultAccess(curaccess);
-                   }
-                   curaccess->name = str;
-                   inwhat = 2;
-                   break;
-               }
-
-               break;
-
-               /* end of a group declaration */
-
-             case PERMrbrace:
-               if (curgroup == NULL) {
-                   ReportError(cf->f, "Unmatched '}'");
-               }
-
-               newgroup = curgroup;
-               curgroup = curgroup->above;
-               if (newgroup->auth)
-                   free_authgroup(newgroup->auth);
-               if (newgroup->access)
-                   free_accessgroup(newgroup->access);
-               free(newgroup->name);
-               free(newgroup);
-               break;
-
-               /* stuff that belongs in an authgroup */
-             case PERMhost:
-#ifdef HAVE_SSL
-              case PERMrequire_ssl:
-#endif
-             case PERMauthprog:
-             case PERMresprog:
-             case PERMdefuser:
-             case PERMdefdomain:
-               if (curgroup == NULL) {
-                   curgroup = xcalloc(1, sizeof(GROUP));
-                   memset(ConfigBit, '\0', ConfigBitsize);
-               }
-               if (curgroup->auth == NULL) {
-                   curgroup->auth = xcalloc(1, sizeof(AUTHGROUP));
-                   memset(ConfigBit, '\0', ConfigBitsize);
-                    SetDefaultAuth(curgroup->auth);
-               }
-
-               authdecl_parse(curgroup->auth, cf->f, tok);
-               break;
-
-               /* stuff that belongs in an accessgroup */
-             case PERMusers:
-             case PERMrejectwith:
-             case PERMnewsgroups:
-             case PERMread:
-             case PERMpost:
-             case PERMaccessrp:
-             case PERMlocaltime:
-             case PERMstrippath:
-             case PERMnnrpdperlfilter:
-             case PERMnnrpdpythonfilter:
-             case PERMfromhost:
-             case PERMpathhost:
-             case PERMorganization:
-             case PERMmoderatormailer:
-             case PERMdomain:
-             case PERMcomplaints:
-             case PERMspoolfirst:
-             case PERMcheckincludedtext:
-             case PERMclienttimeout:
-             case PERMlocalmaxartsize:
-             case PERMreadertrack:
-             case PERMstrippostcc:
-             case PERMaddnntppostinghost:
-             case PERMaddnntppostingdate:
-             case PERMnnrpdposthost:
-             case PERMnnrpdpostport:
-             case PERMnnrpdoverstats:
-             case PERMbackoff_auth:
-             case PERMbackoff_db:
-             case PERMbackoff_k:
-             case PERMbackoff_postfast:
-             case PERMbackoff_postslow:
-             case PERMbackoff_trigger:
-             case PERMnnrpdcheckart:
-             case PERMnnrpdauthsender:
-             case PERMvirtualhost:
-             case PERMnewsmaster:
-               if (!curgroup) {
-                   curgroup = xcalloc(1, sizeof(GROUP));
-                   memset(ConfigBit, '\0', ConfigBitsize);
-               }
-               if (!curgroup->access) {
-                   curgroup->access = xcalloc(1, sizeof(ACCESSGROUP));
-                   memset(ConfigBit, '\0', ConfigBitsize);
-                   SetDefaultAccess(curgroup->access);
-               }
-               accessdecl_parse(curgroup->access, cf->f, tok);
-               break;
-             default:
-               snprintf(buff, sizeof(buff), "Unexpected token: %s", tok->name);
-               ReportError(cf->f, buff);
-               break;
-           }
-       } else if (inwhat == 1) {
-           /* authgroup parser */
-           if (tok->type == PERMrbrace) {
-               inwhat = 0;
-
-               if (curauth->name
-#ifdef HAVE_SSL
-                   && ((curauth->require_ssl == false) || (ClientSSL == true))
-#endif
-                   && MatchHost(curauth->hosts, ClientHost, ClientIpString)) {
-                   if (!MatchHost(curauth->localaddress, ServerHost, ServerIpString)) {
-                       syslog(L_TRACE, "Auth strategy '%s' does not match localhost.  Removing.",
-                          curauth->name == NULL ? "(NULL)" : curauth->name);
-                       free_authgroup(curauth);
-                   } else
-                       add_authgroup(curauth);
-               } else {
-                   syslog(L_TRACE, "Auth strategy '%s' does not match client.  Removing.",
-                          curauth->name == NULL ? "(NULL)" : curauth->name);
-                   free_authgroup(curauth);
-               }
-                curauth = NULL;
-               goto again;
-           }
-
-           authdecl_parse(curauth, cf->f, tok);
-       } else if (inwhat == 2) {
-           /* accessgroup parser */
-           if (tok->type == PERMrbrace) {
-               inwhat = 0;
-
-               if (curaccess->name)
-                   add_accessgroup(curaccess);
-               else
-                   free_accessgroup(curaccess);
-               curaccess = NULL;
-               goto again;
-           }
-
-           accessdecl_parse(curaccess, cf->f, tok);
-       } else {
-           /* should never happen */
-           syslog(L_TRACE, "SHOULD NEVER HAPPEN!");
-       }
-again:
-       /* go back up the 'include' chain. */
-       tok = CONFgettoken(PERMtoks, cf->f);
-
-       while (tok == NULL && cf) {
-           hold = cf;
-           cf = hold->parent;
-           CONFfclose(hold->f);
-           free(hold);
-           if (cf) {
-               tok = CONFgettoken(PERMtoks, cf->f);
-           }
-       }
-    }
-
-    return;
-}
-
-void PERMgetaccess(char *nnrpaccess)
-{
-    int i;
-    char *uname;
-    int canauthenticate;
-
-    auth_realms            = NULL;
-    access_realms   = NULL;
-    success_auth    = NULL;
-
-    PERMcanread            = PERMcanpost   = false;
-    PERMreadlist    = PERMpostlist  = false;
-    PERMaccessconf = NULL;
-
-    if (ConfigBit == NULL) {
-       if (PERMMAX % 8 == 0)
-           ConfigBitsize = PERMMAX/8;
-       else
-           ConfigBitsize = (PERMMAX - (PERMMAX % 8))/8 + 1;
-       ConfigBit = xcalloc(ConfigBitsize, 1);
-    }
-    PERMreadfile(nnrpaccess);
-
-    strip_accessgroups();
-
-    if (auth_realms == NULL) {
-       /* no one can talk, empty file */
-       syslog(L_NOTICE, "%s no_permission", ClientHost);
-       Printf("%d You have no permission to talk.  Goodbye.\r\n",
-         NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    }
-
-    /* auth_realms are all expected to match the user. */
-    canauthenticate = 0;
-    for (i = 0; auth_realms[i]; i++)
-       if (auth_realms[i]->auth_methods)
-           canauthenticate = 1;
-    uname = 0;
-    while (!uname && i--) {
-       if ((uname = ResolveUser(auth_realms[i])) != NULL)
-           PERMauthorized = true;
-       if (!uname && auth_realms[i]->default_user)
-           uname = auth_realms[i]->default_user;
-    }
-    if (uname) {
-       strlcpy(PERMuser, uname, sizeof(PERMuser));
-       uname = strchr(PERMuser, '@');
-       if (!uname && auth_realms[i]->default_domain) {
-           /* append the default domain to the username */
-           strlcat(PERMuser, "@", sizeof(PERMuser));
-           strlcat(PERMuser, auth_realms[i]->default_domain,
-                    sizeof(PERMuser));
-       }
-       PERMneedauth = false;
-       success_auth = auth_realms[i];
-       syslog(L_TRACE, "%s res %s", ClientHost, PERMuser);
-    } else if (!canauthenticate) {
-       /* couldn't resolve the user. */
-       syslog(L_NOTICE, "%s no_user", ClientHost);
-       Printf("%d Could not get your access name.  Goodbye.\r\n",
-         NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    } else {
-       PERMneedauth = true;
-    }
-    /* check maximum allowed permissions for any host that matches (for
-     * the greeting string) */
-    for (i = 0; access_realms[i]; i++) {
-       if (!PERMcanread)
-           PERMcanread = (access_realms[i]->read != NULL);
-       if (!PERMcanpost)
-           PERMcanpost = (access_realms[i]->post != NULL);
-    }
-    if (!i) {
-       /* no applicable access groups. Zeroing all these makes INN 
-        * return permission denied to client. */
-       PERMcanread = PERMcanpost = PERMneedauth = false;
-    }
-}
-
-void PERMlogin(char *uname, char *pass, char *errorstr)
-{
-    int i   = 0;
-    char *runame;
-
-    if (ConfigBit == NULL) {
-       if (PERMMAX % 8 == 0)
-           ConfigBitsize = PERMMAX/8;
-       else
-           ConfigBitsize = (PERMMAX - (PERMMAX % 8))/8 + 1;
-       ConfigBit = xcalloc(ConfigBitsize, 1);
-    }
-    /* The check in CMDauthinfo uses the value of PERMneedauth to know if
-     * authentication succeeded or not.  By default, authentication doesn't
-     * succeed. */
-    PERMneedauth = true;
-
-    if(auth_realms != NULL) {
-       for (i = 0; auth_realms[i]; i++) {
-           ;
-       }
-    }
-
-    runame  = NULL;
-
-    while (runame == NULL && i--)
-       runame = AuthenticateUser(auth_realms[i], uname, pass, errorstr);
-    if (runame) {
-       strlcpy(PERMuser, runame, sizeof(PERMuser));
-       uname = strchr(PERMuser, '@');
-       if (!uname && auth_realms[i]->default_domain) {
-           /* append the default domain to the username */
-           strlcat(PERMuser, "@", sizeof(PERMuser));
-           strlcat(PERMuser, auth_realms[i]->default_domain,
-                    sizeof(PERMuser));
-       }
-       PERMneedauth = false;
-       PERMauthorized = true;
-       success_auth = auth_realms[i];
-    }
-}
-
-static int MatchUser(char *pat, char *user)
-{
-    char *cp, **list;
-    char *userlist[2];
-    int ret;
-
-    if (!pat)
-       return(1);
-    if (!user || !*user)
-       return(0);
-    cp = xstrdup(pat);
-    list = 0;
-    NGgetlist(&list, cp);
-    userlist[0] = user;
-    userlist[1] = 0;
-    ret = PERMmatch(list, userlist);
-    free(cp);
-    free(list[0]);
-    free(list);
-    return(ret);
-}
-
-void PERMgetpermissions()
-{
-    int i;
-    char *cp, **list;
-    char *user[2];
-    static ACCESSGROUP *noaccessconf;
-    char *uname;
-    char *cpp, *script_path;
-    char **args;
-    struct vector *access_vec;
-
-    if (ConfigBit == NULL) {
-       if (PERMMAX % 8 == 0)
-           ConfigBitsize = PERMMAX/8;
-       else
-           ConfigBitsize = (PERMMAX - (PERMMAX % 8))/8 + 1;
-       ConfigBit = xcalloc(ConfigBitsize, 1);
-    }
-    if (!success_auth) {
-       /* if we haven't successfully authenticated, we can't do anything. */
-       syslog(L_TRACE, "%s no_success_auth", ClientHost);
-       if (!noaccessconf)
-           noaccessconf = xmalloc(sizeof(ACCESSGROUP));
-       PERMaccessconf = noaccessconf;
-       SetDefaultAccess(PERMaccessconf);
-       return;
-#ifdef DO_PERL
-    } else if ((success_auth->access_script != NULL) && (success_auth->access_type == PERMperl_access)) {
-      i = 0;
-      cpp = xstrdup(success_auth->access_script);
-      args = 0;
-      Argify(cpp, &args);
-      script_path = concat(args[0], (char *) 0);
-      if ((script_path != NULL) && (strlen(script_path) > 0)) {
-        if(!PerlLoaded) {
-          loadPerl();
-        }
-        PERLsetup(NULL, script_path, "access");
-        free(script_path);
-
-        uname = xstrdup(PERMuser);
-        
-        access_vec = vector_new();
-
-        perlAccess(uname, access_vec);
-        free(uname);
-
-        access_realms[0] = xcalloc(1, sizeof(ACCESSGROUP));
-
-        PERMvectortoaccess(access_realms[0], "perl-dynamic", access_vec);
-
-        vector_free(access_vec);
-      } else {
-        syslog(L_ERROR, "No script specified in perl_access method.\n");
-        Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-        ExitWithStats(1, true);
-      }
-      free(cpp);
-      free(args);
-#endif /* DO_PERL */
-#ifdef DO_PYTHON
-    } else if ((success_auth->access_script != NULL) && (success_auth->access_type == PERMpython_access)) {
-        i = 0;
-        cpp = xstrdup(success_auth->access_script);
-        args = 0;
-        Argify(cpp, &args);
-        script_path = concat(args[0], (char *) 0);
-        if ((script_path != NULL) && (strlen(script_path) > 0)) {
-            uname = xstrdup(PERMuser);
-            access_vec = vector_new();
-
-            PY_access(script_path, access_vec, uname);
-            free(script_path);
-            free(uname);
-            free(args);
-            
-            access_realms[0] = xcalloc(1, sizeof(ACCESSGROUP));
-            memset(access_realms[0], 0, sizeof(ACCESSGROUP));
-            
-            PERMvectortoaccess(access_realms[0], "python-dynamic", access_vec);
-            
-            vector_free(access_vec);
-        } else {
-            syslog(L_ERROR, "No script specified in python_access method.\n");
-            Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-            ExitWithStats(1, true);
-        }
-        free(cpp);
-#endif /* DO_PYTHON */
-    } else {
-      for (i = 0; access_realms[i]; i++)
-        ;
-      user[0] = PERMuser;
-      user[1] = 0;
-      while (i--) {
-        if ((!success_auth->key && !access_realms[i]->key) ||
-            (access_realms[i]->key && success_auth->key &&
-             strcmp(access_realms[i]->key, success_auth->key) == 0)) {
-          if (!access_realms[i]->users)
-            break;
-          else if (!*PERMuser)
-            continue;
-          cp = xstrdup(access_realms[i]->users);
-          list = 0;
-          NGgetlist(&list, cp);
-          if (PERMmatch(list, user)) {
-            syslog(L_TRACE, "%s match_user %s %s", ClientHost,
-                   PERMuser, access_realms[i]->users);
-            free(cp);
-            free(list[0]);
-            free(list);
-            break;
-          } else
-            syslog(L_TRACE, "%s no_match_user %s %s", ClientHost,
-                   PERMuser, access_realms[i]->users);
-          free(cp);
-         free(list[0]);
-          free(list);
-       }
-      }
-    }
-    if (i >= 0) {
-       /* found the right access group */
-       if (access_realms[i]->rejectwith) {
-           syslog(L_ERROR, "%s rejected by rule (%s)",
-               ClientHost, access_realms[i]->rejectwith);
-           Reply("%d Permission denied:  %s\r\n",
-               NNTP_ACCESS_VAL, access_realms[i]->rejectwith);
-           ExitWithStats(1, true);
-       }
-       if (access_realms[i]->read) {
-           cp = xstrdup(access_realms[i]->read);
-           PERMspecified = NGgetlist(&PERMreadlist, cp);
-           free(cp);
-           PERMcanread = true;
-       } else {
-           syslog(L_TRACE, "%s no_read %s", ClientHost, access_realms[i]->name);
-           PERMcanread = false;
-       }
-       if (access_realms[i]->post) {
-           cp = xstrdup(access_realms[i]->post);
-           NGgetlist(&PERMpostlist, cp);
-           free(cp);
-           PERMcanpost = true;
-       } else {
-           syslog(L_TRACE, "%s no_post %s", ClientHost, access_realms[i]->name);
-           PERMcanpost = false;
-       }
-       PERMaccessconf = access_realms[i];
-       MaxBytesPerSecond = PERMaccessconf->maxbytespersecond;
-       if (PERMaccessconf->virtualhost) {
-           if (PERMaccessconf->domain == NULL) {
-               syslog(L_ERROR, "%s virtualhost needs domain parameter(%s)",
-                   ClientHost, PERMaccessconf->name);
-               Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-               ExitWithStats(1, true);
-           }
-           if (VirtualPath)
-               free(VirtualPath);
-           if (strcmp(innconf->pathhost, PERMaccessconf->pathhost) == 0) {
-               /* use domain, if pathhost in access relm matches one in
-                  inn.conf to differentiate virtual host */
-               if (innconf->domain != NULL && strcmp(innconf->domain, PERMaccessconf->domain) == 0) {
-                   syslog(L_ERROR, "%s domain parameter(%s) in readers.conf must be different from the one in inn.conf",
-                       ClientHost, PERMaccessconf->name);
-                   Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
-                   ExitWithStats(1, true);
-               }
-                VirtualPath = concat(PERMaccessconf->domain, "!", (char *) 0);
-           } else {
-                VirtualPath = concat(PERMaccessconf->pathhost, "!",
-                                     (char *) 0);
-           }
-            VirtualPathlen = strlen(VirtualPath);
-       } else
-           VirtualPathlen = 0;
-    } else {
-       if (!noaccessconf)
-           noaccessconf = xmalloc(sizeof(ACCESSGROUP));
-       PERMaccessconf = noaccessconf;
-       SetDefaultAccess(PERMaccessconf);
-       syslog(L_TRACE, "%s no_access_realm", ClientHost);
-    }
-    /* check if dynamic access control is enabled, if so init it */
-#ifdef DO_PYTHON
-    if ((success_auth->dynamic_type == PERMpython_dynamic) && success_auth->dynamic_script) {
-      PY_dynamic_init(success_auth->dynamic_script);
-    }
-#endif /* DO_PYTHON */
-}
-
-/* strip blanks out of a string */
-static void CompressList(char *list)
-{
-    char *cpto;
-    bool inword = false;
-
-    for (cpto = list; *list; ) {
-       if (strchr("\n \t,", *list) != NULL) {
-           list++;
-           if(inword) {
-               *cpto++ = ',';
-               inword = false;
-           }
-       } else {
-           *cpto++ = *list++;
-           inword = true;
-       }
-    }
-    *cpto = '\0';
-}
-
-static bool MatchHost(char *hostlist, char *host, char *ip)
-{
-    char    **list;
-    bool    ret        = false;
-    char    *cp;
-    int            iter;
-    char    *pat, 
-           *p;
-
-    /* If no hostlist are specified, by default they match.   */
-
-    if (hostlist == NULL) {
-       return(true);
-    }
-
-    list    = 0;
-    cp     = xstrdup(hostlist);
-
-    NGgetlist(&list, cp);
-
-    /* default is no access */
-    for (iter = 0; list[iter]; iter++) {
-       ;
-    }
-
-    while (iter-- > 0) {
-       pat = list[iter];
-       if (*pat == '!')
-           pat++;
-       ret = uwildmat(host, pat);
-       if (!ret && *ip) {
-           ret = uwildmat(ip, pat);
-           if (!ret && (p = strchr(pat, '/')) != (char *)NULL) {
-               unsigned int bits, c;
-               struct in_addr ia, net, tmp;
-#ifdef HAVE_INET6
-               struct in6_addr ia6, net6;
-               unsigned char bits8;
-#endif
-               unsigned int mask;
-
-               *p = '\0';
-                if (inet_aton(ip, &ia) && inet_aton(pat, &net)) {
-                   if (strchr(p+1, '.') == (char *)NULL) {
-                       /* string following / is a masklength */
-                       mask = atoi(p+1);
-                       for (bits = c = 0; c < mask && c < 32; c++)
-                           bits |= (1 << (31 - c));
-                       mask = htonl(bits);
-                   } else {    /* or it may be a dotted quad bitmask */
-                        if (inet_aton(p+1, &tmp))
-                            mask = tmp.s_addr;
-                        else   /* otherwise skip it */
-                            continue;
-                   }
-                   if ((ia.s_addr & mask) == (net.s_addr & mask))
-                       ret = true;
-               }
-#ifdef HAVE_INET6
-                else if (inet_pton(AF_INET6, ip, &ia6) && 
-                        inet_pton(AF_INET6, pat, &net6)) {
-                   mask = atoi(p+1);
-                   ret = true;
-                   /* do a prefix match byte by byte */
-                   for (c = 0; c*8 < mask && c < sizeof(ia6); c++) {
-                       if ( (c+1)*8 <= mask &&
-                           ia6.s6_addr[c] != net6.s6_addr[c] ) {
-                           ret = false;
-                           break;
-                       } else if ( (c+1)*8 > mask ) {
-                            unsigned int b;
-
-                           for (bits8 = b = 0; b < (mask % 8); b++)
-                               bits8 |= (1 << (7 - b));
-                           if ((ia6.s6_addr[c] & bits8) !=
-                               (net6.s6_addr[c] & bits8) ) {
-                               ret = false;
-                               break;
-                           }
-                       }
-                   }
-               }
-#endif
-           }
-        }
-       if (ret)
-           break;
-    }
-    if (ret && list[iter][0] == '!')
-       ret = false;
-    free(list[0]);
-    free(list);
-    free(cp);
-    return(ret);
-}
-
-static void add_authgroup(AUTHGROUP *group)
-{
-    int i;
-
-    if (auth_realms == NULL) {
-       i = 0;
-       auth_realms = xmalloc(2 * sizeof(AUTHGROUP *));
-    } else {
-       for (i = 0; auth_realms[i]; i++)
-           ;
-        auth_realms = xrealloc(auth_realms, (i + 2) * sizeof(AUTHGROUP *));
-    }
-    auth_realms[i] = group;
-    auth_realms[i+1] = 0;
-}
-
-static void add_accessgroup(ACCESSGROUP *group)
-{
-    int i;
-
-    if (access_realms == NULL) {
-       i = 0;
-       access_realms = xmalloc(2 * sizeof(ACCESSGROUP *));
-    } else {
-       for (i = 0; access_realms[i]; i++)
-           ;
-        access_realms = xrealloc(access_realms, (i + 2) * sizeof(ACCESSGROUP *));
-    }
-    access_realms[i] = group;
-    access_realms[i+1] = 0;
-}
-
-/* clean out access groups that don't apply to any of our auth groups. */
-
-static void strip_accessgroups(void)
-{
-    int i, j;
-
-    /* flag the access group as used or not */
-
-    if(access_realms != NULL) {
-       for (j = 0; access_realms[j] != NULL; j++) {
-           access_realms[j]->used = 0;
-       }
-    } else {
-       syslog(L_TRACE, "No access realms to check!");
-    }
-
-    /* If there are auth realms to check...    */
-
-    if(auth_realms != NULL) {
-       /*  ... Then for each auth realm...     */
-
-       for (i = 0; auth_realms[i] != NULL; i++) {
-
-           /*  ... for each access realm...    */
-
-           for (j = 0; access_realms[j] != NULL; j++) {
-
-               /*  If the access realm isn't already in use... */
-
-               if (! access_realms[j]->used) {
-                   /*  Check to see if both the access_realm key and 
-                       auth_realm key are NULL...                      */
-
-                   if (!access_realms[j]->key && !auth_realms[i]->key) {
-                       /*  If so, mark the realm in use and continue on... */
-
-                       access_realms[j]->used = 1;
-                   } else { 
-                       /*  If not, check to see if both the access_realm and 
-                           auth_realm are NOT _both_ NULL, and see if they are
-                           equal...                                            */
-
-                       if (access_realms[j]->key && auth_realms[i]->key &&
-                           strcmp(access_realms[j]->key, auth_realms[i]->key) == 0) {
-
-                           /*  And if so, mark the realm in use.   */
-
-                           access_realms[j]->used = 1;
-                       }
-                   }
-               }
-           }
-       }
-    } else {
-       syslog(L_TRACE, "No auth realms to check!");
-    }
-
-    /* strip out unused access groups */
-    i = j = 0;
-
-    while (access_realms[i] != NULL) {
-       if (access_realms[i]->used)
-           access_realms[j++] = access_realms[i];
-       else
-           syslog(L_TRACE, "%s removing irrelevant access group %s", 
-                  ClientHost, access_realms[i]->name);
-       i++;
-    }
-    access_realms[j] = 0;
-}
-
-typedef struct _EXECSTUFF {
-    pid_t pid;
-    int rdfd, errfd, wrfd;
-} EXECSTUFF;
-
-static EXECSTUFF *ExecProg(char *arg0, char **args)
-{
-    EXECSTUFF *ret;
-    int rdfd[2], errfd[2], wrfd[2];
-    pid_t pid;
-    struct stat stb;
-
-#if !defined(S_IXUSR) && defined(_S_IXUSR)
-#define S_IXUSR _S_IXUSR
-#endif /* !defined(S_IXUSR) && defined(_S_IXUSR) */
-
-#if !defined(S_IXUSR) && defined(S_IEXEC)
-#define S_IXUSR S_IEXEC
-#endif  /* !defined(S_IXUSR) && defined(S_IEXEC) */
-
-    if (stat(arg0, &stb) || !(stb.st_mode&S_IXUSR))
-       return(0);
-
-    pipe(rdfd);
-    pipe(errfd);
-    pipe(wrfd);
-    switch (pid = fork()) {
-      case -1:
-       close(rdfd[0]);
-       close(rdfd[1]);
-       close(errfd[0]);
-       close(errfd[1]);
-       close(wrfd[0]);
-       close(wrfd[1]);
-       return(0);
-      case 0:
-       close(rdfd[0]);
-       dup2(rdfd[1], 1);
-       close(errfd[0]);
-       dup2(errfd[1], 2);
-       close(wrfd[1]);
-       dup2(wrfd[0], 0);
-       execv(arg0, args);
-       /* if we got here, there was an error */
-       syslog(L_ERROR, "%s perm could not exec %s: %m", ClientHost, arg0);
-       exit(1);
-    }
-    close(rdfd[1]);
-    close(errfd[1]);
-    close(wrfd[0]);
-    ret = xmalloc(sizeof(EXECSTUFF));
-    ret->pid = pid;
-    ret->rdfd = rdfd[0];
-    ret->errfd = errfd[0];
-    ret->wrfd = wrfd[1];
-    return(ret);
-}
-
-static void GetConnInfo(METHOD *method, char *buf)
-{
-    int i;
-
-    buf[0] = '\0';
-    if (*ClientHost)
-       sprintf(buf, "ClientHost: %s\r\n", ClientHost);
-    if (*ClientIpString)
-       sprintf(buf+strlen(buf), "ClientIP: %s\r\n", ClientIpString);
-    if (ClientPort)
-       sprintf(buf+strlen(buf), "ClientPort: %d\r\n", ClientPort);
-    if (*ServerIpString)
-       sprintf(buf+strlen(buf), "LocalIP: %s\r\n", ServerIpString);
-    if (ServerPort)
-       sprintf(buf+strlen(buf), "LocalPort: %d\r\n", ServerPort);
-    /* handle this here, since we only get here when we're about to exec
-     * something. */
-    if (method->extra_headers) {
-       for (i = 0; method->extra_headers[i]; i++)
-           sprintf(buf+strlen(buf), "%s\r\n", method->extra_headers[i]);
-    }
-}
-
-static char ubuf[SMBUF];
-
-typedef void (*LineFunc)(char*);
-
-/* messages from a program's stdout */
-static void HandleProgLine(char *ln)
-{
-    if (strncasecmp(ln, "User:", strlen("User:")) == 0)
-       strlcpy(ubuf, ln + strlen("User:"), sizeof(ubuf));
-}
-
-/* messages from a programs stderr */
-static void HandleErrorLine(char *ln)
-{
-    syslog(L_NOTICE, "%s auth_err %s", ClientHost, ln);
-}
-
-static bool
-HandleProgInput(int fd, char *buf, int buflen, LineFunc f)
-{
-    char *nl;
-    char *start;
-    int curpos, got;
-
-    /* read the data */
-    curpos = strlen(buf);
-    if (curpos >= buflen-1) {
-       /* data overflow (on one line!) */
-       return false;
-    }
-    got = read(fd, buf+curpos, buflen-curpos-1);
-    if (got <= 0)
-       return false;
-    buf[curpos+got] = '\0';
-
-    /* break what we got up into lines */
-    start = nl = buf;
-    while ((nl = strchr(nl, '\n')) != NULL) {
-       if (nl != buf && *(nl-1) == '\r')
-           *(nl-1) = '\0';
-       *nl++ = '\0';
-       f(start);
-       start = nl;
-    }
-
-    /* delete all the lines we've read from the buffer. */
-    /* 'start' points to the end of the last unterminated string */
-    nl = start;
-    start = buf;
-    if (nl == start) {
-       return true;
-    }
-
-    while (*nl) {
-       *start++ = *nl++;
-    }
-
-    *start = '\0';
-
-    return true;
-}
-
-static void GetProgInput(EXECSTUFF *prog)
-{
-    fd_set rfds, tfds;
-    int maxfd;
-    int got;
-    bool okay;
-    struct timeval tmout;
-    pid_t tmp;
-    int status;
-    char rdbuf[BIG_BUFFER], errbuf[BIG_BUFFER];
-    double start, end;
-
-    FD_ZERO(&rfds);
-    FD_SET(prog->rdfd, &rfds);
-    FD_SET(prog->errfd, &rfds);
-    tfds = rfds;
-    maxfd = prog->rdfd > prog->errfd ? prog->rdfd : prog->errfd;
-    tmout.tv_sec = 5;
-    tmout.tv_usec = 0;
-    rdbuf[0] = errbuf[0] = '\0';
-    start = TMRnow_double();
-    while ((got = select(maxfd+1, &tfds, 0, 0, &tmout)) >= 0) {
-        end = TMRnow_double();
-       IDLEtime += end - start;
-        start = end;
-       tmout.tv_sec = 5;
-       tmout.tv_usec = 0;
-       if (got > 0) {
-           if (FD_ISSET(prog->rdfd, &tfds)) {
-               okay = HandleProgInput(prog->rdfd, rdbuf, sizeof(rdbuf), HandleProgLine);
-               if (!okay) {
-                   close(prog->rdfd);
-                   FD_CLR(prog->rdfd, &tfds);
-                   kill(prog->pid, SIGTERM);
-               }
-           }
-           if (FD_ISSET(prog->errfd, &tfds)) {
-               okay = HandleProgInput(prog->errfd, errbuf, sizeof(errbuf), HandleErrorLine);
-               if (!okay) {
-                   close(prog->errfd);
-                   FD_CLR(prog->errfd, &tfds);
-                   kill(prog->pid, SIGTERM);
-               }
-           }
-       }
-       tfds = rfds;
-    }
-    end = TMRnow_double();
-    IDLEtime += end - start;
-    /* wait for it if he's toast. */
-    do {
-       tmp = waitpid(prog->pid, &status, 0);
-    } while ((tmp >= 0 || (tmp < 0 && errno == EINTR)) &&
-      !WIFEXITED(status) && !WIFSIGNALED(status));
-    if (WIFSIGNALED(status)) {
-       ubuf[0] = '\0';
-       syslog(L_NOTICE, "%s bad_hook program caught signal %d", ClientHost,
-         WTERMSIG(status));
-    } else if (WIFEXITED(status)) {
-       if (WEXITSTATUS(status) != 0) {
-           ubuf[0] = '\0';
-           syslog(L_TRACE, "%s bad_hook program exited with status %d",
-             ClientHost, WEXITSTATUS(status));
-       }
-    } else {
-       syslog(L_ERROR, "%s bad_hook waitpid failed: %m", ClientHost);
-       ubuf[0] = '\0';
-    }
-}
-
-/* execute a series of resolvers to get the remote username */
-static char *ResolveUser(AUTHGROUP *auth)
-{
-    int i, j;
-    char *cp;
-    char **args;
-    char *arg0;
-    char *resdir;
-    char *tmp;
-    EXECSTUFF *foo;
-    int done       = 0;
-    char buf[BIG_BUFFER];
-
-    if (!auth->res_methods)
-       return(0);
-
-    tmp = concatpath(innconf->pathbin, _PATH_AUTHDIR);
-    resdir = concatpath(tmp, _PATH_AUTHDIR_NOPASS);
-    free(tmp);
-
-    ubuf[0] = '\0';
-    for (i = 0; auth->res_methods[i]; i++) {
-       /* build the command line */
-       syslog(L_TRACE, "%s res starting resolver %s", ClientHost, auth->res_methods[i]->program);
-       if (auth->res_methods[i]->extra_logs) {
-           for (j = 0; auth->res_methods[i]->extra_logs[j]; j++)
-               syslog(L_NOTICE, "%s res also-log: %s", ClientHost,
-                 auth->res_methods[i]->extra_logs[j]);
-       }
-       cp = xstrdup(auth->res_methods[i]->program);
-       args = 0;
-       Argify(cp, &args);
-       arg0 = args[0];
-       if (args[0][0] != '/')
-           arg0 = concat(resdir, "/", arg0, (char *) 0);
-       /* exec the resolver */
-       foo = ExecProg(arg0, args);
-       if (foo) {
-           GetConnInfo(auth->res_methods[i], buf);
-           strlcat(buf, ".\r\n", sizeof(buf));
-           xwrite(foo->wrfd, buf, strlen(buf));
-           close(foo->wrfd);
-
-           GetProgInput(foo);
-           done = (ubuf[0] != '\0');
-           if (done)
-               syslog(L_TRACE, "%s res resolver successful, user %s", ClientHost, ubuf);
-           else
-               syslog(L_TRACE, "%s res resolver failed", ClientHost);
-           free(foo);
-       } else
-           syslog(L_ERROR, "%s res couldnt start resolver: %m", ClientHost);
-       /* clean up */
-       if (args[0][0] != '/') {
-           free(arg0);
-       }
-       free(args);
-       free(cp);
-       if (done)
-           /* this resolver succeeded */
-           break;
-    }
-    free(resdir);
-    if (ubuf[0])
-       return(ubuf);
-    return(0);
-}
-
-/* execute a series of authenticators to get the remote username */
-static char *AuthenticateUser(AUTHGROUP *auth, char *username, char *password, char *errorstr)
-{
-    int i, j;
-    char *cp;
-    char **args;
-    char *arg0;
-    char *resdir;
-    char *tmp;
-    char *script_path;
-    char newUser[BIG_BUFFER];
-    EXECSTUFF *foo;
-    int done       = 0;
-    int code;
-    char buf[BIG_BUFFER];
-
-    if (!auth->auth_methods)
-       return(0);
-
-    tmp = concatpath(innconf->pathbin, _PATH_AUTHDIR);
-    resdir = concatpath(tmp, _PATH_AUTHDIR_PASSWD);
-    free(tmp);
-
-    ubuf[0] = '\0';
-    newUser[0] = '\0';
-    for (i = 0; auth->auth_methods[i]; i++) {
-      if (auth->auth_methods[i]->type == PERMperl_auth) {
-#ifdef DO_PERL
-            cp = xstrdup(auth->auth_methods[i]->program);
-            args = 0;
-            Argify(cp, &args);
-            script_path = concat(args[0], (char *) 0);
-            if ((script_path != NULL) && (strlen(script_path) > 0)) {
-                if(!PerlLoaded) {
-                    loadPerl();
-                }
-                PERLsetup(NULL, script_path, "authenticate");
-                free(script_path);
-                perlAuthInit();
-          
-                code = perlAuthenticate(username, password, errorstr, newUser);
-                if (code == NNTP_AUTH_OK_VAL) {
-                    /* Set the value of ubuf to the right username */
-                    if (newUser[0] != '\0') {
-                      strlcpy(ubuf, newUser, sizeof(ubuf));
-                    } else {
-                      strlcpy(ubuf, username, sizeof(ubuf));
-                    }
-
-                    syslog(L_NOTICE, "%s user %s", ClientHost, ubuf);
-                    if (LLOGenable) {
-                        fprintf(locallog, "%s user %s\n", ClientHost, ubuf);
-                        fflush(locallog);
-                    }
-                    break;
-                } else {
-                    syslog(L_NOTICE, "%s bad_auth", ClientHost);
-                }            
-            } else {
-              syslog(L_ERROR, "No script specified in auth method.\n");
-            }
-#endif /* DO_PERL */    
-      } else if (auth->auth_methods[i]->type == PERMpython_auth) {
-#ifdef DO_PYTHON
-       cp = xstrdup(auth->auth_methods[i]->program);
-       args = 0;
-       Argify(cp, &args);
-       script_path = concat(args[0], (char *) 0);
-       if ((script_path != NULL) && (strlen(script_path) > 0)) {
-         code = PY_authenticate(script_path, username, password, errorstr, newUser);
-         free(script_path);
-         if (code < 0) {
-           syslog(L_NOTICE, "PY_authenticate(): authentication skipped due to no Python authentication method defined.");
-         } else {
-           if (code == NNTP_AUTH_OK_VAL) {
-              /* Set the value of ubuf to the right username */
-              if (newUser[0] != '\0') {
-                  strlcpy(ubuf, newUser, sizeof(ubuf));
-              } else {
-                  strlcpy(ubuf, username, sizeof(ubuf));
-              }
-              
-             syslog(L_NOTICE, "%s user %s", ClientHost, ubuf);
-             if (LLOGenable) {
-               fprintf(locallog, "%s user %s\n", ClientHost, ubuf);
-               fflush(locallog);
-             }
-             break;
-           } else {
-             syslog(L_NOTICE, "%s bad_auth", ClientHost);
-           }
-         }
-       } else {
-         syslog(L_ERROR, "No script specified in auth method.\n");
-       }
-#endif /* DO_PYTHON */
-      } else {
-       if (auth->auth_methods[i]->users &&
-         !MatchUser(auth->auth_methods[i]->users, username))
-           continue;
-
-       /* build the command line */
-       syslog(L_TRACE, "%s auth starting authenticator %s", ClientHost, auth->auth_methods[i]->program);
-       if (auth->auth_methods[i]->extra_logs) {
-           for (j = 0; auth->auth_methods[i]->extra_logs[j]; j++)
-               syslog(L_NOTICE, "%s auth also-log: %s", ClientHost,
-                 auth->auth_methods[i]->extra_logs[j]);
-       }
-       cp = xstrdup(auth->auth_methods[i]->program);
-       args = 0;
-       Argify(cp, &args);
-       arg0 = args[0];
-       if (args[0][0] != '/')
-           arg0 = concat(resdir, "/", arg0, (char *) 0);
-       /* exec the authenticator */
-       foo = ExecProg(arg0, args);
-       if (foo) {
-           GetConnInfo(auth->auth_methods[i], buf);
-           snprintf(buf+strlen(buf), sizeof(buf) - strlen(buf) - 3,
-                     "ClientAuthname: %s\r\n", username);
-           snprintf(buf+strlen(buf), sizeof(buf) - strlen(buf) - 3,
-                     "ClientPassword: %s\r\n", password);
-           strlcat(buf, ".\r\n", sizeof(buf));
-           xwrite(foo->wrfd, buf, strlen(buf));
-           close(foo->wrfd);
-
-           GetProgInput(foo);
-           done = (ubuf[0] != '\0');
-           if (done)
-               syslog(L_TRACE, "%s auth authenticator successful, user %s", ClientHost, ubuf);
-           else
-               syslog(L_TRACE, "%s auth authenticator failed", ClientHost);
-           free(foo);
-       } else
-           syslog(L_ERROR, "%s auth couldnt start authenticator: %m", ClientHost);
-       /* clean up */
-       if (args[0][0] != '/') {
-           free(arg0);
-       }
-       free(args);
-       free(cp);
-       if (done)
-           /* this authenticator succeeded */
-           break;
-      }
-    }
-    free(resdir);
-    if (ubuf[0])
-       return(ubuf);
-    return(0);
-}
diff --git a/nnrpd/post.c b/nnrpd/post.c
deleted file mode 100644 (file)
index 15546f3..0000000
+++ /dev/null
@@ -1,1281 +0,0 @@
-/*  $Revision: 7450 $
-**
-**  Check article, send it to the local server.
-*/
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "ov.h"
-#include "post.h"
-
-#define FLUSH_ERROR(F)         (fflush((F)) == EOF || ferror((F)))
-#define HEADER_DELTA           20
-
-static char     *tmpPtr ;
-static char    Error[SMBUF];
-static char    NGSEPS[] = NG_SEPARATOR;
-char   **OtherHeaders;
-int    OtherCount;
-bool   HeadersModified;
-static int     OtherSize;
-static const char * const BadDistribs[] = {
-    BAD_DISTRIBS
-};
-
-HEADER Table[] = {
-    /*  Name                    Canset  Type    Size  Value */
-    {   "Path",                 true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "From",                 true,   HTreq,  0,    NULL,    NULL, 0 },
-    {   "Newsgroups",           true,   HTreq,  0,    NULL,    NULL, 0 },
-    {   "Subject",              true,   HTreq,  0,    NULL,    NULL, 0 },
-    {   "Control",              true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Supersedes",           true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Followup-To",          true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Date",                 true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Organization",         true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Lines",                true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Sender",               true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Approved",             true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Distribution",         true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Expires",              true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Message-ID",           true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "References",           true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Reply-To",             true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "NNTP-Posting-Host",    false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "Mime-Version",         true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Content-Type",         true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Content-Transfer-Encoding", true, HTstd,  0,    NULL,    NULL, 0 },
-    {   "X-Trace",              false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "X-Complaints-To",      false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "NNTP-Posting-Date",    false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "Xref",                 false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "Injector-Info",        false,  HTstd,  0,    NULL,    NULL, 0 },
-    {   "Summary",              true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Keywords",             true,   HTstd,  0,    NULL,    NULL, 0 },
-    {   "Date-Received",        false,  HTobs,  0,    NULL,    NULL, 0 },
-    {   "Received",             false,  HTobs,  0,    NULL,    NULL, 0 },
-    {   "Posted",               false,  HTobs,  0,    NULL,    NULL, 0 },
-    {   "Posting-Version",      false,  HTobs,  0,    NULL,    NULL, 0 },
-    {   "Relay-Version",        false,  HTobs,  0,    NULL,    NULL, 0 },
-    {   "Cc",                   true, HTstd,  0,    NULL,    NULL, 0 },
-    {   "Bcc",                  true, HTstd,  0,    NULL,    NULL, 0 },
-    {   "To",                   true, HTstd,  0,    NULL,    NULL, 0 },
-};
-
-HEADER *EndOfTable = ARRAY_END(Table);
-
-\f
-
-/* Join() and MaxLength() are taken from innd.c */
-/*
-**  Turn any \r or \n in text into spaces.  Used to splice back multi-line
-**  headers into a single line.
-*/
-static char *
-Join(char      *text)
-{
-    char       *p;
-
-    for (p = text; *p; p++)
-       if (*p == '\n' || *p == '\r')
-           *p = ' ';
-    return text;
-}
-
-/*
-**  Return a short name that won't overrun our bufer or syslog's buffer.
-**  q should either be p, or point into p where the "interesting" part is.
-*/
-static char *
-MaxLength(char *p, char *q)
-{
-    static char                buff[80];
-    unsigned int       i;
-
-    /* Already short enough? */
-    i = strlen(p);
-    if (i < sizeof buff - 1)
-       return Join(p);
-
-    /* Don't want casts to unsigned to go horribly wrong. */
-    if (q < p || q > p + i)
-       q = p;
-
-    /* Simple case of just want the begining? */
-    if ((size_t)(q - p) < sizeof(buff) - 4) {
-       strlcpy(buff, p, sizeof(buff) - 3);
-        strlcat(buff, "...", sizeof(buff));
-    } else if ((p + i) - q < 10) {
-       /* Is getting last 10 characters good enough? */
-       strlcpy(buff, p, sizeof(buff) - 13);
-        strlcat(buff, "...", sizeof(buff) - 10);
-        strlcat(buff, &p[i - 10], sizeof(buff));
-    } else {
-       /* Not in last 10 bytes, so use double elipses. */
-        strlcpy(buff, p, sizeof(buff) - 16);
-        strlcat(buff, "...", sizeof(buff) - 13);
-        strlcat(buff, &q[-5], sizeof(buff) - 3);
-        strlcat(buff, "...", sizeof(buff));
-    }
-    return Join(buff);
-}
-/*
-**  Trim trailing spaces, return pointer to first non-space char.
-*/
-int
-TrimSpaces(char *p)
-{
-    char       *start;
-
-    for (start = p; ISWHITE(*start) || *start == '\n'; start++)
-       continue;
-    for (p = start + strlen(start); p > start && CTYPE(isspace, (int)p[-1]); p--)
-       continue;
-    return (int)(p - start);
-}
-
-
-/*
-**  Mark the end of the header starting at p, and return a pointer
-**  to the start of the next one or NULL.  Handles continuations.
-*/
-static char *
-NextHeader(char *p)
-{
-    for ( ; (p = strchr(p, '\n')) != NULL; p++) {
-       if (ISWHITE(p[1]))
-           continue;
-       *p = '\0';
-       return p + 1;
-    }
-    return NULL;
-}
-
-
-/*
-**  Strip any headers off the article and dump them into the table.
-**  On error, return NULL and fill in Error.
-*/
-static char *
-StripOffHeaders(char *article)
-{
-    char       *p;
-    char       *q;
-    HEADER     *hp;
-    char       c;
-
-    /* Scan through buffer, a header at a time. */
-    for (p = article; ; ) {
-
-       /* See if it's a known header. */
-       c = CTYPE(islower, (int)*p) ? toupper(*p) : *p;
-       for (hp = Table; hp < ARRAY_END(Table); hp++) {
-           if (c == hp->Name[0]
-            && p[hp->Size] == ':'
-            && strncasecmp(p, hp->Name, hp->Size) == 0) {
-               if (hp->Type == HTobs) {
-                   snprintf(Error, sizeof(Error), "Obsolete \"%s\" header",
-                             hp->Name);
-                   return NULL;
-               }
-               if (hp->Value) {
-                   snprintf(Error, sizeof(Error), "Duplicate \"%s\" header",
-                             hp->Name);
-                   return NULL;
-               }
-               hp->Value = &p[hp->Size + 1];
-               /* '\r\n' is replaced with '\n', and unnecessary to consider
-                  '\r' */
-               for (q = &p[hp->Size + 1]; ISWHITE(*q) || *q == '\n'; q++)
-                   continue;
-               hp->Body = q;
-               break;
-           }
-       }
-
-       /* No; add it to the set of other headers. */
-       if (hp == ARRAY_END(Table)) {
-           if (OtherCount >= OtherSize - 1) {
-               OtherSize += HEADER_DELTA;
-                OtherHeaders = xrealloc(OtherHeaders, OtherSize * sizeof(char *));
-           }
-           OtherHeaders[OtherCount++] = p;
-       }
-
-       /* Get start of next header; if it's a blank line, we hit the end. */
-       if ((p = NextHeader(p)) == NULL) {
-           strlcpy(Error, "Article has no body -- just headers",
-                    sizeof(Error));
-           return NULL;
-       }
-       if (*p == '\n')
-           break;
-    }
-
-    return p + 1;
-}
-
-\f
-
-/*
-**  Check the control message, and see if it's legit.  Return pointer to
-**  error message if not.
-*/
-static const char *
-CheckControl(char *ctrl)
-{
-    char       *p;
-    char       *q;
-    char       save;
-
-    /* Snip off the first word. */
-    for (p = ctrl; ISWHITE(*p); p++)
-       continue;
-    for (ctrl = p; *p && !ISWHITE(*p); p++)
-       continue;
-    if (p == ctrl)
-       return "Empty control message";
-    save = *p;
-    *p = '\0';
-
-    if (strcmp(ctrl, "cancel") == 0) {
-       for (q = p + 1; ISWHITE(*q); q++)
-           continue;
-       if (*q == '\0')
-           return "Message-ID missing in cancel";
-    }
-    else if (strcmp(ctrl, "sendsys")     == 0
-          || strcmp(ctrl, "senduuname")  == 0
-         || strcmp(ctrl, "version")     == 0
-          || strcmp(ctrl, "checkgroups") == 0
-         || strcmp(ctrl, "ihave")       == 0
-          || strcmp(ctrl, "sendme")      == 0
-         || strcmp(ctrl, "newgroup")    == 0
-          || strcmp(ctrl, "rmgroup")     == 0)
-       ;
-    else {
-       snprintf(Error, sizeof(Error),
-                 "\"%s\" is not a valid control message",
-                 MaxLength(ctrl,ctrl));
-       return Error;
-    }
-    *p = save;
-    return NULL;
-}
-
-
-/*
-**  Check the Distribution header, and exit on error.
-*/
-static const char *
-CheckDistribution(char *p)
-{
-    static char        SEPS[] = " \t,";
-    const char * const *dp;
-
-    if ((p = strtok(p, SEPS)) == NULL)
-       return "Can't parse Distribution line.";
-    do {
-       for (dp = BadDistribs; *dp; dp++)
-           if (uwildmat(p, *dp)) {
-               snprintf(Error, sizeof(Error), "Illegal distribution \"%s\"",
-                         MaxLength(p,p));
-               return Error;
-           }
-    } while ((p = strtok((char *)NULL, SEPS)) != NULL);
-    return NULL;
-}
-
-
-/*
-**  Process all the headers.  FYI, they're done in RFC-order.
-**  Return NULL if okay, or an error message.
-*/
-static const char *
-ProcessHeaders(int linecount, char *idbuff, bool ihave)
-{
-    static char                MONTHS[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
-    static char                datebuff[40];
-    static char                localdatebuff[40];
-    static char                orgbuff[SMBUF];
-    static char                linebuff[40];
-    static char                tracebuff[SMBUF];
-    static char        complaintsbuff[SMBUF];
-    static char                sendbuff[SMBUF];
-    static char                *newpath = NULL;
-    HEADER             *hp;
-    char               *p;
-    time_t             t;
-    struct tm          *gmt;
-    TIMEINFO           Now;
-    const char          *error;
-    pid_t               pid;
-    bool               addvirtual = false;
-
-    /* Various things need Now to be set. */
-    if (GetTimeInfo(&Now) < 0) {
-        snprintf(Error, sizeof(Error), "Can't get the time, %s",
-                 strerror(errno));
-        return Error;
-    }
-
-    /* Do some preliminary fix-ups. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++) {
-       if (!ihave && !hp->CanSet && hp->Value) {
-           snprintf(Error, sizeof(Error),
-                    "Can't set system \"%s\" header", hp->Name);
-           return Error;
-       }
-       if (hp->Value) {
-           hp->Len = TrimSpaces(hp->Value);
-           if (hp->Len == 0)
-               hp->Value = hp->Body = NULL;
-       }
-    }
-
-    /* If authorized, add the header based on our info.  If not authorized,
-       zap the Sender so we don't put out unauthenticated data. */
-    if (PERMaccessconf->nnrpdauthsender) {
-       if (PERMauthorized && PERMuser[0] != '\0') {
-            p = strchr(PERMuser, '@');
-            if (p == NULL) {
-                snprintf(sendbuff, sizeof(sendbuff), "%s@%s", PERMuser,
-                         ClientHost);
-            } else {
-                snprintf(sendbuff, sizeof(sendbuff), "%s", PERMuser);
-            }
-           HDR_SET(HDR__SENDER, sendbuff);
-       } else {
-           HDR_SET(HDR__SENDER, NULL);
-       }
-    }
-
-    /* Set Date.  datebuff is used later for NNTP-Posting-Date, so we have
-       to set it and it has to be the UTC date. */
-    if (!makedate(-1, false, datebuff, sizeof(datebuff)))
-        return "Can't generate date header";
-    if (HDR(HDR__DATE) == NULL) {
-       if (ihave)
-           return "Missing \"Date\" header";
-        if (PERMaccessconf->localtime) {
-            if (!makedate(-1, true, localdatebuff, sizeof(localdatebuff)))
-                return "Can't generate local date header";
-           HDR_SET(HDR__DATE, localdatebuff);
-       } else {
-           HDR_SET(HDR__DATE, datebuff);
-       }
-    } else {
-       if ((t = parsedate(HDR(HDR__DATE), &Now)) == -1)
-           return "Can't parse \"Date\" header";
-       if (t > Now.time + DATE_FUZZ)
-           return "Article posted in the future";
-    }
-
-    /* Newsgroups are checked later. */
-
-    if (HDR(HDR__CONTROL)) {
-       if ((error = CheckControl(HDR(HDR__CONTROL))) != NULL)
-           return error;
-    } else {
-       p = HDR(HDR__SUBJECT);
-       if (p == NULL)
-           return "Required \"Subject\" header is missing";
-        if (strncmp(p, "cmsg ", 5) == 0) {
-            HDR_SET(HDR__CONTROL, p + 5);
-            if ((error = CheckControl(HDR(HDR__CONTROL))) != NULL)
-                return error;
-        }
-    }
-
-    /* Set Message-ID */
-    if (HDR(HDR__MESSAGEID) == NULL) {
-       if (ihave)
-           return "Missing \"Message-ID\" header";
-       HDR_SET(HDR__MESSAGEID, idbuff);
-    }
-
-    /* Set Path */
-    if (HDR(HDR__PATH) == NULL) {
-       if (ihave)
-           return "Missing \"Path\" header";
-       /* Note that innd will put host name here for us. */
-       HDR_SET(HDR__PATH, PATHMASTER);
-       if (VirtualPathlen > 0)
-           addvirtual = true;
-    } else if (PERMaccessconf->strippath) {
-       /* Here's where to do Path changes for new Posts. */
-       if ((p = strrchr(HDR(HDR__PATH), '!')) != NULL) {
-           p++;
-           if (*p == '\0') {
-               HDR_SET(HDR__PATH, PATHMASTER);
-               if (VirtualPathlen > 0)
-                   addvirtual = true;
-           } else {
-               HDR_SET(HDR__PATH, p);
-               if ((VirtualPathlen > 0) &&
-                   strcmp(p, PERMaccessconf->pathhost) != 0)
-                   addvirtual = true;
-           }
-       } else if (VirtualPathlen > 0)
-           addvirtual = true;
-    } else {
-       if ((VirtualPathlen > 0) &&
-           (p = strchr(HDR(HDR__PATH), '!')) != NULL) {
-           *p = '\0';
-           if (strcmp(HDR(HDR__PATH), PERMaccessconf->pathhost) != 0)
-               addvirtual = true;
-           *p = '!';
-       } else if (VirtualPathlen > 0)
-           addvirtual = true;
-    }
-    if (addvirtual) {
-       if (newpath != NULL)
-           free(newpath);
-        newpath = concat(VirtualPath, HDR(HDR__PATH), (char *) 0);
-       HDR_SET(HDR__PATH, newpath);
-    }
-    
-
-    /* Reply-To; left alone. */
-    /* Sender; set above. */
-
-    /* Check Expires. */
-    if (HDR(HDR__EXPIRES) && parsedate(HDR(HDR__EXPIRES), &Now) == -1)
-       return "Can't parse \"Expires\" header";
-
-    /* References; left alone. */
-    /* Control; checked above. */
-
-    /* Distribution. */
-    if ((p = HDR(HDR__DISTRIBUTION)) != NULL) {
-       p = xstrdup(p);
-       error = CheckDistribution(p);
-       free(p);
-       if (error != NULL)
-           return error;
-    }
-
-    /* Set Organization */
-    if (!ihave && HDR(HDR__ORGANIZATION) == NULL
-     && (p = PERMaccessconf->organization) != NULL) {
-       strlcpy(orgbuff, p, sizeof(orgbuff));
-       HDR_SET(HDR__ORGANIZATION, orgbuff);
-    }
-
-    /* Keywords; left alone. */
-    /* Summary; left alone. */
-    /* Approved; left alone. */
-
-    /* Set Lines */
-    if (!ihave) {
-       snprintf(linebuff, sizeof(linebuff), "%d", linecount);
-       HDR_SET(HDR__LINES, linebuff);
-    }
-
-    /* Supersedes; left alone. */
-
-    /* NNTP-Posting host; set. */
-    if (!ihave && PERMaccessconf->addnntppostinghost) 
-    HDR_SET(HDR__NNTPPOSTINGHOST, ClientHost);
-    /* NNTP-Posting-Date - not in RFC (yet) */
-    if (!ihave && PERMaccessconf->addnntppostingdate)
-    HDR_SET(HDR__NNTPPOSTINGDATE, datebuff);
-
-    /* X-Trace; set */
-    t = time((time_t *)NULL) ;
-    pid = (long) getpid() ;
-    if ((gmt = gmtime(&Now.time)) == NULL)
-       return "Can't get the time";
-    if (VirtualPathlen > 0)
-       p = PERMaccessconf->domain;
-    else
-       if ((p = GetFQDN(PERMaccessconf->domain)) == NULL)
-           p = "unknown";
-    snprintf(tracebuff, sizeof(tracebuff),
-             "%s %ld %ld %s (%d %3.3s %d %02d:%02d:%02d GMT)",
-             p, (long) t, (long) pid, ClientIpString,
-             gmt->tm_mday, &MONTHS[3 * gmt->tm_mon], 1900 + gmt->tm_year,
-             gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
-    HDR_SET(HDR__XTRACE, tracebuff);
-
-    /* X-Complaints-To; set */
-    if ((p = PERMaccessconf->complaints) != NULL)
-       snprintf (complaintsbuff, sizeof(complaintsbuff), "%s", p);
-    else {
-       static const char newsmaster[] = NEWSMASTER;
-
-       if ((p = PERMaccessconf->fromhost) != NULL && strchr(newsmaster, '@') == NULL)
-           snprintf (complaintsbuff, sizeof(complaintsbuff), "%s@%s",
-                      newsmaster, p);
-       else
-           snprintf (complaintsbuff, sizeof(complaintsbuff), "%s",
-                      newsmaster);
-    }
-    HDR_SET(HDR__XCOMPLAINTSTO, complaintsbuff);
-
-    /* Clear out some headers that should not be here */
-    if (!ihave && PERMaccessconf->strippostcc) {
-       HDR_SET(HDR__CC, NULL);
-       HDR_SET(HDR__BCC, NULL);
-       HDR_SET(HDR__TO, NULL);
-    }
-    /* Now make sure everything is there. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Type == HTreq && hp->Value == NULL) {
-           snprintf(Error, sizeof(Error),
-                     "Required \"%s\" header is missing", hp->Name);
-           return Error;
-       }
-
-    return NULL;
-}
-
-
-/*
-**  See if the user has more included text than new text.  Simple-minded,
-**  but reasonably effective for catching neophyte's mistakes.  Son-of-1036
-**  says:
-**
-**      NOTE: While encouraging trimming is desirable, the 50% rule imposed
-**      by some old posting agents is both inadequate and counterproductive.
-**      Posters do not respond to it by being more selective about quoting;
-**      they respond by padding short responses, or by using different
-**      quoting styles to defeat automatic analysis.  The former adds
-**      unnecessary noise and volume, while the latter also defeats more
-**      useful forms of automatic analysis that reading agents might wish to
-**      do.
-**
-**      NOTE:  At the very least, if a minimum-unquoted quota is being set,
-**      article bodies shorter than (say) 20 lines, or perhaps articles
-**      which exceed the quota by only a few lines, should be exempt.  This
-**      avoids the ridiculous situation of complaining about a 5-line
-**      response to a 6-line quote.
-**
-**  Accordingly, bodies shorter than 20 lines are exempt.  A line starting
-**  with >, |, or : is included text.  Decrement the count on lines starting
-**  with < so that we don't reject diff(1) output.
-*/
-static const char *
-CheckIncludedText(const char *p, int lines)
-{
-    int i;
-
-    if (lines < 20)
-        return NULL;
-    for (i = 0; ; p++) {
-        switch (*p) {
-            case '>': i++; break;
-            case '|': i++; break;
-            case ':': i++; break;
-            case '<': i--; break;
-            default:       break;
-        }
-        p = strchr(p, '\n');
-        if (p == NULL)
-            break;
-    }
-    if (i * 2 > lines)
-        return "Article not posted -- more included text than new text";
-    return NULL;
-}
-
-\f
-
-/*
-**  Try to mail an article to the moderator of the group.
-*/
-static const char *
-MailArticle(char *group, char *article)
-{
-    static char        CANTSEND[] = "Can't send text to mailer";
-    FILE       *F;
-    HEADER     *hp;
-    int                i;
-    char       *address;
-    char       buff[SMBUF];
-    char       *mta;
-
-    /* Try to get the address first. */
-    if ((address = GetModeratorAddress(NULL, NULL, group, PERMaccessconf->moderatormailer)) == NULL) {
-       snprintf(Error, sizeof(Error), "No mailing address for \"%s\" -- %s",
-                 group, "ask your news administrator to fix this");
-       free(group);  
-       return Error;
-    }
-    free(group);
-
-    /* Now build up the command (ignore format/argument mismatch errors,
-     * in case %s isn't in inconf->mta) and send the headers. */
-    if ((mta = innconf->mta) == NULL)
-       return "Can't start mailer - mta not set";
-    snprintf(buff, sizeof(buff), innconf->mta, address);
-    if ((F = popen(buff, "w")) == NULL)
-       return "Can't start mailer";
-    fprintf(F, "To: %s\n", address);
-    if (FLUSH_ERROR(F)) {
-       pclose(F);
-       return CANTSEND;
-    }
-
-    /* Write the headers, a blank line, then the article. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value) {
-           if (*hp->Value == ' ' || *hp->Value == '\t')
-                fprintf(F, "%s:%s\n", hp->Name, hp->Value);
-           else
-                fprintf(F, "%s: %s\n", hp->Name, hp->Value);
-           if (FLUSH_ERROR(F)) {
-               pclose(F);
-               return CANTSEND;
-           }
-       }
-    for (i = 0; i < OtherCount; i++) {
-       fprintf(F, "%s\n", OtherHeaders[i]);
-       if (FLUSH_ERROR(F)) {
-           pclose(F);
-           return CANTSEND;
-       }
-    }
-    fprintf(F, "\n");
-    i = strlen(article);
-    if (fwrite(article, 1, i, F) != (size_t)i)
-       return "Can't send article";
-    if (FLUSH_ERROR(F)) {
-       pclose(F);
-       return CANTSEND;
-    }
-    i = pclose(F);
-    if (i) {
-       snprintf(Error, sizeof(Error), "Mailer exited with status %d -- %s",
-                 i, "Article might not have been mailed");
-       return Error;
-    }
-    return NULL;
-}
-
-
-/*
-**  Check the newsgroups and make sure they're all valid, that none are
-**  moderated, etc.
-*/
-static const char *
-ValidNewsgroups(char *hdr, char **modgroup)
-{
-    static char                distbuff[SMBUF];
-    char               *groups;
-    char               *p;
-    bool               approved;
-    struct _DDHANDLE   *h;
-    char               *grplist[2];
-    bool               IsNewgroup;
-    bool               FoundOne;
-    int                 flag;
-    bool                hookpresent = false;
-
-#ifdef DO_PYTHON
-    hookpresent = PY_use_dynamic;
-#endif /* DO_PYTHON */
-
-    p = HDR(HDR__CONTROL);
-    IsNewgroup = (p && strncmp(p, "newgroup", 8) == 0);
-    groups = xstrdup(hdr);
-    if ((p = strtok(groups, NGSEPS)) == NULL)
-       return "Can't parse newsgroups line";
-    Error[0] = '\0';
-
-    /* Reject all articles with Approved headers unless the user is allowed to
-       add them, even to unmoderated or local groups.  We want to reject them
-       to unmoderated groups in case there's a disagreement of opinion
-       between various sites as to the moderation status. */
-    approved = HDR(HDR__APPROVED) != NULL;
-    if (approved && !PERMaccessconf->allowapproved) {
-        snprintf(Error, sizeof(Error),
-                 "You are not allowed to approve postings");
-    }
-
-    FoundOne = false;
-    h = DDstart((FILE *)NULL, (FILE *)NULL);
-    do {
-       if (innconf->mergetogroups && p[0] == 't' && p[1] == 'o' && p[2] == '.')
-           p = "to";
-        if (!hookpresent && PERMspecified) {
-           grplist[0] = p;
-           grplist[1] = NULL;
-           if (!PERMmatch(PERMpostlist, grplist)) {
-               snprintf(Error, sizeof(Error),
-                         "You are not allowed to post to %s\r\n", p);
-           }
-        }
-       if (!OVgroupstats(p, NULL, NULL, NULL, &flag))
-           continue;
-       FoundOne = true;
-       DDcheck(h, p);
-       switch (flag) {
-       case NF_FLAG_OK:
-#ifdef DO_PYTHON
-       if (PY_use_dynamic) {
-           char    *reply;
-
-           /* Authorize user using Python module method dynamic */
-           if (PY_dynamic(PERMuser, p, true, &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);
-                   snprintf(Error, sizeof(Error), "%s\r\n", reply);
-                    free(reply);
-                   break;
-               }
-           }
-       }
-#endif /* DO_PYTHON */
-           break;
-       case NF_FLAG_MODERATED:
-           if (!approved && modgroup != NULL && !*modgroup)
-               *modgroup = xstrdup(p);
-           break;
-       case NF_FLAG_IGNORE:
-       case NF_FLAG_NOLOCAL:
-           if (!PERMaccessconf->locpost)
-               snprintf(Error, sizeof(Error),
-                         "Postings to \"%s\" are not allowed here.", p);
-           break;
-       case NF_FLAG_EXCLUDED:
-           /* Do NOT return an error. */
-           break;
-       case NF_FLAG_ALIAS:
-           snprintf(Error, sizeof(Error),
-                     "The newsgroup \"%s\" has been renamed.\n", p);
-           break;
-       }
-    } while ((p = strtok((char *)NULL, NGSEPS)) != NULL);
-    free(groups);
-
-    if (!FoundOne && !IsNewgroup)
-       snprintf(Error, sizeof(Error), "No valid newsgroups in \"%s\"",
-                 MaxLength(hdr,hdr));
-    if (Error[0]) {
-        tmpPtr = DDend(h);
-       free(tmpPtr);
-        if (modgroup != NULL && *modgroup != NULL) {
-            free(*modgroup);
-            *modgroup = NULL;
-        }
-       return Error;
-    }
-
-    p = DDend(h);
-    if (HDR(HDR__DISTRIBUTION) == NULL && *p) {
-       strlcpy(distbuff, p, sizeof(distbuff));
-       HDR_SET(HDR__DISTRIBUTION, distbuff);
-    }
-    free(p);
-    return NULL;
-}
-
-
-/*
-**  Send a quit message to the server, eat its reply.
-*/
-static void
-SendQuit(FILE *FromServer, FILE *ToServer)
-{
-    char       buff[NNTP_STRLEN];
-
-    fprintf(ToServer, "quit\r\n");
-    fflush(ToServer);
-    fclose(ToServer);
-    fgets(buff, sizeof buff, FromServer);
-    fclose(FromServer);
-}
-
-
-/*
-**  Offer the article to the server, return its reply.
-*/
-static int
-OfferArticle(char *buff, int buffsize, FILE *FromServer, FILE *ToServer)
-{
-    static char                CANTSEND[] = "Can't send %s to server, %s";
-
-    fprintf(ToServer, "ihave %s\r\n", HDR(HDR__MESSAGEID));
-    if (FLUSH_ERROR(ToServer)
-     || fgets(buff, buffsize, FromServer) == NULL) {
-       snprintf(buff, sizeof(buff), CANTSEND, "IHAVE", strerror(errno));
-       return -1;
-    }
-    return atoi(buff);
-}
-
-
-/*
-**  Spool article to temp file.
-*/
-static const char *
-SpoolitTo(char *article, char *err, char *SpoolDir)
-{
-    static char        CANTSPOOL[NNTP_STRLEN+2];
-    HEADER *hp;
-    FILE *F = NULL;
-    int        i, fd;
-    char *tmpspool = NULL;
-    char *spoolfile = NULL;
-    char *q;
-
-    /* Initialize the returned error message */
-    snprintf(CANTSPOOL, sizeof(CANTSPOOL),
-             "%s and can't write text to local spool file", err);
-
-    /* Try to write it to the spool dir. */
-    tmpspool = concatpath(SpoolDir, ".XXXXXX");
-    fd = mkstemp(tmpspool);
-    if (fd < 0) {
-        syslog(L_FATAL, "cant create temporary spool file %s %m", tmpspool);
-        goto fail;
-    }
-    F = fdopen(fd, "w");
-    if (F == NULL) {
-        syslog(L_FATAL, "cant open %s %m", tmpspool);
-        goto fail;
-    }
-    fchmod(fileno(F), BATCHFILE_MODE);
-
-    /* Write the headers and a blank line. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value) {
-            q = xstrndup(hp->Value, hp->Body - hp->Value + hp->Len);
-           if (*hp->Value == ' ' || *hp->Value == '\t')
-               fprintf(F, "%s:%s\n", hp->Name, q);
-           else
-               fprintf(F, "%s: %s\n", hp->Name, q);
-           if (FLUSH_ERROR(F)) {
-               fclose(F);
-               free(q);
-                goto fail;
-           }
-           free(q);
-       }
-    for (i = 0; i < OtherCount; i++) {
-       fprintf(F, "%s\n", OtherHeaders[i]);
-       if (FLUSH_ERROR(F)) {
-           fclose(F);
-           goto fail;
-       }
-    }
-    fprintf(F, "\n");
-
-    /* Write the article body */
-    i = strlen(article);
-    if (fwrite(article, 1, i, F) != (size_t)i) {
-        fclose(F);
-        goto fail;
-    }
-
-    /* Flush and catch any errors */
-    if (fclose(F))
-        goto fail;
-
-    /* Rename the spool file to something rnews will pick up. */
-    spoolfile = concatpath(SpoolDir, "XXXXXX");
-    fd = mkstemp(spoolfile);
-    if (fd < 0) {
-        syslog(L_FATAL, "cant create spool file %s %m", spoolfile);
-        goto fail;
-    }
-    close(fd);
-    if (rename(tmpspool, spoolfile) < 0) {
-        syslog(L_FATAL, "cant rename %s %s %m", tmpspool, spoolfile);
-       goto fail;
-    }
-
-    /* Article has been spooled */
-    free(tmpspool);
-    free(spoolfile);
-    return NULL;
-
- fail:
-    if (tmpspool != NULL)
-        free(tmpspool);
-    if (spoolfile != NULL)
-        free(spoolfile);
-    return CANTSPOOL;
-}
-
-/*
-**  Spool article to temp file.
-*/
-static const char *
-Spoolit(char *article, char *err)
-{
-    return SpoolitTo(article, err, innconf->pathincoming);
-}
-static char *Towire(char *p) {
-    char       *q, *r, *s;
-    int                curlen, len = BIG_BUFFER;
-
-    for (r = p, q = s = xmalloc(len); *r != '\0' ;) {
-       curlen = q - s;
-       if (curlen + 3 > len) {
-           len += BIG_BUFFER;
-            s = xrealloc(s, len);
-           q = s + curlen;
-       }
-       if (*r == '\n') {
-           if (r > p) {
-               if (*(r - 1) != '\r')
-                   *q++ = '\r';
-           } else {
-               /* this should not happen */
-               free(s);
-               return NULL;
-           }
-       }
-       *q++ = *r++;
-    }
-    curlen = q - s;
-    if (curlen + 1 > len) {
-       len++;
-        s = xrealloc(s, len);
-       q = s + curlen;
-    }
-    *q = '\0';
-    return s;
-}
-
-const char *
-ARTpost(char *article,
-       char *idbuff,
-       bool ihave,
-       bool *permanent)
-{
-    static char        CANTSEND[] = "Can't send %s to server, %s";
-    int                i;
-    char       *p, *q;
-    char       *next;
-    HEADER     *hp;
-    FILE       *ToServer;
-    FILE       *FromServer;
-    char       buff[NNTP_STRLEN + 2], frombuf[SMBUF];
-    char       *modgroup = NULL;
-    const char *error;
-    char       *TrackID;
-    char       *DirTrackID;
-    FILE       *ftd;
-    char       SDir[255];
-
-    /* Assume errors are permanent, until we discover otherwise */
-    *permanent = true;
-
-    /* Set up the other headers list. */
-    if (OtherHeaders == NULL) {
-       OtherSize = HEADER_DELTA;
-       OtherHeaders = xmalloc(OtherSize * sizeof(char *));
-    }
-
-    /* Basic processing. */
-    OtherCount = 0;
-    for (hp = Table; hp < ARRAY_END(Table); hp++) {
-       hp->Size = strlen(hp->Name);
-       hp->Value = hp->Body = NULL;
-    }
-    if ((article = StripOffHeaders(article)) == NULL)
-       return Error;
-    for (i = 0, p = article; p; i++, p = next + 1)
-       if ((next = strchr(p, '\n')) == NULL)
-           break;
-    if (PERMaccessconf->checkincludedtext) {
-       if ((error = CheckIncludedText(article, i)) != NULL)
-               return error;
-    }
-    if ((error = ProcessHeaders(i, idbuff, ihave)) != NULL)
-       return error;
-    if (i == 0 && HDR(HDR__CONTROL) == NULL)
-       return "Article is empty";
-
-    if ((error = ValidNewsgroups(HDR(HDR__NEWSGROUPS), &modgroup)) != NULL)
-       return error;
-    
-    strlcpy(frombuf, HDR(HDR__FROM), sizeof(frombuf));
-    for (i = 0, p = frombuf;p < frombuf + sizeof(frombuf);)
-       if ((p = strchr(p, '\n')) == NULL)
-           break;
-       else
-           *p++ = ' ';
-    HeaderCleanFrom(frombuf);
-    p = strchr(frombuf, '@');
-    if (p) {
-       strlcpy(frombuf, p+1, sizeof(frombuf));
-       p = strrchr(frombuf, '.');
-       if (!p) {
-           if (modgroup)
-               free(modgroup);
-           return "From: address not in Internet syntax";
-       }
-    }
-    else {
-       if (modgroup)
-           free(modgroup);
-       return "From: address not in Internet syntax";
-    }
-    if ((p = HDR(HDR__FOLLOWUPTO)) != NULL
-     && strcmp(p, "poster") != 0
-     && (error = ValidNewsgroups(p, (char **)NULL)) != NULL) {
-       if (modgroup)
-           free(modgroup);
-       return error;
-    }
-    if ((PERMaccessconf->localmaxartsize > 0) &&
-               (strlen(article) > (unsigned)PERMaccessconf->localmaxartsize)) {
-        snprintf(Error, sizeof(Error),
-                 "Article is bigger then local limit of %ld bytes\n",
-                 PERMaccessconf->localmaxartsize);
-        if (modgroup)
-            free(modgroup);
-        return Error;
-    }
-
-#if defined(DO_PERL)
-    /* Calls the Perl subroutine for headers management */
-    p = PERMaccessconf->nnrpdperlfilter ? HandleHeaders(article) : NULL;
-    if (p != NULL) {
-       if (idbuff) {
-           if (modgroup)
-               sprintf(idbuff, "(mailed to moderator for %s)", modgroup);
-           else
-               strlcpy(idbuff, HDR(HDR__MESSAGEID), SMBUF);
-       }
-       if (strncmp(p, "DROP", 4) == 0) {
-           syslog(L_NOTICE, "%s post %s", ClientHost, p);
-           if (modgroup)
-               free(modgroup);
-           return NULL;
-       }
-       else if (strncmp(p, "SPOOL", 5) == 0) {
-           syslog(L_NOTICE, "%s post %s", ClientHost, p);
-           strlcpy(SDir, innconf->pathincoming, sizeof(SDir));
-           if (modgroup) {
-               free(modgroup);
-                strlcat(SDir, "/spam/mod", sizeof(SDir));
-               return SpoolitTo(article, p, SDir);
-           }
-           else {
-                strlcat(SDir, "/spam", sizeof(SDir));
-               return SpoolitTo(article, p, SDir);
-            }
-       }
-       else
-       {
-           if (modgroup)
-               free(modgroup);
-           return p;
-       }
-    }
-#endif /* defined(DO_PERL) */
-
-    /* handle mailing to moderated groups */
-
-    if (modgroup) {
-       if (idbuff != NULL) {
-           const char *retstr;
-           retstr = MailArticle(modgroup, article);
-           strcpy (idbuff,"(mailed to moderator)") ;
-           return retstr;
-       }
-       return MailArticle(modgroup, article);
-    }
-
-    if (idbuff)
-       strlcpy(idbuff, HDR(HDR__MESSAGEID), SMBUF);
-
-    if (PERMaccessconf->spoolfirst)
-       return Spoolit(article, Error);
-
-    if (Offlinepost)
-         return Spoolit(article,Error);
-
-    /* Open a local connection to the server. */
-    if (PERMaccessconf->nnrpdposthost != NULL)
-       i = NNTPconnect(PERMaccessconf->nnrpdposthost, PERMaccessconf->nnrpdpostport,
-                                       &FromServer, &ToServer, buff);
-    else {
-#if    defined(HAVE_UNIX_DOMAIN_SOCKETS)
-       i = NNTPlocalopen(&FromServer, &ToServer, buff);
-#else
-       i = NNTPremoteopen(innconf->port, &FromServer,
-                                       &ToServer, buff);
-#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
-    }
-
-    /* If we cannot open the connection, initialize the error message and
-     * attempt to recover from this by spooling it locally */
-    if (i < 0) {
-       if (buff[0])
-           strlcpy(Error, buff, sizeof(Error));
-       else
-           snprintf(Error, sizeof(Error), CANTSEND, "connect request",
-                     strerror(errno));
-        return Spoolit(article,Error);
-    }
-    if (Tracing)
-       syslog(L_TRACE, "%s post_connect %s",
-           ClientHost, PERMaccessconf->nnrpdposthost ? PERMaccessconf->nnrpdposthost : "localhost");
-
-    /* The code below ignores too many return values for my tastes.  At least
-     * they are all inside cases that are most likely never going to happen --
-     * for example, if the server crashes. */
-
-    /* Offer article to server. */
-    i = OfferArticle(buff, (int)sizeof buff, FromServer, ToServer);
-    if (i == NNTP_AUTH_NEEDED_VAL) {
-        /* Send authorization. */
-        if (NNTPsendpassword(PERMaccessconf->nnrpdposthost, FromServer, ToServer) < 0) {
-            snprintf(Error, sizeof(Error), "Can't authorize with %s",
-                     PERMaccessconf->nnrpdposthost ? PERMaccessconf->nnrpdposthost : "innd");
-            return Spoolit(article,Error);
-        }
-        i = OfferArticle(buff, (int)sizeof buff, FromServer, ToServer);
-    }
-    if (i != NNTP_SENDIT_VAL) {
-        strlcpy(Error, buff, sizeof(Error));
-        SendQuit(FromServer, ToServer);
-       if (i != NNTP_HAVEIT_VAL)
-           return Spoolit(article, Error);
-       if (i == NNTP_REJECTIT_VAL || i == NNTP_RESENDIT_VAL) {
-           *permanent = false;
-       }
-        return Error;
-    }
-    if (Tracing)
-       syslog(L_TRACE, "%s post starting", ClientHost);
-
-    /* Write the headers and a blank line. */
-    for (hp = Table; hp < ARRAY_END(Table); hp++)
-       if (hp->Value) {
-            q = xstrndup(hp->Value, hp->Body - hp->Value + hp->Len);
-           if (strchr(q, '\n') != NULL) {
-               if ((p = Towire(q)) != NULL) {
-                   /* there is no white space, if hp->Value and hp->Body is the same */
-                   if (*hp->Value == ' ' || *hp->Value == '\t')
-                       fprintf(ToServer, "%s:%s\r\n", hp->Name, p);
-                   else
-                       fprintf(ToServer, "%s: %s\r\n", hp->Name, p);
-                   free(p);
-               }
-           } else {
-               /* there is no white space, if hp->Value and hp->Body is the same */
-               if (*hp->Value == ' ' || *hp->Value == '\t')
-                   fprintf(ToServer, "%s:%s\r\n", hp->Name, q);
-               else
-                   fprintf(ToServer, "%s: %s\r\n", hp->Name, q);
-           }
-           free(q);
-       }
-    for (i = 0; i < OtherCount; i++) {
-       if (strchr(OtherHeaders[i], '\n') != NULL) {
-           if ((p = Towire(OtherHeaders[i])) != NULL) {
-               fprintf(ToServer, "%s\r\n", p);
-               free(p);
-           }
-       } else {
-           fprintf(ToServer, "%s\r\n", OtherHeaders[i]);
-       }
-    }
-    fprintf(ToServer, "\r\n");
-    if (FLUSH_ERROR(ToServer)) {
-       snprintf(Error, sizeof(Error), CANTSEND, "headers", strerror(errno));
-       fclose(FromServer);
-       fclose(ToServer);
-       return Spoolit(article, Error);
-    }
-
-    /* Send the article, get the server's reply. */
-    if (NNTPsendarticle(article, ToServer, true) < 0
-     || fgets(buff, sizeof buff, FromServer) == NULL) {
-       snprintf(Error, sizeof(Error), CANTSEND, "article", strerror(errno));
-       fclose(FromServer);
-       fclose(ToServer);
-       return Spoolit(article, Error);
-    }
-
-    /* Did the server want the article? */
-    if ((i = atoi(buff)) != NNTP_TOOKIT_VAL) {
-       strlcpy(Error, buff, sizeof(Error));
-       SendQuit(FromServer, ToServer);
-       syslog(L_TRACE, "%s server rejects %s from %s", ClientHost, HDR(HDR__MESSAGEID), HDR(HDR__PATH));
-       if (i != NNTP_REJECTIT_VAL && i != NNTP_HAVEIT_VAL)
-           return Spoolit(article, Error);
-       if (i == NNTP_REJECTIT_VAL || i == NNTP_RESENDIT_VAL) {
-           *permanent = false;
-       }
-       return Error;
-    }
-
-    /* Send a quit and close down */
-    SendQuit(FromServer, ToServer);
-
-    /* Tracking */
-    if (PERMaccessconf->readertrack) {
-        TrackID = concat(innconf->pathlog, "/trackposts/track.",
-                         HDR(HDR__MESSAGEID), (char *) 0);
-       if ((ftd = fopen(TrackID,"w")) == NULL) {
-           DirTrackID = concatpath(innconf->pathlog, "trackposts");
-           MakeDirectory(DirTrackID, false);
-           free(DirTrackID);
-       }
-       if (ftd == NULL && (ftd = fopen(TrackID,"w")) == NULL) {
-           syslog(L_ERROR, "%s (%s) open %s: %m",
-               ClientHost, Username, TrackID);
-           free(TrackID);
-           return NULL;
-       }
-       for (hp = Table; hp < ARRAY_END(Table); hp++)
-           if (hp->Value) {
-                q = xstrndup(hp->Value, hp->Body - hp->Value + hp->Len);
-               if (strchr(q, '\n') != NULL) {
-                   if ((p = Towire(q)) != NULL) {
-                       /* there is no white space, if hp->Value and hp->Body is the same */
-                       if (*hp->Value == ' ' || *hp->Value == '\t')
-                           fprintf(ftd, "%s:%s\r\n", hp->Name, p);
-                       else
-                           fprintf(ftd, "%s: %s\r\n", hp->Name, p);
-                       free(p);
-                   }
-               } else {
-                   /* there is no white space, if hp->Value and hp->Body is the same */
-                   if (*hp->Value == ' ' || *hp->Value == '\t')
-                       fprintf(ftd, "%s:%s\r\n", hp->Name, q);
-                   else
-                       fprintf(ftd, "%s: %s\r\n", hp->Name, q);
-               }
-               free(q);
-           }
-       for (i = 0 ; i < OtherCount ; i++) {
-           if (strchr(OtherHeaders[i], '\n') != NULL) {
-               if ((p = Towire(OtherHeaders[i])) != NULL) {
-                   fprintf(ftd, "%s\r\n", p);
-                   free(p);
-               }
-           } else {
-               fprintf(ftd, "%s\r\n", OtherHeaders[i]);
-           }
-       }
-       fprintf(ftd,"\r\n");
-       NNTPsendarticle(article, ftd, true);
-       if (fclose(ftd) != EOF) {
-           syslog(L_NOTICE, "%s (%s) posttrack ok %s",
-               ClientHost, Username, TrackID);
-           if (LLOGenable)
-               fprintf(locallog, "%s (%s) posttrack ok %s\n",
-                   ClientHost, Username, TrackID);
-       } else {
-           syslog(L_ERROR, "%s (%s) posttrack error 2 %s",
-               ClientHost, Username, TrackID);
-       }
-       free(TrackID);
-    }
-
-    return NULL;
-}
diff --git a/nnrpd/post.h b/nnrpd/post.h
deleted file mode 100644 (file)
index 9799205..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*  $Id: post.h 6474 2003-09-15 07:32:56Z rra $
-**
-**  Net News Reading Protocol server.
-*/
-
-typedef enum _HEADERTYPE {
-    HTobs,
-    HTreq,
-    HTstd
-} HEADERTYPE;
-
-typedef struct _HEADER {
-    const char * Name;
-    bool         CanSet;
-    HEADERTYPE   Type;
-    int          Size;
-    char *       Value; /* just after ':' in header */
-    char *       Body;  /* where actual body begins */
-    int          Len;   /* body length excluding trailing white spaces */
-} HEADER;
-
-#define HDR(_x) (Table[(_x)].Body)
-#define HDR_SET(_x, _y) do { \
-    Table[(_x)].Body = Table[(_x)].Value = _y; \
-    if (_y == NULL) { \
-       Table[(_x)].Len = 0; \
-    } else { \
-       Table[(_x)].Len = strlen(_y); \
-    } \
-} while (0)
-
-#define HDR__PATH            0
-#define HDR__FROM            1
-#define HDR__NEWSGROUPS              2
-#define HDR__SUBJECT         3
-#define HDR__CONTROL         4
-#define HDR__FOLLOWUPTO              6
-#define HDR__DATE            7
-#define HDR__ORGANIZATION     8
-#define HDR__LINES           9
-#define HDR__SENDER         10
-#define HDR__APPROVED       11
-#define HDR__DISTRIBUTION    12
-#define HDR__EXPIRES        13
-#define HDR__MESSAGEID      14
-#define HDR__NNTPPOSTINGHOST 17
-#define HDR__XTRACE          21
-#define HDR__XCOMPLAINTSTO   22
-#define HDR__NNTPPOSTINGDATE 23
-#define HDR__CC                     33
-#define HDR__BCC            34
-#define HDR__TO                     35
diff --git a/nnrpd/python.c b/nnrpd/python.c
deleted file mode 100644 (file)
index a68e85d..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-/*  $Id: python.c 7893 2008-06-22 10:24:42Z iulius $
-**
-**  python.c: Embed Python in the style of nnrpd's TCL and Perl stuff
-**            (authentication and authorization hooks only at this point).
-** 
-**  Written by Ilya Etingof <ilya@glas.net>, 1999.
-**
-**  This code bases on Python work for innd filtering done by
-**  G.J. Andruk <meowing@banet.net>. Also it borrows some ideas from
-**  TCL/Perl work done by Bob Heiney and Christophe Wolfhugel.
-**
-**  A quick note regarding Python exceptions:  functions like
-**      PyObject_GetAttrString(PyObject *o, const char *attr_name)
-**  raise an exception when they fail, even though they return NULL.
-**  And as exceptions accumulate from caller to caller and so on,
-**  it generates weird issues with Python scripts afterwards.  So such
-**  uses should be checked before.  For instance with:
-**      PyObject_HasAttrString(PyObject *o, const char *attr_name). 
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "inn/hashtab.h"
-
-#if defined(DO_PYTHON)
-
-#include "Python.h"
-
-/* values relate name of hook to array index */
-#define PYTHONauthen           1
-#define PYTHONaccess           2
-#define PYTHONdynamic          3
-
-#define PYTHONtypes_max        4
-
-/* values relate type of method to array index */
-#define PYTHONmain             1
-#define PYTHONinit             2
-#define PYTHONclose            3
-
-#define PYTHONmethods_max      4
-
-/* key names for attributes dictionary */
-#define PYTHONhostname         "hostname"
-#define PYTHONipaddress        "ipaddress"
-#define PYTHONport             "port"
-#define PYTHONinterface        "interface"
-#define PYTHONintipaddr        "intipaddr"
-#define PYTHONintport          "intport"
-#define PYTHONuser             "user"
-#define PYTHONpass             "pass"
-#define PYTHONtype             "type"
-#define PYTHONnewsgroup        "newsgroup"
-
-/* Max number of items in dictionary to pass to auth methods */
-#define        _PY_MAX_AUTH_ITEM       10
-
-
-/* Pointers to external Python objects */
-PyObject       *PYAuthObject = NULL;
-
-/* Dictionary of params to pass to authentication methods */
-PyObject       *PYauthinfo = NULL;
-PyObject       **PYauthitem = NULL;
-
-/* Forward declaration */
-static PyObject *PY_set_auth_hook(PyObject *dummy, PyObject *args);
-void PY_load_python(void);
-PyObject* PY_setup(int type, int method, char *file);
-static const void *file_key(const void *p);
-static bool file_equal(const void *k, const void *p);
-static void file_free(void *p);
-static void file_trav(void *data, void* null);
-
-bool   PythonLoaded = false;
-
-/* structure for storage of attributes for a module file */
-typedef struct PyFile {
-  char          *file;  
-  bool          loaded[PYTHONtypes_max];
-  PyObject     *procs[PYTHONtypes_max][PYTHONmethods_max];
-} PyFile;
-
-/* hash for storing files */
-struct hash *files;
-
-/* for passing the dynamic module filename from perm.c */
-char*    dynamic_file;
-
-/*
-** Authenticate connecting host by username&password.
-**
-** Return NNTP reply code as returned by Python method or -1 if method
-** is not defined.
-*/
-int PY_authenticate(char* file, char *Username, char *Password, char *errorstring, char *newUser) {
-    PyObject    *result, *item, *proc;
-    int         authnum;
-    int         code, i;
-    char        *temp;
-
-    PY_load_python();
-    proc = PY_setup(PYTHONauthen, PYTHONmain, file);
-
-    /* Return if authentication method is not defined */
-    if (proc == NULL)
-        return -1;
-
-    /* Initialize PythonAuthObject with connect method specific items */
-    authnum = 0;
-
-    /* Client hostname */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientHost, strlen(ClientHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
-
-    /* Client IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientIpString, strlen(ClientIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
-
-    /* Client port number */
-    PYauthitem[authnum] = PyInt_FromLong(ClientPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
-
-    /* Server interface the connection comes to */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerHost, strlen(ServerHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
-
-    /* Server IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerIpString, strlen(ServerIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
-
-    /* Server port number */
-    PYauthitem[authnum] = PyInt_FromLong(ServerPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
-
-    /* Username if known */
-    if (Username == NULL) {
-        PYauthitem[authnum] = Py_None;
-    } else {
-        PYauthitem[authnum] = PyBuffer_FromMemory(Username, strlen(Username));
-    }
-    PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
-
-    /* Password if known */
-    if (Password == NULL) {
-        PYauthitem[authnum] = Py_None;
-    } else {
-        PYauthitem[authnum] = PyBuffer_FromMemory(Password, strlen(Password));
-    }
-    PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
-
-    /* Now invoke authenticate method and see if it likes this user */
-    result = PyObject_CallFunction(proc, "O", PYauthinfo);
-
-    /* Check the response */
-    if (result == NULL || !PyTuple_Check(result) 
-        || ((PyTuple_Size(result) != 2) && (PyTuple_Size(result) != 3)))
-    {
-        syslog(L_ERROR, "python authenticate method returned wrong result");
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    }
-
-    /* Get the NNTP response code */
-    item = PyTuple_GetItem(result, 0);
-
-    /* Check the item */
-    if (!PyInt_Check(item))
-    {
-        syslog(L_ERROR, "python authenticate method returned bad NNTP response code");
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    }
-
-    /* Store the code */
-    code = PyInt_AS_LONG(item);
-
-    /* Get the error string */
-    item = PyTuple_GetItem(result, 1);
-
-    /* Check the item */
-    if (!PyString_Check(item))
-    {
-        syslog(L_ERROR, "python authenticate method returned bad error string");
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-    }
-
-    /* Store error string */
-    temp = PyString_AS_STRING(item);
-    errorstring = xstrdup(temp);
-    
-    if (PyTuple_Size(result) == 3) {
-        
-        /* Get the username string */
-        item = PyTuple_GetItem(result, 2);
-        
-        /* Check the item */
-        if (!PyString_Check(item)) {
-            syslog(L_ERROR, "python authenticate method returned bad username string");
-            Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-            ExitWithStats(1, true);
-        }
-
-        /* Store error string */
-        temp = PyString_AS_STRING(item);
-        newUser = xstrdup(temp);
-    }
-
-    /* Clean up the dictionary object */
-    PyDict_Clear(PYauthinfo);
-
-    /* Clean up dictionary items */
-    for (i = 0; i < authnum; i++) {
-        if (PYauthitem[i] != Py_None) {
-            Py_DECREF(PYauthitem[i]);
-        }
-    }
-
-    /* Log auth result */
-    syslog(L_NOTICE, "python authenticate method succeeded, return code %d, error string %s", code, errorstring);
-
-    /* Return response code */
-    return code;
-}
-
-/*
-** Create an access group based on the values returned by the script in file
-**
-*/
-void PY_access(char* file, struct vector *access_vec, char *Username) {
-    PyObject   *result, *key, *value, *proc;
-    char       *buffer;
-    int                authnum;
-    int                i;
-
-    PY_load_python();
-    proc = PY_setup(PYTHONaccess, PYTHONmain, file);
-
-    /* Exit if access method is not defined */
-    if (proc == NULL) {
-        syslog(L_ERROR, "python access method not defined");
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-     }
-    /* Initialize PythonAuthObject with group method specific items */
-    authnum = 0;
-
-    /* Client hostname */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientHost, strlen(ClientHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
-
-    /* Client IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientIpString, strlen(ClientIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
-
-    /* Client port number */
-    PYauthitem[authnum] = PyInt_FromLong(ClientPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
-
-    /* Server interface the connection comes to */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerHost, strlen(ServerHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
-
-    /* Server IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerIpString, strlen(ServerIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
-
-    /* Server port number */
-    PYauthitem[authnum] = PyInt_FromLong(ServerPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
-
-    /* Username */
-    PYauthitem[authnum] = PyBuffer_FromMemory(Username, strlen(Username));
-    PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
-    /* Password is not known */
-    PYauthitem[authnum] = Py_None;
-    PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
-
-    /*
-     * Now invoke newsgroup access method
-     */
-    result = PyObject_CallFunction(proc, "O", PYauthinfo);
-
-    /* Check the response */
-    if (result == NULL || result == Py_None || !PyDict_Check(result)) {
-        syslog(L_ERROR, "python access method returned wrong result -- expected a dictionary");
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, true);
-     }
-    /* resize vector to dictionary length */
-    vector_resize(access_vec, PyDict_Size(result) - 1);
-
-    /* store dict values in proper format in access vector */
-    i = 0;
-    buffer = xmalloc(BIG_BUFFER);
-
-    while(PyDict_Next(result, &i, &key, &value)) {
-        if (!PyString_Check(key)) {
-            syslog(L_ERROR, "python access method return dictionary key %i not a string", i);
-            Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-            ExitWithStats(1, false);
-        }
-        if (!PyString_Check(value)) {
-            syslog(L_ERROR, "python access method return dictionary value %i not a string", i);
-            Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-            ExitWithStats(1, false);
-        }
-
-        strlcpy(buffer, PyString_AsString(key), BIG_BUFFER);
-        strlcat(buffer, ": \"", BIG_BUFFER);
-        strlcat(buffer, PyString_AsString(value), BIG_BUFFER);
-        strlcat(buffer, "\"\n", BIG_BUFFER);
-
-        vector_add(access_vec, xstrdup(buffer));
-    }
-
-    free(buffer);
-
-    /* Clean up the dictionary object */
-    PyDict_Clear(PYauthinfo);
-    /* Clean up dictionary items */
-    for (i = 0; i < authnum; i++) {
-        if (PYauthitem[i] != Py_None) {
-            Py_DECREF(PYauthitem[i]);
-       }
-    }
-
-    /* Log auth result */
-    syslog(L_NOTICE, "python access method succeeded");
-}
-
-/*
-** Initialize dynamic access control code
-*/
-
-void PY_dynamic_init (char* file) {
-  dynamic_file = xstrdup(file);
-  PY_use_dynamic = true;
-}
-
-
-/*
-** Determine dynamic user access rights to a given newsgroup.
-**
-** Return 0 if requested privelege is granted or positive value
-** and a reply_message pointer initialized with reply message.
-** Return negative value if dynamic method is not defined.
-*/
-int PY_dynamic(char *Username, char *NewsGroup, int PostFlag, char **reply_message) {
-    PyObject   *result, *item, *proc;
-    char       *string, *temp;
-    int                authnum;
-    int                i;
-
-    PY_load_python();
-    proc = PY_setup(PYTHONdynamic, PYTHONmain, dynamic_file);
-
-    /* Return if dynamic method is not defined */
-    if (proc == NULL)
-        return -1;
-
-    /* Initialize PythonAuthObject with group method specific items */
-    authnum = 0;
-
-    /* Client hostname */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientHost, strlen(ClientHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONhostname, PYauthitem[authnum++]);
-
-    /* Client IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ClientIpString, strlen(ClientIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONipaddress, PYauthitem[authnum++]);
-
-    /* Client port number */
-    PYauthitem[authnum] = PyInt_FromLong(ClientPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONport, PYauthitem[authnum++]);
-
-    /* Server interface the connection comes to */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerHost, strlen(ServerHost));
-    PyDict_SetItemString(PYauthinfo, PYTHONinterface, PYauthitem[authnum++]);
-
-    /* Server IP number */
-    PYauthitem[authnum] = PyBuffer_FromMemory(ServerIpString, strlen(ServerIpString));
-    PyDict_SetItemString(PYauthinfo, PYTHONintipaddr, PYauthitem[authnum++]);
-
-    /* Server port number */
-    PYauthitem[authnum] = PyInt_FromLong(ServerPort);
-    PyDict_SetItemString(PYauthinfo, PYTHONintport, PYauthitem[authnum++]);
-    
-    /* Username */
-    PYauthitem[authnum] = PyBuffer_FromMemory(Username, strlen(Username));
-    PyDict_SetItemString(PYauthinfo, PYTHONuser, PYauthitem[authnum++]);
-    
-    /* Password is not known */
-    PYauthitem[authnum] = Py_None;
-    PyDict_SetItemString(PYauthinfo, PYTHONpass, PYauthitem[authnum++]);
-
-    /* Assign authentication type */
-    PYauthitem[authnum] = PyBuffer_FromMemory(PostFlag ? "post" : "read", 4);
-    PyDict_SetItemString(PYauthinfo, PYTHONtype, PYauthitem[authnum++]);
-    /* Newsgroup user tries to access */
-    PYauthitem[authnum] = PyBuffer_FromMemory(NewsGroup, strlen(NewsGroup));
-    PyDict_SetItemString(PYauthinfo, PYTHONnewsgroup,  PYauthitem[authnum++]);
-    
-    /*
-     * Now invoke newsgroup dynamic access method and see if
-     * it likes this user to access this newsgroup.
-     */
-    result = PyObject_CallFunction(proc, "O", PYauthinfo);
-
-    /* Check the response */
-    if (result == NULL || (result != Py_None && !PyString_Check(result)))
-    {
-        syslog(L_ERROR, "python dynamic method (%s access) returned wrong result: %s", PostFlag ? "post" : "read", result);
-       Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-       ExitWithStats(1, false);
-    }
-
-    /* Get the response string */
-    if (result == Py_None) {
-        string = NULL;
-    } else {
-        temp = PyString_AS_STRING(result);
-        string = xstrdup(temp);
-    }
-    /* Clean up the dictionary object */
-    PyDict_Clear(PYauthinfo);
-
-    /* Clean up dictionary items */
-    for (i = 0; i < authnum; i++) {
-        if (PYauthitem[i] != Py_None) {
-            Py_DECREF(PYauthitem[i]);
-        }
-    }
-
-    /* Log auth result */
-    syslog(L_NOTICE, "python dynamic method (%s access) succeeded, refusion string: %s", PostFlag ? "post" : "read", string == NULL ? "<empty>" : string);
-
-    /* Initialize reply string */
-    if (reply_message != NULL)
-        *reply_message = string;
-    
-    /* Return result */
-    return string == NULL ? 0 : 1;
-}
-
-
-/*
-**  This runs when nnrpd shuts down.  If Python is closed and reopened
-**  in the same process, files and dynamic_file are reused so they
-**  must point to NULL.
-*/
-void
-PY_close_python(void)
-{
-    if (files != NULL) {
-       hash_traverse(files, file_trav, NULL);
-       hash_free(files);
-        files = NULL;
-    }
-    if (dynamic_file != NULL) {
-       free(dynamic_file);
-        dynamic_file = NULL;
-    }
-}
-
-/*
-** Traversal function for PY_close_python
-*/
-void
-file_trav(void *data, void* null UNUSED)
-{
-    PyFile *fp = data;
-    int j;
-    PyObject   *result, *func;
-
-    for (j = 1; j < PYTHONtypes_max; j++) {
-        if (fp->loaded[j] != false) {
-            func = fp->procs[j][PYTHONclose];
-              if (func != NULL) {
-                  result = PyObject_CallFunction(func, NULL);
-                  Py_XDECREF(result);
-              }
-        }
-    }
-}
-
-/*
-**  Python's syslog module isn't compiled in by default.  It's easier
-**  to do it this way, and the switch block looks pretty in a color
-**  editor).
-*/
-static PyObject *
-PY_syslog(PyObject *self UNUSED, PyObject *args)
-{
-    char        *loglevel;
-    int         levellen;
-    char        *logmsg;
-    int         msglen;
-    int         priority;
-
-    /* Get loglevel and message */
-    if (!PyArg_ParseTuple(args, "s#s#", &loglevel, &levellen, &logmsg, &msglen))
-        return NULL;
-
-    /* Assign syslog priority by abbreviated names */
-    switch (*loglevel) {
-    default:           priority = LOG_NOTICE ;
-    case 'd': case 'D': priority = LOG_DEBUG ;         break;
-    case 'i': case 'I': priority = LOG_INFO ;          break;
-    case 'n': case 'N': priority = LOG_NOTICE ;                break;
-    case 'w': case 'W': priority = LOG_WARNING ;       break;
-    case 'e': case 'E': priority = LOG_ERR ;           break;
-    case 'c': case 'C': priority = LOG_CRIT ;          break;
-    case 'a': case 'A': priority = LOG_ALERT ;         break;
-    }
-
-    /* Log the message */
-    syslog(priority, "python: %s", logmsg);
-
-    /* Return None */
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-
-/*
-**  Make the internal nnrpd module's functions visible to Python.
-*/
-static PyMethodDef nnrpdPyMethods[] = {
-    {"set_auth_hook",   PY_set_auth_hook,      METH_VARARGS},
-    {"syslog",         PY_syslog,              METH_VARARGS},
-    {NULL,             NULL}
-};
-
-
-/*
-**  Called by the external module so it can register itself with nnrpd.
-*/
-static PyObject *
-PY_set_auth_hook(PyObject *dummy UNUSED, PyObject *args)
-{
-    PyObject    *result = NULL;
-    PyObject    *temp;
-
-    /* set_auth_hook method should return a pointer to nnrpd auth object */
-    if (PyArg_ParseTuple(args, "O:set_auth_hook", &temp)) {
-        Py_XINCREF(temp);
-        Py_XDECREF(PYAuthObject);
-        PYAuthObject = temp;
-        Py_INCREF(Py_None);
-        result = Py_None;
-    }
-
-    /* Return a pointer to nnrpd auth method */
-    return result;
-}
-
-/*
-** Load the Python interpreter
-*/
-void PY_load_python() {
-    if (!PythonLoaded) {
-        /* add path for nnrpd module */    
-        setenv("PYTHONPATH", innconf->pathfilter, 1);
-
-        /* Load up the interpreter ;-O */
-        Py_Initialize();
-    
-        /* It makes Python sad when its stdout and stderr are closed. */
-        if ((fileno(stdout) == -1) || (fileno(stderr) == -1))
-            PyRun_SimpleString("import sys; sys.stdout=sys.stderr=open('/dev/null', 'a')");
-   
-        /* See if Python initialized OK */
-        if (!Py_IsInitialized ()) {
-            syslog(L_ERROR, "python interpreter NOT initialized");
-            return;
-        }
-
-
-        /* Build a module interface to certain nnrpd functions */
-        (void) Py_InitModule("nnrpd", nnrpdPyMethods);
-
-        /*
-        ** Grab space for authinfo dictionary so we aren't forever
-        ** recreating them.
-        */
-        PYauthinfo = PyDict_New();
-        PYauthitem = xcalloc(_PY_MAX_AUTH_ITEM, sizeof(PyObject *));
-
-        /* create hash to store file attributes */
-        
-        files = hash_create(4, hash_string, file_key,
-                            file_equal, file_free);
-
-        PythonLoaded = true;
-
-        syslog(L_NOTICE, "python interpreter initialized OK");
-    }
-}
-
-/*
-**  Check that a method exists and is callable.         Set up a pointer to
-**  the corresponding PyObject, or NULL if not found.
-*/
-void
-PYdefonemethod(PyFile *fp, int type, int method, char *methname, int realtype) {
-    PyObject **methptr;
-
-    methptr = &fp->procs[type][method];
-    /* There is no need to check the existence of methods useless for our realtype. */
-    if (type == realtype) {
-        /*
-        ** We check with HasAttrString() the existence of the method because
-        ** otherwise, in case it does not exist, an exception is raised by Python,
-        ** although the result of the function is NULL.
-        */
-        if (PyObject_HasAttrString(PYAuthObject, (char *) methname) == 1) {
-            /* Get a pointer to given method. */
-            *methptr = PyObject_GetAttrString(PYAuthObject, (char *) methname);
-        } else {
-            *methptr = NULL;
-        }
-
-        /* See if such method is defined */
-        if (*methptr == NULL)
-            syslog(L_NOTICE, "python method %s not found", methname);
-        else {
-            /* See if it is callable */
-            if (PyCallable_Check(*methptr) == 0) {
-                syslog(L_ERROR, "python object %s found but not a function", methname);
-                Py_DECREF(*methptr);
-                *methptr = NULL;
-            }
-        }
-    } else {
-        *methptr = NULL;
-    }
-}
-
-
-/*
-**  Look up all the known python methods and set up
-**  pointers to them so that we could call them from nnrpd.
-*/
-void
-PYdefmethods(PyFile *fp, int realtype)
-{
-    /* Get a reference to authenticate() method */
-    PYdefonemethod(fp, PYTHONauthen, PYTHONmain, "authenticate", realtype);
-
-    /* Get a reference to authen_init() method */
-    PYdefonemethod(fp, PYTHONauthen, PYTHONinit, "authen_init", realtype);
-    
-    /* Get a reference to authen_close() method */
-    PYdefonemethod(fp, PYTHONauthen, PYTHONclose, "authen_close", realtype);
-
-    /* Get a reference to access() method */
-    PYdefonemethod(fp, PYTHONaccess, PYTHONmain, "access", realtype);
-    
-    /* Get a reference to access_init() method */
-    PYdefonemethod(fp, PYTHONaccess, PYTHONinit, "access_init", realtype);
-    
-    /* Get a reference to access_close() method */
-    PYdefonemethod(fp, PYTHONaccess, PYTHONclose, "access_close", realtype);
-    
-    /* Get a reference to dynamic() method */
-    PYdefonemethod(fp, PYTHONdynamic, PYTHONmain, "dynamic", realtype);
-    
-    /* Get a reference to dynamic_init() method */
-    PYdefonemethod(fp, PYTHONdynamic, PYTHONinit, "dynamic_init", realtype);
-    
-    /* Get a reference to dynamic_close() method */
-    PYdefonemethod(fp, PYTHONdynamic, PYTHONclose, "dynamic_close", realtype);
-}
-
-
-/*
-**  Called when a python hook is needed -- this gets the scripts hooked in.
-*/
-PyObject*
-PY_setup(int type, int method, char *file)
-{
-    int  i;
-    PyFile *fp;
-    PyObject    *result;
-
-    /* check to see if this file is in files */
-    if (!(hash_lookup(files, file))) {
-        fp = xmalloc(sizeof(PyFile));
-        fp->file = xstrdup(file);
-
-        for (i = 1; i < PYTHONtypes_max; i++) {
-            fp->loaded[i] = false;
-        }
-        
-        /* Load up external module */
-        (void) PyImport_ImportModule(file);
-
-        /* See if nnrpd auth object is defined in auth module */
-        if (PYAuthObject == NULL) {
-            syslog(L_ERROR, "python auth object is not defined");
-            Reply("%d Internal Error (7).  Goodbye\r\n", NNTP_ACCESS_VAL);
-            PY_close_python();
-            ExitWithStats(1, false);
-        } else {
-            /* Set up pointers to known Python methods */
-            PYdefmethods(fp, type);
-        }
-        hash_insert(files, file, fp);
-
-        if ((!fp->loaded[type]) && (fp->procs[type][PYTHONinit] != NULL)) {
-            result = PyObject_CallFunction(fp->procs[type][PYTHONinit], NULL);
-            if (result != NULL) {
-                Py_XDECREF(result);
-            }
-            fp->loaded[type] = true;
-        }
-        return fp->procs[type][method];
-    }
-    return NULL;
-}
-
-/*
-**  Return the key (filename) from a file struct, used by the hash table.
-*/
-static const void *
-file_key(const void *p)
-{
-    const struct PyFile *f = p;
-
-    return f->file;
-}
-
-/*
-**  Check to see if a provided key matches the key of a PyFile struct,
-**  used by the hash table.
-*/
-static bool
-file_equal(const void *k, const void *p)
-{
-    const char *key = k;
-    const struct PyFile *f = p;
-
-    return strcmp(key, f->file) == 0;
-}
-
-/*
-**  Free a file, used by the hash table.
-*/
-static void
-file_free(void *p)
-{
-    struct PyFile *fp = p;
-    int i, j;
-
-    free(fp->file);
-
-    for (i = 1; i < PYTHONtypes_max; i++) {
-        for (j = 1; j < PYTHONmethods_max; j++) {
-            if (fp->procs[i][j] != NULL) {
-                Py_DECREF(fp->procs[i][j]);
-            }
-        }
-    }
-
-    free(fp);
-}
-
-#endif /* defined(DO_PYTHON) */
diff --git a/nnrpd/sasl_config.c b/nnrpd/sasl_config.c
deleted file mode 100644 (file)
index e356e57..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* sasl_config.c -- Configuration routines
-   Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
-
-   Author: Kenichi Okada <okada@opaopa.org>
-   Created: 2000-03-04
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-#include "paths.h"
-#include "sasl_config.h"
-
-#ifdef HAVE_SSL
-
-struct configlist {
-    char *key;
-    char *value;
-};
-
-static struct configlist *configlist;
-static int nconfiglist;
-
-const char *sasl_config_getstring(key, def)
-const char *key;
-const char *def;
-{
-    int opt;
-
-    for (opt = 0; opt < nconfiglist; opt++) {
-       if (*key == configlist[opt].key[0] &&
-           !strcmp(key, configlist[opt].key))
-         return configlist[opt].value;
-    }
-    return def;
-}
-
-int sasl_config_getint(key, def)
-const char *key;
-int def;
-{
-    const char *val = sasl_config_getstring(key, (char *)0);
-
-    if (!val) return def;
-    if (!isdigit(*val) && (*val != '-' || !isdigit(val[1]))) return def;
-    return atoi(val);
-}
-
-int sasl_config_getswitch(key, def)
-const char *key;
-int def;
-{
-    const char *val = sasl_config_getstring(key, (char *)0);
-
-    if (!val) return def;
-
-    if (*val == '0' || *val == 'n' ||
-       (*val == 'o' && val[1] == 'f') || *val == 'f') {
-       return 0;
-    }
-    else if (*val == '1' || *val == 'y' ||
-            (*val == 'o' && val[1] == 'n') || *val == 't') {
-       return 1;
-    }
-    return def;
-}
-
-const char *sasl_config_partitiondir(partition)
-const char *partition;
-{
-    char buf[80];
-
-    if (strlen(partition) > 70) return 0;
-    snprintf(buf, sizeof(buf), "partition-%s", partition);
-
-    return sasl_config_getstring(buf, (char *)0);
-}
-
-#define CONFIGLISTGROWSIZE 10 /* 100 */
-void
-sasl_config_read()
-{
-    FILE *infile;
-    int lineno = 0;
-    int alloced = 0;
-    char buf[4096];
-    char *p, *key;
-    static char *SASL_CONFIG = NULL;
-
-    if (!SASL_CONFIG)
-       SASL_CONFIG = concatpath(innconf->pathetc, _PATH_SASL_CONFIG);
-    infile = fopen(SASL_CONFIG, "r");
-    if (!infile) {
-      fprintf(stderr, "can't open configuration file %s\n", SASL_CONFIG);
-      exit(1);
-    }
-    
-    while (fgets(buf, sizeof(buf), infile)) {
-       lineno++;
-
-       if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
-       for (p = buf; *p && isspace(*p); p++);
-       if (!*p || *p == '#') continue;
-
-       key = p;
-       while (*p && (isalnum(*p) || *p == '-' || *p == '_')) {
-           if (isupper(*p)) *p = tolower(*p);
-           p++;
-       }
-       if (*p != ':') {
-           fprintf(stderr,
-                   "invalid option name on line %d of configuration file\n",
-                   lineno);
-           exit(1);
-       }
-       *p++ = '\0';
-
-       while (*p && isspace(*p)) p++;
-       
-       if (!*p) {
-           fprintf(stderr, "empty option value on line %d of configuration file\n",
-                   lineno);
-           exit(1);
-       }
-
-       if (nconfiglist == alloced) {
-           alloced += CONFIGLISTGROWSIZE;
-            configlist = xrealloc(configlist, alloced * sizeof(struct configlist));
-       }
-
-       configlist[nconfiglist].key = xstrdup(key);
-       configlist[nconfiglist].value = xstrdup(p);
-       nconfiglist++;
-    }
-    fclose(infile);
-}
-
-#endif /* HAVE_SSL */
diff --git a/nnrpd/sasl_config.h b/nnrpd/sasl_config.h
deleted file mode 100644 (file)
index 084207e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* sasl_config.h
-   Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
-
-   Author: Kenichi Okada <okada@opaopa.org>
-   Created: 2000-03-04
-*/
-
-#ifndef SASL_CONFIG_H
-#define SASL_CONFIG_H
-
-#ifndef P
-#ifdef __STDC__
-#define P(x) x
-#else
-#define P(x) ()
-#endif
-#endif
-
-extern void sasl_config_read P((void));
-extern const char *sasl_config_getstring P((const char *key, const char *def));
-extern int sasl_config_getint P((const char *key, int def));
-extern int sasl_config_getswitch P((const char *key, int def));
-extern const char *sasl_config_partitiondir P((const char *partition));
-
-#endif /* SASL_SASL_CONFIG_H */
diff --git a/nnrpd/tls.c b/nnrpd/tls.c
deleted file mode 100644 (file)
index cfc8f03..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-/* tls.c --- TLSv1 functions
-   Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
-
-   Author: Kenichi Okada <okada@opaopa.org>
-   Created: 2000-02-22
-
-   Keywords: TLS, OpenSSL
-
-   Commentary:
-
-   [RFC 2246] "The TLS Protocol Version 1.0"
-        by Christopher Allen <callen@certicom.com> and
-        Tim Dierks <tdierks@certicom.com> (1999/01)
-
-   [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
-        by Chris Newman <chris.newman@innosoft.com> (1999/06)
-
-*/
-
-#include <sys/types.h>
-#include "config.h"
-#include "nnrpd.h"
-
-#ifdef HAVE_SSL
-
-/* System library. */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#endif
-
-/* outside the ifdef so `make depend` works even ifndef HAVE_SSL */
-#include "tls.h"
-#include "sasl_config.h"
-
-#ifdef HAVE_SSL
-
-/* We must keep some of the info available */
-static const char hexcodes[] = "0123456789ABCDEF";
-
-static bool tls_initialized = false;
-
-static int verify_depth;
-static int verify_error = X509_V_OK;
-static int do_dump = 0;
-static SSL_CTX *CTX = NULL;
-SSL *tls_conn = NULL;
-
-#define CCERT_BUFSIZ 256
-
-int     tls_serverengine = 0;
-int     tls_serveractive = 0;  /* available or not */
-char   *tls_peer_subject = NULL;
-char   *tls_peer_issuer = NULL;
-char   *tls_peer_fingerprint = NULL;
-
-int     tls_clientactive = 0;  /* available or not */
-char   *tls_peer_CN = NULL;
-char   *tls_issuer_CN = NULL;
-
-const char   *tls_protocol = NULL;
-const char   *tls_cipher_name = NULL;
-int    tls_cipher_usebits = 0;
-int    tls_cipher_algbits = 0;
-
-
-int tls_loglevel = 0;
-
-
-/* taken from OpenSSL apps/s_cb.c 
- * tim - this seems to just be giving logging messages
- */
-
-static void apps_ssl_info_callback(SSL * s, int where, int ret)
-{
-    const char  *str;
-    int         w;
-
-    if (tls_loglevel==0) return;
-
-    w = where & ~SSL_ST_MASK;
-
-    if (w & SSL_ST_CONNECT)
-       str = "SSL_connect";
-    else if (w & SSL_ST_ACCEPT)
-       str = "SSL_accept";
-    else
-       str = "undefined";
-
-    if (where & SSL_CB_LOOP) {
-       if (tls_serverengine && (tls_loglevel >= 2))
-           Printf("%s:%s", str, SSL_state_string_long(s));
-    } else if (where & SSL_CB_ALERT) {
-       str = (where & SSL_CB_READ) ? "read" : "write";
-       if ((tls_serverengine && (tls_loglevel >= 2)) ||
-           ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY))
-         Printf("SSL3 alert %s:%s:%s", str,
-                SSL_alert_type_string_long(ret),
-                SSL_alert_desc_string_long(ret));
-    } else if (where & SSL_CB_EXIT) {
-       if (ret == 0)
-           Printf("%s:failed in %s",
-                    str, SSL_state_string_long(s));
-       else if (ret < 0) {
-           Printf("%s:error in %s",
-                    str, SSL_state_string_long(s));
-       }
-    }
-}
-
-
-/*
- *     Hardcoded DH parameter files, from OpenSSL.
- *     For information on how these files were generated, see
- *     "Assigned Number for SKIP Protocols" 
- *     (http://www.skip-vpn.org/spec/numbers.html.
- */
-static const char file_dh512[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
-XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh1024[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
-jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
-ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh2048[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
-89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
-T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
-zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
-Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
-CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh4096[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
-l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
-Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
-Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
-VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
-alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
-sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
-ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
-OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
-AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
-KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
------END DH PARAMETERS-----\n";
-
-/*
- *     Load hardcoded DH parameters.
- */
-static DH *
-load_dh_buffer (const char *buffer, size_t len)
-{
-       BIO *bio;
-       DH *dh = NULL;
-
-       bio = BIO_new_mem_buf((char *) buffer, len);
-       if (bio == NULL)
-               return NULL;
-       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
-/*     if (dh == NULL) log error */
-       BIO_free(bio);
-
-       return dh;
-}
-
-/*
- *     Generate empheral DH key.  Because this can take a long
- *     time to compute, we use precomputed parameters of the
- *     common key sizes.
- *
- *     These values can be static (once loaded or computed) since
- *     the OpenSSL library can effectively generate random keys
- *     from the information provided.
- *
- *     EDH keying is slightly less efficient than static RSA keying,
- *     but it offers Perfect Forward Secrecy (PFS).
- *
- *     FIXME: support user-specified files, to eliminate risk of
- *     "small group" attacks.
- */
-static DH *tmp_dh_cb(SSL *s UNUSED, int export UNUSED, int keylength)
-{
-       DH *r = NULL;
-       static DH *dh = NULL;
-       static DH *dh512 = NULL;
-       static DH *dh1024 = NULL;
-       static DH *dh2048 = NULL;
-       static DH *dh4096 = NULL;
-
-       switch (keylength)
-       {
-       case 512:
-               if (dh512 == NULL)
-                       dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
-               r = dh512;
-               break;
-       case 1024:
-               if (dh1024 == NULL)
-                       dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
-               r = dh1024;
-               break;
-       case 2048:
-               if (dh2048 == NULL)
-                       dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
-               r = dh2048;
-               break;
-       case 4096:
-               if (dh4096 == NULL)
-                       dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
-               r = dh4096;
-               break;
-       default:
-               /* we should check current keylength vs. requested keylength */
-               /* also, this is an extremely expensive operation! */
-               dh = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
-               r = dh;
-       }
-
-       return r;
-}
-
-/* taken from OpenSSL apps/s_cb.c */
-
-static int verify_callback(int ok, X509_STORE_CTX * ctx)
-{
-    char    buf[256];
-    X509   *err_cert;
-    int     err;
-    int     depth;
-
-    syslog(L_NOTICE,"Doing a peer verify");
-
-    err_cert = X509_STORE_CTX_get_current_cert(ctx);
-    err = X509_STORE_CTX_get_error(ctx);
-    depth = X509_STORE_CTX_get_error_depth(ctx);
-
-    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
-    if ((tls_serveractive) && (tls_loglevel >= 1))
-      Printf("Peer cert verify depth=%d %s", depth, buf);
-    if (ok==0)
-    {
-      syslog(L_NOTICE, "verify error:num=%d:%s", err,
-            X509_verify_cert_error_string(err));
-      
-       if (verify_depth >= depth) {
-           ok = 1;
-           verify_error = X509_V_OK;
-       } else {
-           ok = 0;
-           verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
-       }
-    }
-    switch (ctx->error) {
-    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-       X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
-       syslog(L_NOTICE, "issuer= %s", buf);
-       break;
-    case X509_V_ERR_CERT_NOT_YET_VALID:
-    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
-       syslog(L_NOTICE, "cert not yet valid");
-       break;
-    case X509_V_ERR_CERT_HAS_EXPIRED:
-    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
-       syslog(L_NOTICE, "cert has expired");
-       break;
-    }
-    if ((tls_serveractive) && (tls_loglevel >= 1))
-      Printf("verify return:%d", ok);
-
-    return (ok);
-}
-
-
-/*
- * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
- * and strcat by Matti Aarnio.
- */
-
-#define TRUNCATE
-#define DUMP_WIDTH     16
-
-static int tls_dump(const char *s, int len)
-{
-    int     ret = 0;
-    char    buf[160 + 1];
-    char    *ss;
-    int     i;
-    int     j;
-    int     rows;
-    int     trunc;
-    unsigned char ch;
-
-    trunc = 0;
-
-
-#ifdef TRUNCATE
-    for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
-       trunc++;
-#endif
-
-    rows = (len / DUMP_WIDTH);
-    if ((rows * DUMP_WIDTH) < len)
-       rows++;
-
-    for (i = 0; i < rows; i++) {
-       buf[0] = '\0';                          /* start with empty string */
-       ss = buf;
-
-       sprintf(ss, "%04x ", i * DUMP_WIDTH);
-       ss += strlen(ss);
-       for (j = 0; j < DUMP_WIDTH; j++) {
-           if (((i * DUMP_WIDTH) + j) >= len) {
-               strcpy(ss, "   ");
-           } else {
-               ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
-                   & 0xff;
-               sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' ');
-               ss += 3;
-           }
-       }
-       ss += strlen(ss);
-       *ss+= ' ';
-       for (j = 0; j < DUMP_WIDTH; j++) {
-           if (((i * DUMP_WIDTH) + j) >= len)
-               break;
-           ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
-               & 0xff;
-           *ss+= (((ch >= ' ') && (ch <= '~')) ? ch : '.');
-           if (j == 7) *ss+= ' ';
-       }
-       *ss = 0;
-       /* 
-        * if this is the last call then update the ddt_dump thing so that
-         * we will move the selection point in the debug window
-         */    
-       if (tls_loglevel>0)
-         Printf("%s", buf);
-       ret += strlen(buf);
-    }
-#ifdef TRUNCATE
-    if (trunc > 0) {
-       snprintf(buf, sizeof(buf), "%04x - <SPACES/NULS>\n", len+ trunc);
-       if (tls_loglevel>0)
-         Printf("%s", buf);
-       ret += strlen(buf);
-    }
-#endif
-    return (ret);
-}
-
- /*
-  * Set up the cert things on the server side. We do need both the
-  * private key (in key_file) and the cert (in cert_file).
-  * Both files may be identical.
-  *
-  * This function is taken from OpenSSL apps/s_cb.c
-  */
-
-static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
-{
-    struct stat buf;
-
-    if (cert_file != NULL) {
-       if (SSL_CTX_use_certificate_file(ctx, cert_file,
-                                        SSL_FILETYPE_PEM) <= 0) {
-           syslog(L_ERROR, "unable to get certificate from '%s'", cert_file);
-           return (0);
-       }
-       if (key_file == NULL)
-           key_file = cert_file;
-
-       /* check ownership and permissions of key file */
-       if (lstat(key_file, &buf) == -1) {
-           syslog(L_ERROR, "unable to stat private key '%s'", key_file);
-           return (0);
-       }
-       if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) != 0 ||
-           buf.st_uid != getuid()) {
-           syslog(L_ERROR, "bad ownership or permissions on private key"
-                   " '%s': private key must be mode 600 and owned by "
-                   NEWSUSER, cert_file);
-           return (0);
-       }
-
-       if (SSL_CTX_use_PrivateKey_file(ctx, key_file,
-                                       SSL_FILETYPE_PEM) <= 0) {
-           syslog(L_ERROR, "unable to get private key from '%s'", key_file);
-           return (0);
-       }
-       /* Now we know that a key and cert have been set against
-         * the SSL context */
-       if (!SSL_CTX_check_private_key(ctx)) {
-           syslog(L_ERROR, "Private key does not match the certificate public key");
-           return (0);
-       }
-    }
-    return (1);
-}
-
-
-
- /*
-  * This is the setup routine for the SSL server. As smtpd might be called
-  * more than once, we only want to do the initialization one time.
-  *
-  * The skeleton of this function is taken from OpenSSL apps/s_server.c.
-
-  * returns -1 on error
-  */
-
-int tls_init_serverengine(int verifydepth,
-                         int askcert,
-                         int requirecert,
-                         char *tls_CAfile,
-                         char *tls_CApath,
-                         char *tls_cert_file,
-                         char *tls_key_file
-                         )
-{
-    int     off = 0;
-    int     verify_flags = SSL_VERIFY_NONE;
-    char   *CApath;
-    char   *CAfile;
-    char   *s_cert_file;
-    char   *s_key_file;
-    struct stat buf;
-
-    if (tls_serverengine)
-      return (0);                              /* already running */
-
-    if (tls_loglevel >= 2)
-      Printf("starting TLS engine");
-
-    SSL_load_error_strings();
-    SSLeay_add_ssl_algorithms();
-
-    CTX = SSL_CTX_new(SSLv23_server_method());
-    if (CTX == NULL) {
-      return (-1);
-    };
-
-    off |= SSL_OP_ALL;         /* Work around all known bugs */
-    SSL_CTX_set_options(CTX, off);
-    SSL_CTX_set_info_callback(CTX, apps_ssl_info_callback);
-    SSL_CTX_sess_set_cache_size(CTX, 128);
-
-    if (strlen(tls_CAfile) == 0)
-      CAfile = NULL;
-    else
-      CAfile = tls_CAfile;
-    if (strlen(tls_CApath) == 0)
-      CApath = NULL;
-    else
-      CApath = tls_CApath;
-
-    if ((!SSL_CTX_load_verify_locations(CTX, CAfile, CApath)) ||
-       (!SSL_CTX_set_default_verify_paths(CTX))) {
-      if (tls_loglevel >= 2)
-       Printf("TLS engine: cannot load CA data\n");
-      return (-1);
-    }
-    
-    if (strlen(tls_cert_file) == 0)
-      s_cert_file = NULL;
-    else
-      s_cert_file = tls_cert_file;
-    if (strlen(tls_key_file) == 0)
-      s_key_file = NULL;
-    else
-      s_key_file = tls_key_file;
-    
-    if (!set_cert_stuff(CTX, s_cert_file, s_key_file)) {
-      if (tls_loglevel >= 2)
-       Printf("TLS engine: cannot load cert/key data\n");
-      return (-1);
-    }
-
-    /* load some randomization data from /dev/urandom, if it exists */
-    /* FIXME: should also check for ".rand" file, update it on exit */
-    if (stat("/dev/urandom", &buf) == 0)
-      RAND_load_file("/dev/urandom", 16 * 1024);
-
-    SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
-    SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
-
-    verify_depth = verifydepth;
-    if (askcert!=0)
-       verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
-    if (requirecert)
-       verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
-           | SSL_VERIFY_CLIENT_ONCE;
-    SSL_CTX_set_verify(CTX, verify_flags, verify_callback);
-
-    SSL_CTX_set_client_CA_list(CTX, SSL_load_client_CA_file(CAfile));
-
-    tls_serverengine = 1;
-    return (0);
-}
-
-
-/*
-**  The function called by nnrpd to initialize the TLS support.  Calls
-**  tls_init_server_engine and checks the result.  On any sort of failure,
-**  nnrpd will exit.
-*/
-void
-tls_init(void)
-{
-    int ssl_result;
-
-    if (tls_initialized)
-        return;
-    sasl_config_read();
-    ssl_result = tls_init_serverengine(5,        /* depth to verify */
-                                      0,        /* can client auth? */
-                                      0,        /* required client to auth? */
-                                      (char *)sasl_config_getstring("tls_ca_file", ""),
-                                      (char *)sasl_config_getstring("tls_ca_path", ""),
-                                      (char *)sasl_config_getstring("tls_cert_file", ""),
-                                      (char *)sasl_config_getstring("tls_key_file", ""));
-    if (ssl_result == -1) {
-        Reply("%d Error initializing TLS\r\n", NNTP_STARTTLS_BAD_VAL);
-        syslog(L_ERROR, "error initializing TLS: "
-               "[CA_file: %s] [CA_path: %s] [cert_file: %s] [key_file: %s]",
-               sasl_config_getstring("tls_ca_file", ""),
-               sasl_config_getstring("tls_ca_path", ""),
-               sasl_config_getstring("tls_cert_file", ""),
-               sasl_config_getstring("tls_key_file", ""));
-        ExitWithStats(1, false);
-    }
-    tls_initialized = true;
-}
-
-
-/* taken from OpenSSL apps/s_cb.c */
-
-static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi,
-                       long argl UNUSED, long ret)
-{
-    if (!do_dump)
-       return (ret);
-
-    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
-       Printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int) argp,
-                argi, ret, (unsigned int) ret);
-       tls_dump(argp, (int) ret);
-       return (ret);
-    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
-       Printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int)argp,
-                argi, ret, (unsigned int) ret);
-       tls_dump(argp, (int) ret);
-    }
-    return (ret);
-}
-
- /*
-  * This is the actual startup routine for the connection. We expect
-  * that the buffers are flushed and the "220 Ready to start TLS" was
-  * send to the client, so that we can immediately can start the TLS
-  * handshake process.
-  *
-  * layerbits and authid are filled in on sucess. authid is only
-  * filled in if the client authenticated
-  * 
-  */
-int tls_start_servertls(int readfd, int writefd)
-{
-    int     sts;
-    int     keepalive;
-    SSL_SESSION *session;
-    SSL_CIPHER *cipher;
-
-    if (!tls_serverengine)
-    {          
-      /* should never happen */
-      syslog(L_ERROR, "tls_engine not running");
-      return (-1);
-    }
-    if (tls_loglevel >= 1)
-       Printf("setting up TLS connection");
-
-    if (tls_conn == NULL)
-    {
-       tls_conn = (SSL *) SSL_new(CTX);
-    }
-    if (tls_conn == NULL)
-    {
-       return (-1);
-    }
-    SSL_clear(tls_conn);
-
-#if    defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
-    /* Set KEEPALIVE to catch broken socket connections. */
-    keepalive = 1;
-    if (setsockopt(readfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
-        syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", readfd);
-    if (setsockopt(writefd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
-        syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", writefd);
-#endif /* SOL_SOCKET && SO_KEEPALIVE */
-    
-    /* set the file descriptors for SSL to use */
-    if (SSL_set_rfd(tls_conn, readfd)==0)
-    {
-      return (-1);
-    }
-
-    if (SSL_set_wfd(tls_conn, writefd)==0)
-    {
-      return (-1);
-    }
-    
-    /*
-     * This is the actual handshake routine. It will do all the negotiations
-     * and will check the client cert etc.
-     */
-    SSL_set_accept_state(tls_conn);
-
-    /*
-     * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
-     * Well there is a BIO below the SSL routines that is automatically
-     * created for us, so we can use it for debugging purposes.
-     */
-    if (tls_loglevel >= 3)
-       BIO_set_callback(SSL_get_rbio(tls_conn), bio_dump_cb);
-
-    /* Dump the negotiation for loglevels 3 and 4*/
-    if (tls_loglevel >= 3)
-       do_dump = 1;
-
-      if ((sts = SSL_accept(tls_conn)) <= 0) { /* xxx <= 0 */
-       session = SSL_get_session(tls_conn);
-
-       if (session) {
-         SSL_CTX_remove_session(CTX, session);
-       }
-       if (tls_conn)
-         SSL_free(tls_conn);
-       tls_conn = NULL;
-       return (-1);
-      }
-      /* Only loglevel==4 dumps everything */
-      if (tls_loglevel < 4)
-       do_dump = 0;
-
-    tls_protocol = SSL_get_version(tls_conn);
-    cipher = SSL_get_current_cipher(tls_conn);
-
-    tls_cipher_name = SSL_CIPHER_get_name(cipher);
-    tls_cipher_usebits = SSL_CIPHER_get_bits(cipher,
-                                                &tls_cipher_algbits);
-    tls_serveractive = 1;
-
-    syslog(L_NOTICE, "starttls: %s with cipher %s (%d/%d bits) no authentication", tls_protocol, tls_cipher_name,
-          tls_cipher_usebits, tls_cipher_algbits);
-
-    return (0);
-}
-
-ssize_t
-SSL_writev (ssl, vector, count)
-     SSL *ssl;
-     const struct iovec *vector;
-     int count;
-{
-  static char *buffer = NULL;
-  static size_t allocsize = 0;
-  char *bp;
-  size_t bytes, to_copy;
-  int i;
-  /* Find the total number of bytes to be written.  */
-  bytes = 0;
-  for (i = 0; i < count; ++i)
-    bytes += vector[i].iov_len;
-  /* Allocate a buffer to hold the data.  */
-  if (NULL == buffer) {
-    buffer = (char *) xmalloc(bytes);
-    allocsize = bytes;
-  } else if (bytes > allocsize) {
-    buffer = (char *) xrealloc (buffer, bytes);
-    allocsize = bytes;
-  }
-  /* Copy the data into BUFFER.  */
-  to_copy = bytes;
-  bp = buffer;
-  for (i = 0; i < count; ++i)
-    {
-#define min(a, b)       ((a) > (b) ? (b) : (a))
-      size_t copy = min (vector[i].iov_len, to_copy);
-      memcpy (bp, vector[i].iov_base, copy);
-      bp += copy;
-      to_copy -= copy;
-      if (to_copy == 0)
-        break;
-    }
-  return SSL_write (ssl, buffer, bytes);
-}
-
-
-#endif /* HAVE_SSL */
diff --git a/nnrpd/tls.h b/nnrpd/tls.h
deleted file mode 100644 (file)
index 8837b3f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* tls.h --- TLSv1 functions
-   Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
-
-   Author: Kenichi Okada <okada@opaopa.org>
-   Created: 2000-02-22
-
-   Keywords: TLS, OpenSSL
-
-   Commentary:
-
-   [RFC 2246] "The TLS Protocol Version 1.0"
-        by Christopher Allen <callen@certicom.com> and
-        Tim Dierks <tdierks@certicom.com> (1999/01)
-
-   [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
-        by Chris Newman <chris.newman@innosoft.com> (1999/06)
-
-*/
-
-#ifdef HAVE_SSL
-
-#ifndef TLS_H
-#define TLS_H
-
-#include <openssl/lhash.h>
-#include <openssl/bn.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/rand.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-
-/* init tls engine */
-int tls_init_serverengine(int verifydepth, /* depth to verify */
-                         int askcert,     /* 1 = verify client */
-                         int requirecert, /* 1 = another client verify? */
-                         char *tls_CAfile,
-                         char *tls_CApath,
-                         char *tls_cert_file,
-                         char *tls_key_file);
-
-/* init tls */
-void tls_init(void);
-
-/* start tls negotiation */
-int tls_start_servertls(int readfd, int writefd);
-
-ssize_t SSL_writev (SSL *ssl, const struct iovec *vector, int count);
-
-#endif /* CYRUSTLS_H */
-
-#endif /* HAVE_SSL */
diff --git a/nnrpd/track.c b/nnrpd/track.c
deleted file mode 100644 (file)
index 4090147..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*  $Revision: 6124 $
-**
-**  User and post tracking database.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "nnrpd.h"
-
-#define MAX_LEN 180
-
-/* TrackClient determines whether or not
-   we are interested in tracking the activities
-   of the currently connected host. We have to
-   rely on an external process to set up the
-   entries in the database though which makes
-   this only as reliable as the process that
-   sets this up...
-*/
-
-/* Format of the input line is <host>:<username>
-*/
-
-int TrackClient(char *client, char *user)
-{
-       int RARTon;
-       FILE *fd;
-       char line[MAX_LEN],*p,*pp,*lp;
-        char *dbfile;
-
-        dbfile = concatpath(innconf->pathetc, "nnrpd.track");
-
-       RARTon=false;
-       strcpy(user, "unknown");
-
-       if ((fd=fopen(dbfile,"r"))!=NULL) {
-               while((fgets(line,(MAX_LEN - 1),fd))!=NULL) {
-                       if (line[0] == '#' || line[0] == '\n') continue;
-                       if ((p=strchr(line,' ')) != NULL) *p='\0';
-                       if ((p=strchr(line,'\n')) != NULL) *p='\0';
-                       if ((p=strchr(line,':')) != NULL) {
-                               *p++='\0';
-                       } else {
-                               p=NULL;
-                       }
-                       pp=line;
-                       if ((lp=strchr(pp,'*')) != NULL) {
-                               pp=++lp;
-                       }
-                       if (strstr(client,pp)!=NULL) {
-                               RARTon=true;
-                               if (p != NULL) 
-                                       strcpy(user,p);
-                               break;
-                       }
-               }
-               fclose(fd);
-       } else {
-               RARTon=false;
-               syslog(L_NOTICE, "%s No logging - can't read %s", ClientHost, dbfile);
-       }
-
-        free(dbfile);
-       return RARTon;
-}
diff --git a/samples/INN.py b/samples/INN.py
deleted file mode 100644 (file)
index 964ad34..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-##  $Id: INN.py 7897 2008-06-22 18:04:31Z iulius $
-##
-##  This module supplies stub Python functions corresponding to the ones
-##  provided by innd.  It is not used by the server; it is only here so
-##  that you can test your filter scripts before loading.
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-
-from types import *
-
-def set_filter_hook(anObject):
-    if type(anObject) == InstanceType:
-        print "** set_filter_hook for " + repr(anObject)
-    else:
-        print "** <Your object is not a class instance.>"
-
-def addhist(messageid):
-    print "** addhist Message-ID: " + messageid
-
-def havehist(messageid):
-    print "** havehist Message-ID: " + messageid
-
-def cancel(messageid):
-    print "** cancel Message-ID: " + messageid
-
-def newsgroup(groupname):
-    print "** newsgroup: " + groupname
-
-def head(messageid):
-    print "** head Message-ID: " + messageid
-
-def article(messageid):
-    print "** article Message-ID: " + messageid
-
-def hashstring(mystring):
-    print "** hash: " + mystring
-
-def syslog(level, message):
-    print "-- syslog level: %s message: %s" % (level, message)
diff --git a/samples/Makefile b/samples/Makefile
deleted file mode 100644 (file)
index bcda7c5..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-##  $Id: Makefile 6299 2003-04-20 19:04:14Z vinocur $
-##
-##  All the actual installation work of any files in the samples directory
-##  is done via the site directory, so that one can maintain one's news
-##  configuration in the site directory and use make commands to update the
-##  server automatically.  All this Makefile does is run fixscript on a few
-##  files that don't need the full power of configure (and clean up after
-##  them on make clean).
-
-include ../Makefile.global
-
-top          = ..
-
-ALL           = nnrpd_auth.pl nnrpd_access.pl \
-                nnrpd_auth_wrapper.pl nnrpd_access_wrapper.pl
-
-EXTRA         = inn.conf innreport.conf newsfeeds sasl.conf
-
-all: $(ALL) $(EXTRA)
-
-clean:
-       rm -f $(ALL)
-
-clobber distclean: clean
-       rm -f $(EXTRA)
-
-install:
-depend:
-
-profiled: all
-
-$(EXTRA) $(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Build rules.
-
-FIX             = $(FIXSCRIPT)
-
-nnrpd_auth.pl:                 nnrpd_auth.pl.in           $(FIX) ; $(FIX) $@.in
-nnrpd_access.pl:               nnrpd_access.pl.in         $(FIX) ; $(FIX) $@.in
-nnrpd_auth_wrapper.pl:         nnrpd_auth_wrapper.pl.in   $(FIX) ; $(FIX) $@.in
-nnrpd_access_wrapper.pl:       nnrpd_access_wrapper.pl.in $(FIX) ; $(FIX) $@.in
diff --git a/samples/active.minimal b/samples/active.minimal
deleted file mode 100644 (file)
index 1d0cbe0..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-control 0000000000 0000000001 n
-control.cancel 0000000000 0000000001 n
-control.checkgroups 0000000000 0000000001 n
-control.newgroup 0000000000 0000000001 n
-control.rmgroup 0000000000 0000000001 n
-junk 0000000000 0000000001 n
diff --git a/samples/actsync.cfg b/samples/actsync.cfg
deleted file mode 100644 (file)
index 48975c1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# $Id: actsync.cfg 7081 2004-12-22 04:20:47Z rra $
-
-host=ftp.isc.org
-ftppath=/pub/usenet/CONFIG/active.gz
-flags=-v 0 -p 80
-ignore_file=actsync.ign
diff --git a/samples/actsync.ign b/samples/actsync.ign
deleted file mode 100644 (file)
index 7572ce0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# $Id: actsync.ign 7079 2004-12-22 04:20:14Z rra $
-#
-# Sample actsync ignore_file.
-
-# For now by default do not sync
-#
-i *
-
-# sync on the 8 majors
-#
-c comp.*
-c humanities.*
-c misc.*
-c news.*
-c rec.*
-c sci.*
-c soc.*
-c talk.*
-
-# don't compare to.* groups as they will differ
-#
-i to.*
-
-# we always want our special top level groups
-#
-i control
-i general
-i junk
-i test
-i to
diff --git a/samples/buffindexed.conf b/samples/buffindexed.conf
deleted file mode 100644 (file)
index 7ba411b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# overview buffer configuration file
-#
-# The order in this items appear in this file is not important
-
-# Format:
-# index(0-65535) : path to buffer file : 
-#       length of buffer in kilobytes in decimal (1KB = 1024 bytes)
-
-0:/var/spool/news/overview/OV1:1536000
-1:/var/spool/news/overview/OV2:1536000
diff --git a/samples/control.ctl b/samples/control.ctl
deleted file mode 100644 (file)
index 50c5c10..0000000
+++ /dev/null
@@ -1,2535 +0,0 @@
-##  control.ctl - Access control for control messages.
-##  Last modified: 2008-03-05
-##
-##  Based on rone's unified control.ctl file.
-##
-##  For a web presentation of the information recorded here, as well as
-##  other useful information about Usenet hierarchies, please see:
-##
-##      <http://usenet.trigofacile.com/hierarchies/>
-##
-##  Please copy usenet-config@isc.org on any updates to this file so that
-##  it can be updated in the INN CVS repository and on ftp.isc.org.  For
-##  changes to a public hierarchy, please also post the changes to
-##  news.admin.hierarchies.
-##
-##  The canonical version of this file can be found in the latest INN
-##  release and at <ftp://ftp.isc.org/pub/usenet/CONFIG/control.ctl>; these
-##  two files will be kept in sync.  Please refer to the latest version of
-##  this file for the most up-to-date hierarchy control information and
-##  please use the latest version if you intend to carry all hierarchies.
-##
-##  You may wish to review and change the policy for alt.*, free.*,
-##  it-alt.*, and oesterreich.* below before using this file on your
-##  server.
-##
-##  Format:
-##     <message>:<from>:<newsgroups>:<action>
-##
-##     <message>      Control message or "all" if it applies to all control
-##                    messages.
-##     <from>         Pattern that must match the From line.
-##     <newsgroups>   Pattern that must match the newsgroup being newgroup'd
-##                    or rmgroup'd (ignored for other messages).
-##     <action>       What to do:
-##                          doit        Perform action
-##                          drop        Ignore message
-##                          log         One line to error log
-##                          mail        Send mail to admin
-##                          verify-pgp_userid   Do PGP verification on user.
-##                    All actions except drop and mail can be given a log
-##                    location by following the action with an = and the
-##                    log ("mail" says to mail the admin, an empty location
-##                    tosses the log information, and a relative path xxx
-##                    logs to $LOG/xxx.log).
-##
-##  The *last* matching entry is used.  See the expire.ctl(5) man page for
-##  complete information.
-##
-##  This file follows the following policies:
-##
-##   * Most unknown or invalid control messages no longer result in mail.
-##     This is due to the proliferation of forged control messages filling
-##     up mailboxes.  Some news servers even get overwhelmed with trying to
-##     log failure, so unsigned control messages for hierarchies that use
-##     PGP are simply dropped.
-##
-##   * The assumption is that you now have PGP on your system.  If you
-##     don't, you should get it to help protect yourself against all the
-##     control message forgeries.  See <ftp://ftp.isc.org/pub/pgpcontrol/>.
-##     PGP control message verification comes with all versions of INN since
-##     1.5, but you will need to install either PGP or GnuPG; see the
-##     installation instructions for your news server.
-##
-##     If for some reason you can't use PGP, search for the *PGP* comments
-##     and modify the control lines to change "verify-..." in the action
-##     field to "mail" or "doit=mail" or "doit=<log file>" or whatever you
-##     prefer (replacing <log file> with the name of an appropriate log
-##     file).
-## 
-##   * A number of hierarchies are for local use only but have leaked out
-##     into the general stream.  In this config file, they are set so that
-##     the groups will be easy to remove, and are marked with a comment of
-##     *LOCAL* (for use by that organization only, not generally
-##     distributed), *DEFUNCT* (a hierarchy that's no longer used), or
-##     *PRIVATE* (should only be carried after making arrangements with the
-##     given contact address).  Please delete all groups in those
-##     hierarchies from your server if you carry them, unless you've
-##     contacted the listed contact address and arranged a feed.
-##
-##     If you have permission to carry any of the hierarchies so listed in
-##     this file, you should change the entries for those hierarchies below.
-##
-##  The comments of this file aren't in any formal or well-defined syntax,
-##  but they are meant to use a consistent syntax to allow eventual parsing
-##  by scripts into a better database format.  Please follow the syntax of
-##  existing entries when providing new ones.  The recognized "fields" are
-##  Contact (contact e-mail address), Admin group (the administrative group
-##  for the hierarchy), URL, Key URL (URL for PGP key), Key fingerprint, Key
-##  mail (address to mail for PGP key), and Syncable server (for actsync or
-##  a similar tool).
-##
-##  Names used in this file that cannot be encoded in 7bit ASCII are in
-##  UTF-8.  The only non-7bit-ASCII content is in comments.
-
-## -------------------------------------------------------------------------
-##     DEFAULT
-## -------------------------------------------------------------------------
-
-# Default to dropping control messages that aren't recognized to allow
-# people to experiment without inadvertently mailbombing news admins.
-all:*:*:drop
-
-## -------------------------------------------------------------------------
-##     CHECKGROUPS MESSAGES
-## -------------------------------------------------------------------------
-
-# Default to mailing all checkgroups messages to the administrator.
-checkgroups:*:*:mail
-
-## -------------------------------------------------------------------------
-##     MISCELLANEOUS CONTROL MESSAGES
-## -------------------------------------------------------------------------
-
-# Mostly only used for UUCP feeds, very rarely used these days.
-ihave:*:*:drop
-sendme:*:*:drop
-
-# Request to send a copy of the newsfeeds file, intended for mapping
-# projects.  Almost never used for anything other than mailbombing now.
-sendsys:*:*:log=sendsys
-
-# Request to send the server's path entry.  Not particularly useful.
-senduuname:*:*:log=senduuname
-
-# Request to send the server's version number.
-version:*:*:log=version
-
-## -------------------------------------------------------------------------
-##     NEWGROUP/RMGROUP MESSAGES
-## -------------------------------------------------------------------------
-
-## Default (for any group)
-newgroup:*:*:mail
-rmgroup:*:*:mail
-
-## A.BSU (*DEFUNCT* -- Ball State University, USA)
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:a.bsu.*:mail
-rmgroup:*:a.bsu.*:doit
-
-## ACS & OSU (*LOCAL* -- Ohio State University, USA)
-# Contact: Albert J. School <school.1@osu.edu>
-# Contact: Harpal Chohan <chohan+@osu.edu>
-# For local use only, contact the above address for information.
-newgroup:*:acs.*|osu.*:mail
-rmgroup:*:acs.*|osu.*:doit
-
-## ADASS (Astronomical Data Analysis Software and Systems)
-# URL: http://iraf.noao.edu/iraf/web/adass_news.html
-checkgroups:news@iraf.noao.edu:adass.*:doit
-newgroup:news@iraf.noao.edu:adass.*:doit
-rmgroup:news@iraf.noao.edu:adass.*:doit
-
-## AHN (Athens-Clarke County, Georgia, USA)
-checkgroups:greg@*.ucns.uga.edu:ahn.*:doit
-newgroup:greg@*.ucns.uga.edu:ahn.*:doit
-rmgroup:greg@*.ucns.uga.edu:ahn.*:doit
-
-## AIOE (Aioe.org)
-# Contact: usenet@aioe.org
-# URL: http://news.aioe.org/hierarchy/
-# Admin group: aioe.system
-# Key URL: http://news.aioe.org/hierarchy/aioe.txt
-# Key fingerprint = 2203 1AAC 51E7 C7FD 664F  1D80 90DF 6C71 2322 A7F8
-# Syncable server: nntp.aioe.org
-# *PGP*   See comment at top of file.
-newgroup:*:aioe.*:drop
-rmgroup:*:aioe.*:drop
-checkgroups:usenet@aioe.org:aioe.*:verify-usenet@aioe.org
-newgroup:usenet@aioe.org:aioe.*:verify-usenet@aioe.org
-rmgroup:usenet@aioe.org:aioe.*:verify-usenet@aioe.org
-
-## AIR (*DEFUNCT* -- Stanford University, USA)
-# Contact: news@news.stanford.edu
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:air.*:mail
-rmgroup:*:air.*:doit
-
-## AKR (Akron, Ohio, USA)
-checkgroups:red@redpoll.mrfs.oh.us:akr.*:doit
-newgroup:red@redpoll.mrfs.oh.us:akr.*:doit
-rmgroup:red@redpoll.mrfs.oh.us:akr.*:doit
-
-## ALABAMA & HSV (Huntsville, Alabama, USA)
-# Contact: jpc@suespammers.org
-# Admin group: alabama.config
-# *PGP*   See comment at top of file.
-newgroup:*:alabama.*|hsv.*:drop
-rmgroup:*:alabama.*|hsv.*:drop
-checkgroups:jpc@suespammers.org:alabama.*|hsv.*:verify-alabama-group-admin
-newgroup:jpc@suespammers.org:alabama.*|hsv.*:verify-alabama-group-admin
-rmgroup:jpc@suespammers.org:alabama.*|hsv.*:verify-alabama-group-admin
-
-## ALIVE (*DEFUNCT* -- ?)
-# Contact: thijs@kink.xs4all.nl
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:alive.*:mail
-rmgroup:*:alive.*:doit
-
-## ALT
-#
-# Accept all newgroups (except ones forged from Big 8 newgroup issuers,
-# who never issue alt.* control messages) and silently ignore all
-# rmgroups.
-#
-# What policy to use for alt.* groups varies widely from site to site.
-# For a small site, it is strongly recommended that this policy be changed
-# to drop all newgroups and rmgroups for alt.*.  The local news admin can
-# then add new alt.* groups only on user request.  Tons of alt.* newgroups
-# are sent out regularly with the intent more to create nonsense entries
-# in active files than to actually create a useable newsgroup.  The admin
-# may still want to check the control message archive, as described below.
-#
-# Quality, user-desirable new groups can often be discovered by a quick
-# perusal of recent alt.* newgroup messages after discarding obvious junk
-# groups.  One good initial filter is to check the archive of control
-# messages for a requested group to see if a syntactically valid newgroup
-# message was issued.  Many of the junk control messages are invalid and
-# won't be archived, and many sites will only add alt.* groups with valid
-# control messages.  To check the archive, see if:
-#
-#     ftp://ftp.isc.org/pub/usenet/control/alt/<group-name>.gz
-#
-# exists (replacing <group-name> with the name of the group) and read the
-# first and last few control messages to see if the newsgroup should be
-# moderated.  (Some alt.* groups that should be moderated are created
-# unmoderated by hijackers to try to damage the newsgroup.)
-#
-# Be aware that there is no official, generally accepted alt.* policy and
-# all information about alt.* groups available is essentially someone's
-# opinion, including these comments.  There are nearly as many different
-# policies with regard to alt.* groups as there are Usenet sites.
-#
-newgroup:*:alt.*:doit
-newgroup:group-admin@isc.org:alt.*:drop
-newgroup:tale@*uu.net:alt.*:drop
-rmgroup:*:alt.*:drop
-
-## AR (Argentina)
-checkgroups:jorge_f@nodens.fisica.unlp.edu.ar:ar.*:doit
-newgroup:jorge_f@nodens.fisica.unlp.edu.ar:ar.*:doit
-rmgroup:jorge_f@nodens.fisica.unlp.edu.ar:ar.*:doit
-
-## ARC (*LOCAL* -- NASA Ames Research Center, USA)
-# Contact: news@arc.nasa.gov
-# For local use only, contact the above address for information.
-newgroup:*:arc.*:mail
-rmgroup:*:arc.*:doit
-
-## ARKANE (Arkane Systems, UK)
-# Contact: newsbastard@arkane.demon.co.uk
-checkgroups:newsbastard@arkane.demon.co.uk:arkane.*:doit
-newgroup:newsbastard@arkane.demon.co.uk:arkane.*:doit
-rmgroup:newsbastard@arkane.demon.co.uk:arkane.*:doit
-
-## AT (Austria)
-# URL: http://www.usenet.at/
-# Admin group: at.usenet.gruppen
-# Key URL: http://www.usenet.at/pgpkey.asc
-# *PGP*   See comment at top of file.
-newgroup:*:at.*:drop
-rmgroup:*:at.*:drop
-checkgroups:control@usenet.backbone.at:at.*:verify-control@usenet.backbone.at
-newgroup:control@usenet.backbone.at:at.*:verify-control@usenet.backbone.at
-rmgroup:control@usenet.backbone.at:at.*:verify-control@usenet.backbone.at
-
-## AUS (Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://aus.news-admin.org/
-# Admin group: aus.net.news
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:aus.*:drop
-rmgroup:*:aus.*:drop
-checkgroups:ausadmin@aus.news-admin.org:aus.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:aus.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:aus.*:verify-ausadmin@aus.news-admin.org
-
-## AUSTIN (Austin, Texas, USA)
-# URL: http://frenzy.austin.tx.us/austin/
-# Admin group: austin.usenet.config
-checkgroups:chip@unicom.com:austin.*:doit
-checkgroups:fletcher@cs.utexas.edu:austin.*:doit
-checkgroups:pug@pug.net:austin.*:doit
-newgroup:chip@unicom.com:austin.*:doit
-newgroup:fletcher@cs.utexas.edu:austin.*:doit
-newgroup:pug@pug.net:austin.*:doit
-rmgroup:chip@unicom.com:austin.*:doit
-rmgroup:fletcher@cs.utexas.edu:austin.*:doit
-rmgroup:pug@pug.net:austin.*:doit
-
-## AZ (Arizona, USA)
-checkgroups:system@asuvax.eas.asu.edu:az.*:doit
-newgroup:system@asuvax.eas.asu.edu:az.*:doit
-rmgroup:system@asuvax.eas.asu.edu:az.*:doit
-
-## BA (San Francisco Bay Area, USA)
-# Contact: ba-mod@nas.nasa.gov
-# URL: http://ennui.org/ba/
-# Admin group: ba.news.config
-# Key URL: http://ennui.org/ba/ba-mod.asc
-# *PGP*   See comment at top of file.
-newgroup:*:ba.*:drop
-rmgroup:*:ba.*:drop
-checkgroups:ba-mod@nas.nasa.gov:ba.*:verify-ba.news.config
-newgroup:ba-mod@nas.nasa.gov:ba.*:verify-ba.news.config
-rmgroup:ba-mod@nas.nasa.gov:ba.*:verify-ba.news.config
-
-## BACKBONE (*LOCAL* -- ruhr.de/ruhrgebiet.individual.net in Germany)
-# Contact: admin@ruhr.de
-# For local use only, contact the above address for information.
-newgroup:*:backbone.*:mail
-rmgroup:*:backbone.*:doit
-
-## BC (British Columbia, Canada)
-checkgroups:bc_van_usenet@fastmail.ca:bc.*:doit
-newgroup:bc_van_usenet@fastmail.ca:bc.*:doit
-rmgroup:bc_van_usenet@fastmail.ca:bc.*:doit
-
-## BDA (German groups?)
-checkgroups:news@*netuse.de:bda.*:doit
-newgroup:news@*netuse.de:bda.*:doit
-rmgroup:news@*netuse.de:bda.*:doit
-
-## BE (Belgique/Belgie/Belgien/Belgium)
-# Contact: be-hierarchy-admin@usenet.be
-# URL: http://usenet.be/
-# Admin group: be.announce
-# Key URL: http://usenet.be/be.announce.newgroups.asc
-# Key fingerprint = 30 2A 45 94 70 DE 1F D5  81 8C 58 64 D2 F7 08 71
-# *PGP*   See comment at top of file.
-newgroup:*:be.*:drop
-rmgroup:*:be.*:drop
-checkgroups:group-admin@usenet.be:be.*:verify-be.announce.newgroups
-newgroup:group-admin@usenet.be:be.*:verify-be.announce.newgroups
-rmgroup:group-admin@usenet.be:be.*:verify-be.announce.newgroups
-
-## BELWUE (Baden-Wuerttemberg, Germany)
-# Admin group: belwue.infos
-# *PGP*   See comment at top of file.
-newgroup:*:belwue.*:drop
-rmgroup:*:belwue.*:drop
-checkgroups:news@news.belwue.de:belwue.*:verify-belwue-hir-control
-newgroup:news@news.belwue.de:belwue.*:verify-belwue-hir-control
-rmgroup:news@news.belwue.de:belwue.*:verify-belwue-hir-control
-
-## BERMUDA (Bermuda)
-checkgroups:news@*ibl.bm:bermuda.*:doit
-newgroup:news@*ibl.bm:bermuda.*:doit
-rmgroup:news@*ibl.bm:bermuda.*:doit
-
-## BES (*PRIVATE* -- Beijing Electron Spectrometer)
-# Contact: news@news.stanford.edu
-# For private use only, contact the above address for information.
-newgroup:news@news.stanford.edu:bes.*:mail
-rmgroup:news@news.stanford.edu:bes.*:doit
-
-## BEST (*LOCAL* -- Best Internet Communications, Inc.)
-# Contact: news@best.net
-# For local use only, contact the above address for information.
-newgroup:*:best.*:mail
-rmgroup:*:best.*:doit
-
-## BIONET (Biology Network)
-# URL: http://www.bio.net/
-# Admin group: bionet.general
-# Key fingerprint = EB C0 F1 BA 26 0B C6 D6  FB 8D ED C4 AE 5D 10 54
-# *PGP*   See comment at top of file.
-newgroup:*:bionet.*:drop
-rmgroup:*:bionet.*:drop
-checkgroups:Biosci-control-key@net.bio.net:bionet.*:verify-Biosci-control-key@net.bio.net
-newgroup:Biosci-control-key@net.bio.net:bionet.*:verify-Biosci-control-key@net.bio.net
-rmgroup:Biosci-control-key@net.bio.net:bionet.*:verify-Biosci-control-key@net.bio.net
-
-## BIRK (*LOCAL* -- University of Oslo, Norway)
-# Contact: birk-admin@ping.uio.no
-# For local use only, contact the above address for information.
-newgroup:*:birk.*:mail
-rmgroup:*:birk.*:doit
-
-## BIT (Gatewayed Mailing lists)
-# URL: http://www.newsadmin.com/bit/bit.htm
-# Admin group: bit.admin
-# *PGP*   See comment at top of file.
-newgroup:*:bit.*:drop
-rmgroup:*:bit.*:drop
-checkgroups:bit@newsadmin.com:bit.*:verify-bit@newsadmin.com
-newgroup:bit@newsadmin.com:bit.*:verify-bit@newsadmin.com
-rmgroup:bit@newsadmin.com:bit.*:verify-bit@newsadmin.com
-
-## BIZ (Business Groups)
-checkgroups:edhew@xenitec.on.ca:biz.*:doit
-newgroup:edhew@xenitec.on.ca:biz.*:doit
-rmgroup:edhew@xenitec.on.ca:biz.*:doit
-
-## BLGTN (Bloomington, In, USA)
-checkgroups:control@news.bloomington.in.us:blgtn.*:doit
-newgroup:control@news.bloomington.in.us:blgtn.*:doit
-rmgroup:control@news.bloomington.in.us:blgtn.*:doit
-
-## BLN (Berlin, Germany)
-checkgroups:news@*fu-berlin.de:bln.*:doit
-newgroup:news@*fu-berlin.de:bln.*:doit
-rmgroup:news@*fu-berlin.de:bln.*:doit
-
-## BNE (Brisbane, Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://bne.news-admin.org/
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:bne.*:drop
-rmgroup:*:bne.*:drop
-checkgroups:ausadmin@aus.news-admin.org:bne.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:bne.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:bne.*:verify-ausadmin@aus.news-admin.org
-
-## BOFH (*PRIVATE* -- Bastard Operator From Hell)
-# Contact: myname@myhost.mydomain.com
-# For private use only, contact the above address for information.
-newgroup:*:bofh.*:mail
-rmgroup:*:bofh.*:doit
-
-## CA (California, USA)
-# Contact: ikluft@thunder.sbay.org
-# URL: http://www.sbay.org/ca/
-checkgroups:ikluft@thunder.sbay.org:ca.*:doit
-newgroup:ikluft@thunder.sbay.org:ca.*:doit
-rmgroup:ikluft@thunder.sbay.org:ca.*:doit
-
-## CAIS (*LOCAL* -- Capital Area Internet Services)
-# Contact: news@cais.com
-# For local use only, contact the above address for information.
-newgroup:*:cais.*:mail
-rmgroup:*:cais.*:doit
-
-## CALSTATE (California State University)
-checkgroups:*@*calstate.edu:calstate.*:doit
-newgroup:*@*calstate.edu:calstate.*:doit
-rmgroup:*@*calstate.edu:calstate.*:doit
-
-## CANB (Canberra, Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://canb.news-admin.org/
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:canb.*:drop
-rmgroup:*:canb.*:drop
-checkgroups:ausadmin@aus.news-admin.org:canb.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:canb.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:canb.*:verify-ausadmin@aus.news-admin.org
-
-## CAPDIST (Albany, The Capital District, New York, USA)
-checkgroups:danorton@albany.net:capdist.*:doit
-newgroup:danorton@albany.net:capdist.*:doit
-rmgroup:danorton@albany.net:capdist.*:doit
-
-## CARLETON (Carleton University, Canada)
-newgroup:news@cunews.carleton.ca:carleton.*:doit
-newgroup:news@cunews.carleton.ca:carleton*class.*:mail
-rmgroup:news@cunews.carleton.ca:carleton.*:doit
-
-## CD-ONLINE (*LOCAL* -- ?)
-# Contact: newsmaster@worldonline.nl
-# For local use only, contact the above address for information.
-newgroup:*:cd-online.*:mail
-rmgroup:*:cd-online.*:doit
-
-## CENTRAL (*LOCAL* -- The Internet Company of New Zealand, Wellington, NZ)
-# Contact: usenet@iconz.co.nz
-# For local use only, contact the above address for information.
-newgroup:*:central.*:mail
-rmgroup:*:central.*:doit
-
-## CERN (*PRIVATE* -- CERN European Laboratory for Particle Physics)
-# Contact: Dietrich Wiegandt <News.Support@cern.ch>
-# For private use only, contact the above address for information.
-newgroup:News.Support@cern.ch:cern.*:mail
-rmgroup:News.Support@cern.ch:cern.*:doit
-
-## CH (Switzerland)
-# Contact: ch-news-admin@use-net.ch
-# URL: http://www.use-net.ch/Usenet/
-# Key URL: http://www.use-net.ch/Usenet/adminkey.html
-# Key fingerprint = 71 80 D6 8C A7 DE 2C 70  62 4A 48 6E D9 96 02 DF
-# *PGP*   See comment at top of file.
-newgroup:*:ch.*:drop
-rmgroup:*:ch.*:drop
-checkgroups:felix.rauch@nice.ch:ch.*:verify-ch-news-admin@use-net.ch
-newgroup:felix.rauch@nice.ch:ch.*:verify-ch-news-admin@use-net.ch
-rmgroup:felix.rauch@nice.ch:ch.*:verify-ch-news-admin@use-net.ch
-
-## CHAVEN (*LOCAL* -- Celestian Haven ISP, Midwest, USA)
-# Contact: news@chaven.com
-# For local use only, contact the above address for information.
-newgroup:*:chaven.*:mail
-rmgroup:*:chaven.*:doit
-
-## CHI (Chicago, USA)
-# URL: http://lull.org/pub/chi-newsgroup-faq
-checkgroups:lisbon@*chi.il.us:chi.*:doit
-newgroup:lisbon@*chi.il.us:chi.*:doit
-rmgroup:lisbon@*chi.il.us:chi.*:doit
-
-## CHILE (Chile and Chilean affairs)
-# Contact: mod-cga@usenet.cl
-# URL: http://www.usenet.cl/
-# Admin group: chile.grupos.anuncios
-checkgroups:mod-cga@*lj.cl:chile.*:doit
-newgroup:mod-cga@*lj.cl:chile.*:doit
-rmgroup:mod-cga@*lj.cl:chile.*:doit
-
-## CHINESE (China and Chinese language groups)
-checkgroups:pinghua@stat.berkeley.edu:chinese.*:doit
-newgroup:pinghua@stat.berkeley.edu:chinese.*:doit
-rmgroup:pinghua@stat.berkeley.edu:chinese.*:doit
-
-## CHRISTNET (Christian Discussion)
-checkgroups:news@fdma.com:christnet.*:doit
-newgroup:news@fdma.com:christnet.*:doit
-rmgroup:news@fdma.com:christnet.*:doit
-
-## CL (*PRIVATE* -- CL-Netz, German)
-# Contact: koordination@cl-netz.de
-# URL: http://www.cl-netz.de/
-# Key URL: http://www.cl-netz.de/control.txt
-# For private use only, contact above address for questions.
-# *PGP*   See comment at top of file.
-newgroup:*:cl.*:drop
-rmgroup:*:cl.*:doit
-# The following three lines are only for authorized cl.* sites.
-#checkgroups:koordination@cl-netz.de:cl.*:verify-cl.netz.infos
-#newgroup:koordination@cl-netz.de:cl.*:verify-cl.netz.infos
-#rmgroup:koordination@cl-netz.de:cl.*:verify-cl.netz.infos
-
-## CLARI (*PRIVATE* -- Features and News, available on a commercial basis)
-# Contact: support@clari.net
-# Admin group: clari.net.admin
-# Key URL: http://www.clari.net/tech/clarikey.txt
-# For private use only, contact the above address for information.
-# *PGP*   See comment at top of file.
-newgroup:*:clari.*:drop
-rmgroup:*:clari.*:drop
-newgroup:cl*@clarinet.com:clari.*:mail
-rmgroup:cl*@clarinet.com:clari.*:verify-ClariNet.Group
-
-## CMI (*LOCAL* -- Champaign County, IL, USA)
-# Contact: news@ks.uiuc.edu
-# For local use only, contact the above address for information.
-newgroup:*:cmi.*:mail
-rmgroup:*:cmi.*:doit
-
-## CMU (*LOCAL* -- Carnegie-Mellon University, Pennsylvania, USA)
-# Contact: Daniel Edward Lovinger <del+@CMU.EDU>
-# For local use only, contact the above address for information.
-newgroup:*:cmu.*:mail
-rmgroup:*:cmu.*:doit
-
-## CN (China)
-# URL: http://news.yaako.com/
-# Admin group: cn.announce
-# Key fingerprint = 62 97 EE 33 F7 16 25 C1  A4 9E 47 BA C5 3E 5E 9E
-# *PGP*   See comment at top of file.
-newgroup:*:cn.*:drop
-rmgroup:*:cn.*:drop
-checkgroups:control@bentium.com:cn.*:verify-cn.admin.news.announce
-newgroup:control@bentium.com:cn.*:verify-cn.admin.news.announce
-rmgroup:control@bentium.com:cn.*:verify-cn.admin.news.announce
-
-## CN.BBS (China)
-# URL: http://bbs.cn.news-admin.org/
-# Admin group: cn.bbs.admin.announce
-# *PGP*   See comment at top of file.
-newgroup:*:cn.bbs.*:drop
-rmgroup:*:cn.bbs.*:drop
-checkgroups:control@cn-bbs.org:cn.bbs.*:verify-cn.bbs.admin.announce
-newgroup:control@cn-bbs.org:cn.bbs.*:verify-cn.bbs.admin.announce
-rmgroup:control@cn-bbs.org:cn.bbs.*:verify-cn.bbs.admin.announce
-
-## CO (Colorado, USA)
-# Contact: coadmin@boyznoyz.com (Bill of Denver)
-checkgroups:coadmin@boyznoyz.com:co.*:doit
-newgroup:coadmin@boyznoyz.com:co.*:doit
-rmgroup:coadmin@boyznoyz.com:co.*:doit
-
-## CODEWARRIOR (CodeWarrior discussion)
-checkgroups:news@supernews.net:codewarrior.*:doit
-newgroup:news@supernews.net:codewarrior.*:doit
-rmgroup:news@supernews.net:codewarrior.*:doit
-
-## COMP, HUMANITIES, MISC, NEWS, REC, SCI, SOC, TALK (The Big Eight)
-# Contact: board@big-8.org
-# URL: http://www.big-8.org/
-# Admin group: news.announce.newgroups
-# Key fingerprint = F5 35 58 D3 55 64 10 14  07 C6 95 53 13 6F D4 07
-# *PGP*   See comment at top of file.
-newgroup:*:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:drop
-rmgroup:*:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:drop
-checkgroups:group-admin@isc.org:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:verify-news.announce.newgroups
-newgroup:group-admin@isc.org:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:verify-news.announce.newgroups
-rmgroup:group-admin@isc.org:comp.*|humanities.*|misc.*|news.*|rec.*|sci.*|soc.*|talk.*:verify-news.announce.newgroups
-
-## COMPUTER42 (Computer 42, Germany)
-# Contact: Dirk Schmitt <news@computer42.org>
-checkgroups:news@computer42.org:computer42.*:doit
-newgroup:news@computer42.org:computer42.*:doit
-rmgroup:news@computer42.org:computer42.*:doit
-
-## CONCORDIA (Concordia University, Montreal, Canada)
-# Contact: newsmaster@concordia.ca
-# URL: General University info at http://www.concordia.ca/
-checkgroups:news@newsflash.concordia.ca:concordia.*:doit
-newgroup:news@newsflash.concordia.ca:concordia.*:doit
-rmgroup:news@newsflash.concordia.ca:concordia.*:doit
-
-## COURTS (*DEFUNCT* -- Court discussion)
-# Contact: trier@ins.cwru.edu
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:courts.*:mail
-rmgroup:*:courts.*:doit
-
-## CPCUIIA (Chartered Prop. Casulty Underwriter/Insurance Institute of America)
-# Contact: miller@cpcuiia.org
-# URL: http://www.aicpcu.org/
-checkgroups:miller@cpcuiia.org:cpcuiia.*:doit
-newgroup:miller@cpcuiia.org:cpcuiia.*:doit
-rmgroup:miller@cpcuiia.org:cpcuiia.*:doit
-
-## CU (*LOCAL* -- University of Colorado)
-# Contact: Doreen Petersen <news@colorado.edu>
-# For local use only, contact the above address for information.
-newgroup:*:cu.*:mail
-rmgroup:*:cu.*:doit
-
-## CUHK (*LOCAL* -- Chinese University of Hong Kong)
-# Contact: shlam@ie.cuhk.edu.hk (Alan S H Lam)
-# For local use only, contact the above address for information.
-newgroup:*:cuhk.*:mail
-rmgroup:*:cuhk.*:doit
-
-## CZ (Czech Republic)
-# URL: ftp://ftp.vslib.cz/pub/news/config/cz/newsgroups (text)
-checkgroups:petr.kolar@vslib.cz:cz.*:doit
-newgroup:petr.kolar@vslib.cz:cz.*:doit
-rmgroup:petr.kolar@vslib.cz:cz.*:doit
-
-## DC (Washington, D.C., USA)
-checkgroups:news@mattress.atww.org:dc.*:doit
-newgroup:news@mattress.atww.org:dc.*:doit
-rmgroup:news@mattress.atww.org:dc.*:doit
-
-## DE (German language)
-# Contact: moderator@dana.de
-# URL: http://www.dana.de/mod/
-# Admin group: de.admin.news.announce
-# Key URL: http://www.dana.de/mod/pgp/dana.asc
-# Key fingerprint = 5B B0 52 88 BF 55 19 4F  66 7D C2 AE 16 26 28 25
-# *PGP*   See comment at top of file.
-newgroup:*:de.*:drop
-rmgroup:*:de.*:drop
-checkgroups:moderator@dana.de:de.*:verify-de.admin.news.announce
-newgroup:moderator@dana.de:de.*:verify-de.admin.news.announce
-rmgroup:moderator@dana.de:de.*:verify-de.admin.news.announce
-
-## DE.ALT (German language alternative hierarchy)
-# *PGP*   See comment at top of file.
-newgroup:*:de.alt.*:doit
-rmgroup:moderator@dana.de:de.alt.*:verify-de.admin.news.announce
-
-## DFW (Dallas/Fort Worth, Texas, USA)
-# URL: http://www.cirr.com/dfw/
-# Admin group: dfw.usenet.config
-checkgroups:eric@*cirr.com:dfw.*:doit
-newgroup:eric@*cirr.com:dfw.*:doit
-rmgroup:eric@*cirr.com:dfw.*:doit
-
-## DK (Denmark)
-# URL: http://www.usenet.dk/dk-admin/
-# Key URL: http://www.usenet.dk/dk-admin/pubkey.html
-# Key fingerprint = 7C B2 C7 50 F3 7D 5D 73  8C EE 2E 3F 55 80 72 FF
-# *PGP*   See comment at top of file.
-newgroup:*:dk.*:drop
-rmgroup:*:dk.*:drop
-checkgroups:news@news.dknet.dk:dk.*:verify-news@news.dknet.dk
-newgroup:news@news.dknet.dk:dk.*:verify-news@news.dknet.dk
-rmgroup:news@news.dknet.dk:dk.*:verify-news@news.dknet.dk
-
-## DUKE (*LOCAL* -- Duke University, USA)
-# Contact: news@newsgate.duke.edu
-# For local use only, contact the above address for information.
-newgroup:*:duke.*:mail
-rmgroup:*:duke.*:doit
-
-## EASYNET (Easynet PLC, UK)
-# Contact: Christiaan Keet <newsmaster@easynet.net>
-# Admin group: easynet.support
-# *PGP*   See comment at top of file.
-newgroup:*:easynet.*:drop
-rmgroup:*:easynet.*:drop
-checkgroups:newsmaster@easynet.net:easynet.*:verify-easynet.news
-newgroup:newsmaster@easynet.net:easynet.*:verify-easynet.news
-rmgroup:newsmaster@easynet.net:easynet.*:verify-easynet.news
-
-## EE (Estonia)
-# Contact: usenet@news.ut.ee
-# URL: http://news.ut.ee/
-# Key URL: http://news.ut.ee/pubkey.asc
-# *PGP*   See comment at top of file.
-newgroup:*:ee.*:drop
-rmgroup:*:ee.*:drop
-checkgroups:news@news.ut.ee:ee.*:verify-ee.news
-newgroup:news@news.ut.ee:ee.*:verify-ee.news
-rmgroup:news@news.ut.ee:ee.*:verify-ee.news
-
-## EFN & EUG (Eugene Free Computer Network, Eugene/Springfield, Oregon, USA)
-# Admin group: eug.config
-# *PGP*   See comment at top of file.
-newgroup:*:efn.*|eug.*:drop
-rmgroup:*:efn.*|eug.*:drop
-checkgroups:newsadmin@efn.org:efn.*|eug.*:verify-eug.config
-newgroup:newsadmin@efn.org:efn.*|eug.*:verify-eug.config
-rmgroup:newsadmin@efn.org:efn.*|eug.*:verify-eug.config
-
-## EHIME-U (? University, Japan ?)
-checkgroups:news@cc.nias.ac.jp:ehime-u.*:doit
-checkgroups:news@doc.dpc.ehime-u.ac.jp:ehime-u.*:doit
-newgroup:news@cc.nias.ac.jp:ehime-u.*:doit
-newgroup:news@doc.dpc.ehime-u.ac.jp:ehime-u.*:doit
-rmgroup:news@cc.nias.ac.jp:ehime-u.*:doit
-rmgroup:news@doc.dpc.ehime-u.ac.jp:ehime-u.*:doit
-
-## ENGLAND (England)
-# Contact: admin@england.news-admin.org
-# Admin group: england.news.policy
-# Key fingerprint = DA 3E C2 01 46 E5 61 CB  A2 43 09 CA 13 6D 31 1F
-# *PGP*   See comment at top of file.
-newgroup:*:england.*:drop
-rmgroup:*:england.*:drop
-checkgroups:admin@england.news-admin.org:england.*:verify-england-usenet
-newgroup:admin@england.news-admin.org:england.*:verify-england-usenet
-rmgroup:admin@england.news-admin.org:england.*:verify-england-usenet
-
-## ES (Spain)
-# Contact: moderador@corus-es.org
-# URL: http://www.corus-es.org/docs/es_newsadmins_faq.txt
-# Admin group: es.news.anuncios
-# Key URL: http://www.corus-es.org/docs/esnews.asc
-# *PGP*   See comment at top of file.
-newgroup:*:es.*:drop
-rmgroup:*:es.*:drop
-checkgroups:moderador@corus-es.org:es.*:verify-es.news
-newgroup:moderador@corus-es.org:es.*:verify-es.news
-rmgroup:moderador@corus-es.org:es.*:verify-es.news
-
-## ESP (Spanish-language newsgroups)
-# Contact: <mod-ena@ennui.org>
-# URL: http://ennui.org/esp/
-# Key URL: http://ennui.org/esp/mod-ena.asc
-# *PGP*   See comment at top of file.
-newgroup:*:esp.*:drop
-rmgroup:*:esp.*:drop
-checkgroups:mod-ena@ennui.org:esp.*:verify-esp.news.administracion
-newgroup:mod-ena@ennui.org:esp.*:verify-esp.news.administracion
-rmgroup:mod-ena@ennui.org:esp.*:verify-esp.news.administracion
-
-## EUNET (Europe)
-checkgroups:news@noc.eu.net:eunet.*:doit
-newgroup:news@noc.eu.net:eunet.*:doit
-rmgroup:news@noc.eu.net:eunet.*:doit
-
-## EUROPA (Europe)
-# URL: http://www.europa.usenet.eu.org/
-# Admin group: europa.usenet.admin
-# Key URL: http://www.europa.usenet.eu.org/pgp/index.html
-# Key fingerprint = 3A 05 A8 49 FB 16 29 25  75 E3 DE BB 69 E0 1D B4
-# *PGP*   See comment at top of file.
-newgroup:*:europa.*:drop
-rmgroup:*:europa.*:drop
-checkgroups:group-admin@usenet.eu.org:europa.*:verify-group-admin@usenet.eu.org
-newgroup:group-admin@usenet.eu.org:europa.*:verify-group-admin@usenet.eu.org
-rmgroup:group-admin@usenet.eu.org:europa.*:verify-group-admin@usenet.eu.org
-
-## EXAMPLE (Bogus hierarchy reserved for standards documents)
-newgroup:*:example.*:mail
-rmgroup:*:example.*:doit
-
-## FA (Gated mailing lists)
-# This hierarchy was removed in the "Great Renaming" of 1988.
-#
-# A site in Norway is currently (as of 2002) gatewaying various mailing
-# lists into fa.* newsgroups, but that site does not appear to be issuing
-# any control messages for those groups.
-#
-newgroup:*:fa.*:mail
-rmgroup:*:fa.*:doit
-
-## FFM (Frankfurt/M., Germany)
-# URL: http://ffm.arcornews.de/
-# Key URL: ftp://ftp.arcor-online.net/pub/news/PGPKEY.FFM
-# *PGP*   See comment at top of file.
-newgroup:*:ffm.*:drop
-rmgroup:*:ffm.*:drop
-checkgroups:ffm.admin@arcor.de:ffm.*:verify-ffm.admin
-newgroup:ffm.admin@arcor.de:ffm.*:verify-ffm.admin
-rmgroup:ffm.admin@arcor.de:ffm.*:verify-ffm.admin
-
-## FIDO (FidoNet)
-checkgroups:root@mbh.org:fido.*:doit
-newgroup:root@mbh.org:fido.*:doit
-rmgroup:root@mbh.org:fido.*:doit
-
-## FIDO.BELG (Belgian FidoNet)
-# Admin group: fido.belg.news
-# *PGP*   See comment at top of file.
-newgroup:*:fido.belg.*:drop
-rmgroup:*:fido.belg.*:drop
-checkgroups:fidobelg@mail.z2.fidonet.org:fido.belg.*:verify-fido.belg.news
-newgroup:fidobelg@mail.z2.fidonet.org:fido.belg.*:verify-fido.belg.news
-rmgroup:fidobelg@mail.z2.fidonet.org:fido.belg.*:verify-fido.belg.news
-
-## FIDO.GER (German FIDO Net Echos)
-# URL: ftp://ftp.fu-berlin.de/doc/news/fido.ger/fido.ger-info.english
-# Key URL: ftp://ftp.fu-berlin.de/doc/news/fido.ger/PGP-Key
-# *PGP*   See comment at top of file.
-newgroup:*:fido.ger.*:drop
-rmgroup:*:fido.ger.*:drop
-checkgroups:fido.ger@news.fu-berlin.de:fido.ger.*:verify-fido.ger@news.fu-berlin.de
-newgroup:fido.ger@news.fu-berlin.de:fido.ger.*:verify-fido.ger@news.fu-berlin.de
-rmgroup:fido.ger@news.fu-berlin.de:fido.ger.*:verify-fido.ger@news.fu-berlin.de
-
-## FIDO7 (Russian FidoNet)
-# URL: http://www.fido7.ru/
-# Admin group: fido7.postmasters
-# Key URL: http://www.fido7.ru/pgpcontrol.html
-# *PGP*   See comment at top of file.
-newgroup:*:fido7.*:drop
-rmgroup:*:fido7.*:drop
-checkgroups:newgroups-request@fido7.ru:fido7.*:verify-fido7.announce.newgroups
-newgroup:newgroups-request@fido7.ru:fido7.*:verify-fido7.announce.newgroups
-rmgroup:newgroups-request@fido7.ru:fido7.*:verify-fido7.announce.newgroups
-
-## FINET (Finland and Finnish language alternative newsgroups)
-checkgroups:*@*.fi:finet.*:doit
-newgroup:*@*.fi:finet.*:doit
-rmgroup:*@*.fi:finet.*:doit
-
-## FJ (Japan and Japanese language)
-# Contact: committee@fj-news.org
-# URL: http://www.fj-news.org/index.html.en
-# Admin group: fj.news.announce
-# Key URL: http://www.is.tsukuba.ac.jp/~yas/fj/fj.asc
-# *PGP*   See comment at top of file.
-newgroup:*:fj.*:drop
-rmgroup:*:fj.*:drop
-checkgroups:committee@fj-news.org:fj.*:verify-fj.news.announce
-newgroup:committee@fj-news.org:fj.*:verify-fj.news.announce
-rmgroup:committee@fj-news.org:fj.*:verify-fj.news.announce
-
-## FL (Florida, USA)
-checkgroups:hgoldste@news1.mpcs.com:fl.*:doit
-checkgroups:scheidell@fdma.fdma.com:fl.*:doit
-newgroup:hgoldste@news1.mpcs.com:fl.*:doit
-newgroup:scheidell@fdma.fdma.com:fl.*:doit
-rmgroup:hgoldste@news1.mpcs.com:fl.*:doit
-rmgroup:scheidell@fdma.fdma.com:fl.*:doit
-
-## FLORA (FLORA Community WEB, Canada)
-# Contact: russell@flora.org
-# Admin group: flora.general
-# *PGP*   See comment at top of file.
-newgroup:*:flora.*:drop
-rmgroup:*:flora.*:drop
-checkgroups:news@flora.ottawa.on.ca:flora.*:verify-flora-news
-newgroup:news@flora.ottawa.on.ca:flora.*:verify-flora-news
-rmgroup:news@flora.ottawa.on.ca:flora.*:verify-flora-news
-
-## FR (French language)
-# URL: http://www.usenet-fr.news.eu.org/
-# Admin group: fr.usenet.forums.annonces
-# Key URL: http://www.usenet-fr.news.eu.org/fur/usenet/presentation-fr.html
-# *PGP*   See comment at top of file.
-newgroup:*:fr.*:drop
-rmgroup:*:fr.*:drop
-checkgroups:control@usenet-fr.news.eu.org:fr.*:verify-control@usenet-fr.news.eu.org
-newgroup:control@usenet-fr.news.eu.org:fr.*:verify-control@usenet-fr.news.eu.org
-rmgroup:control@usenet-fr.news.eu.org:fr.*:verify-control@usenet-fr.news.eu.org
-
-## FRANCE (France)
-# Contact: control@usenet-france.news.eu.org
-# Admin group: france.admin.evolutions
-# *PGP*   See comment at top of file.
-newgroup:*:france.*:drop
-rmgroup:*:france.*:drop
-checkgroups:control@usenet-france.news.eu.org:france.*:verify-control@usenet-france.news.eu.org
-newgroup:control@usenet-france.news.eu.org:france.*:verify-control@usenet-france.news.eu.org
-rmgroup:control@usenet-france.news.eu.org:france.*:verify-control@usenet-france.news.eu.org
-
-## FREE (Open Hierarchy where anyone can create a group)
-newgroup:*:free.*:doit
-newgroup:group-admin@isc.org:free.*:drop
-newgroup:tale@*uu.net:free.*:drop
-rmgroup:*:free.*:drop
-
-## FUDAI (Japanese ?)
-checkgroups:news@picard.cs.osakafu-u.ac.jp:fudai.*:doit
-newgroup:news@picard.cs.osakafu-u.ac.jp:fudai.*:doit
-rmgroup:news@picard.cs.osakafu-u.ac.jp:fudai.*:doit
-
-## FUR (*PRIVATE* -- furrynet)
-# Contact: fur-config@news.furry.net
-# For private use only, contact the above address for information.
-newgroup:*:fur.*:mail
-rmgroup:*:fur.*:doit
-
-## GER & HANNET & HANNOVER & HILDESHEIM & HISS (Hannover, Germany)
-checkgroups:fifi@hiss.han.de:ger.*|hannover.*|hannet.*|hildesheim.*|hiss.*:doit
-newgroup:fifi@hiss.han.de:ger.*|hannover.*|hannet.*|hildesheim.*|hiss.*:doit
-rmgroup:fifi@hiss.han.de:ger.*|hannover.*|hannet.*|hildesheim.*|hiss.*:doit
-
-## GIT (Georgia Institute of Technology, USA)
-newgroup:news@news.gatech.edu:git.*:doit
-newgroup:news@news.gatech.edu:git*class.*:mail
-rmgroup:news@news.gatech.edu:git.*:doit
-
-## GNU (Free Software Foundation)
-# URL: http://www.gnu.org/usenet/usenet.html
-# Admin group: gnu.gnusenet.config
-# Key URL: http://www.gnu.org/usenet/usenet-pgp-key.txt
-# *PGP*   See comment at top of file.
-newgroup:*:gnu.*:drop
-rmgroup:*:gnu.*:drop
-checkgroups:usenet@gnu.org:gnu.*:verify-usenet@gnu.org
-newgroup:usenet@gnu.org:gnu.*:verify-usenet@gnu.org
-rmgroup:usenet@gnu.org:gnu.*:verify-usenet@gnu.org
-
-## GNUU (*PRIVATE* -- GNUU e.V., Oberursel, Germany)
-# Contact: news@gnuu.de
-# For private use only, contact the above address for information.
-newgroup:*:gnuu.*:mail
-rmgroup:*:gnuu.*:doit
-
-## GOV (Government Information)
-# Admin group: gov.usenet.announce
-# *PGP*   See comment at top of file.
-newgroup:*:gov.*:drop
-rmgroup:*:gov.*:drop
-checkgroups:gov-usenet-announce-moderator@govnews.org:gov.*:verify-gov.usenet.announce
-newgroup:gov-usenet-announce-moderator@govnews.org:gov.*:verify-gov.usenet.announce
-rmgroup:gov-usenet-announce-moderator@govnews.org:gov.*:verify-gov.usenet.announce
-
-## GWU (George Washington University, Washington, DC)
-# Contact: Sweth Chandramouli <news@nit.gwu.edu>
-checkgroups:news@nit.gwu.edu:gwu.*:doit
-newgroup:news@nit.gwu.edu:gwu.*:doit
-rmgroup:news@nit.gwu.edu:gwu.*:doit
-
-## HAMBURG (City of Hamburg, Germany)
-# Contact: hamburg@steering-group.net
-# URL: http://www.steering-group.net/hamburg/
-# Admin group: hamburg.koordination
-# Key URL: http://www.steering-group.net/hamburg/hamburg.koordination.txt
-# Key fingerprint = 3E E7 0C BB 6E 01 94 EE  45 6F C5 57 F4 B9 54 8E
-# *PGP*   See comment at top of file.
-newgroup:*:hamburg.*:drop
-rmgroup:*:hamburg.*:drop
-checkgroups:hamburg@steering-group.net:hamburg.*:verify-hamburg.koordination
-newgroup:hamburg@steering-group.net:hamburg.*:verify-hamburg.koordination
-rmgroup:hamburg@steering-group.net:hamburg.*:verify-hamburg.koordination
-
-## HAMILTON (Canadian)
-checkgroups:news@*dcss.mcmaster.ca:hamilton.*:doit
-newgroup:news@*dcss.mcmaster.ca:hamilton.*:doit
-rmgroup:news@*dcss.mcmaster.ca:hamilton.*:doit
-
-## HAMSTER (Hamster, a Win32 news and mail proxy server)
-# Contact: hamster-contact@snafu.de
-# Admin group: hamster.de.config
-# Key fingerprint = 12 75 A9 42 8A D6 1F 77  6A CF B4 0C 79 15 5F 93
-# *PGP*   See comment at top of file.
-newgroup:*:hamster.*:drop
-rmgroup:*:hamster.*:drop
-checkgroups:hamster-control@snafu.de:hamster.*:verify-hamster-control@snafu.de
-newgroup:hamster-control@snafu.de:hamster.*:verify-hamster-control@snafu.de
-rmgroup:hamster-control@snafu.de:hamster.*:verify-hamster-control@snafu.de
-
-## HAN (Korean Hangul)
-# Contact: newgroups-request@usenet.or.kr
-# Admin group: han.news.admin
-# Key URL: ftp://ftp.usenet.or.kr/pub/korea/usenet/pgp/PGPKEY.han
-# *PGP*   See comment at top of file.
-newgroup:*:han.*:drop
-rmgroup:*:han.*:drop
-checkgroups:newgroups-request@usenet.or.kr:han.*:verify-han.news.admin
-newgroup:newgroups-request@usenet.or.kr:han.*:verify-han.news.admin
-rmgroup:newgroups-request@usenet.or.kr:han.*:verify-han.news.admin
-
-## HARVARD (*LOCAL* -- Harvard University, Cambridge, MA)
-# For local use only.
-newgroup:*@*.harvard.edu:harvard.*:mail
-rmgroup:*@*.harvard.edu:harvard.*:doit
-
-## HAWAII (Hawaii, USA)
-checkgroups:news@lava.net:hawaii.*:doit
-newgroup:news@lava.net:hawaii.*:doit
-rmgroup:news@lava.net:hawaii.*:doit
-
-## HFX (Halifax, Nova Scotia)
-checkgroups:stevemackie@gmail.com:hfx.*:doit
-newgroup:stevemackie@gmail.com:hfx.*:doit
-rmgroup:stevemackie@gmail.com:hfx.*:doit
-
-## HIV (HIVNET Foundation, for HIV+/AIDS information)
-# Contact: news@hivnet.org
-# Admin group: hiv.config
-# Key fingerprint = 5D D6 0E DC 1E 2D EA 0B  B0 56 4D D6 52 53 D7 A4
-# *PGP*   See comment at top of file.
-newgroup:*:hiv.*:drop
-rmgroup:*:hiv.*:drop
-checkgroups:news@hivnet.org:hiv.*:verify-news@hivnet.org
-newgroup:news@hivnet.org:hiv.*:verify-news@hivnet.org
-rmgroup:news@hivnet.org:hiv.*:verify-news@hivnet.org
-
-## HK (Hong Kong)
-checkgroups:hknews@comp.hkbu.edu.hk:hk.*:doit
-newgroup:hknews@comp.hkbu.edu.hk:hk.*:doit
-rmgroup:hknews@comp.hkbu.edu.hk:hk.*:doit
-
-## HOUSTON (Houston, Texas, USA)
-# Admin group: houston.usenet.config
-# *PGP*   See comment at top of file.
-newgroup:*:houston.*:drop
-rmgroup:*:houston.*:drop
-checkgroups:news@academ.com:houston.*:verify-houston.usenet.config
-newgroup:news@academ.com:houston.*:verify-houston.usenet.config
-rmgroup:news@academ.com:houston.*:verify-houston.usenet.config
-
-## HR (Croatian language)
-# Contact: newsmaster@carnet.hr
-# URL: http://newsfeed.carnet.hr/control/
-# Admin group: hr.news.admin
-# Key URL: http://newsfeed.carnet.hr/control/key.txt
-# Key fingerprint = 0EE5 74FB 1C40 7ADB 0AAC  A52F 7192 1BA3 ED63 AD9A
-# Syncable server: news.carnet.hr
-# *PGP*   See comment at top of file.
-newgroup:*:hr.*:drop
-rmgroup:*:hr.*:drop
-checkgroups:newsmaster@carnet.hr:hr.*:verify-newsmaster@carnet.hr
-newgroup:newsmaster@carnet.hr:hr.*:verify-newsmaster@carnet.hr
-rmgroup:newsmaster@carnet.hr:hr.*:verify-newsmaster@carnet.hr
-
-## HUMANITYQUEST (Humanities discussion)
-# Contact: news-admin@humanityquest.com
-# URL: http://www.humanityquest.com/projects/newsgroups/
-# Key URL: http://www.humanityquest.com/projects/newsgroups/PGP.htm
-# Key fingerprint = BA3D B306 B6F5 52AA BA8F 32F0 8C4F 5040 16F9 C046
-# *PGP*   See comment at top of file.
-newgroup:*:humanityquest.*:drop
-rmgroup:*:humanityquest.*:drop
-checkgroups:news-admin@humanityquest.com:humanityquest.*:verify-humanityquest.admin.config
-newgroup:news-admin@humanityquest.com:humanityquest.*:verify-humanityquest.admin.config
-rmgroup:news-admin@humanityquest.com:humanityquest.*:verify-humanityquest.admin.config
-
-## HUN (Hungary)
-# URL: http://www.sztaki.hu/~kissg/news/hiteles.html
-# Admin group: hun.admin.news
-# Key URL: http://gatling.ikk.sztaki.hu/~kissg/news/hun.admin.news.asc
-# *PGP*   See comment at top of file.
-newgroup:*:hun.*:drop
-rmgroup:*:hun.*:drop
-checkgroups:hun-mnt@news.sztaki.hu:hun.*:verify-hun.admin.news
-newgroup:hun-mnt@news.sztaki.hu:hun.*:verify-hun.admin.news
-rmgroup:hun-mnt@news.sztaki.hu:hun.*:verify-hun.admin.news
-
-## IA (Iowa, USA)
-checkgroups:skunz@iastate.edu:ia.*:doit
-newgroup:skunz@iastate.edu:ia.*:doit
-rmgroup:skunz@iastate.edu:ia.*:doit
-
-## IBMNET (*LOCAL* -- ?)
-# Contact: news@ibm.net
-# For local use only, contact the above address for information.
-newgroup:*:ibmnet.*:mail
-rmgroup:*:ibmnet.*:doit
-
-## ICONZ (*LOCAL* -- The Internet Company of New Zealand, New Zealand)
-# Contact: usenet@iconz.co.nz
-# For local use only, contact the above address for information.
-newgroup:*:iconz.*:mail
-rmgroup:*:iconz.*:doit
-
-## IDOCTRA (Idoctra Translation Software, Translation Discussion)
-# Contact: support@idoctra.com
-checkgroups:support@idoctra.com:idoctra.*:doit
-newgroup:support@idoctra.com:idoctra.*:doit
-rmgroup:support@idoctra.com:idoctra.*:doit
-
-## IE (Ireland)
-# Contact: control@usenet.ie
-# Admin group: ie.news.group
-# *PGP*   See comment at top of file.
-newgroup:*:ie.*:drop
-rmgroup:*:ie.*:drop
-checkgroups:control@usenet.ie:ie.*:verify-control@usenet.ie
-newgroup:control@usenet.ie:ie.*:verify-control@usenet.ie
-rmgroup:control@usenet.ie:ie.*:verify-control@usenet.ie
-
-## IEEE (*DEFUNCT* -- Institute of Electrical and Electronic Engineers)
-# Contact: postoffice@ieee.org
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:ieee.*:mail
-rmgroup:*:ieee.*:doit
-
-## INFO (Gatewayed mailing lists)
-checkgroups:rjoyner@uiuc.edu:info.*:doit
-newgroup:rjoyner@uiuc.edu:info.*:doit
-rmgroup:rjoyner@uiuc.edu:info.*:doit
-
-## IS (Iceland)
-# Contact: IS Group Admins <group-admin@usenet.is>
-# URL: http://www.usenet.is/
-# Admin group: is.isnet
-# Key URL: http://www.usenet.is/group-admin.asc
-# Key fingerprint = 33 32 8D 46 1E 5E 1C 7F  48 60 8E 72 E5 3E CA EA
-# *PGP*   See comment at top of file.
-newgroup:*:is.*:drop
-rmgroup:*:is.*:drop
-checkgroups:group-admin@usenet.is:is.*:verify-group-admin@usenet.is
-newgroup:group-admin@usenet.is:is.*:verify-group-admin@usenet.is
-rmgroup:group-admin@usenet.is:is.*:verify-group-admin@usenet.is
-
-## ISC (Japanese ?)
-checkgroups:news@sally.isc.chubu.ac.jp:isc.*:doit
-newgroup:news@sally.isc.chubu.ac.jp:isc.*:doit
-rmgroup:news@sally.isc.chubu.ac.jp:isc.*:doit
-
-## ISRAEL & IL (Israel)
-newgroup:news@news.biu.ac.il:israel.*:doit
-rmgroup:news@news.biu.ac.il:israel.*|il.*:doit
-
-## ISU (I-Shou University, Taiwan)
-# Contact: news@news.isu.edu.tw
-# URL: http://news.isu.edu.tw/
-# Admin group: isu.newgroups
-# Key URL: http://news.isu.edu.tw/isu.asc
-# *PGP*   See comment at top of file.
-newgroup:*:isu.*:drop
-rmgroup:*:isu.*:drop
-checkgroups:news@news.isu.edu.tw:isu.*:verify-news@news.isu.edu.tw
-newgroup:news@news.isu.edu.tw:isu.*:verify-news@news.isu.edu.tw
-rmgroup:news@news.isu.edu.tw:isu.*:verify-news@news.isu.edu.tw
-
-## IT (Italian)
-# Contact: gcn@news.nic.it
-# URL: http://www.news.nic.it/
-# Admin group: it.news.annunci
-# Key URL: http://www.news.nic.it/pgp.txt
-# Key fingerprint = 94 A4 F7 B5 46 96 D6 C7  A6 73 F2 98 C4 8C D0 E0
-# *PGP*   See comment at top of file.
-newgroup:*:it.*:drop
-rmgroup:*:it.*:drop
-checkgroups:gcn@news.nic.it:it.*:verify-gcn@news.nic.it
-newgroup:gcn@news.nic.it:it.*:verify-gcn@news.nic.it
-rmgroup:gcn@news.nic.it:it.*:verify-gcn@news.nic.it
-
-## IT-ALT (Alternate Italian)
-#
-# There is no one official control message issuer for the it-alt.*
-# hierarchy, so this file doesn't choose any particular one.  Several
-# different people issue control messages for this hierarchy, which may
-# or may not agree, and sites carrying this hierarchy are encouraged to
-# pick one and add it below.
-#
-# Newgroup and removal requests are to be posted to it-alt.config.  A list
-# of people issuing PGP/GPG signed control messages is available in a
-# periodic posting to news.admin.hierarchies and it-alt.config.
-#
-newgroup:*:it-alt.*:drop
-rmgroup:*:it-alt.*:drop
-
-## ITALIA (Italy)
-# Contact: news@news.cineca.it
-# URL: http://news.cineca.it/italia/
-# Admin group: italia.announce.newgroups
-# Key URL: http://news.cineca.it/italia/italia-pgp.txt
-# Key fingerprint = 0F BB 71 62 DA 5D 5D B8  D5 86 FC 28 02 67 1A 6B
-# *PGP*   See comment at top of file.
-newgroup:*:italia.*:drop
-rmgroup:*:italia.*:drop
-checkgroups:news@news.cineca.it:italia.*:verify-italia.announce.newgroups
-newgroup:news@news.cineca.it:italia.*:verify-italia.announce.newgroups
-rmgroup:news@news.cineca.it:italia.*:verify-italia.announce.newgroups
-
-## IU (Indiana University)
-newgroup:news@usenet.ucs.indiana.edu:iu.*:doit
-newgroup:root@usenet.ucs.indiana.edu:iu.*:doit
-newgroup:*@usenet.ucs.indiana.edu:iu*class.*:mail
-rmgroup:news@usenet.ucs.indiana.edu:iu.*:doit
-rmgroup:root@usenet.ucs.indiana.edu:iu.*:doit
-
-## JAPAN (Japan)
-# Contact: Tsuneo Tanaka <tt+null@efnet.com>
-# URL: http://www.asahi-net.or.jp/~AE5T-KSN/japan-e.html
-# Admin group: japan.admin.announce
-# Key URL: http://grex.cyberspace.org/~tt/japan.admin.announce.asc
-# Key fingerprint = 6A FA 19 47 69 1B 10 74  38 53 4B 1B D8 BA 3E 85
-# *PGP*   See comment at top of file.
-newgroup:*:japan.*:drop
-rmgroup:*:japan.*:drop
-checkgroups:japan.admin.announce@news.efnet.com:japan.*:verify-japan.admin.announce@news.efnet.com
-newgroup:japan.admin.announce@news.efnet.com:japan.*:verify-japan.admin.announce@news.efnet.com
-rmgroup:japan.admin.announce@news.efnet.com:japan.*:verify-japan.admin.announce@news.efnet.com
-
-## JLUG (Japan Linux Users Group)
-# Contact: news@linux.or.jp
-# URL: http://www.linux.or.jp/community/news/index.html
-# Admin group: jlug.config
-# Key URL: http://www.linux.or.jp/pgpkey/news
-# *PGP*   See comment at top of file.
-newgroup:*:jlug.*:drop
-rmgroup:*:jlug.*:drop
-checkgroups:news@linux.or.jp:jlug.*:verify-news@linux.or.jp
-newgroup:news@linux.or.jp:jlug.*:verify-news@linux.or.jp
-rmgroup:news@linux.or.jp:jlug.*:verify-news@linux.or.jp
-
-## K12 (US Educational Network)
-# URL: http://www.k12groups.org/
-checkgroups:braultr@*csmanoirs.qc.ca:k12.*:doit
-newgroup:braultr@*csmanoirs.qc.ca:k12.*:doit
-rmgroup:braultr@*csmanoirs.qc.ca:k12.*:doit
-
-## KA (*PRIVATE* -- Karlsruhe, Germany)
-# Contact: usenet@karlsruhe.org
-# URL: http://www.karlsruhe.org/
-# Key URL: http://www.karlsruhe.org/pubkey-news.karlsruhe.org.asc
-# Key fingerprint = DE 19 BB 25 76 19 81 17  F0 67 D2 23 E8 C8 7C 90
-# For private use only, contact the above address for information.
-# *PGP*   See comment at top of file.
-newgroup:*:ka.*:drop
-rmgroup:*:ka.*:drop
-# The following three lines are only for authorized ka.* sites.
-#checkgroups:usenet@karlsruhe.org:ka.*:verify-usenet@karlsruhe.org
-#newgroup:usenet@karlsruhe.org:ka.*:verify-usenet@karlsruhe.org
-#rmgroup:usenet@karlsruhe.org:ka.*:verify-usenet@karlsruhe.org
-
-## KANTO (?)
-# *PGP*   See comment at top of file.
-rmgroup:*:kanto.*:drop
-checkgroups:ty@kamoi.imasy.or.jp:kanto.*:verify-kanto.news.network
-# NOTE: newgroups aren't verified...
-newgroup:*@*.jp:kanto.*:doit
-rmgroup:ty@kamoi.imasy.or.jp:kanto.*:verify-kanto.news.network
-
-## KASSEL (Kassel, Germany)
-# *PGP*   See comment at top of file.
-newgroup:*:kassel.*:drop
-rmgroup:*:kassel.*:drop
-checkgroups:dirk.meyer@dinoex.sub.org:kassel.*:verify-kassel-admin
-newgroup:dirk.meyer@dinoex.sub.org:kassel.*:verify-kassel-admin
-rmgroup:dirk.meyer@dinoex.sub.org:kassel.*:verify-kassel-admin
-
-## KC (Kansas City, Kansas/Missouri, USA)
-checkgroups:dan@sky.net:kc.*:doit
-newgroup:dan@sky.net:kc.*:doit
-rmgroup:dan@sky.net:kc.*:doit
-
-## KGK (Administered by KGK, Japan)
-# Contact: Keiji KOSAKA <kgk@film.rlss.okayama-u.ac.jp>
-# URL: http://film.rlss.okayama-u.ac.jp/~kgk/kgk/index.html
-# Admin group: kgk.admin
-checkgroups:usenet@film.rlss.okayama-u.ac.jp:kgk.*:doit
-newgroup:usenet@film.rlss.okayama-u.ac.jp:kgk.*:doit
-rmgroup:usenet@film.rlss.okayama-u.ac.jp:kgk.*:doit
-
-## KIEL (Kiel, Germany)
-# URL: http://news.koehntopp.de/kiel/
-checkgroups:kris@koehntopp.de:kiel.*:doit
-newgroup:kris@koehntopp.de:kiel.*:doit
-rmgroup:kris@koehntopp.de:kiel.*:doit
-
-## KRST (*LOCAL* -- University of Oslo, Norway)
-# Contact: jani@ifi.uio.no
-# For local use only, contact the above address for information.
-newgroup:*:krst.*:mail
-rmgroup:*:krst.*:doit
-
-## KWNET (*LOCAL* -- Kitchener-Waterloo?)
-# Contact: Ed Hew <edhew@xenitec.on.ca>
-# For local use only, contact the above address for information.
-newgroup:*:kwnet.*:mail
-rmgroup:*:kwnet.*:doit
-
-## LAW (?)
-# Contact: Jim Burke <jburke@kentlaw.edu>
-checkgroups:*@*.kentlaw.edu:law.*:doit
-checkgroups:*@*.law.vill.edu:law.*:doit
-newgroup:*@*.kentlaw.edu:law.*:doit
-newgroup:*@*.law.vill.edu:law.*:doit
-rmgroup:*@*.kentlaw.edu:law.*:doit
-rmgroup:*@*.law.vill.edu:law.*:doit
-
-## LINUX (Gated Linux mailing lists)
-# Contact: Marco d'Itri <md@linux.it>
-# Admin group: linux.admin.news
-# Key fingerprint = 81 B3 27 99 4F CE 32 D1  1B C9 01 0D BB B3 2E 41
-# *PGP*   See comment at top of file.
-newgroup:*:linux.*:drop
-rmgroup:*:linux.*:drop
-checkgroups:linux-admin@bofh.it:linux.*:verify-linux-admin@bofh.it
-newgroup:linux-admin@bofh.it:linux.*:verify-linux-admin@bofh.it
-rmgroup:linux-admin@bofh.it:linux.*:verify-linux-admin@bofh.it
-
-## LOCAL (Local-only groups)
-# It is not really a good idea for sites to use these since they may occur
-# on many unconnected sites.
-newgroup:*:local.*:mail
-rmgroup:*:local.*:drop
-
-## LUEBECK (Luebeck, Germany)
-# Contact: usenet@zybrkat.org
-# Admin group: luebeck.admin
-checkgroups:usenet@zybrkat.org:luebeck.*:doit
-newgroup:usenet@zybrkat.org:luebeck.*:doit
-rmgroup:usenet@zybrkat.org:luebeck.*:doit
-
-## MALTA (Nation of Malta)
-# Contact: cmeli@cis.um.edu.mt
-# URL: http://www.malta.news-admin.org/
-# Admin group: malta.config
-# Key URL: http://www.cis.um.edu.mt/news-malta/PGP.PUBLICKEY
-# Key fingerprint = 20 17 01 5C F0 D0 1A 42  E4 13 30 58 0B 14 48 A6
-# *PGP*   See comment at top of file.
-newgroup:*:malta.*:drop
-rmgroup:*:malta.*:drop
-checkgroups:cmeli@cis.um.edu.mt:malta.*:verify-malta.config
-newgroup:cmeli@cis.um.edu.mt:malta.*:verify-malta.config
-rmgroup:cmeli@cis.um.edu.mt:malta.*:verify-malta.config
-
-## MANAWATU (*LOCAL* -- Manawatu district, New Zealand)
-# Contact: alan@manawatu.gen.nz or news@manawatu.gen.nz
-# For local use only, contact the above address for information.
-newgroup:*:manawatu.*:mail
-rmgroup:*:manawatu.*:doit
-
-## MAUS (MausNet, Germany)
-# Admin group: maus.info
-# Key fingerprint = 82 52 C7 70 26 B9 72 A1  37 98 55 98 3F 26 62 3E
-# *PGP*   See comment at top of file.
-newgroup:*:maus.*:drop
-rmgroup:*:maus.*:drop
-checkgroups:guenter@gst0hb.hb.provi.de:maus.*:verify-maus-info
-checkgroups:guenter@gst0hb.north.de:maus.*:verify-maus-info
-newgroup:guenter@gst0hb.hb.provi.de:maus.*:verify-maus-info
-newgroup:guenter@gst0hb.north.de:maus.*:verify-maus-info
-rmgroup:guenter@gst0hb.hb.provi.de:maus.*:verify-maus-info
-rmgroup:guenter@gst0hb.north.de:maus.*:verify-maus-info
-
-## MCMASTER (*LOCAL* -- McMaster University, Ontario)
-# Contact: Brian Beckberger <news@informer1.cis.mcmaster.ca>
-# For local use only, contact the above address for information.
-newgroup:*:mcmaster.*:mail
-rmgroup:*:mcmaster.*:doit
-
-## MCOM (*LOCAL* -- Netscape Inc, USA)
-# For local use only.
-newgroup:*:mcom.*:mail
-rmgroup:*:mcom.*:doit
-
-## ME (Maine, USA)
-checkgroups:kerry@maine.maine.edu:me.*:doit
-newgroup:kerry@maine.maine.edu:me.*:doit
-rmgroup:kerry@maine.maine.edu:me.*:doit
-
-## MEDLUX (All-Russia medical teleconferences)
-# URL: ftp://ftp.medlux.ru/pub/news/medlux.grp
-checkgroups:neil@new*.medlux.ru:medlux.*:doit
-newgroup:neil@new*.medlux.ru:medlux.*:doit
-rmgroup:neil@new*.medlux.ru:medlux.*:doit
-
-## MELB (Melbourne, Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://melb.news-admin.org/
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:melb.*:drop
-rmgroup:*:melb.*:drop
-checkgroups:ausadmin@aus.news-admin.org:melb.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:melb.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:melb.*:verify-ausadmin@aus.news-admin.org
-
-## MENSA (The Mensa Organisation)
-# Contact: usenet@newsgate.mensa.org
-# Admin group: mensa.config
-# Key fingerprint = 52B9 3963 85D9 0806 8E19  7344 973C 5005 DC7D B7A7
-# *PGP*   See comment at top of file.
-newgroup:*:mensa.*:drop
-rmgroup:*:mensa.*:drop
-checkgroups:usenet@newsgate.mensa.org:mensa.*:verify-mensa.config
-newgroup:usenet@newsgate.mensa.org:mensa.*:verify-mensa.config
-rmgroup:usenet@newsgate.mensa.org:mensa.*:verify-mensa.config
-
-## METOCEAN (ISP in Japan)
-checkgroups:fwataru@*.metocean.co.jp:metocean.*:doit
-newgroup:fwataru@*.metocean.co.jp:metocean.*:doit
-rmgroup:fwataru@*.metocean.co.jp:metocean.*:doit
-
-## METROPOLIS (*LOCAL* -- ?)
-# Contact: newsmaster@worldonline.nl
-# For local use only, contact the above address for information.
-newgroup:*:metropolis.*:mail
-rmgroup:*:metropolis.*:doit
-
-## MI (Michigan, USA)
-# Contact: Steve Simmons <scs@lokkur.dexter.mi.us>
-checkgroups:scs@lokkur.dexter.mi.us:mi.*:doit
-newgroup:scs@lokkur.dexter.mi.us:mi.*:doit
-rmgroup:scs@lokkur.dexter.mi.us:mi.*:doit
-
-## MICROSOFT (Microsoft Corporation, USA)
-#
-# Control articles for that hierarchy are not issued by Microsoft itself
-# but by a Usenet active participant in order to improve the quality of
-# the propagation of Microsoft newsgroups.  Their official URL is:
-# http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx
-#
-# Contact: control-microsoft@trigofacile.com
-# URL: http://www.trigofacile.com/divers/usenet/clefs/index.htm
-# Admin group: microsoft.public.news.server
-# Key URL: http://www.trigofacile.com/divers/usenet/clefs/pgpkey-microsoft.asc
-# Key fingerprint = DF70 5FC9 F615 D52E 02DB  A3CB 63A9 8D13 E60E 2FAA
-# Syncable server: msnews.microsoft.com
-# *PGP*   See comment at top of file.
-newgroup:*:microsoft.*:drop
-rmgroup:*:microsoft.*:drop
-checkgroups:control-microsoft@trigofacile.com:microsoft.*:verify-control-microsoft@trigofacile.com
-newgroup:control-microsoft@trigofacile.com:microsoft.*:verify-control-microsoft@trigofacile.com
-rmgroup:control-microsoft@trigofacile.com:microsoft.*:verify-control-microsoft@trigofacile.com
-
-## MILW (Milwaukee, Wisconsin, USA)
-# Contact: milw@usenet.mil.wi.us
-# URL: http://usenet.mil.wi.us/
-# Admin group: milw.config
-# Key URL: http://usenet.mil.wi.us/pgpkey
-# Key fingerprint = 6E 9B 9F 70 98 AB 9C E5  C3 C0 05 82 21 5B F4 9E
-# *PGP*   See comment at top of file.
-newgroup:*:milw.*:drop
-rmgroup:*:milw.*:drop
-checkgroups:milw@usenet.mil.wi.us:milw.*:verify-milw.config
-newgroup:milw@usenet.mil.wi.us:milw.*:verify-milw.config
-rmgroup:milw@usenet.mil.wi.us:milw.*:verify-milw.config
-
-## MOD (*DEFUNCT* -- Original top level moderated hierarchy)
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:mod.*:mail
-rmgroup:*:mod.*:doit
-
-## MUC (Munchen [Munich], Germany)
-# Admin group: muc.admin
-# Key fingerprint = 43 C7 0E 7C 45 C7 06 E0  BD 6F 76 CE 07 39 5E 66
-# *PGP*   See comment at top of file.
-newgroup:*:muc.*:drop
-rmgroup:*:muc.*:drop
-checkgroups:muc-cmsg@muenchen.pro-bahn.org:muc.*:verify-muc.admin
-newgroup:muc-cmsg@muenchen.pro-bahn.org:muc.*:verify-muc.admin
-rmgroup:muc-cmsg@muenchen.pro-bahn.org:muc.*:verify-muc.admin
-
-## NAGASAKI-U (Nagasaki University, Japan ?)
-checkgroups:root@*nagasaki-u.ac.jp:nagasaki-u.*:doit
-newgroup:root@*nagasaki-u.ac.jp:nagasaki-u.*:doit
-rmgroup:root@*nagasaki-u.ac.jp:nagasaki-u.*:doit
-
-## NAS (*LOCAL* -- NAS, NASA Ames Research Center, USA)
-# Contact: news@nas.nasa.gov
-# For local use only, contact the above address for information.
-newgroup:*:nas.*:mail
-rmgroup:*:nas.*:doit
-
-## NASA (*LOCAL* -- National Aeronautics and Space Administration, USA)
-# Contact: news@nas.nasa.gov
-# For local use only, contact the above address for information.
-newgroup:*:nasa.*:mail
-rmgroup:*:nasa.*:doit
-
-## NC (North Carolina, USA)
-#
-# Tim Seaver <tas@bellsouth.net> says he hasn't had any dealings with nc.*
-# for over two years and the hierarchy is basically "open to anyone who
-# wants it."
-#
-# newgroup:tas@ncren.net:nc.*:doit
-# rmgroup:tas@ncren.net:nc.*:doit
-
-## NCF (*LOCAL* -- National Capital Freenet, Ottawa, Ontario, Canada)
-# Contact: news@freenet.carleton.ca
-# For local use only, contact the above address for information.
-newgroup:*:ncf.*:mail
-rmgroup:*:ncf.*:doit
-
-## NCTU (Taiwan)
-checkgroups:chen@cc.nctu.edu.tw:nctu.*:doit
-newgroup:chen@cc.nctu.edu.tw:nctu.*:doit
-rmgroup:chen@cc.nctu.edu.tw:nctu.*:doit
-
-## NCU (*LOCAL* -- National Central University, Taiwan)
-# Contact: Ying-Hao Chang <aqlott@db.csie.ncu.edu.tw>
-# Contact: <runn@news.ncu.edu.tw>
-# For local use only, contact the above address for information.
-newgroup:*:ncu.*:mail
-rmgroup:*:ncu.*:doit
-
-## NERSC (National Energy Research Scientific Computing Center)
-# Contact: <usenet@nersc.gov>
-# newgroup:*:nersc.*:mail
-# rmgroup:*:nersc.*:doit
-
-## NET (Usenet 2)
-#
-# This was a failed experiment in a different newsgroup creation policy and
-# administrative policy which has now been almost entirely abandoned.  The
-# information is retained here for the few sites still using it, but sites
-# not already carrying the groups probably won't be interested.
-#
-# (This was also the original unmoderated Usenet hierarchy from before the
-# Great Renaming.  The groups that used to be in net.* in the 1980s are now
-# in the Big Eight hierarchies.)
-#
-# URL: http://www.usenet2.org
-# Admin group: net.config
-# Key URL: http://www.usenet2.org/control@usenet2.org.asc
-# Key fingerprint = D7 D3 5C DB 18 6A 29 79  BF 74 D4 58 A3 78 9D 22
-# *PGP*   See comment at top of file.
-newgroup:*:net.*:drop
-rmgroup:*:net.*:drop
-#checkgroups:control@usenet2.org:net.*:verify-control@usenet2.org
-#newgroup:control@usenet2.org:net.*:verify-control@usenet2.org
-#rmgroup:control@usenet2.org:net.*:verify-control@usenet2.org
-
-## NETINS (*LOCAL* -- netINS, Inc)
-# Contact: news@netins.net
-# For local use only, contact the above address for information.
-newgroup:*:netins.*:mail
-rmgroup:*:netins.*:doit
-
-## NETSCAPE (Netscape Communications Corp)
-# Contact: news@netscape.com
-# URL: http://www.mozilla.org/community.html
-# Admin group: netscape.public.admin
-# Key URL: http://www.mozilla.org/newsfeeds.html
-# Key fingerprint = B7 80 55 12 1F 9C 17 0B  86 66 AD 3B DB 68 35 EC
-# *PGP*   See comment at top of file.
-newgroup:*:netscape.*:drop
-rmgroup:*:netscape.*:drop
-checkgroups:news@netscape.com:netscape.*:verify-netscape.public.admin
-newgroup:news@netscape.com:netscape.*:verify-netscape.public.admin
-rmgroup:news@netscape.com:netscape.*:verify-netscape.public.admin
-
-## NF (Newfoundland and Labrador, Canada)
-# Contact: randy@mun.ca
-checkgroups:randy@mun.ca:nf.*:doit
-newgroup:randy@mun.ca:nf.*:doit
-rmgroup:randy@mun.ca:nf.*:doit
-
-## NIAGARA (Niagara Peninsula, USA/Canada)
-checkgroups:news@niagara.com:niagara.*:doit
-newgroup:news@niagara.com:niagara.*:doit
-rmgroup:news@niagara.com:niagara.*:doit
-
-## NIAS (Japanese ?)
-checkgroups:news@cc.nias.ac.jp:nias.*:doit
-newgroup:news@cc.nias.ac.jp:nias.*:doit
-rmgroup:news@cc.nias.ac.jp:nias.*:doit
-
-## NIGERIA (Nigeria)
-checkgroups:news@easnet.net:nigeria.*:doit
-newgroup:news@easnet.net:nigeria.*:doit
-rmgroup:news@easnet.net:nigeria.*:doit
-
-## NIHON (Japan)
-checkgroups:ktomita@jade.dti.ne.jp:nihon.*:doit
-newgroup:ktomita@jade.dti.ne.jp:nihon.*:doit
-rmgroup:ktomita@jade.dti.ne.jp:nihon.*:doit
-
-## NIPPON (*PRIVATE* -- Japan)
-# URL: http://www.gcd.org/news/nippon/
-# Admin group: nippon.news.group
-# Key URL: http://www.gcd.org/news/nippon/
-# Key fingerprint = BC CF 15 CD B1 3C DF B3  C3 DE 35 6F 2F F7 46 DB
-# For private use only.
-# *PGP*   See comment at top of file.
-newgroup:*:nippon.*:drop
-rmgroup:*:nippon.*:drop
-newgroup:news@gcd.org:nippon.*:mail
-rmgroup:news@gcd.org:nippon.*:verify-nippon.news.group
-
-## NJ (New Jersey, USA)
-# Contact: nj-admin@gunslinger.net
-# URL: http://www.exit109.com/~jeremy/nj/
-checkgroups:nj-admin@gunslinger.net:nj.*:doit
-newgroup:nj-admin@gunslinger.net:nj.*:doit
-rmgroup:nj-admin@gunslinger.net:nj.*:doit
-
-## NL (Netherlands)
-# Contact: nl-admin@nic.surfnet.nl
-# URL: http://nl.news-admin.org/info/nladmin.html
-# Admin group: nl.newsgroups
-# Key fingerprint = 45 20 0B D5 A1 21 EA 7C  EF B2 95 6C 25 75 4D 27
-# *PGP*   See comment at top of file.
-newgroup:*:nl.*:drop
-rmgroup:*:nl.*:drop
-checkgroups:nl-admin@nic.surfnet.nl:nl.*:verify-nl.newsgroups
-newgroup:nl-admin@nic.surfnet.nl:nl.*:verify-nl.newsgroups
-rmgroup:nl-admin@nic.surfnet.nl:nl.*:verify-nl.newsgroups
-
-## NL-ALT (Alternative Netherlands groups)
-# Key fingerprint = 6B 62 EB 53 4D 5D 2F 96  35 D9 C8 9C B0 65 0E 4C
-# *PGP*   See comment at top of file.
-checkgroups:nl-alt-janitor@surfer.xs4all.nl:nl-alt.*:verify-nl-alt.config.admin
-newgroup:*:nl-alt.*:doit
-rmgroup:nl-alt-janitor@surfer.xs4all.nl:nl-alt.*:verify-nl-alt.config.admin
-rmgroup:news@kink.xs4all.nl:nl-alt.*:verify-nl-alt.config.admin
-
-## NLO (Open Source / Free Software, hosted by nl.linux.org)
-# URL: http://news.nl.linux.org/doc/nlo.html
-# Key URL: http://news.nl.linux.org/doc/nlo-3.html#ss3.1
-# Key fingerprint = 63 DC B2 51 0A F3 DD 72  C2 BD C6 FD C1 C5 44 CF
-# *PGP*   See comment at top of file.
-newgroup:*:nlo.*:drop
-rmgroup:*:nlo.*:drop
-checkgroups:news@nl.linux.org:nlo.*:verify-nlo.newsgroups
-newgroup:news@nl.linux.org:nlo.*:verify-nlo.newsgroups
-rmgroup:news@nl.linux.org:nlo.*:verify-nlo.newsgroups
-
-## NM (New Mexico, USA)
-checkgroups:news@tesuque.cs.sandia.gov:nm.*:doit
-newgroup:news@tesuque.cs.sandia.gov:nm.*:doit
-rmgroup:news@tesuque.cs.sandia.gov:nm.*:doit
-
-## NO (Norway)
-# URL: http://www.usenet.no/
-# Admin group: no.usenet.admin
-# Key URL: http://www.usenet.no/pgp-key.txt
-# *PGP*   See comment at top of file.
-newgroup:*:no.*:drop
-rmgroup:*:no.*:drop
-checkgroups:control@usenet.no:no.*:verify-no-hir-control
-newgroup:control@usenet.no:no.*:verify-no-hir-control
-rmgroup:control@usenet.no:no.*:verify-no-hir-control
-
-## NO.ALT (Norway alternative hierarchy)
-# *PGP*   See comment at top of file.
-newgroup:*:no.alt.*:drop
-rmgroup:*:no.alt.*:drop
-newgroup:*@*.no:no.alt.*:doit
-rmgroup:control@usenet.no:no.alt.*:verify-no-hir-control
-
-## NORD (Northern Germany)
-# thilo@own.deceiver.org no longer a valid address
-# newgroup:thilo@own.deceiver.org:nord.*:doit
-# rmgroup:thilo@own.deceiver.org:nord.*:doit
-
-## NRW (Northrine-Westfalia, Germany)
-# Contact: moderator@nrw.usenetverwaltung.de
-# URL: http://nrw.usenetverwaltung.de/
-# Admin group: nrw.admin.announce
-# Key URL: http://nrw.usenetverwaltung.de/pgp/nrw.asc
-# Key fingerprint = 13 4A 80 FE D6 34 B4 64  AF 32 08 3F 62 0E B1 E2
-# *PGP*   See comment at top of file.
-newgroup:*:nrw.*:drop
-rmgroup:*:nrw.*:drop
-checkgroups:moderator@nrw.usenetverwaltung.de:nrw.*:verify-moderator@nrw.usenetverwaltung.de
-newgroup:moderator@nrw.usenetverwaltung.de:nrw.*:verify-moderator@nrw.usenetverwaltung.de
-rmgroup:moderator@nrw.usenetverwaltung.de:nrw.*:verify-moderator@nrw.usenetverwaltung.de
-
-## NV (Nevada)
-checkgroups:cshapiro@netcom.com:nv.*:doit
-checkgroups:doctor@netcom.com:nv.*:doit
-newgroup:cshapiro@netcom.com:nv.*:doit
-newgroup:doctor@netcom.com:nv.*:doit
-rmgroup:cshapiro@netcom.com:nv.*:doit
-rmgroup:doctor@netcom.com:nv.*:doit
-
-## NY (New York State, USA)
-checkgroups:root@ny.psca.com:ny.*:doit
-newgroup:root@ny.psca.com:ny.*:doit
-rmgroup:root@ny.psca.com:ny.*:doit
-
-## NYC (New York City)
-# Contact: Perry E. Metzger <perry@piermont.com>
-checkgroups:perry@piermont.com:nyc.*:doit
-newgroup:perry@piermont.com:nyc.*:doit
-rmgroup:perry@piermont.com:nyc.*:doit
-
-## NZ (New Zealand)
-# Contact: root@usenet.net.nz
-# URL: http://www.faqs.org/faqs/usenet/nz-news-hierarchy
-# Admin group: nz.net.announce
-# Key fingerprint = 07 DF 48 AA D0 ED AA 88  16 70 C5 91 65 3D 1A 28
-# *PGP*   See comment at top of file.
-newgroup:*:nz.*:drop
-rmgroup:*:nz.*:drop
-checkgroups:root@usenet.net.nz:nz.*:verify-nz-hir-control
-newgroup:root@usenet.net.nz:nz.*:verify-nz-hir-control
-rmgroup:root@usenet.net.nz:nz.*:verify-nz-hir-control
-
-## OC (Orange County, California, USA)
-checkgroups:bob@tsunami.sugarland.unocal.com:oc.*:doit
-newgroup:bob@tsunami.sugarland.unocal.com:oc.*:doit
-rmgroup:bob@tsunami.sugarland.unocal.com:oc.*:doit
-
-## OESTERREICH (Free Austria)
-#
-# This is apparently another alt.* or free.* but specific to Austria.
-# Currently, the ftp.isc.org list doesn't honor newgroup messages in the
-# hierarchy due to lack of requests, but here is the information in case
-# any news admin wishes to carry it.
-#
-# URL: http://www.tahina.priv.at/~cm/oe/index.en.html
-#newgroup:*:oesterreich.*:doit
-#newgroup:group-admin@isc.org:oesterreich.*:drop
-#newgroup:tale@*uu.net:oesterreich.*:drop
-#rmgroup:*:oesterreich.*:drop
-
-## OH (Ohio, USA)
-checkgroups:trier@ins.cwru.edu:oh.*:doit
-newgroup:trier@ins.cwru.edu:oh.*:doit
-rmgroup:trier@ins.cwru.edu:oh.*:doit
-
-## OK (Oklahoma, USA)
-checkgroups:quentin@*qns.com:ok.*:doit
-newgroup:quentin@*qns.com:ok.*:doit
-rmgroup:quentin@*qns.com:ok.*:doit
-
-## OKINAWA (Okinawa, Japan)
-checkgroups:news@opus.or.jp:okinawa.*:doit
-newgroup:news@opus.or.jp:okinawa.*:doit
-rmgroup:news@opus.or.jp:okinawa.*:doit
-
-## ONT (Ontario, Canada)
-checkgroups:pkern@gpu.utcc.utoronto.ca:ont.*:doit
-newgroup:pkern@gpu.utcc.utoronto.ca:ont.*:doit
-rmgroup:pkern@gpu.utcc.utoronto.ca:ont.*:doit
-
-## OPENNEWS (Open News Network)
-# URL: http://www.open-news-network.org/
-# *PGP*   See comment at top of file.
-newgroup:*:opennews.*:drop
-rmgroup:*:opennews.*:drop
-checkgroups:schiller@babsi.de:opennews.*:verify-news@news2.open-news-network.org
-newgroup:schiller@babsi.de:opennews.*:verify-news@news2.open-news-network.org
-rmgroup:schiller@babsi.de:opennews.*:verify-news@news2.open-news-network.org
-
-## OPENWATCOM (Open Watcom compilers)
-# Contact: admin@openwatcom.news-admin.org
-# URL: http://www.openwatcom.org/
-# Admin group: openwatcom.contributors
-# Key URL: http://cmeerw.org/files/openwatcom/pgp-openwatcom.asc
-# Syncable server: news.openwatcom.org
-# *PGP*   See comment at top of file.
-newgroup:*:openwatcom.*:drop
-rmgroup:*:openwatcom.*:drop
-checkgroups:admin@openwatcom.news-admin.org:openwatcom.*:verify-admin@openwatcom.news-admin.org
-newgroup:admin@openwatcom.news-admin.org:openwatcom.*:verify-admin@openwatcom.news-admin.org
-rmgroup:admin@openwatcom.news-admin.org:openwatcom.*:verify-admin@openwatcom.news-admin.org
-
-## OPERA (Opera Software, Oslo, Norway)
-# Contact: usenet@opera.com
-# Syncable server: news.opera.com
-# *PGP*   See comment at top of file.
-newgroup:*:opera.*:drop
-rmgroup:*:opera.*:drop
-checkgroups:*@opera.com:opera.*:verify-opera-group-admin
-newgroup:*@opera.com:opera.*:verify-opera-group-admin
-rmgroup:*@opera.com:opera.*:verify-opera-group-admin
-
-## OTT (Ottawa, Ontario, Canada)
-# Contact: onag@pinetree.org
-# URL: http://www.pinetree.org/ONAG/
-checkgroups:clewis@ferret.ocunix.on.ca:ott.*:doit
-checkgroups:dave@revcan.ca:ott.*:doit
-checkgroups:gordon@*pinetree.org:ott.*:doit
-checkgroups:news@*pinetree.org:ott.*:doit
-checkgroups:news@bnr.ca:ott.*:doit
-checkgroups:news@ferret.ocunix.on.ca:ott.*:doit
-checkgroups:news@nortel.ca:ott.*:doit
-newgroup:clewis@ferret.ocunix.on.ca:ott.*:doit
-newgroup:dave@revcan.ca:ott.*:doit
-newgroup:gordon@*pinetree.org:ott.*:doit
-newgroup:news@*pinetree.org:ott.*:doit
-newgroup:news@bnr.ca:ott.*:doit
-newgroup:news@ferret.ocunix.on.ca:ott.*:doit
-newgroup:news@nortel.ca:ott.*:doit
-rmgroup:clewis@ferret.ocunix.on.ca:ott.*:doit
-rmgroup:dave@revcan.ca:ott.*:doit
-rmgroup:gordon@*pinetree.org:ott.*:doit
-rmgroup:news@*pinetree.org:ott.*:doit
-rmgroup:news@bnr.ca:ott.*:doit
-rmgroup:news@ferret.ocunix.on.ca:ott.*:doit
-rmgroup:news@nortel.ca:ott.*:doit
-
-## PA (Pennsylvania, USA)
-# URL: http://www.netcom.com/~rb1000/pa_hierarchy/
-checkgroups:fxp@epix.net:pa.*:doit
-newgroup:fxp@epix.net:pa.*:doit
-rmgroup:fxp@epix.net:pa.*:doit
-
-## PBINFO (Paderborn, Germany)
-# Contact: news@uni-paderborn.de
-# *PGP*   See comment at top of file.
-newgroup:*:pbinfo.*:drop
-rmgroup:*:pbinfo.*:drop
-checkgroups:postmaster@upb.de:pbinfo.*:verify-news@uni-paderborn.de
-newgroup:postmaster@upb.de:pbinfo.*:verify-news@uni-paderborn.de
-rmgroup:postmaster@upb.de:pbinfo.*:verify-news@uni-paderborn.de
-
-## PERL (Perl Programming Language)
-# Contact: newsadmin@perl.org
-# URL: http://www.nntp.perl.org/about/
-# Key URL: http://www.nntp.perl.org/about/newsadmin@perl.org.pgp
-# Key fingerprint = 438F D1BA 4DCC 3B1A BED8  2BCC 3298 8A7D 8B2A CFBB
-# *PGP*   See comment at top of file.
-newgroup:*:perl.*:drop
-rmgroup:*:perl.*:drop
-checkgroups:newsadmin@perl.org:perl.*:verify-newsadmin@perl.org
-newgroup:newsadmin@perl.org:perl.*:verify-newsadmin@perl.org
-rmgroup:newsadmin@perl.org:perl.*:verify-newsadmin@perl.org
-
-## PGH (Pittsburgh, Pennsylvania, USA)
-# Admin group: pgh.config
-# *PGP*   See comment at top of file.
-newgroup:*:pgh.*:drop
-rmgroup:*:pgh.*:drop
-checkgroups:pgh-config@psc.edu:pgh.*:verify-pgh.config
-newgroup:pgh-config@psc.edu:pgh.*:verify-pgh.config
-rmgroup:pgh-config@psc.edu:pgh.*:verify-pgh.config
-
-## PGSQL (Gated PostgreSQL mailing lists)
-# Contact: news@postgresql.org
-# URL: http://news.hub.org/gpg_public_keys.html
-# Key URL: http://news.hub.org/gpg_public_keys.html
-# *PGP*   See comment at top of file.
-newgroup:*:pgsql.*:drop
-rmgroup:*:pgsql.*:drop
-checkgroups:news@postgresql.org:pgsql.*:verify-news@postgresql.org
-newgroup:news@postgresql.org:pgsql.*:verify-news@postgresql.org
-rmgroup:news@postgresql.org:pgsql.*:verify-news@postgresql.org
-
-## PHL (Philadelphia, Pennsylvania, USA)
-checkgroups:news@vfl.paramax.com:phl.*:doit
-newgroup:news@vfl.paramax.com:phl.*:doit
-rmgroup:news@vfl.paramax.com:phl.*:doit
-
-## PIN (Personal Internauts' NetNews)
-checkgroups:pin-admin@forus.or.jp:pin.*:doit
-newgroup:pin-admin@forus.or.jp:pin.*:doit
-rmgroup:pin-admin@forus.or.jp:pin.*:doit
-
-## PIPEX (UUNET WorldCom UK)
-# Contact: Russell Vincent <news-control@ops.pipex.net>
-checkgroups:news-control@ops.pipex.net:pipex.*:doit
-newgroup:news-control@ops.pipex.net:pipex.*:doit
-rmgroup:news-control@ops.pipex.net:pipex.*:doit
-
-## PITT (University of Pittsburgh, PA)
-checkgroups:news+@pitt.edu:pitt.*:doit
-checkgroups:news@toads.pgh.pa.us:pitt.*:doit
-newgroup:news+@pitt.edu:pitt.*:doit
-newgroup:news@toads.pgh.pa.us:pitt.*:doit
-rmgroup:news+@pitt.edu:pitt.*:doit
-rmgroup:news@toads.pgh.pa.us:pitt.*:doit
-
-## PL (Poland and Polish language)
-# URL: http://www.usenet.pl/doc/news-pl-new-site-faq.html
-# Admin group: pl.news.admin
-# Key URL: http://www.usenet.pl/doc/news-pl-new-site-faq.html#pgp
-# *PGP*   See comment at top of file.
-newgroup:*:pl.*:drop
-rmgroup:*:pl.*:drop
-checkgroups:michalj@*fuw.edu.pl:pl.*:verify-pl.announce.newgroups
-checkgroups:newgroup@usenet.pl:pl.*:verify-pl.announce.newgroups
-newgroup:michalj@*fuw.edu.pl:pl.*:verify-pl.announce.newgroups
-newgroup:newgroup@usenet.pl:pl.*:verify-pl.announce.newgroups
-rmgroup:michalj@*fuw.edu.pl:pl.*:verify-pl.announce.newgroups
-rmgroup:newgroup@usenet.pl:pl.*:verify-pl.announce.newgroups
-
-## PLANET (*LOCAL* -- PlaNet FreeNZ co-operative, New Zealand)
-# Contact: office@pl.net
-# For local use only, contact the above address for information.
-newgroup:*:planet.*:mail
-rmgroup:*:planet.*:doit
-
-## PRIMA (*LOCAL* -- prima.ruhr.de/Prima e.V. in Germany)
-# Contact: admin@prima.ruhr.de
-# For local use only, contact the above address for information.
-newgroup:*:prima.*:mail
-rmgroup:*:prima.*:doit
-
-## PSU (*LOCAL* -- Penn State University, USA)
-# Contact: Dave Barr (barr@math.psu.edu)
-# For local use only, contact the above address for information.
-newgroup:*:psu.*:mail
-rmgroup:*:psu.*:doit
-
-## PT (Portugal and Portuguese language)
-# URL: http://www.usenet-pt.org/
-# Admin group: pt.internet.usenet
-# Key URL: http://www.usenet-pt.org/control@usenet-pt.org.asc
-# *PGP*   See comment at top of file.
-newgroup:*:pt.*:drop
-rmgroup:*:pt.*:drop
-checkgroups:pmelo@*.inescc.pt:pt.*:verify-control@usenet-pt.org
-newgroup:pmelo@*.inescc.pt:pt.*:verify-control@usenet-pt.org
-rmgroup:pmelo@*.inescc.pt:pt.*:verify-control@usenet-pt.org
-
-## PUBNET (*DEFUNCT* -- ?)
-# URL: ftp://ftp.isc.org/pub/usenet/control/pubnet/pubnet.config.Z
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:pubnet.*:mail
-rmgroup:*:pubnet.*:doit
-
-## RELCOM (Commonwealth of Independent States)
-# URL: ftp://ftp.relcom.ru/pub/relcom/netinfo/
-# Admin group: relcom.netnews
-# Key URL: ftp://ftp.relcom.ru/pub/relcom/netinfo/coordpubkey.txt
-# *PGP*   See comment at top of file.
-newgroup:*:relcom.*:drop
-rmgroup:*:relcom.*:drop
-checkgroups:coord@*.relcom.ru:relcom.*:verify-relcom.newsgroups
-newgroup:coord@*.relcom.ru:relcom.*:verify-relcom.newsgroups
-rmgroup:coord@*.relcom.ru:relcom.*:verify-relcom.newsgroups
-
-## RPI (*LOCAL* -- Rensselaer Polytechnic Institute, Troy, NY, USA)
-# Contact: sofkam@rpi.edu
-# For local use only, contact the above address for information.
-newgroup:*:rpi.*:mail
-rmgroup:*:rpi.*:doit
-
-## SAAR (Saarland Region, Germany)
-# URL: http://www.saar-admin-news.de/
-# Admin group: saar.admin.news
-# Key URL: http://www.saar-admin-news.de/saar-control.asc
-# *PGP*   See comment at top of file.
-newgroup:*:saar.*:drop
-rmgroup:*:saar.*:drop
-checkgroups:control@saar-admin-news.de:saar.*:verify-saar-control
-newgroup:control@saar-admin-news.de:saar.*:verify-saar-control
-rmgroup:control@saar-admin-news.de:saar.*:verify-saar-control
-
-## SACHSNET (German)
-checkgroups:root@lusatia.de:sachsnet.*:doit
-newgroup:root@lusatia.de:sachsnet.*:doit
-rmgroup:root@lusatia.de:sachsnet.*:doit
-
-## SAT (San Antonio, Texas, USA)
-# Contact: satgroup@endicor.com
-# Admin group: sat.usenet.config
-# *PGP*   See comment at top of file.
-newgroup:*:sat.*:drop
-rmgroup:*:sat.*:drop
-checkgroups:satgroup@endicor.com:sat.*:verify-satgroup@endicor.com
-newgroup:satgroup@endicor.com:sat.*:verify-satgroup@endicor.com
-rmgroup:satgroup@endicor.com:sat.*:verify-satgroup@endicor.com
-
-## SBAY (South Bay/Silicon Valley, California)
-# URL: http://www.sbay.org/sbay-newsgroups.html
-checkgroups:ikluft@thunder.sbay.org:sbay.*:doit
-checkgroups:steveh@grafex.sbay.org:sbay.*:doit
-newgroup:ikluft@thunder.sbay.org:sbay.*:doit
-newgroup:steveh@grafex.sbay.org:sbay.*:doit
-rmgroup:ikluft@thunder.sbay.org:sbay.*:doit
-rmgroup:steveh@grafex.sbay.org:sbay.*:doit
-
-## SCHULE (?)
-# Contact: schule-admin@roxel.ms.sub.org
-# URL: http://home.pages.de/~schule-admin/
-# Admin group: schule.admin
-# Key URL: http://www.afaik.de/usenet/admin/schule/control/schule.asc
-# Key fingerprint = 64 06 F0 AE E1 46 85 0C  BD CA 0E 53 8B 1E 73 D2
-# *PGP*   See comment at top of file.
-newgroup:*:schule.*:drop
-rmgroup:*:schule.*:drop
-checkgroups:newsctrl@schule.de:schule.*:verify-schule.konfig
-newgroup:newsctrl@schule.de:schule.*:verify-schule.konfig
-rmgroup:newsctrl@schule.de:schule.*:verify-schule.konfig
-
-## SCOT (Scotland)
-# URL: http://scot.news-admin.org/
-# Admin group: scot.newsgroups.discuss
-# Key URL: http://scot.news-admin.org/signature.html
-# *PGP*   See comment at top of file.
-newgroup:*:scot.*:drop
-rmgroup:*:scot.*:drop
-checkgroups:control@scot.news-admin.org:scot.*:verify-control@scot.news-admin.org
-newgroup:control@scot.news-admin.org:scot.*:verify-control@scot.news-admin.org
-rmgroup:control@scot.news-admin.org:scot.*:verify-control@scot.news-admin.org
-
-## SCOUT (Scouts and guides)
-# URL: http://news.scoutnet.org/
-# Admin group: scout.admin
-# Key URL: http://news.scoutnet.org/scout-pgpkey.asc
-# *PGP*   See comment at top of file.
-newgroup:*:scout.*:drop
-rmgroup:*:scout.*:drop
-checkgroups:control@news.scoutnet.org:scout.*:verify-control@news.scoutnet.org
-newgroup:control@news.scoutnet.org:scout.*:verify-control@news.scoutnet.org
-rmgroup:control@news.scoutnet.org:scout.*:verify-control@news.scoutnet.org
-
-## SDNET (Greater San Diego Area, California, USA)
-# URL: http://www-rohan.sdsu.edu/~wk/sdnet/sdnet.html
-checkgroups:wkronert@sunstroke.sdsu.edu:sdnet.*:doit
-newgroup:wkronert@sunstroke.sdsu.edu:sdnet.*:doit
-rmgroup:wkronert@sunstroke.sdsu.edu:sdnet.*:doit
-
-## SDSU (*LOCAL* -- San Diego State University, CA)
-# Contact: Craig R. Sadler <usenet@sdsu.edu>
-# For local use only, contact the above address for information.
-newgroup:*:sdsu.*:mail
-rmgroup:*:sdsu.*:doit
-
-## SE (Sweden)
-# Contact: usenet@usenet-se.net
-# Admin group: se.internet.news.meddelanden
-# Key fingerprint = 68 03 F0 FD 0C C3 4E 69  6F 0D 0C 60 3C 58 63 96
-# *PGP*   See comment at top of file.
-newgroup:*:se.*:drop
-rmgroup:*:se.*:drop
-checkgroups:usenet@usenet-se.net:se.*:verify-usenet-se
-newgroup:usenet@usenet-se.net:se.*:verify-usenet-se
-rmgroup:usenet@usenet-se.net:se.*:verify-usenet-se
-
-## SEATTLE (Seattle, Washington, USA)
-checkgroups:billmcc@akita.com:seattle.*:doit
-checkgroups:graham@ee.washington.edu:seattle.*:doit
-newgroup:billmcc@akita.com:seattle.*:doit
-newgroup:graham@ee.washington.edu:seattle.*:doit
-rmgroup:billmcc@akita.com:seattle.*:doit
-rmgroup:graham@ee.washington.edu:seattle.*:doit
-
-## SFNET (Finland)
-# Contact: sfnet@cs.tut.fi
-# URL: http://www.cs.tut.fi/sfnet/
-# Admin group: sfnet.ryhmat+listat
-# Key fingerprint = DE79 33C2 D359 D128 44E5  6A0C B6E3 0E53 6933 A636
-# *PGP*   See comment at top of file.
-newgroup:*:sfnet.*:drop
-rmgroup:*:sfnet.*:drop
-checkgroups:sfnet@*cs.tut.fi:sfnet.*:verify-sfnet@cs.tut.fi
-newgroup:sfnet@*cs.tut.fi:sfnet.*:verify-sfnet@cs.tut.fi
-rmgroup:sfnet@*cs.tut.fi:sfnet.*:verify-sfnet@cs.tut.fi
-
-## SHAMASH (Jewish)
-checkgroups:archives@israel.nysernet.org:shamash.*:doit
-newgroup:archives@israel.nysernet.org:shamash.*:doit
-rmgroup:archives@israel.nysernet.org:shamash.*:doit
-
-## SI (The Republic of Slovenia)
-# URL: http://www.arnes.si/news/config/
-# Admin group: si.news.announce.newsgroups
-# Key URL: http://www.arnes.si/news/config/
-# *PGP*   See comment at top of file.
-newgroup:*:si.*:drop
-rmgroup:*:si.*:drop
-checkgroups:news-admin@arnes.si:si.*:verify-si.news.announce.newsgroups
-newgroup:news-admin@arnes.si:si.*:verify-si.news.announce.newsgroups
-rmgroup:news-admin@arnes.si:si.*:verify-si.news.announce.newsgroups
-
-## SJ (St. John's, Newfoundland and Labrador, Canada)
-# Contact: randy@mun.ca
-checkgroups:randy@mun.ca:sj.*:doit
-newgroup:randy@mun.ca:sj.*:doit
-rmgroup:randy@mun.ca:sj.*:doit
-
-## SK (Slovakia)
-checkgroups:uhlar@ccnews.ke.sanet.sk:sk.*:doit
-newgroup:uhlar@ccnews.ke.sanet.sk:sk.*:doit
-rmgroup:uhlar@ccnews.ke.sanet.sk:sk.*:doit
-
-## SLAC (*PRIVATE* -- Stanford Linear Accelerator Center, Stanford, USA)
-# Contact: news@news.stanford.edu
-# For private use only, contact the above address for information.
-newgroup:news@news.stanford.edu:slac.*:mail
-rmgroup:news@news.stanford.edu:slac.*:doit
-
-## SLO (San Luis Obispo, CA)
-checkgroups:news@punk.net:slo.*:doit
-newgroup:news@punk.net:slo.*:doit
-rmgroup:news@punk.net:slo.*:doit
-
-## SOLENT (Solent region, England)
-checkgroups:news@tcp.co.uk:solent.*:doit
-newgroup:news@tcp.co.uk:solent.*:doit
-rmgroup:news@tcp.co.uk:solent.*:doit
-
-## SPOKANE (Spokane, Washington, USA)
-checkgroups:usenet@news.spokane.wa.us:spokane.*:doit
-newgroup:usenet@news.spokane.wa.us:spokane.*:doit
-rmgroup:usenet@news.spokane.wa.us:spokane.*:doit
-
-## SSLUG (*PRIVATE* -- SkÃ¥ne Sjælland Linux User Group)
-# URL: http://en.sslug.dk/
-# For private use only.
-newgroup:sparre@sslug.se:sslug.*:mail
-rmgroup:sparre@sslug.se:sslug.*:doit
-
-## STAROFFICE (StarOffice business suite, Sun Microsystems, Inc.)
-# Contact: news@starnews.sun.com
-# Admin group: staroffice.admin
-# Key fingerprint = C6 3E 81 6F 2A 19 D3 84  72 51 F9 1B E3 B9 B2 C9
-# Syncable server: starnews.sun.com
-# *PGP*   See comment at top of file.
-newgroup:*:staroffice.*:drop
-rmgroup:*:staroffice.*:drop
-checkgroups:news@stardivision.de:staroffice.*:verify-staroffice.admin
-newgroup:news@stardivision.de:staroffice.*:verify-staroffice.admin
-rmgroup:news@stardivision.de:staroffice.*:verify-staroffice.admin
-
-## STGT (Stuttgart, Germany)
-# URL: http://news.uni-stuttgart.de/hierarchie/stgt/
-# Key URL: http://news.uni-stuttgart.de/hierarchie/stgt/stgt-control.txt
-# *PGP*   See comment at top of file.
-newgroup:*:stgt.*:drop
-rmgroup:*:stgt.*:drop
-checkgroups:stgt-control@news.uni-stuttgart.de:stgt.*:verify-stgt-control
-newgroup:stgt-control@news.uni-stuttgart.de:stgt.*:verify-stgt-control
-rmgroup:stgt-control@news.uni-stuttgart.de:stgt.*:verify-stgt-control
-
-## STL (Saint Louis, Missouri, USA)
-checkgroups:news@icon-stl.net:stl.*:doit
-newgroup:news@icon-stl.net:stl.*:doit
-rmgroup:news@icon-stl.net:stl.*:doit
-
-## SU (*LOCAL* -- Stanford University, USA)
-# Contact: news@news.stanford.edu
-# For local use only, contact the above address for information.
-newgroup:*:su.*:mail
-rmgroup:*:su.*:doit
-
-## SUNET (Swedish University Network)
-checkgroups:ber@*.sunet.se:sunet.*:doit
-newgroup:ber@*.sunet.se:sunet.*:doit
-rmgroup:ber@*.sunet.se:sunet.*:doit
-
-## SURFNET (Dutch Universities network)
-checkgroups:news@info.nic.surfnet.nl:surfnet.*:doit
-newgroup:news@info.nic.surfnet.nl:surfnet.*:doit
-rmgroup:news@info.nic.surfnet.nl:surfnet.*:doit
-
-## SWNET (Sverige, Sweden)
-checkgroups:ber@sunic.sunet.se:swnet.*:doit
-newgroup:ber@sunic.sunet.se:swnet.*:doit
-rmgroup:ber@sunic.sunet.se:swnet.*:doit
-
-## SYD (Sydney, Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://syd.news-admin.org/
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:syd.*:drop
-rmgroup:*:syd.*:drop
-checkgroups:ausadmin@aus.news-admin.org:syd.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:syd.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:syd.*:verify-ausadmin@aus.news-admin.org
-
-## T-NETZ (*DEFUNCT* -- Germany)
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:t-netz.*:mail
-rmgroup:*:t-netz.*:doit
-
-## TAMU (Texas A&M University)
-# Contact: Philip Kizer <news@tamu.edu>
-checkgroups:news@tamsun.tamu.edu:tamu.*:doit
-newgroup:news@tamsun.tamu.edu:tamu.*:doit
-rmgroup:news@tamsun.tamu.edu:tamu.*:doit
-
-## TAOS (Taos, New Mexico, USA)
-# Contact: Chris Gunn <cgunn@laplaza.org>
-checkgroups:cgunn@laplaza.org:taos.*:doit
-newgroup:cgunn@laplaza.org:taos.*:doit
-rmgroup:cgunn@laplaza.org:taos.*:doit
-
-## TCFN (Toronto Free Community Network, Canada)
-checkgroups:news@t-fcn.net:tcfn.*:doit
-newgroup:news@t-fcn.net:tcfn.*:doit
-rmgroup:news@t-fcn.net:tcfn.*:doit
-
-## TELE (*LOCAL* -- Tele Danmark Internet)
-# Contact: usenet@tdk.net
-# For local use only, contact the above address for information.
-newgroup:*:tele.*:mail
-rmgroup:*:tele.*:doit
-
-## TERMVAKT (*LOCAL* -- University of Oslo, Norway)
-# Contact: jani@ifi.uio.no
-# For local use only, contact the above address for information.
-newgroup:*:termvakt.*:mail
-rmgroup:*:termvakt.*:doit
-
-## TEST (Local test hierarchy)
-# It is not really a good idea for sites to use these since they may occur
-# on many unconnected sites.
-newgroup:*:test.*:mail
-rmgroup:*:test.*:mail
-
-## THUR (Thuringia, Germany)
-# Key fingerprint = 7E 3D 73 13 93 D4 CA 78  39 DE 3C E7 37 EE 22 F1
-# *PGP*   See comment at top of file.
-newgroup:*:thur.*:drop
-rmgroup:*:thur.*:drop
-checkgroups:usenet@thur.de:thur.*:verify-thur.net.news.groups
-newgroup:usenet@thur.de:thur.*:verify-thur.net.news.groups
-rmgroup:usenet@thur.de:thur.*:verify-thur.net.news.groups
-
-## TNN (*DEFUNCT* -- The Network News, Japan)
-# This hierarchy is defunct.  Please remove it.
-newgroup:netnews@news.iij.ad.jp:tnn.*:mail
-newgroup:tnn@iij-mc.co.jp:tnn.*:mail
-rmgroup:netnews@news.iij.ad.jp:tnn.*:doit
-rmgroup:tnn@iij-mc.co.jp:tnn.*:doit
-
-## TRIANGLE (Research Triangle, Central North Carolina, USA)
-checkgroups:jfurr@acpub.duke.edu:triangle.*:doit
-checkgroups:news@news.duke.edu:triangle.*:doit
-checkgroups:tas@concert.net:triangle.*:doit
-newgroup:jfurr@acpub.duke.edu:triangle.*:doit
-newgroup:news@news.duke.edu:triangle.*:doit
-newgroup:tas@concert.net:triangle.*:doit
-rmgroup:jfurr@acpub.duke.edu:triangle.*:doit
-rmgroup:news@news.duke.edu:triangle.*:doit
-rmgroup:tas@concert.net:triangle.*:doit
-
-## TUM (Technische Universitaet Muenchen)
-checkgroups:news@informatik.tu-muenchen.de:tum.*:doit
-newgroup:news@informatik.tu-muenchen.de:tum.*:doit
-rmgroup:news@informatik.tu-muenchen.de:tum.*:doit
-
-## TW (Taiwan)
-checkgroups:ltc@news.cc.nctu.edu.tw:tw.*:doit
-newgroup:ltc@news.cc.nctu.edu.tw:tw.*:doit
-rmgroup:ltc@news.cc.nctu.edu.tw:tw.*:doit
-
-## TW.K-12 (Taiwan K-12 Discussion)
-checkgroups:k-12@news.nchu.edu.tw:tw.k-12.*:doit
-newgroup:k-12@news.nchu.edu.tw:tw.k-12.*:doit
-rmgroup:k-12@news.nchu.edu.tw:tw.k-12.*:doit
-
-## TX (Texas, USA)
-checkgroups:eric@cirr.com:tx.*:doit
-checkgroups:fletcher@cs.utexas.edu:tx.*:doit
-checkgroups:usenet@academ.com:tx.*:doit
-newgroup:eric@cirr.com:tx.*:doit
-newgroup:fletcher@cs.utexas.edu:tx.*:doit
-newgroup:usenet@academ.com:tx.*:doit
-rmgroup:eric@cirr.com:tx.*:doit
-rmgroup:fletcher@cs.utexas.edu:tx.*:doit
-rmgroup:usenet@academ.com:tx.*:doit
-
-## UCB (University of California Berkeley, USA)
-# Contact: Chris van den Berg <usenet@agate.berkeley.edu>
-# URL: http://www.net.berkeley.edu/usenet/
-# Key URL: http://www.net.berkeley.edu/usenet/usenet.asc
-# Key fingerprint = 96 B8 8E 9A 98 09 37 7D  0E EC 81 88 DB 90 29 BF
-# *PGP*   See comment at top of file.
-newgroup:*:ucb.*:drop
-rmgroup:*:ucb.*:drop
-checkgroups:usenet@agate.berkeley.edu:ucb.*:verify-ucb.news
-newgroup:usenet@agate.berkeley.edu:ucb.*:verify-ucb.news
-rmgroup:usenet@agate.berkeley.edu:ucb.*:verify-ucb.news
-
-## UCD (University of California Davis, USA)
-checkgroups:usenet@mark.ucdavis.edu:ucd.*:doit
-checkgroups:usenet@rocky.ucdavis.edu:ucd.*:doit
-newgroup:usenet@mark.ucdavis.edu:ucd.*:doit
-newgroup:usenet@rocky.ucdavis.edu:ucd.*:doit
-rmgroup:usenet@mark.ucdavis.edu:ucd.*:doit
-rmgroup:usenet@rocky.ucdavis.edu:ucd.*:doit
-
-## UFRA (Unterfranken, Deutschland)
-# Contact: news@mayn.de
-# URL: http://www.mayn.de/users/news/
-# Admin group: ufra.admin
-# Key fingerprint = F7 AD 96 D8 7A 3F 7E 84  02 0C 83 9A DB 8F EB B8
-# Syncable server: news.mayn.de (contact news@mayn.de if permission denied)
-# *PGP*   See comment at top of file.
-newgroup:*:ufra.*:drop
-rmgroup:*:ufra.*:drop
-checkgroups:news@mayn.de:ufra.*:verify-news.mayn.de
-newgroup:news@mayn.de:ufra.*:verify-news.mayn.de
-rmgroup:news@mayn.de:ufra.*:verify-news.mayn.de
-
-## UIUC (*LOCAL* -- University of Illinois at Urbana-Champaign, USA)
-# Contact: news@ks.uiuc.edu
-# For local use only, contact the above address for information.
-newgroup:*:uiuc.*:mail
-rmgroup:*:uiuc.*:doit
-
-## UK (United Kingdom of Great Britain and Northern Ireland)
-# URL: http://www.usenet.org.uk/
-# Admin group: uk.net.news.announce
-# Key URL: http://www.usenet.org.uk/newsadmins.html
-# *PGP*   See comment at top of file.
-newgroup:*:uk.*:drop
-rmgroup:*:uk.*:drop
-checkgroups:control@usenet.org.uk:uk.*:verify-uk.net.news.announce
-newgroup:control@usenet.org.uk:uk.*:verify-uk.net.news.announce
-rmgroup:control@usenet.org.uk:uk.*:verify-uk.net.news.announce
-
-## UKR (Ukraine)
-checkgroups:ay@sita.kiev.ua:ukr.*:doit
-newgroup:ay@sita.kiev.ua:ukr.*:doit
-rmgroup:ay@sita.kiev.ua:ukr.*:doit
-
-## UMICH (University of Michigan, USA)
-checkgroups:*@*.umich.edu:umich.*:doit
-newgroup:*@*.umich.edu:umich.*:doit
-rmgroup:*@*.umich.edu:umich.*:doit
-
-## UMN (University of Minnesota, USA)
-newgroup:edh@*.tc.umn.edu:umn.*:doit
-newgroup:news@*.tc.umn.edu:umn.*:doit
-newgroup:Michael.E.Hedman-1@umn.edu:umn.*:doit
-newgroup:edh@*.tc.umn.edu:umn*class.*:mail
-newgroup:news@*.tc.umn.edu:umn*class.*:mail
-newgroup:Michael.E.Hedman-1@umn.edu:umn*class.*:mail
-rmgroup:news@*.tc.umn.edu:umn.*:doit
-rmgroup:edh@*.tc.umn.edu:umn.*:doit
-rmgroup:Michael.E.Hedman-1@umn.edu:umn.*:doit
-
-## UN (The United Nations)
-# Admin group: un.public.usenet.admin
-# *PGP*   See comment at top of file.
-newgroup:*:un.*:drop
-rmgroup:*:un.*:drop
-checkgroups:news@news.itu.int:un.*:verify-ungroups@news.itu.int
-newgroup:news@news.itu.int:un.*:verify-ungroups@news.itu.int
-rmgroup:news@news.itu.int:un.*:verify-ungroups@news.itu.int
-
-## UO (University of Oregon, Eugene, Oregon, USA)
-checkgroups:newsadmin@news.uoregon.edu:uo.*:doit
-newgroup:newsadmin@news.uoregon.edu:uo.*:doit
-rmgroup:newsadmin@news.uoregon.edu:uo.*:doit
-
-## US (United States of America)
-# Contact: admin@usenetnews.us
-# URL: http://www.usenetnews.us/
-# Admin group: us.config
-checkgroups:control@usenetnews.us:us.*:doit
-newgroup:control@usenetnews.us:us.*:doit
-rmgroup:control@usenetnews.us:us.*:doit
-
-## UT (*LOCAL* -- University of Toronto, Canada)
-# URL: http://www.utoronto.ca/ns/utornews/
-#newgroup:news@ecf.toronto.edu:ut.*:doit
-#newgroup:news@ecf.toronto.edu:ut.class.*:mail
-#rmgroup:news@ecf.toronto.edu:ut.*:doit
-
-## UTA (Finnish)
-checkgroups:news@news.cc.tut.fi:uta.*:doit
-newgroup:news@news.cc.tut.fi:uta.*:doit
-rmgroup:news@news.cc.tut.fi:uta.*:doit
-
-## UTEXAS (*LOCAL* -- University of Texas, USA)
-# URL: http://www.utexas.edu/its/usenet/index.php
-newgroup:fletcher@cs.utexas.edu:utexas.*:doit
-newgroup:news@geraldo.cc.utexas.edu:utexas.*:doit
-newgroup:fletcher@cs.utexas.edu:utexas*class.*:mail
-newgroup:news@geraldo.cc.utexas.edu:utexas*class.*:mail
-rmgroup:fletcher@cs.utexas.edu:utexas.*:doit
-rmgroup:news@geraldo.cc.utexas.edu:utexas.*:doit
-
-## UTWENTE (*LOCAL* -- University of Twente, Netherlands)
-# Contact: newsmaster@utwente.nl
-# For local use only, contact the above address for information.
-newgroup:*:utwente.*:mail
-rmgroup:*:utwente.*:doit
-
-## UVA (*LOCAL* -- University of Virginia, USA)
-# Contact: usenet@virginia.edu
-# For local use only, contact the above address for information.
-newgroup:*:uva.*:mail
-rmgroup:*:uva.*:doit
-
-## UW (University of Waterloo, Canada)
-# Admin group: uw.newsgroups
-# Syncable server: news.uwaterloo.ca
-# *PGP*   See comment at top of file.
-newgroup:*:uw.*:drop
-rmgroup:*:uw.*:drop
-checkgroups:newsgroups@news.uwaterloo.ca:uw.*:verify-uw.newsgroups
-newgroup:newsgroups@news.uwaterloo.ca:uw.*:verify-uw.newsgroups
-rmgroup:newsgroups@news.uwaterloo.ca:uw.*:verify-uw.newsgroups
-
-## UWARWICK (*LOCAL* -- University of Warwick, UK)
-# Contact: Jon Harley <news@csv.warwick.ac.uk>
-# For local use only, contact the above address for information.
-newgroup:*:uwarwick.*:mail
-rmgroup:*:uwarwick.*:doit
-
-## UWO (University of Western Ontario, London, Canada)
-# URL: http://www.uwo.ca/its/news/groups.uwo.html
-checkgroups:reggers@julian.uwo.ca:uwo.*:doit
-newgroup:reggers@julian.uwo.ca:uwo.*:doit
-rmgroup:reggers@julian.uwo.ca:uwo.*:doit
-
-## VAN (Vancouver, British Columbia, Canada)
-checkgroups:bc_van_usenet@fastmail.ca:van.*:doit
-newgroup:bc_van_usenet@fastmail.ca:van.*:doit
-rmgroup:bc_van_usenet@fastmail.ca:van.*:doit
-
-## VEGAS (Las Vegas, Nevada, USA)
-checkgroups:cshapiro@netcom.com:vegas.*:doit
-checkgroups:doctor@netcom.com:vegas.*:doit
-newgroup:cshapiro@netcom.com:vegas.*:doit
-newgroup:doctor@netcom.com:vegas.*:doit
-rmgroup:cshapiro@netcom.com:vegas.*:doit
-rmgroup:doctor@netcom.com:vegas.*:doit
-
-## VGC (Japan groups?)
-checkgroups:news@isl.melco.co.jp:vgc.*:doit
-newgroup:news@isl.melco.co.jp:vgc.*:doit
-rmgroup:news@isl.melco.co.jp:vgc.*:doit
-
-## VMSNET (VMS Operating System)
-checkgroups:cts@dragon.com:vmsnet.*:doit
-newgroup:cts@dragon.com:vmsnet.*:doit
-rmgroup:cts@dragon.com:vmsnet.*:doit
-
-## WA (Western Australia)
-# Contact: ausadmin@aus.news-admin.org
-# URL: http://wa.news-admin.org/
-# Key URL: http://aus.news-admin.org/ausadmin.asc
-# *PGP*   See comment at top of file.
-newgroup:*:wa.*:drop
-rmgroup:*:wa.*:drop
-checkgroups:ausadmin@aus.news-admin.org:wa.*:verify-ausadmin@aus.news-admin.org
-newgroup:ausadmin@aus.news-admin.org:wa.*:verify-ausadmin@aus.news-admin.org
-rmgroup:ausadmin@aus.news-admin.org:wa.*:verify-ausadmin@aus.news-admin.org
-
-## WADAI (Japanese ?)
-checkgroups:kohe-t@*wakayama-u.ac.jp:wadai.*:doit
-newgroup:kohe-t@*wakayama-u.ac.jp:wadai.*:doit
-rmgroup:kohe-t@*wakayama-u.ac.jp:wadai.*:doit
-
-## WALES (Wales)
-# Contact: committee@wales-usenet.org
-# URL: http://www.wales-usenet.org/
-# Admin group: wales.usenet.config
-# Key URL: http://www.wales-usenet.org/english/newsadmin.txt
-# Key fingerprint = 2D 9E DE DF 12 DA 34 5C  49 E1 EE 28 E3 AB 0D AD
-# *PGP*   See comment at top of file.
-newgroup:*:wales.*:drop
-rmgroup:*:wales.*:drop
-checkgroups:control@wales-usenet.org:wales.*:verify-wales-usenet
-newgroup:control@wales-usenet.org:wales.*:verify-wales-usenet
-rmgroup:control@wales-usenet.org:wales.*:verify-wales-usenet
-
-## WASH (Washington State, USA)
-checkgroups:graham@ee.washington.edu:wash.*:doit
-newgroup:graham@ee.washington.edu:wash.*:doit
-rmgroup:graham@ee.washington.edu:wash.*:doit
-
-## WEST-VIRGINIA (West Virginia, USA)
-# Note: checkgroups only by bryan27, not mark.
-checkgroups:bryan27@hgo.net:west-virginia.*:doit
-newgroup:mark@bluefield.net:west-virginia.*:doit
-newgroup:bryan27@hgo.net:west-virginia.*:doit
-rmgroup:mark@bluefield.net:west-virginia.*:doit
-rmgroup:bryan27@hgo.net:west-virginia.*:doit
-
-## WORLDONLINE (*LOCAL* -- ?)
-# Contact: newsmaster@worldonline.nl
-# For local use only, contact the above address for information.
-newgroup:*:worldonline.*:mail
-rmgroup:*:worldonline.*:doit
-
-## WPG (Winnipeg, Manitoba, Canada)
-# Contact: Gary Mills <mills@cc.umanitoba.ca>
-checkgroups:mills@cc.umanitoba.ca:wpg.*:doit
-newgroup:mills@cc.umanitoba.ca:wpg.*:doit
-rmgroup:mills@cc.umanitoba.ca:wpg.*:doit
-
-## WPI (*LOCAL* -- Worcester Polytechnic Institute, Worcester, MA)
-# For local use only.
-newgroup:aej@*.wpi.edu:wpi.*:mail
-rmgroup:aej@*.wpi.edu:wpi.*:doit
-
-## WU (Washington University at St. Louis, MO)
-checkgroups:*@*.wustl.edu:wu.*:doit
-newgroup:*@*.wustl.edu:wu.*:doit
-rmgroup:*@*.wustl.edu:wu.*:doit
-
-## X-PRIVAT (Italian)
-# Contact: dmitry@x-privat.org
-# URL: http://www.x-privat.org/
-# Admin group: x-privat.info
-# Key URL: http://www.x-privat.org/dmitry.asc
-# Key fingerprint = 9B 0A 7E 68 27 80 C7 96  47 6B 03 90 51 05 68 43
-# *PGP*   See comment at top of file.
-newgroup:*:x-privat.*:drop
-rmgroup:*:x-privat.*:drop
-checkgroups:dmitry@x-privat.org:x-privat.*:verify-dmitry@x-privat.org
-newgroup:dmitry@x-privat.org:x-privat.*:verify-dmitry@x-privat.org
-rmgroup:dmitry@x-privat.org:x-privat.*:verify-dmitry@x-privat.org
-
-## XS4ALL (XS4ALL, Netherlands)
-# Contact: Cor Bosman <news@xs4all.nl>
-checkgroups:news@*xs4all.nl:xs4all.*:doit
-newgroup:news@*xs4all.nl:xs4all.*:doit
-rmgroup:news@*xs4all.nl:xs4all.*:doit
-
-## YORK (*LOCAL* -- York University, Toronto, ON)
-# Contact: Peter Marques <news@yorku.ca>
-# For local use only, contact the above address for information.
-newgroup:*:york.*:mail
-rmgroup:*:york.*:doit
-
-## Z-NETZ (German non-Internet based network)
-# Contact: teko@dinoex.sub.org
-# Admin group: z-netz.koordination.user+sysops
-# Key URL: ftp://ftp.dinoex.de/pub/keys/z-netz.koordination.user+sysops.asc
-# *PGP*   See comment at top of file.
-newgroup:*:z-netz.*:drop
-rmgroup:*:z-netz.*:drop
-checkgroups:teko@dinoex.sub.org:z-netz.*:verify-z-netz.koordination.user+sysops
-newgroup:teko@dinoex.sub.org:z-netz.*:verify-z-netz.koordination.user+sysops
-rmgroup:teko@dinoex.sub.org:z-netz.*:verify-z-netz.koordination.user+sysops
-
-## ZA (South Africa)
-checkgroups:ccfj@hippo.ru.ac.za:za.*:doit
-checkgroups:root@duvi.eskom.co.za:za.*:doit
-newgroup:ccfj@hippo.ru.ac.za:za.*:doit
-newgroup:root@duvi.eskom.co.za:za.*:doit
-rmgroup:ccfj@hippo.ru.ac.za:za.*:doit
-rmgroup:root@duvi.eskom.co.za:za.*:doit
-
-## ZER (*DEFUNCT* -- Germany)
-# This hierarchy is defunct.  Please remove it.
-newgroup:*:zer.*:mail
-rmgroup:*:zer.*:doit
diff --git a/samples/cycbuff.conf b/samples/cycbuff.conf
deleted file mode 100644 (file)
index 3dec250..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Meta cnfs cyclic buffer configuration file (and assignments of newsgroups to
-# metacyclic buffers)
-#
-# The order of lines in this file is not important among the same item.
-# But all cycbuff item should be presented before any metacycbuff item.
-
-# 1. Cyclic buffers
-# Format:
-# "cycbuff" (literally) : symbolic buffer name : path to buffer file : 
-#       length of symbolic buffer in kilobytes in decimal (1KB = 1024 bytes)
-
-cycbuff:ONE:/export/cycbuffs/one:512000
-cycbuff:TWO:/export/cycbuffs/two:512000
-cycbuff:THREE:/export/cycbuffs/three:512000
-
-# 2. Meta-cyclic buffers
-# Format:
-# "metacycbuff" (literally) : symbolic meta-cyclic buffer name :
-#       comma separated list of cyclic buffer symbolic names
-#
-# symbolic meta-cyclic buffer names are used in storage.conf in the
-# options field
-
-metacycbuff:BIGAREA:ONE,TWO
-metacycbuff:SMALLAREA:THREE
diff --git a/samples/distrib.pats b/samples/distrib.pats
deleted file mode 100644 (file)
index 7029eef..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-##  $Revision: 6312 $
-##  distrib.pats -- specify default Distribution header for newsgroups
-##  Format:
-##     <weight>:<pattern>:<value>
-##  All articles are matched against all patterns, value to be used is the
-##  one with the highest weight.
-##     <weight>        The weight assigned to this match, integer
-##     <pattern>       Newsgroup name or single wildmat(3) pattern
-##     <value>         Value of Distribution header.
-##
-##
-## Uncomment to default all local.* groups to a distribution of local.
-#10:local.*:local
diff --git a/samples/expire.ctl b/samples/expire.ctl
deleted file mode 100644 (file)
index dc47af3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-##  $Revision: 7143 $
-##  expire.ctl - expire control file
-##  Format:
-##     /remember/:<keep>
-##     <class>:<min>:<default>:<max>
-##     <wildmat>:<flag>:<min>:<default>:<max>
-##  First line gives history retention; second line specifies expiration
-##  for classes; third line specifies expiration for group if groupbaseexpiry
-##  is true
-##     <class>         class specified in storage.conf
-##     <wildmat>       wildmat-style patterns for the newsgroups
-##     <min>           Mininum number of days to keep article
-##     <default>       Default number of days to keep the article
-##     <max>           Flush article after this many days
-##  <min>, <default>, and <max> can be floating-point numbers or the
-##  word "never."  Times are based on when received unless -p is used;
-##  see expire.8
-
-##  If article expires before 10 days, we still remember it for 10 days in
-##  case we get offered it again.  Depending on what you use for the innd
-##  -c flag and how paranoid you are about old news, you might want to
-##  make this 28, 30, etc, but it's probably safe to reduce it to 7 in most
-##  cases if you want to keep your history file smaller.
-/remember/:10
-
-##  Keep for 1-10 days, allow Expires headers to work.  This entry uses
-##  the syntax appropriate when groupbaseexpiry is true in inn.conf.
-*:A:1:10:never
-
-##  Keep for 1-10 days, allow Expires headers to work.  This is an entry
-##  based on storage class, used when groupbaseexpiry is false.
-#0:1:10:never
diff --git a/samples/filter.tcl b/samples/filter.tcl
deleted file mode 100644 (file)
index 7338884..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- tcl -*-
-#
-# $Revision: 4171 $
-#
-# A TCL procedure that will be run over every article. See doc/hook-tcl
-# for more details.
-
-proc filter_news {} {
-#  global o Headers
-#  set sum [checksum_article]
-#  puts $o "$Headers(Message-ID) $sum"
-#  set newsgroups [split $Headers(Newsgroups) ,]
-#  foreach i $newsgroups {
-#    if {$i=="alt.test" && [string match "*heiney@pa.dec.com*" $Headers(From)]} {
-#      return "dont like alt.test from heiney"
-#    }
-#  }
-  return "accept"
-}
diff --git a/samples/filter_innd.pl b/samples/filter_innd.pl
deleted file mode 100644 (file)
index a56b908..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-#
-# $Id: filter_innd.pl 7860 2008-06-07 12:46:49Z iulius $
-#
-# Sample Perl filtering file for the innd hooks.
-# 
-
-# This file gets loaded at innd process startup, and everytime a
-# "ctlinnd reload filter.perl 'reason'" or a
-# "ctlinnd reload all 'reason'" is done.
-#
-# Before this file is loaded, the perl routine `filter_before_reload' is
-# called, and after it's finished loading, the perl routine
-# `filter_after_reload' is called. See startup_innd.pl for more details.
-#
-# The following routines can be defined here for use by innd:
-#
-#      sub filter_art { ... }
-#
-#              This routine is called before every article is accepted for
-#              posting. Is is called with no arguments, but has access to
-#              all the non-empty standard headers of the article via the
-#              global associative array `%hdr.'  If it returns the empty
-#              string ("") then the article is accepted. If it returns any
-#              non-null string value, then the article is rejected and the
-#              returned string value is logged as the reason why.
-#
-#              The standard headers are:
-#
-#                      Approved, Control, Date, Distribution, Expires,
-#                      From, Lines, Message-ID, Newsgroups, Path,
-#                      Reply-To, Sender, Subject, Supersedes, Bytes,
-#                      Also-Control, References
-#
-#      sub filter_mode { ... }
-#
-#              This routine is called every time `go', `pause', or
-#              `throttle' is called. It is called with no arguments and
-#              returns no value. The global associative array `%mode' has
-#              three keyed values stored in it:
-#
-#                      'Mode'          The current mode
-#                                         ("running", "paused", "throttled") 
-#                      'NewMode"       The new mode
-#                      'reason'        The reason given.
-#
-#              For example:    %mode = ('Mode', 'running', 
-#                                      'NewMode', 'throttled', 
-#                                      'reason', 'doing nightly backups')
-#
-# If filter_art is not defined when this file is done loading, then
-# filtering is disabled. If any syntax error occurs when loading the file,
-# then filtering is disabled.
-#
-#      sub filter_messageid { ... }
-#
-#              This routine is called when each article (in streaming
-#              mode only) is checked to see if INN wants to accept the
-#              article.  If it returns the empty string, the article
-#              is accepted. If it returns a non-empty value, the
-#              article is refused.  It is called with one argument,
-#              the message-id to check.
-
-
-
-#
-# Called on each article innd receives from a peer. Return "" to accept,
-# and any other non-null string to reject. If rejecting the string returned
-# will be part of the logged reason.
-#
-
-sub filter_art {
-       my $rval = "" ; # Assume we'll accept. Cannot be `0'
-
-### Remove two leading '##' from the following section (and then
-### "ctlinnd reload filter.perl 'reason'" and the filter will reject articles that
-### have "make money" in the subject, or are posted to more than 10
-### newsgroups. 
-
-##     my ($maxgroups) = 10 ;
-##
-### Normally this output would be lost, but if you run innd with '-d -f' you
-### can see what's going on.
-###
-###    foreach $key (sort keys %hdr) {
-###            print "Header:\t$key Value:\t $hdr{$key}\n" ;
-###    }
-##
-##     if ($hdr{"Subject"} =~ /\$*make.*money.*\$*/i ) {
-##             $rval = "no money requests here"
-##     } elsif ( ( @_ = split(",",$hdr{'Newsgroups'}) ) > $maxgroups ) {
-##             $rval = "too many groups" ;
-###    Kill article with "Re: " but no References:
-##     } elsif ($hdr{'Subject'} =~ /^Re: /o and $hdr{'References'} eq "") {
-##       $rval = "Followup without References:";
-###    Kill article with invalid From:
-##     } elsif ($hdr{'From'} =~ /^\w*$/o or
-##          $hdr{'From'} !~ /^(.+?)\@([-\w\d]+\.)*([-\w\d]+)\.([-\w\d]{2,})$/o) {
-##       $rval = "From: is invalid, must be user\@[host.]domain.tld";
-##   }
-###
-###    print "Accepting\n" if ! $rval ;
-
-       $rval ;
-}
-
-sub filter_mode {
-       if ($mode{'NewMode'} eq "throttled" || $mode{'NewMode'} eq "paused") {
-#              print "Closing spam database\n" ; # won't kill server.
-#              &close_spam_database ;
-       } else {
-#              print "Opening spam database\n" ; # won't kill server
-#              &open_spam_database ;
-       }
-}
-
-sub filter_messageid {
-    my ($messageid) = @_;
-    $rval = '';
-#    $rval = 'No' if ($messageid =~ /a\.spam\.domain>?/i);
-     $rval;
-}
-
-
-
-
-
-###########################################################################
-##
-## Another sample. More elaborate, but cleaner... from Christophe
-## Wolfhugel <wolf@pasteur.fr>.
-##
-
-
-#### Regular expressions we reject.
-#### Format : Header => regexp => reason
-##%reject = (
-##   'Subject' => {
-##      'make.*money.*fast'            =>      'MMF rejected',
-##      'cash.*cash.*cash'             =>      'Cash rejected'
-##   },
-##);
-##
-##sub filter_art {
-##   my($rval) = '';
-##   my(@ng, $i, $j, $k, $l);
-##
-##   if ($hdr{'From'} !~ /\@/o) {
-##      $rval = 'Invalid From';
-##   } else {
-##      while (($i, $j) = each %reject) {
-##         while (($k, $l) = each %{$j}) {
-##            if ($hdr{$i} =~ /$k/i) {
-##               $rval = $l;
-##               goto the_end;
-##            }
-##         }
-##      }
-##   }
-##   @ng = split(/,/, $hdr{'Newsgroups'});
-##   if ($#ng > 10) {
-##     $rval = 'ECP rejected';
-##   }
-##the_end:
-##   undef %hdr;
-##   return $rval
-##}
-##
-##sub filter_mode {
-##}
-##
-###%hdr = (
-###    'Subject'       =>      'Make money fast',
-###    'From'          =>      'bozo@gov.org'
-###);
-###&filter_art;
-
-
-
-###########################################################################
-##
-## From Chrisophe Wolfhugel again (wolf@pasteur.fr). This is not 
-## standalone code. 
-##
-
-##Just for the fun, I've added following code to filter_innd.pl :
-##
-##   ## Keep track of the From and subject.
-##   $i = "$hdr{'From'} $hdr{'Subject'}";
-##   push(@history, $i);
-##   $history{$i}++;
-##
-##   ## Reject the EMP.
-##   if ($history{$i} > 10) {
-##      $rval = "EMP rejected (appeared $history{$i} times): $i";
-##   }
-##
-##   ## Remove too old things.
-##   while ($#history > 1000) {
-##      delete($history{shift(@history)});
-##   }
-##
-##It is pretty successfull in detecting and refusing excessive multi-posting.
-##Same sender, same subject, appearing more than 10 times without the last
-##1000 articles gets junked.
-##
-##Already catched a few hundreds :
-##
-##Nov 20 08:27:23.175 - vishnu.jussieu.fr <3292ac9a.4064710@nntp.cts.com> 437 EMP rejected (btr@trenet.com Be a Beta Tester!)
-##
-##That was just for the pleasure. It is still sucking a non significant CPU
-##time on my slow Alpha.
-
diff --git a/samples/filter_innd.py b/samples/filter_innd.py
deleted file mode 100644 (file)
index 21d094f..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-##  $Id: filter_innd.py 7903 2008-06-22 20:41:59Z iulius $
-##
-##  This is a sample filter for the Python innd hook.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##
-##  You have access to the following methods from the module INN:
-##   - addhist(message-id)
-##   - article(message-id)
-##   - cancel(message-id)
-##   - havehist(message-id)
-##   - hashstring(string)
-##   - head(message-id)
-##   - newsgroup(groupname)
-##   - set_filter_hook(instance)
-##   - syslog(level, message)
-
-import re
-from string import *
-
-##  This looks weird, but creating and interning these strings should
-##  let us get faster access to header keys (which innd also interns) by
-##  losing some strcmps under the covers.
-Also_Control = intern("Also-Control")
-Approved = intern("Approved")
-Bytes = intern("Bytes")
-Cancel_Key = intern("Cancel-Key")
-Cancel_Lock = intern("Cancel-Lock")
-Content_Base = intern("Content-Base")
-Content_Disposition = intern("Content-Disposition")
-Content_Transfer_Encoding = intern("Content-Transfer-Encoding")
-Content_Type = intern("Content-Type")
-Control = intern("Control")
-Date = intern("Date")
-Date_Received = intern("Date-Received")
-Distribution = intern("Distribution")
-Expires = intern("Expires")
-Face = intern("Face")
-Followup_To = intern("Followup-To")
-From = intern("From")
-In_Reply_To = intern("In-Reply-To")
-Injection_Date = intern("Injection-Date")
-Injection_Info = intern("Injection-Info")
-Keywords = intern("Keywords")
-Lines = intern("Lines")
-List_ID = intern("List-ID")
-Message_ID = intern("Message-ID")
-MIME_Version = intern("MIME-Version")
-Newsgroups = intern("Newsgroups")
-NNTP_Posting_Date = intern("NNTP-Posting-Date")
-NNTP_Posting_Host = intern("NNTP-Posting-Host")
-Organization = intern("Organization")
-Originator = intern("Originator")
-Path = intern("Path")
-Posted = intern("Posted")
-Posting_Version = intern("Posting-Version")
-Received = intern("Received")
-References = intern("References")
-Relay_Version = intern("Relay-Version")
-Reply_To = intern("Reply-To")
-Sender = intern("Sender")
-Subject = intern("Subject")
-Supersedes = intern("Supersedes")
-User_Agent = intern("User-Agent")
-X_Auth = intern("X-Auth")
-X_Canceled_By = intern("X-Canceled-By")
-X_Cancelled_By = intern("X-Cancelled-By")
-X_Complaints_To = intern("X-Complaints-To")
-X_Face = intern("X-Face")
-X_HTTP_UserAgent = intern("X-HTTP-UserAgent")
-X_HTTP_Via = intern("X-HTTP-Via")
-X_Mailer = intern("X-Mailer")
-X_Modbot = intern("X-Modbot")
-X_Modtrace = intern("X-Modtrace")
-X_Newsposter = intern("X-Newsposter")
-X_Newsreader = intern("X-Newsreader")
-X_No_Archive = intern("X-No-Archive")
-X_Original_Message_ID = intern("X-Original-Message-ID")
-X_Original_Trace = intern("X-Original-Trace")
-X_Originating_IP = intern("X-Originating-IP")
-X_PGP_Key = intern("X-PGP-Key")
-X_PGP_Sig = intern("X-PGP-Sig")
-X_Poster_Trace = intern("X-Poster-Trace")
-X_Postfilter = intern("X-Postfilter")
-X_Proxy_User = intern("X-Proxy-User")
-X_Submissions_To = intern("X-Submissions-To")
-X_Trace = intern("X-Trace")
-X_Usenet_Provider = intern("X-Usenet-Provider")
-Xref = intern("Xref")
-__BODY__ = intern("__BODY__")
-_LINES__ = intern("__LINES__")
-
-
-class InndFilter:
-    """Provide filtering callbacks to innd."""
-
-    def __init__(self):
-        """This runs every time the filter is loaded or reloaded.
-        This is a good place to initialize variables and precompile
-        regular expressions, or maybe reload stats from disk.
-        """
-        self.re_newrmgroup = re.compile('(?:new|rm)group\s')
-        self.re_obsctl = re.compile('(?:sendsys|version|uuname)')
-        # Message-ID pattern from a once-common spambot.
-        self.re_none44 = re.compile('none\d+\.yet>')
-        # There is a mad newgrouper who likes to meow.
-        self.re_meow = re.compile("^Meow\!", re.M)
-        # One of my silly addresses.
-        self.re_fluffymorph = re.compile("andruQ@myremarQ.coM", re.I)
-
-    def filter_before_reload(self):
-        """Runs just before the filter gets reloaded.
-
-        You can use this method to save state information to be
-        restored by the __init__() method or down in the main module.
-        """
-        syslog('notice', "filter_before_reload executing...")
-
-    def filter_close(self):
-        """Runs when innd exits.
-
-        You can use this method to save state information to be
-        restored by the __init__() method or down in the main module.
-        """
-        syslog('notice', "filter_close running, bye!")
-
-    def filter_messageid(self, msgid):
-        """Filter articles just by their Message-IDs.
-
-        This method interacts with the IHAVE and CHECK NNTP commands.
-        If you return a non-empty string here, the offered article
-        will be refused before you ever have to waste any bandwidth
-        looking at it.  This is not foolproof, so you should do your
-        ID checks both here and in filter_art.  (TAKETHIS does not
-        offer the ID for examination, and a TAKETHIS isn't always
-        preceded by a CHECK.)
-        """
-        return ""               # Deactivate the samples.
-        
-        if self.re_none44.search(msgid):
-            return "But I don't like spam!"
-        if msgid[0:8] == '<cancel.':
-            return "I don't do cybercancels."
-
-    def filter_art(self, art):
-        """Decide whether to keep offered articles.
-
-        art is a dictionary with a bunch of headers, the article's
-        body, and innd's reckoning of the line count.  Items not
-        in the article will have a value of None.
-
-        The available headers are the ones listed near the top of
-        innd/art.c.  At this writing, they are:
-
-            Also-Control, Approved, Bytes, Cancel-Key, Cancel-Lock,
-            Content-Base, Content-Disposition, Content-Transfer-Encoding,
-            Content-Type, Control, Date, Date-Received, Distribution, Expires,
-            Face, Followup-To, From, In-Reply-To, Injection-Date, Injection-Info,
-            Keywords, Lines, List-ID, Message-ID, MIME-Version, Newsgroups,
-            NNTP-Posting-Date, NNTP-Posting-Host, Organization, Originator,
-            Path, Posted, Posting-Version, Received, References, Relay-Version,
-            Reply-To, Sender, Subject, Supersedes, User-Agent,
-            X-Auth, X-Canceled-By, X-Cancelled-By, X-Complaints-To, X-Face,
-            X-HTTP-UserAgent, X-HTTP-Via, X-Mailer, X-Modbot, X-Modtrace,
-            X-Newsposter, X-Newsreader, X-No-Archive, X-Original-Message-ID,
-            X-Original-Trace, X-Originating-IP, X-PGP-Key, X-PGP-Sig,
-            X-Poster-Trace, X-Postfilter, X-Proxy-User, X-Submissions-To,
-            X-Trace, X-Usenet-Provider, Xref.
-
-        The body is the buffer in art['__BODY__'] and the INN-reckoned
-        line count is held as an integer in art['__LINES__'].  (The
-        Lines: header is often generated by the poster, and large
-        differences can be a good indication of a corrupt article.)
-
-        If you want to keep an article, return None or "".  If you
-        want to reject, return a non-empty string.  The rejection
-        string will appear in transfer and posting response banners,
-        and local posters will see them if their messages are
-        rejected.
-        """
-        return ""               # Deactivate the samples.
-
-        # Catch bad Message-IDs from articles fed with TAKETHIS but no CHECK.
-        idcheck = self.filter_messageid(art[Message_ID])
-        if idcheck:
-            return idcheck
-
-        # There are some control messages we don't want to process or
-        # forward to other sites.
-        try:
-            if art[Control] is not None:
-                if self.re_newrmgroup.match(art[Control]):
-                    if self.re_meow.search(art[__BODY__]):
-                        return "The fake tale meows again."
-                    if art[Distribution] == buffer('mxyzptlk'):
-                        return "Evil control message from the 10th dimension"
-                if self.re_obsctl.match(art[Control]):
-                    return "Obsolete control message"
-
-            # If you don't know, you don't want to know.
-            if self.re_fluffymorph.search(art[From]):
-                return "No, you may NOT meow."
-        except:
-            syslog('n', str(sys.exc_info[1]))
-
-    def filter_mode(self, oldmode, newmode, reason):
-        """Capture server events and do something useful.
-
-        When the admin throttles or pauses innd (and lets it go
-        again), this method will be called.  oldmode is the state we
-        just left, and newmode is where we are going.  reason is
-        usually just a comment string.
-
-        The possible values of newmode and oldmode are the five
-        strings 'running', 'paused', 'throttled', 'shutdown' and
-        'unknown'.  Actually 'unknown' shouldn't happen; it's there
-        in case feeping creatures invade innd.
-        """
-        syslog('notice', 'state change from %s to %s - %s'
-               % (oldmode, newmode, reason))
-
-
-"""
-Okay, that's the end of our class definition.  What follows is the
-stuff you need to do to get it all working inside innd.
-"""
-
-##  This import must succeed, or your filter won't work.  I'll repeat
-##  that: You MUST import INN.
-from INN import *
-
-##  Some of the stuff below is gratuitous, just demonstrating how the
-##  INN.syslog call works.  That first thingy tells the Unix syslogger
-##  what severity to use; you can abbreviate down to one letter and
-##  it's case insensitive.  Available levels are (in increasing levels
-##  of seriousness) Debug, Info, Notice, Warning, Err, Crit, and
-##  Alert.  If you provide any other string, it will be defaulted to
-##  Notice.  You'll find the entries in the same log files innd itself
-##  uses, with an 'innd: python:' prefix.
-##
-##  The native Python syslog module seems to clash with INN, so use
-##  INN's.  Oh yeah -- you may notice that stdout and stderr have been
-##  redirected to /dev/null -- if you want to print stuff, open your
-##  own files.
-
-try:
-    import sys
-except Exception, errmsg:
-    syslog('Error', "import boo-boo: " + errmsg[0])
-
-
-##  If you want to do something special when the server first starts
-##  up, this is how to find out when it's time.
-
-if 'spamfilter' not in dir():
-    syslog('n', "First load, so I can do initialization stuff.")
-    # You could unpickle a saved hash here, so that your hard-earned
-    # spam scores aren't lost whenever you shut down innd.
-else:
-    syslog('NoTicE', "I'm just reloading, so skip the formalities.")
-
-
-##  Finally, here is how we get our class on speaking terms with innd.
-##  The hook is refreshed on every reload, so that you can change the
-##  methods on a running server.  Don't forget to test your changes
-##  before reloading!
-spamfilter = InndFilter()
-try:
-    set_filter_hook(spamfilter)
-    syslog('n', "spamfilter successfully hooked into INN")
-except Exception, errmsg:
-    syslog('e', "Cannot obtain INN hook for spamfilter: %s" % errmsg[0])
-
diff --git a/samples/filter_nnrpd.pl b/samples/filter_nnrpd.pl
deleted file mode 100644 (file)
index 6591b06..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# $Id: filter_nnrpd.pl 5981 2002-12-12 05:01:42Z vinocur $
-#
-# Sample perl filtering code for nnrpd hook.
-#
-
-#
-# This file is loaded when nnrpd starts up. If it defines a sub named
-# `filter_post', then that function will be called during processing of a
-# posting. It has access to the headers of the article via the associative
-# array `%hdr'. If it returns a null string then the article is accepted
-# for posting. A non-null string rejects it, and the value returned is used
-# in the rejection message.
-#
-
-#
-# Do any initialization steps.
-#
-my %config = (checkincludedtext => 0,
-              includedcutoff => 40,
-              includedratio => 0.6,
-              quotere => '^[>:]',
-              antiquotere => '^[<]',  # so as not to reject dict(1) output
-             );
-
-
-#
-# Sample filter
-#
-sub filter_post {
-    my $rval = "" ;             # assume we'll accept.
-
-### Uncomment this next block to reject articles that have 'make money'
-### in their subject, or which have a "Re: " subject, but no References:
-### header, or which have an invalid From.
-
-##    if ($hdr{"Subject"} =~ /make.*money/i) {
-##        $rval = "Spam is not acceptable here..." ;
-##    } elsif ($hdr{'Subject'} =~ /^Re: /o and $hdr{'References'} eq "") {
-##        $rval = "Followup without References:";
-##    } elsif ($hdr{'From'} =~ /^\w*$/o or
-##             $hdr{'From'} !~ /^(.+?)\@([-\w\d]+\.)*([-\w\d]+)\.([-\w\d]{2,})$/o) {
-##        $rval = "From: is invalid, must be user\@[host.]domain.tld";
-##    }
-
-
-### The next block rejects articles with too much quoted text, if the
-### config hash directs it to.
-
-    if ($config{checkincludedtext}) {
-        my ($lines, $quoted, $antiquoted) = analyze($body);
-        if ($lines > $config{includedcutoff}
-                && $quoted - $antiquoted > $lines * $config{includedratio}) {
-            $rval = "Article contains too much quoted text";
-        }
-    }
-
-    return $rval;
-}
-
-sub analyze {
-    my ($lines, $quoted, $antiquoted) = (0, 0, 0);
-    local $_ = shift;
-
-    do {
-        if ( /\G$config{quotere}/mgc ) {
-            $quoted++;
-        } elsif ( /\G$config{antiquotere}/mgc ) {
-            $antiquoted++;
-        }
-    } while ( /\G(.*)\n/gc && ++$lines );
-
-    return ($lines, $quoted, $antiquoted);
-}
diff --git a/samples/incoming.conf b/samples/incoming.conf
deleted file mode 100644 (file)
index c4b75c2..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-##  $Revision: 2372 $
-##  incoming.conf - names and addresses that feed us news
-##      
-##  This file consists of three types of entries: key/value, peer and group.
-##  Comments are taken from the hash character ``#'' to the end of the line.
-##  Blank lines are ignored.
-##
-##  Key/value entries are a keyword immediatly followed by a colon, at least
-##  one blank and a value. For example:
-## 
-##         max-connections: 10
-## 
-##  A legal key contains nor blanks, nor colon, nor ``#''.
-##  There are 5 different type of  values:  integers,  booleans, and strings.
-##  Integers are as to be expected. A boolean value is either ``true'' or
-##  ``false'' (case is significant). A string value is any other sequence of
-##  characters. If the string needs to contain whitespace, then it must be
-##  quoted with double quotes.
-##
-##  Peer entries look like:
-## 
-##          peer <name> {
-##               # body
-##          }
-## 
-##  The word ``peer'' is required. <name> is a label for this peer. It is
-##  any string valid as a key. The body of a peer entry contains some number
-##  of key/value entries.
-##
-##  Group entries look like:
-## 
-##          group <name> {
-##               # body
-##          }
-##
-##  The word ``group'' is required. The ``<name>'' is any string valid as a
-##  key. The body of a group entry contains any number of the three types of
-##  entries. So key/value pairs can be defined inside a group, and peers can
-##  be nested inside a group, and other groups can be nested inside a group.
-##
-##  Key/value entries that are defined outside of all peer and group entries
-##  are said to be at ``global scope''. Global key/value entries act as
-##  defaults for peers. When innd looks for a specific value in a peer entry
-##  (for example, the maximum number of connections to allow), if the value
-##  is not defined in the peer entry, then the enclosing groups are examined
-##  for the entry (starting at the closest enclosing group). If there are no
-##  enclosing groups, or the enclosing groups don't define the key/value,
-##  then the value at global scope is used.
-##
-##  A small example could be:
-## 
-##      # Global value applied to all peers that have no value of their own.
-##      max-connections: 5
-## 
-##      # A peer definition.
-##      peer uunet {
-##           hostname: usenet1.uu.net
-##      }
-## 
-##      peer vixie {
-##              hostname: gw.home.vix.com
-##              max-connections: 10      # override global value.
-##      }
-## 
-##      # A group of two peers who can open more connections than normal
-##      group fast-sites {
-##           max-connections: 15
-## 
-##           # Another peer. The ``max-connections'' value from the
-##           # ``fast-sites'' group scope is used.
-##           peer data.ramona.vix.com {
-##                hostname: data.ramona.vix.com
-##           }
-## 
-##           peer bb.home.vix.com {
-##                hostname: bb.home.vix.com
-##                max-connections: 20 # he can really cook.
-##           }
-##      }
-## 
-##  Given the above configuration file, the defined peers would have the
-##  following values for the ``max-connections'' key.
-##
-##          uunet                  5
-##          vixie                 10
-##          data.ramona.vix.com   15
-##          bb.home.vix.com       20
-##
-##  Height keys are allowed:
-##
-##  hostname:
-##   This key is mandatory in a peer block. The value is a string representing
-##   a list of hostnames separated by a comma. A hostname is the host's FQDN,
-##   or the dotted quad ip-address of the peer.
-##
-##  streaming:
-##   This key requires a boolean value. It defines whether streaming commands
-##   are allowed from this peer. (default=true)
-##
-##  max-connections:
-##   This key requires positive integer value. It defines the maximum number
-##   of connections allowed. A value of zero specifies an unlimited number
-##   of maximum connections (``unlimited'' or ``none'' can be used as synonym).
-##   (default=0)
-## 
-##  hold-time:
-##   This key requires positive integer value. It defines the hold time before
-##   close, if the connection is over max-connections. A value of zero
-##   specifies immediate close. (default=0)
-##
-##  password:
-##   This key requires a string value. It is used if you wish to require a peer
-##   to supply a password. (default=no password)
-##
-##  patterns:
-##   This key requires a string value. It is a list of newsfeeds(5)-style list
-##   of newsgroups which are to be accepted from this host. (default="*")
-##
-##  email:
-##   This key requires a string value. Reserved for future use. (default=empty)
-##
-##  comment:
-##   This key requires a string value. Reserved for future use. (default=empty)
-##
-##  skip:
-##   This key requires a boolean value. Setting this entry causes this peer
-##   to be skipped. Reserved for future use. (default=false)
-##
-##  noresendid: 
-##   This key requires a boolean value. It defines whether innd should send
-##   "431 RESENDID" (stream mode) or "436 Retry later" (non-stream mode)
-##   responses if a message is offered that is already received from another
-##   peer. This can be useful for peers that resend messages right away,
-##   as innfeed does. (default=false)
-##
-
-streaming:              true   # streaming allowed by default
-max-connections:        8      # per feed
-
-peer ME {
-  hostname:         "localhost, 127.0.0.1"
-}
diff --git a/samples/inn.conf.in b/samples/inn.conf.in
deleted file mode 100644 (file)
index 8e0f63b..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-##  $Id: inn.conf.in 7751 2008-04-06 14:35:40Z iulius $
-##
-##  inn.conf -- INN configuration data
-##
-##  Format:
-##      <parameter>:<whitespace><value>
-##
-##  Blank values are allowed for certain parameters.
-##
-##  See the inn.conf(5) man page for a full description of each of these
-##  options.  This sample file is divided into two sections; first, there
-##  are the parameters that must be set (or should be set in nearly all
-##  cases), and then all parameters are given with their defaults for
-##  reference in the same order and with the same organization as the
-##  inn.conf(5) documentation.
-
-# The following parameters are most likely to need setting, although the
-# defaults generated by configure may be reasonable.
-
-mta:                    "@SENDMAIL@ -oi -oem %s"
-organization:           "A poorly-installed InterNetNews site"
-ovmethod:               tradindexed
-hismethod:              hisv6
-pathhost:               @HOSTNAME@
-pathnews:               @prefix@
-
-# General Settings
-
-#domain:
-#innflags:
-mailcmd:                @prefix@/bin/innmail
-#server:
-
-# Feed Configuration
-
-artcutoff:              10
-#bindaddress:
-#bindaddress6:
-dontrejectfiltered:    false
-hiscachesize:           0
-ignorenewsgroups:       false
-immediatecancel:        false
-linecountfuzz:          0
-maxartsize:             1000000
-maxconnections:         50
-#pathalias:
-#pathcluster:
-pgpverify:              @pgpverify@
-port:                   119
-refusecybercancels:     false
-remembertrash:          true
-#sourceaddress:
-#sourceaddress6:
-verifycancels:          false
-wanttrash:              false
-wipcheck:               5
-wipexpire:              10
-
-# Article Storage
-
-cnfscheckfudgesize:     0
-enableoverview:         true
-groupbaseexpiry:        true
-mergetogroups:          false
-overcachesize:          15
-#ovgrouppat:
-storeonxref:            true
-useoverchan:            false
-wireformat:             false
-xrefslave:              false
-nfswriter:              false
-
-# Reading
-
-allownewnews:           true
-articlemmap:            false
-clienttimeout:          600
-initialtimeout:         10
-msgidcachesize:         10000
-nnrpdcheckart:          true
-nnrpdflags:             ""
-noreader:               false
-readerswhenstopped:     false
-readertrack:            false
-nfsreader:              false
-nfsreaderdelay:         60
-tradindexedmmap:        true
-nnrpdloadlimit:         16
-
-# Reading -- Keyword Support
-#
-# Enabling this without stopping innd and deleting the existing overview
-# database and adding will probably confuse a lot of things.  You must
-# have compiled this support in too.
-
-keywords:               false
-keyartlimit:            100000
-keylimit:               512
-keymaxwords:            250
-
-# Posting
-
-addnntppostingdate:     true
-addnntppostinghost:     true
-checkincludedtext:      false
-#complaints:
-#fromhost:
-localmaxartsize:        1000000
-#moderatormailer:
-nnrpdauthsender:        false
-#nnrpdposthost:
-nnrpdpostport:          119
-spoolfirst:             false
-strippostcc:            false
-
-# Posting -- Exponential Backoff
-
-backoffauth:            false
-#backoffdb:
-backoffk:               1
-backoffpostfast:        0
-backoffpostslow:        1
-backofftrigger:         10000
-
-# Monitoring
-
-doinnwatch:             true
-innwatchbatchspace:     800
-innwatchlibspace:       25000
-innwatchloload:         1000
-innwatchhiload:         2000
-innwatchpauseload:      1500
-innwatchsleeptime:      600
-innwatchspoolnodes:     200
-innwatchspoolspace:     8000
-
-# Logging
-
-docnfsstat:             false
-logartsize:             true
-logcancelcomm:          false
-logcycles:              3
-logipaddr:              true
-logsitename:            true
-nnrpdoverstats:         false
-nntpactsync:            200
-nntplinklog:            false
-status:                 0
-timer:                  0
-
-# System Tuning
-
-badiocount:             5
-blockbackoff:           120
-chaninacttime:          600
-chanretrytime:          300
-datamovethreshold:      8192
-icdsynccount:           10
-keepmmappedthreshold:   1024
-#maxcmdreadsize:
-maxforks:               10
-nicekids:               4
-nicenewnews:            0
-nicennrpd:              0
-pauseretrytime:         300
-peertimeout:            3600
-rlimitnofile:           -1
-
-# Paths
-
-patharchive:            @SPOOLDIR@/archive
-patharticles:           @SPOOLDIR@/articles
-pathbin:                @prefix@/bin
-pathcontrol:            @CONTROLDIR@
-pathdb:                 @DBDIR@
-pathetc:                @ETCDIR@
-pathfilter:             @FILTERDIR@
-pathhttp:               @LOGDIR@
-pathincoming:           @SPOOLDIR@/incoming
-pathlog:                @LOGDIR@
-pathoutgoing:           @SPOOLDIR@/outgoing
-pathoverview:           @SPOOLDIR@/overview
-pathrun:                @RUNDIR@
-pathspool:              @SPOOLDIR@
-pathtmp:                @tmpdir@
diff --git a/samples/innfeed.conf b/samples/innfeed.conf
deleted file mode 100644 (file)
index e350dda..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-# $Revision: 7559 $
-#
-# Sample innfeed config file. See the comment block at the
-# end for a fuller description of the format, and innfeed.conf(5) for a
-# description of the entries.
-#
-
-##
-## Global values. Not specific to any peer. These are optional, but if
-## used will override the compiled in values.
-##
-
-pid-file:                      innfeed.pid             # relative to pathrun
-debug-level:                   0
-use-mmap:                      false
-log-file:                      innfeed.log             # relative to pathlog
-stdio-fdmax:                   0
-
-## Uncomment the next line to include the contents
-## of ``testfile'' at this point.
-
-#$INCLUDE testfile
-
-backlog-directory:             innfeed                 # relative to pathspool
-backlog-rotate-period:         60
-backlog-ckpt-period:           30
-backlog-newfile-period:                600
-
-dns-retry:                     900
-dns-expire:                    86400
-close-period:                  86400
-gen-html:                      false
-status-file:                   innfeed.status          # relative to pathlog
-connection-stats:              false
-host-queue-highwater:          200
-stats-period:                  600
-stats-reset:                   43200
-
-max-reconnect-time:            3600
-initial-reconnect-time:                30
-
-
-##
-## Defaults for all peers. These must all exist at
-## global scope. Any of them can be redefined
-## inside a peer or group definition.
-##
-
-article-timeout:               600
-response-timeout:              300
-initial-connections:           1
-max-connections:               5
-max-queue-size:                        5
-streaming:                     true
-no-check-high:                 95.0
-no-check-low:                  90.0
-no-check-filter:               50.0
-port-number:                   119
-force-ipv4:                    false
-drop-deferred:                 false
-min-queue-connection:          false
-backlog-limit:                 0
-backlog-factor:                        1.10
-backlog-limit-highwater:       0
-dynamic-method:                        3
-dynamic-backlog-filter:                0.7
-dynamic-backlog-low:           25.0
-dynamic-backlog-high:          50.0
-no-backlog:                    false
-backlog-feed-first:             false
-
-##
-## Peers. 
-##
-#peer decwrl {
-#        ip-name:                news1.pa.dec.com
-#}
-
-#peer uunet {
-#        ip-name:                news.uunet.uu.net
-#        max-connections:        10
-#}
-
-
-##
-## Group peers together to give second level defaults.
-## 
-#group fast-sites {
-#      max-connections: 7
-#
-#      peer data.ramona.vix.com {
-#              # ip-name defaults to data.ramona.vix.com
-#              streaming:              false
-#      }
-#
-#      peer bb.home.vix.com {
-#              ip-name:        192.5.5.33
-#      }
-#}
-
-
-
-# Blank lines are ignored. Exerything after a '#'
-# is ignored too.
-#
-# Format is:
-#               key : value
-#
-# See innfeed.conf(5) for a description of
-# necessary & useful keys. Unknown keys and their
-# values are ignored.
-#
-# Values may be a integer, floating-point, c-style
-# single-quoted characters, boolean, and strings.
-#
-# If a string value contains whitespace, or
-# embedded quotes, or the comment character
-# (``#''), then the whole string must be quoted
-# with double quotes.  Inside the quotes, you may
-# use the standard c-escape sequence
-# (\t,\n,\r,\f,\v,\",\').
-#
-# Examples:
-#       eg-string:      "New\tConfig\tfile\n"
-#       eg-long-string: "A long string that goes
-#                       over multiple lines. The
-#                       newline is kept in the
-#                       string except when quoted 
-#                       with a backslash \
-#                       as here."
-#       eg-simple-string: A-no-quote-string
-#       eg-integer:     10
-#       eg-boolean:     true
-#       eg-char:        'a'
-#       eg-ctrl-g:      '\007'
diff --git a/samples/innreport.conf.in b/samples/innreport.conf.in
deleted file mode 100644 (file)
index 215f63d..0000000
+++ /dev/null
@@ -1,2473 +0,0 @@
-##########################################################
-# Configuration file for innreport (3.*).
-#
-# Sample file for INN.
-# Tested with INN 2.3, 2.1, 1.7.2 and 1.5.1.
-#
-# (c) 1997, 1998, 1999 by Fabien Tassin <fta@sofaraway.org>
-# version 3.0.2
-##########################################################
-
-# Default parameters
-section default {
-       libpath         "@LIBDIR@";
-       logpath         "@LOGDIR@";
-       unknown         true;        # want unknown entries.
-       max_unknown     50;          # max unknown entries to display.
-       casesensitive   true;
-       module          "innreport_inn";  # ${libpath}/${module}.pm
-       unwanted_log    "unwanted.log";   # ${logpath}/${unwanted_log}
-       text            true;
-       html            false;
-       graph           true;        # need 'html'
-       archive         true;  # use false to keep only the latest HTML report.
-       index           "index.html"; # name of the HTML index file.
-      # html_dir     "/var/www/News/stats"; # default to pathhttp in inn.conf
-       img_dir         "pics";      # images will go to ${html_dir}/${img_dir}
-       cycle           none;        # use a number or 'none'.
-        separator       ".";         # use a valid filename character.
-       title           "Daily Usenet report";
-      # title       "Daily Usenet report for <A HREF=\"/News/stats/\">news.y.z</A>";
-      # footer         "Local contact: <A HREF=\"mailto:x@y.z\">x@y.z</A>";
-      # html_body      "BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\"";
-      # html_header_file "header.html";  # ${html_dir}/${html_header_file}
-      # html_footer_file "footer.html";  # ${html_dir}/${html_footer_file}
-        graph_width    550;         # graph width (in pixels)
-        transparent    true;        # graph background transparent ?
-        graph_fg        "#000000";   # graph foreground color.
-        graph_bg        "#FFFFFF";   # graph background color.
-};
-
-###########################################################################
-# Index page
-section index {
-       column {
-               title   "Dates";
-               value   "date";
-       };
-       column {
-               title   "Incoming feeds";
-               name    "Offered|Accepted|Volume";
-               value   "total(%innd_offered) | total(%innd_accepted) |
-                        bytes(total(%inn_flow_size))";
-       };
-       column {
-               title   "Outgoing feeds";
-               name    "Offered|Accepted|Volume";
-               value   "total(%innfeed_offered) + total(%nntplink_offered) +
-                        total(%innxmit_offered) | total(%innfeed_accepted) +
-                        total(%nntplink_accepted) + total(%innxmit_accepted) |
-                        bytes(total(%innfeed_accepted_size) +
-                        total(%innfeed_rejected_size) +
-                        total(%innxmit_bytes) +
-                        total(%innxmit_accepted_size) +
-                        total(%innxmit_rejected_size))";
-       };
-       graph {
-               title         "Incoming feeds";
-               value         val1;
-               color         "#FFFFCE";
-               unit          "art";
-               data {
-                         name    "Offered";
-                         color   "#50A0D0";
-                         value   "val2";       # Incoming feeds: Offered
-               };
-               data {
-                         name    "Accepted";
-                         color   "#0000FF";
-                         value   "val3";       # Incoming feeds: Accepted
-               };
-       };
-       graph {
-               title         "Outgoing feeds";
-               value         val1;
-               color         "#FFFFCE";
-               unit          "art";
-               data {
-                         name    "Offered";
-                         color   "#50A0D0";
-                         value   "val5";       # Outgoing feeds: Offered
-               };
-               data {
-                         name    "Accepted";
-                         color   "#0000FF";
-                         value   "val6";       # Outgoing feeds: Accepted
-               };
-       };
-       graph {
-               title           "Bandwidth";
-               value           val1;
-               color           "#FFFFCE";
-               unit            "Kb";
-               data {
-                       name    "Incoming";
-                       color   "#50A0D0";
-                       value   "byte(val4)";   # Incoming feeds: Volume
-               };
-               data {
-                       name    "Outgoing";
-                       color   "#0000FF";
-                       value   "byte(val7)";   # Outgoing feeds: Volume
-               };
-       };
-};
-
-###########################################################################
-# Report
-
-section prog_type {
-        # skip    true;                          # used to skip a section.
-        title   "Log entries by program:";
-       data    "%prog_type";
-       sort    "$prog_type{$b} <=> $prog_type{$a}";
-       # text  false;             # to skip this section in the text report
-       # html  false;             # to skip this section in the HTML report
-        column {
-                name          "Program name";
-                format        "%-46.46s";
-               value         "$key";
-               format_total  "TOTAL: %-39.39s";
-               total         "$num";
-        };
-        column {
-                name          "Lines";
-                format_name   "%7s";
-                format        "%7d";
-               # text        false;  # to skip this column in the text report
-               value         "$prog_type{$key}";
-               total         "total(%prog_type)";
-        };
-        column {
-                name          "%Lines";
-                format_name   "%7s";
-                format        "%6.1f%%";
-               # html        false;  # to skip this column in the HTML report
-               value         "$prog_type{$key} / total(%prog_type) * 100";
-               total         "100";
-        };
-        column {
-                name          "Size";
-                format        "%9s";
-               value         "bytes($prog_size{$key})";
-               total         "bytes(total(%prog_size))";
-        };
-        column {
-                name          "%Size";
-                format_name   "%6s";
-                format        "%5.1f%%";
-               value         "$prog_size{$key} / total(%prog_size) * 100";
-               total         "100";
-        };
-};
-
-# INN 2.*
-section innd_his {
-       title   "History cache:";
-       data    "%innd_his";
-       sort    "$innd_his{$b} <=> $innd_his{$a}";
-       column {
-               name          "Reason";
-               format        "%-57.57s";
-               value         "$key";
-               format_total  "TOTAL: %-50.50s";
-               total         "$num";
-       };
-       column {
-               name          "Count";
-               format_name   "%10s";
-                format        "%10d";
-               value         "$innd_his{$key}";
-               total         "total(%innd_his)";
-        };
-       column {
-               name          "%Count";
-               format_name   "%10s";
-                format        "%9.1f%%";
-               value         "100 * $innd_his{$key} / total(%innd_his)";
-               total         "100";
-        };
-};
-
-# INN 1.*
-section innd_cache {
-       title   "History cache:";
-       data    "%innd_cache";
-       sort    "$innd_cache{$b} <=> $innd_cache{$a}";
-       column {
-               name          "Reason";
-               format        "%-57.57s";
-               value         "$key";
-               format_total  "TOTAL: %-50.50s";
-               total         "$num";
-       };
-       column {
-               name          "Count";
-               format_name   "%10s";
-                format        "%10d";
-               value         "$innd_cache{$key}";
-               total         "total(%innd_cache)";
-        };
-       column {
-               name          "%Count";
-               format_name   "%10s";
-                format        "%9.1f%%";
-               value         "100 * $innd_cache{$key} / total(%innd_cache)";
-               total         "100";
-        };
-};
-
-section innd_timer {
-        title   "INND timer:";
-       data    "%innd_time_time";
-        column {
-                name          "Code region";
-                format        "%-15.15s";
-               value         "$key";
-               format_total  "TOTAL: %-8.8s";
-               total         "time_ms($innd_time_times)";
-        };
-        column {
-                name          "Time";
-                format        "%13s";
-               value         "time_ms($innd_time_time{$key})";
-               total         "time_ms(total(%innd_time_time))";
-        };
-        column {
-                name          "Pct";
-                format_name   "%6s";
-                format        "%5.1f%%";
-               value         "100 * $innd_time_time{$key} / $innd_time_times";
-               total         "100 * total(%innd_time_time) /
-                              $innd_time_times";
-        };
-        column {
-                name          "Invoked";
-                format        "%10s";
-               value         "$innd_time_num{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Min(ms)";
-                format_name   "%9s";
-                format        "%9.3f";
-               value         "$innd_time_min{$key}";
-                format_total  "%8s-";
-               total         "";
-        };
-        column {
-                name          "Avg(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$innd_time_time{$key} /
-                           ($innd_time_num{$key} ? $innd_time_num{$key} : 1)";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Max(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$innd_time_max{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-};
-
-section innfeed_timer {
-        title   "INNfeed timer:";
-       data    "%innfeed_time_time";
-        column {
-                name          "Code region";
-                format        "%-15.15s";
-               value         "$key";
-               format_total  "TOTAL: %-8.8s";
-               total         "time_ms($innfeed_time_times)";
-        };
-        column {
-                name          "Time";
-                format        "%13s";
-               value         "time_ms($innfeed_time_time{$key})";
-               total         "time_ms(total(%innfeed_time_time))";
-        };
-        column {
-                name          "Pct";
-                format_name   "%6s";
-                format        "%5.1f%%";
-               value         "100 * $innfeed_time_time{$key} / $innfeed_time_times";
-               total         "100 * total(%innfeed_time_time) /
-                              $innfeed_time_times";
-        };
-        column {
-                name          "Invoked";
-                format        "%10s";
-               value         "$innfeed_time_num{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Min(ms)";
-                format_name   "%9s";
-                format        "%9.3f";
-               value         "$innfeed_time_min{$key}";
-                format_total  "%8s-";
-               total         "";
-        };
-        column {
-                name          "Avg(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$innfeed_time_time{$key} /
-                           ($innfeed_time_num{$key} ? $innfeed_time_num{$key} : 1)";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Max(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$innfeed_time_max{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-};
-
-section nnrpd_timer {
-        title   "nnrpd timer:";
-       data    "%nnrpd_time_time";
-        column {
-                name          "Code region";
-                format        "%-15.15s";
-               value         "$key";
-               format_total  "TOTAL: %-8.8s";
-               total         "time_ms($nnrpd_time_times)";
-        };
-        column {
-                name          "Time";
-                format        "%13s";
-               value         "time_ms($nnrpd_time_time{$key})";
-               total         "time_ms(total(%nnrpd_time_time))";
-        };
-        column {
-                name          "Pct";
-                format_name   "%6s";
-                format        "%5.1f%%";
-               value         "100 * $nnrpd_time_time{$key} / $nnrpd_time_times";
-               total         "100 * total(%nnrpd_time_time) /
-                              $nnrpd_time_times";
-        };
-        column {
-                name          "Invoked";
-                format        "%10s";
-               value         "$nnrpd_time_num{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Min(ms)";
-                format_name   "%9s";
-                format        "%9.3f";
-               value         "$nnrpd_time_min{$key}";
-                format_total  "%8s-";
-               total         "";
-        };
-        column {
-                name          "Avg(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$nnrpd_time_time{$key} /
-                           ($nnrpd_time_num{$key} ? $nnrpd_time_num{$key} : 1)";
-                format_total  "%9s-";
-               total         "";
-        };
-        column {
-                name          "Max(ms)";
-                format_name   "%10s";
-                format        "%10.3f";
-               value         "$nnrpd_time_max{$key}";
-                format_total  "%9s-";
-               total         "";
-        };
-};
-
-section innd_control {
-        title   "Control commands to INND:";
-       data    "%innd_control";
-        column {
-                name          "Command";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Number";
-                format_name   "%7s";
-               value         "$innd_control{$key}";
-               format        "%7d";
-               total         "total(%innd_control)";
-        };
-};
-
-section innd_newgroup {
-        title   "Newsgroups created:";
-       data    "%innd_newgroup";
-        column {
-                name          "Group";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL%-66.66s";
-               total         "";
-        };
-        column {
-                name          "Mode";
-               value         "$innd_newgroup{$key}";
-               format        "%7s";
-               total         "$num";
-        };
-};
-
-section innd_changegroup {
-       title   "Newsgroups changed:";
-       data    "%innd_changegroup";
-       column {
-               name          "Group";
-               format        "%-68.68s";
-               value         "$key";
-               format_total  "TOTAL%-63.63s";
-               total         "";
-       };
-       column {
-               name          "New mode";
-               format        "%10s";
-               value         "$innd_changegroup{$key}";
-               total         "$num";
-       };
-};
-
-section innd_rmgroup {
-       title   "Newsgroups removed:";
-       data    "%innd_rmgroup";
-       column {
-               name          "Group";
-               format        "%-78.78s";
-               value         "$key";
-               format_total  "TOTAL: %-71.71s";
-               total         "$num";
-       };
-};
-
-section controlchan {
-       title   "Control Channel:";
-       data    "%controlchan_who";
-       column {
-               name          "Sender";
-               format        "%-25.25s";
-               value         "$key";
-               format_total  "TOTAL%-20.20s";
-               total         "";
-       };
-       column {
-               name          "newgroup";
-               value         "$controlchan_new{$key}";
-               format        "%8s";
-               total         "total(%controlchan_new)";
-       };
-       column {
-               name          "rmgroup";
-               value         "$controlchan_rm{$key}";
-               format        "%8s";
-               total         "total(%controlchan_rm)";
-       };
-       column {
-               name          "Other";
-               value         "$controlchan_other{$key}";
-               format        "%8s";
-               total         "total(%controlchan_other)";
-       };
-       column {
-               name          "Bad PGP";
-               value         "$controlchan_skippgp{$key}";
-               format        "%8s";
-               total         "total(%controlchan_skippgp)";
-       };
-       column {
-               name          "DoIt";
-               value         "$controlchan_doit{$key}";
-               format        "%8s";
-               total         "total(%controlchan_doit)";
-       };
-       column {
-               name          "OK";
-               value         "$controlchan_ok{$key}";
-               format        "%8s";
-               total         "total(%controlchan_ok)";
-       };
-};
-
-section innd_connect {
-        title   "Incoming Feeds (INN):";
-       data    "%innd_seconds";
-       sort    "$innd_accepted{$b} <=> $innd_accepted{$a}";
-       numbering true;
-        column {
-                name          "Server";
-               format_name   "%-21.21s";
-               format        "%-24.24s";
-               value         "$key";
-               format_total  "TOTAL: %-17.17s";
-               total         "$num";
-        };
-        column {
-                name          "Connects";
-               format_name   "%5s";
-               format        "%5d";
-               value         "$innd_connect{$key}";
-               total         "total(%innd_connect)";
-        };
-        column {
-                name          "Offered";
-               format_name   "%8s";
-               format        "%8d";
-               value         "$innd_offered{$key}";
-               total         "total(%innd_offered)";
-        };
-        column {
-                name          "Taken";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innd_accepted{$key}";
-               total         "total(%innd_accepted)";
-        };
-        column {
-                name          "Refused";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innd_refused{$key}";
-               total         "total(%innd_refused)";
-        };
-        column {
-                name          "Reject";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innd_rejected{$key}";
-               total         "total(%innd_rejected)";
-        };
-        column {
-                name          "%Accpt";
-               format_name   "%6s";
-               format        "%4d%%";
-               value         "$innd_offered{$key} == 0 ? 0 :
-                             $innd_accepted{$key} / $innd_offered{$key} * 100";
-               total         "total(%innd_offered) == 0 ? 0 :
-                           total(%innd_accepted) / total(%innd_offered) * 100";
-        };
-        column {
-                name          "Elapsed";
-               format_name   "%8s";
-               format        "%9s";
-               value         "time($innd_seconds{$key})";
-               total         "time(total(%innd_seconds))";
-        };
-       graph {
-               title         "Articles received by server";
-               type          histo3d;
-               sort          "%innd_accepted";
-               data {
-                         name    "Articles accepted";
-                         color   "#0000FF";
-                         value   "%innd_accepted";
-                };
-               data {
-                         name    "Articles refused";
-                         color   "#FFAF00";
-                         value   "%innd_refused";
-                };
-               data {
-                         name    "Articles rejected";
-                         color   "#FF0000";
-                         value   "%innd_rejected";
-                };
-       };
-};
-
-section innd_incoming_vol {
-        title   "Incoming Volume (INN):";
-       data    "%innd_seconds";
-       sort    "$innd_stored_size{$b} <=> $innd_stored_size{$a}";
-       numbering true;
-        column {
-                name          "Server";
-               format        "%-24.24s";
-               value         "$key";
-               format_total  "TOTAL: %-17.17s";
-               total         "$num";
-        };
-        column {
-                name          "AcceptVol";
-               format        "%9s";
-               value         "bytes($innd_stored_size{$key})";
-               total         "bytes(total(%innd_stored_size))";
-        };
-        column {
-                name          "DupVol";
-               format        "%9s";
-               value         "bytes($innd_duplicated_size{$key})";
-               total         "bytes(total(%innd_duplicated_size))";
-        };
-       column {
-               name          "TotalVol";
-               format        "%9s";
-               value         "bytes($innd_stored_size{$key} +
-                                      $innd_duplicated_size{$key})";
-               total         "bytes(total(%innd_stored_size) +
-                                       total(%innd_duplicated_size))";
-       };
-        column {
-                name          "%Acc";
-               format_name   "%4s";
-               format        "%3d%%";
-               value         "$innd_offered_size{$key} == 0 ? 0 :
-                    $innd_stored_size{$key} / $innd_offered_size{$key} * 100";
-               total         "total(%innd_offered_size) == 0 ? 0 :
-                  total(%innd_stored_size) / total(%innd_offered_size) * 100";
-        };
-       column {
-               name            "Vol/Art";
-               format          "%9s";
-               value           "bytes(($innd_stored_size{$key} +
-                                        $innd_duplicated_size{$key}) /
-                                       ($innd_accepted{$key} +
-                                        $innd_rejected{$key}))";
-               total           "bytes((total(%innd_stored_size) +
-                                        total(%innd_duplicated_size)) /
-                                     (total(%innd_accepted) +
-                                     total(%innd_rejected)))";
-       };
-        column {
-                name          "Elapsed";
-               format        "%9s";
-               value         "time($innd_seconds{$key})";
-               total         "time(total(%innd_seconds))";
-        };
-       graph {
-               title         "Incoming Volume received by server";
-               type          histo3d;
-               sort          "%innd_stored_size";
-               data {
-                         name    "Accepted Volume";
-                         color   "#0000FF";
-                         value   "%innd_stored_size";
-                };
-               data {
-                         name    "Duplicated Volume";
-                         color   "#FFAF00";
-                         value   "%innd_duplicated_size";
-                };
-       };
-};
-
-section inn_flow {
-        title   "Incoming articles:";
-       data    "%inn_flow";
-       sort    "&DateCompare";
-        column {
-                name          "Date";
-                format        "%-27.27s";
-               value         "$key";
-               format_total  "TOTAL: %-20.20s";
-               total         "time(total(%inn_flow_time))";
-        };
-        column {
-                name          "Articles";
-               format_name   "%8s";
-               value         "$inn_flow{$key}";
-               format        "%8d";
-               total         "total(%inn_flow)";
-        };
-        column {
-                name          "%Arts";
-               format_name   "%8s";
-               value         "$inn_flow{$key} / $inn_flow_total * 100";
-               format        "%7.1f%%";
-               total         "100";
-        };
-        column {
-                name          "Art/sec";
-               format_name   "%7s";
-               value         "$inn_flow{$key} / $inn_flow_time{$key}";
-               format        "%7.2f";
-               total         "total(%inn_flow) / total(%inn_flow_time)";
-        };
-        column {
-                name          "Size";
-               value         "bytes($inn_flow_size{$key})";
-               format        "%9s";
-               total         "bytes(total(%inn_flow_size))";
-        };
-        column {
-                name          "%Size";
-               format_name   "%7s";
-               value         "$inn_flow_size{$key} /
-                                          total(%inn_flow_size) * 100";
-               format        "%6.1f%%";
-               total         "100";
-        };
-        column {
-                name          "KB/sec";
-               format_name   "%7s";
-               value         "$inn_flow_size{$key} /
-                                      $inn_flow_time{$key} / 1024";
-               format        "%7.2f";
-               total         "total(%inn_flow_size) /
-                                       total(%inn_flow_time) / 1024";
-        };
-       graph {
-               title         "Incoming articles";
-               type          histo;
-               data {
-                         name    "Hours";
-                         value   "%inn_flow_labels";
-                };
-               data {
-                         name    "Art/sec";
-                         factor  3600;
-                         value   "%inn_flow";
-                };
-        };
-       graph {
-               title         "Incoming articles (size)";
-               type          histo;
-               data {
-                         name    "Hours";
-                         value   "%inn_flow_labels";
-                };
-               data {
-                         name    "Kb/sec";
-                         factor  3686400;   # 3600 * 1024
-                         value   "%inn_flow_size";
-                };
-        };
-};
-
-section cnfsstat {
-        title   "CNFS buffer status:";
-        data    "%cnfsstat";
-        column {
-                name          "Buffer";
-                format        "%-13.13s";
-                value         "$key";
-                format_total  "TOTAL: %-6.6s";
-                total         "$num";
-        };
-        column {
-                name          "Class";
-                format        "%-13.13s";
-                value         "$cnfsstat{$key}";
-                format_total  "-%12s";
-                total         "";
-        };
-        column {
-                name          "Size";
-                format        "%9s";
-                value         "bytes($cnfsstat_size{$key})";
-                total         "bytes(total(%cnfsstat_size))";
-        };
-        column {
-                name          "Used";
-                format        "%9s";
-                value         "bytes($cnfsstat_used{$key})";
-                total         "bytes(total(%cnfsstat_used))";
-        };
-        column {
-                name          "%Used";
-                format_name   "%7s";
-                value         "$cnfsstat_used{$key} /
-                                       $cnfsstat_size{$key} * 100";
-                format        "%6.1f%%";
-                total         "total(%cnfsstat_used) /
-                                       total(%cnfsstat_size) * 100";
-        };
-        column {
-                name          "Cycles";
-                format_name   "%6s";
-                format        "%6d";
-                value         "$cnfsstat_cycles{$key}";
-                total         "total(%cnfsstat_cycles)";
-        };
-        column {
-                name          "KB/sec";
-                format_name   "%7s";
-                value         "$cnfsstat_rate{$key} /
-                                       $cnfsstat_samples{$key} / 1024";
-                format        "%7.2f";
-                total         "total(%cnfsstat_rate) /
-                                       total(%cnfsstat_samples) / 1024";
-        };
-        column {
-                name          "Days";
-                format_name   "%8s";
-                value         "$cnfsstat_size{$key} /
-                                 ($cnfsstat_rate{$key} /
-                                    $cnfsstat_samples{$key}) / 86400";
-                format        "%8.2f";
-                format_total  "%7s-";
-                total         "";
-        };
-};
-
-section inn_unwanted {
-        title   "Sites sending bad articles:";
-       data    "%inn_badart";
-       sort    "$inn_badart{$b} <=> $inn_badart{$a}";
-       numbering true;
-        column {
-                name          "Server";
-                format        "%-23.23s";
-               value         "$key";
-               format_total  "TOTAL: %-16.16s";
-               total         "$num";
-        };
-        column {
-                name          "Total";
-                format_name   "%6s";
-                format        "%6d";
-               value         "$inn_badart{$key}";
-               total         "total(%inn_badart)";
-        };
-        column {
-                name          "Group";
-                format_name   "%6s";
-                format        "%6d";
-               value         "$inn_uw_ng_s{$key}";
-               total         "total(%inn_uw_ng_s)";
-        };
-        column {
-                name          "Dist";
-                format_name   "%5s";
-                format        "%5d";
-               value         "$inn_uw_dist_s{$key}";
-               total         "total(%inn_uw_dist_s)";
-        };
-        column {
-                name          "Duplic";
-                format_name   "%6s";
-                format        "%6d";
-               value         "$inn_duplicate{$key}";
-               total         "total(%inn_duplicate)";
-        };
-        column {
-                name          "Unapp";
-                format_name   "%5s";
-                format        "%5d";
-               value         "$inn_unapproved{$key}";
-               total         "total(%inn_unapproved)";
-        };
-        column {
-                name          "TooOld";
-                format_name   "%6s";
-                format        "%6d";
-               value         "$inn_tooold{$key}";
-               total         "total(%inn_tooold)";
-        };
-        column {
-                name          "Site";
-                format_name   "%4s";
-                format        "%4d";
-               value         "$inn_uw_site{$key}";
-               total         "total(%inn_uw_site)";
-        };
-        column {
-                name          "Line";
-                format_name   "%4s";
-                format        "%4d";
-               value         "$inn_linecount{$key}";
-               total         "total(%inn_linecount)";
-        };
-        column {
-                name          "Other";
-                format_name   "%5s";
-                format        "%5d";
-               value         "$innd_others{$key}";
-               total         "total(%innd_others)";
-        };
-};
-
-section inn_unwanted_group {
-        title   "Unwanted newsgroups:";
-       top     20; # default 'top' value or use 'top_text' and 'top_html'
-                    # to specify different values for text and HTML reports.
-       data    "%inn_uw_ng";
-       sort    "$inn_uw_ng{$b} <=> $inn_uw_ng{$a}";
-        column {
-                name          "Newsgroup";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$inn_uw_ng{$key}";
-               total         "total(%inn_uw_ng)";
-        };
-};
-
-section inn_unwanted_dist {
-        title   "Unwanted distributions:";
-       top     20;
-       data    "%inn_uw_dist";
-       sort    "$inn_uw_dist{$b} <=> $inn_uw_dist{$a}";
-        column {
-                name          "Distribution";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$inn_uw_dist{$key}";
-               total         "total(%inn_uw_dist)";
-        };
-};
-
-section inn_unwanted_unapp {
-        title   "Supposedly-moderated groups with unmoderated postings:";
-       top     20;
-       data    "%inn_unapproved_g";
-       sort    "$inn_unapproved_g{$b} <=> $inn_unapproved_g{$a}";
-        column {
-                name          "Groups";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$inn_unapproved_g{$key}";
-               total         "total(%inn_unapproved_g)";
-        };
-};
-
-section inn_unwanted_path {
-        title   "Unwanted sites in Path:";
-       top     20;
-       data    "%inn_site_path";
-       sort    "$inn_site_path{$b} <=> $inn_site_path{$a}";
-        column {
-                name          "Site";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$inn_site_path{$key}";
-               total         "total(%inn_site_path)";
-        };
-};
-
-section innd_perl {
-        title   "INND Perl filter:";
-       top     20;
-       data    "%innd_filter_perl";
-       sort    "$innd_filter_perl{$b} <=> $innd_filter_perl{$a}";
-        column {
-                name          "Reason";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$innd_filter_perl{$key}";
-               total         "total(%innd_filter_perl)";
-        };
-};
-
-section innd_python {
-        title   "INND Python filter:";
-       top     20;
-       data    "%innd_filter_python";
-       sort    "$innd_filter_python{$b} <=> $innd_filter_python{$a}";
-        column {
-                name          "Reason";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$innd_filter_python{$key}";
-               total         "total(%innd_filter_python)";
-        };
-};
-
-section nocem {
-        title   "NoCeM on Spool:";
-       data    "%nocem_goodsigs";
-       sort    "$nocem_goodsigs{$b} <=> $nocem_goodsigs{$a}";
-       column {
-               name            "Id";
-                       format          "%-47.47s";
-                value          "$key";
-               format_total    "TOTAL: %-40.40s";
-                total          "$num";
-       };
-       column {
-               name            "Good";
-               format          "%7s";
-               value           "$nocem_goodsigs{$key}";
-                total          "total(%nocem_goodsigs)";
-       };
-       column {
-               name            "Bad";
-               format          "%7s";
-                value          "$nocem_badsigs{$key}";
-               total           "total(%nocem_badsigs)";
-       };
-       column {
-               name            "Unique";
-               format          "%7s";
-               value           "$nocem_newids{$key}";
-               total           "total(%nocem_newids)";
-       };
-       column {
-               name            "Total";
-               format          "%7s";
-               value           "$nocem_totalids{$key}";
-               total           "total(%nocem_totalids)";
-       };
-};
-
-section innd_no_permission {
-       title   "INND no permission servers:";
-       data    "%innd_no_permission";
-       sort    "$innd_no_permission{$b} <=> $innd_no_permission{$a}";
-       column {
-               name            "System";
-               format          "%-71.71s";
-               value           "$key";
-               format_total    "TOTAL: %-64.64s";
-               total           "$num";
-       };
-       column {
-               name            "Conn";
-               format_name     "%7s";
-               format          "%7d";
-               value           "$innd_no_permission{$key}";
-               total           "total(%innd_no_permission)";
-       };
-};
-
-section innd_max_conn {
-        title   "Too many incoming connections (innd):";
-       data    "%innd_max_conn";
-       sort    "$innd_max_conn{$b} <=> $innd_max_conn{$a}";
-        column {
-                name          "Server";
-                format        "%-70.70s";
-               value         "$key";
-               format_total  "TOTAL: %-63.63s";
-               total         "$num";
-        };
-        column {
-                name          "Conn";
-               format_name   "%8s";
-                format        "%8d";
-               value         "$innd_max_conn{$key}";
-               total         "total(%innd_max_conn)";
-        };
-};
-
-section innd_too_many_connects_per_minute {
-       title   "INND too many connects per minute:";
-       data    "%innd_too_many_connects_per_minute";
-       sort    "$innd_too_many_connects_per_minute{$b} <=>
-                 $innd_too_many_connects_per_minute{$a}";
-       column {
-               name            "System";
-               format          "%-71.71s";
-               value           "$key";
-               format_total    "TOTAL: %-64.64s";
-               total           "$num";
-       };
-       column {
-               name            "Conn";
-               format_name     "%7s";
-               format          "%7d";
-               value           "$innd_too_many_connects_per_minute{$key}";
-               total           "total(%innd_too_many_connects_per_minute)";
-       };
-};
-
-section innd_misc {
-        title   "INND misc events:";
-       data    "%innd_misc";
-       sort    "$innd_misc{$b} <=> $innd_misc{$a}";
-        column {
-                name          "Events";
-                format        "%-71.71s";
-               value         "$key";
-               format_total  "TOTAL: %-64.64s";
-               total         "$num";
-        };
-        column {
-                name          "Count";
-                format_name   "%7s";
-                format        "%7d";
-               value         "$innd_misc{$key}";
-               total         "total(%innd_misc)";
-        };
-};
-
-section innd_misc_stat {
-        title   "Miscellaneous innd statistics:";
-       data    "%innd_misc_stat";
-       sort    "$innd_misc_stat{$b} <=> $innd_misc_stat{$a}";
-       double  true;
-       top     10;
-       #numbering true;
-        column {
-               primary       true;
-                name          "Event";
-               format        "%-69.69s";
-               value         "$key1";
-               format_total  "TOTAL: %-62.62s";
-               total         "$num";
-        };
-        column {
-                name          "Server";
-               format        "  %-67.67s";
-               value         "$key2";
-               total         "$num";
-               format_total  "TOTAL: %-60.60s";
-        };
-        column {
-                name          "Number";
-               format_name   "%9s";
-               format        "%9d";
-               value         "$innd_misc_stat{$key1}{$key2}";
-               total         "total(%innd_misc_stat)";
-        };
-};
-
-section innfeed_connect {
-       title   "Outgoing Feeds (innfeed) by Articles:";
-       data    "%innfeed_offered";
-       sort    "$innfeed_accepted{$b} <=> $innfeed_accepted{$a}";
-       numbering true;
-        column {
-                name          "Server";
-               format        "%-18.18s";
-               value         "$key";
-               format_total  "TOTAL: %-11.11s";
-               total         "$num";
-        };
-        column {
-                name          "Offered";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innfeed_offered{$key}";
-               total         "total(%innfeed_offered)";
-        };
-        column {
-                name          "Taken";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innfeed_accepted{$key}";
-               total         "total(%innfeed_accepted)";
-        };
-        column {
-                name          "Refused";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innfeed_refused{$key}";
-               total         "total(%innfeed_refused)";
-        };
-        column {
-                name          "Reject";
-               format_name   "%6s";
-               format        "%6d";
-               value         "$innfeed_rejected{$key}";
-               total         "total(%innfeed_rejected)";
-        };
-        column {
-                name          "Miss";
-               format_name   "%6s";
-               format        "%6d";
-               value         "$innfeed_missing{$key}";
-               total         "total(%innfeed_missing)";
-        };
-        column {
-                name          "Spool";
-               format_name   "%7s";
-               format        "%7d";
-               value         "$innfeed_spooled{$key}";
-               total         "total(%innfeed_spooled)";
-        };
-        column {
-                name          "%Took";
-               format_name   "%5s";
-               format        "%3d%%";
-               value         "$innfeed_offered{$key} == 0 ? 0 :
-                      $innfeed_accepted{$key} / $innfeed_offered{$key} * 100";
-               total         "total(%innfeed_offered) == 0 ? 0 :
-                    total(%innfeed_accepted) / total(%innfeed_offered) * 100";
-        };
-        column {
-                name          "Elapsed";
-               format_name   "%8s";
-               format        "%9s";
-               value         "time($innfeed_seconds{$key})";
-               total         "time(total(%innfeed_seconds))";
-        };
-       graph {
-               title         "Outgoing feeds (innfeed) by Articles";
-               type          histo3d;
-               sort          "%innfeed_accepted";
-               data {
-                         name    "Accepted";
-                         color   "#0000FF";
-                         value   "%innfeed_accepted";
-                };
-               data {
-                         name    "Refused";
-                         color   "#FFAF00";
-                         value   "%innfeed_refused";
-                };
-               data {
-                         name    "Rejected";
-                         color   "#FF0000";
-                         value   "%innfeed_rejected";
-                };
-               data {
-                         name    "Missing";
-                         color   "#00FF00";
-                         value   "%innfeed_missing";
-                };
-               data {
-                         name    "Spooled";
-                         color   "#AF00FF";
-                         value   "%innfeed_spooled";
-                };
-       };
-};
-
-section innfeed_volume {
-       title   "Outgoing Feeds (innfeed) by Volume:";
-       data    "%innfeed_offered";
-       sort    "$innfeed_accepted_size{$b} <=> $innfeed_accepted_size{$a}";
-       numbering true;
-       column {
-               name            "Server";
-               format          "%-17.17s";
-               value           "$key";
-               format_total    "TOTAL: %-10.10s";
-               total           "$num";
-       };
-       column {
-               name            "AcceptVol";
-               format          "%9s";
-               value           "bytes($innfeed_accepted_size{$key})";
-               total           "bytes(total(%innfeed_accepted_size))";
-       };
-       column {
-               name            "RejectVol";
-               format          "%9s";
-               value           "bytes($innfeed_rejected_size{$key})";
-               total           "bytes(total(%innfeed_rejected_size))";
-       };
-       column {
-               name            "TotalVol";
-               format          "%9s";
-               value           "bytes($innfeed_accepted_size{$key} +
-                                      $innfeed_rejected_size{$key})";
-               total           "bytes(total(%innfeed_accepted_size) +
-                                       total(%innfeed_rejected_size))";
-       };
-       column {
-               name            "Volume/sec";
-               format_name     "%11s";
-               format          "%9s/s";
-               value           "bytes(($innfeed_accepted_size{$key} +
-                                        $innfeed_rejected_size{$key}) /
-                                    $innfeed_seconds{$key})";
-               total           "bytes((total(%innfeed_accepted_size) +
-                                        total(%innfeed_rejected_size)) /
-                                    total(%innfeed_seconds))";
-       };
-       column {
-               name            "Vol/Art";
-               format          "%9s";
-               value           "bytes(($innfeed_accepted_size{$key} +
-                                        $innfeed_rejected_size{$key}) /
-                                       ($innfeed_accepted{$key} +
-                                        $innfeed_rejected{$key}))";
-               total           "bytes((total(%innfeed_accepted_size) +
-                                        total(%innfeed_rejected_size)) /
-                                     (total(%innfeed_accepted) +
-                                     total(%innfeed_rejected)))";
-       };
-       column {
-               name            "Elapsed";
-               format          "%9s";
-               value           "time($innfeed_seconds{$key})";
-               total           "time(total(%innfeed_seconds))";
-       };
-       graph {
-               title           "Outgoing feeds (innfeed) by Volume";
-               type            histo3d;
-               sort            "%innfeed_accepted_size";
-               data {
-                       name    "Accepted";
-                       color   "#0000FF";
-                       value   "%innfeed_accepted_size";
-               };
-               data {
-                       name    "Rejected";
-                       color   "#FFAF00";
-                       value   "%innfeed_rejected_size";
-               };
-       };
-};
-
-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}||0) +
-                               ($nnrpd_post_error{$key}||0)";
-               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}||0) +
-                              ($nnrpd_dom_post_error{$key}||0)";
-                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/samples/innwatch.ctl b/samples/innwatch.ctl
deleted file mode 100644 (file)
index 39195e7..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-##  $Revision: 4351 $
-##  innwatch.ctl -- control file for innwatch.
-##  Indicates what to run to test the state of the news system, and what
-##  to do about it.  Format:
-##     !state!when!command!test!limit!command!reason/comment
-##  where
-##     <!>             Delimiter; pick from [,:@;?!]
-##     <state>         State to enter if true.
-##     <when>          States we must be in to match.
-##     <command>       Command to run to test condition.
-##     <test>          Operator to use in test(1) command.
-##     <limit>         Value to test against.
-##     <command>       Command for innwatch to perform; use exit,
-##                     flush, go, pause, shutdown, skip, or throttle.
-##     <reason>        Used in ctlinnd command (if needed).
-
-##  First, just exit innwatch if innd has gone away.
-!!! test -f ${LOCKS}/innd.pid && echo 0 || echo 1 ! eq ! 1 ! exit ! innd dead
-
-##  If another innwatch has started, exit.
-!!! cat ${LOCKS}/LOCK.${PROGNAME} ! ne ! $$ ! exit ! innwatch replaced
-
-##  Next test the load average.  Above first threshold pause, above higher
-##  threshold throttle, below restart limit undo whatever was done.
-!load!load hiload! uptime | tr -d ,. | awk '{ print $(NF - 2) }' ! lt ! ${INNWATCHLOLOAD} ! go ! loadav
-!hiload!+ load! uptime | tr -d ,. | awk '{ print $(NF - 2) }' ! gt ! ${INNWATCHHILOAD} ! throttle ! loadav
-!load!+! uptime | tr -d ,. | awk '{ print $(NF - 2) }' ! gt ! ${INNWATCHPAUSELOAD} ! pause ! loadav
-##
-## Uncomment these to keep overchan backlog in check.  Assumes your overchan
-## feed is named 'overview!'.
-#::overblog:ctlinnd feedinfo overview!|awk 'NR==1{print $7}':lt:100000:go:overviewbacklog
-#:overblog:+:ctlinnd feedinfo overview!|awk 'NR==1{print $7}':gt:400000:throttle:overviewbacklog
-##
-
-##  If load is OK, check space (and inodes) on various filesystems
-!!! ${INNDF} . ! lt ! ${INNWATCHSPOOLSPACE} ! throttle ! No space (spool)
-!!! ${INNDF} ${BATCH} ! lt ! ${INNWATCHBATCHSPACE} ! throttle ! No space (newsq)
-!!! ${INNDF} ${PATHDB} ! lt ! ${INNWATCHLIBSPACE} ! throttle ! No space (newslib)
-!!! ${INNDF} -i . ! lt ! ${INNWATCHSPOOLNODES} ! throttle ! No space (spool inodes)
-!!! ${INNDF} ${OVERVIEWDIR} ! lt ! ${INNWATCHSPOOLSPACE} ! throttle ! No space (overview)
diff --git a/samples/moderators b/samples/moderators
deleted file mode 100644 (file)
index b85c6e4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-##  $Id: moderators 7448 2005-12-11 22:21:06Z eagle $
-##
-##  moderators - Mailing addresses for moderators.
-##
-##  Whenever possible, the master moderator database at moderators.isc.org
-##  should be used rather than adding specific entries to this file.  The
-##  master database will list any publically propagated moderated group;
-##  changes should be sent to moderators-request@isc.org.
-##
-##  Exceptions listed in this file are mostly hierarchies for which the
-##  master database isn't accurate or updated quickly enough.  Local
-##  moderated newsgroups can also be added to this file.
-##
-##  Format:
-##     <newsgroup>:<pathname>
-##
-##     <newsgroup>     Shell-style newsgroup pattern or specific newsgroup
-##     <pathname>      Mail address, "%s" becomes newgroup name with dots
-##                     changed to dashes.
-##
-##  The first matching entry is used.
-
-## Public hierarchies with exceptions.
-fido7.*:%s@fido7.ru
-ffm.*:%s@moderators.arcornews.de
-fj.*:%s@moderators.fj-news.org
-medlux.*:%s@news.medlux.ru
-nl.*:%s@nl.news-admin.org
-relcom.*:%s@moderators.relcom.ru
-ukr.*:%s@sita.kiev.ua
-
-## Direct all other public hierarchies to the master moderator database.
-*:%s@moderators.isc.org
diff --git a/samples/motd.news b/samples/motd.news
deleted file mode 100644 (file)
index ac880ea..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Sample MOTD file. Any text you put in here will be returned
-to the news reader when it issues the LIST MOTD command. It is not 
-an error if this file does not exist nor if it is empty.
diff --git a/samples/news2mail.cf b/samples/news2mail.cf
deleted file mode 100644 (file)
index 4b89b01..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Sample config file for news2mail. Format is:
-#
-#      mailing-list-name       address
-#
-#
-# In newsfeeds put an entry like:
-#
-#      n2m!:!*:Tc,Ac,Wn*:/usr/news/bin/news2mail
-# 
-# and for each mailing list have an entry list:
-#
-#      news-software@localhost.our.domain.com:rec.pets.redants.*:Tm:n2m!
-#
-# The site name used in the newfeeds entry for a mailing list (above 
-# ``news-software@localhost.our.domain.com'') must be the same as the first
-# field in an entry in this file. It is what is put into the ``To'' header of 
-# mailed messages.
-#
-#
-news-software@localhost.our.domain.com news-software@real-host.somewhere.com
diff --git a/samples/newsfeeds.in b/samples/newsfeeds.in
deleted file mode 100644 (file)
index bc05ddd..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-##  $Id: newsfeeds.in 7741 2008-04-06 09:51:47Z iulius $
-##
-##  newsfeeds - determine where Usenet articles get sent
-##
-##  Format:
-##     site[/exclude,exclude...]\
-##             :pattern,pattern...[/distrib,distrib...]\
-##             :flag,flag...\
-##             :param
-##
-##  This file is complicated -- see newsfeeds(5) for full details.
-
-##  The ME feed entry is special magic.
-##
-##  "/exclude" entries for this feed entry will cause INN to reject all
-##  articles that have passed through those listed sites (by matching
-##  Path: entries).  There are some "pseudo-sites" in general use that can
-##  be listed as exclusions to reject specific types of 3rd-party cancel
-##  messages (see the "Cancel FAQ" in news.admin.net-abuse.usenet):
-##
-##     cyberspam       Cancels for spam, munged articles, binaries
-##     spewcancel      Cancels for munged articles and runaway gateways
-##     bincancel       Cancels for binary postings to non-binary groups
-##      udpcancel       Cancels to force sites to enforce antispam policies
-##
-##  The "pattern" field for this feed entry gives the initial subscription
-##  list for all other feeds specified in this file.  These patterns are
-##  *prepended* to all other feed patterns.  Using this feature is
-##  confusing and mildly discouraged; make sure you understand the man
-##  page before using it.
-##
-##  "/distrib" for this feed entry specifies what distributions the server
-##  will accept.  If any distributions are listed there, the server will
-##  accept only articles with those distributions.  If all the
-##  distributions listed are negated (starting with !), then the server
-##  will only accept articles without those distributions.
-##
-##  For the ME line (and the ME line *only*), patterns affect *outgoing*
-##  feeds and distributions affect *incoming* feeds.
-
-# Empty default subscription list, reject all incoming articles with a
-# distribution of "local" or "collabra-internal," accept all others.
-ME:!*/!local,!collabra-internal::
-
-# The same as the above, but would reject all posts that have
-# news.example.com in the path (posts passing through that site).
-#ME/news.example.com:!*/!local,!collabra-internal::
-
-# The special feed that handles all newsgroup control messages.  Only
-# disable this if you want to ignore all newsgroup control messages; INN
-# no longer handles any control messages except cancel internally.
-controlchan!\
-       :!*,control,control.*,!control.cancel\
-       :Tc,Wnsm:@prefix@/bin/controlchan
-
-##  Uncomment if you're using innfeed.  This feed tells INN how to run
-##  innfeed, and then every site you're feeding with innfeed has a
-##  flag of Tm and an argument of "innfeed!" to funnel into this feed.
-##  The feed pattern for innfeed should *always* be "!*"; don't ever
-##  feed articles directly into innfeed.
-##
-##  Add "-y" as an option to startinnfeed to use the name of each feed as
-##  the name of the host to feed articles to; without "-y" an innfeed.conf
-##  file is needed.
-
-# innfeed funnel master.
-#innfeed!\
-#      :!*\
-#      :Tc,Wnm*:@prefix@/bin/startinnfeed
-
-##  Only uncomment this feed if both enableoverview and useoverchan are
-##  set to true in inn.conf.  By default, innd will write out overview
-##  internally and doesn't need or want this feed, but useoverchan can
-##  optionally be set to true and this feed uncommented to move those
-##  operations out of innd's main loop.
-
-# News overview.
-#overview!:*:Tc,WnteO:@prefix@/bin/overchan
-
-
-##  OUTGOING NORMAL FEED EXAMPLES
-
-# A real-time feed through innfeed.  Don't send articles with a distribution
-# of "foo", since those articles are internal.
-# Note that control messages will be sent even though "!control,!control.*"
-# is specified.  It is useful not to forget that pattern since control
-# messages for local.* would still be sent with "*,@local.*" only.
-#news.uu.net/uunet\
-#      :*,!junk,!control,!control.*/!foo\
-#      :Tm:innfeed!
-
-# Create a batch file in @SPOOLDIR@/outgoing for all articles
-# that haven't already passed through nic.near.net.  The batch file will
-# be named nic.near.net, the default file name, and either nntpsend or
-# send-nntp can send articles from that spool file.
-#nic.near.net\
-#      :*,!junk,!control,!control.*/!foo\
-#      :Tf,Wnm:
-
-# A UUCP feed, where we try to keep the "batching" between 4 KB and 1 KB.
-# You can use send-uucp(8) to process these batch files.
-#ihnp4\
-#      :*,!junk,!control,!control.*/!foo\
-#      :Tf,Wnb,B4096/1024:
-
-
-##  OUTGOING SPECIAL FEED EXAMPLES
-
-# Accumulate Path header statistics.  See ninpaths(8) for more details on
-# how to set this up.
-#inpaths!:*:Tc,WP:@prefix@/bin/ninpaths -p -d @LOGDIR@/path/inpaths.%d
-
-# Feed all moderated source postings to an archiver.
-#source-archive!:!*,*sources*,!*wanted*,!*.d\
-#      :Tc,Wn:@prefix@/bin/archive -f -i @SPOOLDIR@/archive/INDEX
-
-# News to mail gateway.  Similar to innfeed, this uses a master feed and
-# then individual feeds for every separate address that news is being
-# gated to.  This sends all posts to rec.pets.redants.* to the address
-# news-software@example.com.
-#news2mail!:!*:Tc,Ac,Wn*:@prefix@/bin/news2mail
-#news-software@example.com:rec.pets.redants.*:Tm:news2mail!
-
-# Capture all local postings (with a distribution of "foo" and no more
-# than two sites in the Path) using a local program (that doesn't come with
-# INN).
-#capture\
-#      :*/foo\
-#      :Tp,H2:/usr/local/bin/capture %s
diff --git a/samples/newsgroups.minimal b/samples/newsgroups.minimal
deleted file mode 100644 (file)
index 2aeb724..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-control                        Various control messages (no posting).
-control.cancel         Cancel messages (no posting).
-control.checkgroups    Hierarchy check control messages (no posting).
-control.newgroup       Newsgroup creation control messages (no posting).
-control.rmgroup                Newsgroup removal control messages (no posting).
-junk                   Unfiled articles (no posting).
diff --git a/samples/nnrpd.py b/samples/nnrpd.py
deleted file mode 100644 (file)
index 0094836..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-##  $Id: nnrpd.py 7897 2008-06-22 18:04:31Z iulius $
-##
-##  This module supplies stub Python functions corresponding to the ones
-##  provided by nnrpd.  It is not used by the server; it is only here so
-##  that you can test your filter scripts before loading.
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-
-from types import *
-
-def set_auth_hook(anObject):
-    if type(anObject) == InstanceType:
-        print "** set_auth_hook for " + repr(anObject)
-    else:
-        print "** <Your object is not a class instance.>"
-
-def syslog(level, message):
-    print "-- syslog level: %s message: %s" % (level, message)
diff --git a/samples/nnrpd.track b/samples/nnrpd.track
deleted file mode 100644 (file)
index edec23f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-##  $Revision: 513 $    
-##  nnrpd.track - file to specify which hosts to be tracked by nnrpd
-##  Format:
-##      <host>:<identity>
-##  Where:
-##      <host>          Wildcard name or IP address
-##      <identity>      String to be displayed in the logs
-##
-## By adding a host to this file, it will be tracked using the
-## nnrpd tracking system if enabled in inn.conf(5). Each read/post
-## will have an entry logged with the <identity> in the log message
-##
-# nasty.foo.com:nasty@foo.com
-# *.bar.com:VeryNastyClient
diff --git a/samples/nnrpd_access.pl.in b/samples/nnrpd_access.pl.in
deleted file mode 100644 (file)
index bc3d8c9..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-##
-##  Sample code for the nnrpd Perl access hooks.
-
-##  This file is loaded when a perl_access: parameter is reached in
-##  readers.conf.  If it defines a sub named access, which will be
-##  called during processing of a perl_access: parameter. Attributes
-##  about the connection are passed to the program in the %attributes
-##  global variable.  It should return a hash containing
-##  parameter-value pairs for the access group. If there is a problem,
-##  nnrpd will die and syslog the exact error.
-
-##  The default behavior of the following code is to look for nnrp.access
-##  in INN's configuration file directory and to attempt to implement about
-##  the same host-based access control as the previous nnrp.access code in
-##  earlier versions of INN.  This may be useful for backward compatibility.
-
-##  This file cannot be run as a standalone script, although it would be
-##  worthwhile to add some code so that it could so that one could test the
-##  results of various authentication and connection queries from the
-##  command line.  The #! line at the top is just so that fixscript will
-##  work.
-
-# This function is called when perl_access: is reached in readers.conf.
-# For details on all the information passed to it, see
-# ~news/doc/hook-perl.
-sub access {
-   &loadnnrp($inn::newsetc . '/nnrp.access');
-   return &checkhost($attributes{hostname}, $attributes{ipaddress});
-}
-
-# Called at startup, this loads the nnrp.access file and converts it into a
-# convenient internal format for later queries.
-sub loadnnrp {
-    my $file = shift;
-    my ($block, $perm, $user, $pass);
-
-    open (ACCESS, $file) or die "Could not open $file: $!\n";
-    local $_;
-    while (<ACCESS>) {
-        my %tmp;
-
-        chomp;
-        s/\#.*//;
-        ($block, $perm, $user, $pass, $tmp{groups}) = split /:/;
-        next unless (defined $tmp{groups});
-
-        # We don't support username/password entries, so be safe.
-        next if ($user || $pass);
-
-        # Change the wildmat pattern to a regex (this isn't thorough, as
-        # some ranges won't be converted properly, but it should be good
-        # enough for this purpose).
-        if ($block !~ m%^(?:\d+\.){3}\d+/\d+$%) {
-            $block =~ s/\./\\./g;
-            $block =~ s/\?/./g;
-            $block =~ s/\*/.*/g;
-        }
-        $tmp{block} = $block;
-
-        $tmp{canread} = ($perm =~ /r/i);
-        $tmp{canpost} = ($perm =~ /p/i);
-
-        unshift(@hosts, { %tmp });
-    }
-    close ACCESS;
-}
-
-# Given the hostname and IP address of a connecting host, use our @hosts
-# array constructed from nnrp.access and see what permissions that host has.
-sub checkhost {
-    my ($host, $ip) = @_;
-    my %return_hash;
-    my $key;
-    for $key (@hosts) {
-        my ($read, $post) = ($key->{canread}, $key->{canpost});
-
-        # First check for CIDR-style blocks.
-        if ($key->{block} =~ m%^(\d+\.\d+\.\d+\.\d+)/(\d+)$%) {
-            my $block = unpack('N', pack('C4', split(/\./, $1)));
-            my $mask = (0xffffffff << (32 - $2)) & 0xffffffff;
-            $block = $block & $mask;
-            my $packedip = unpack('N', pack('C4', split(/\./, $ip)));
-            if (($packedip & $mask) == $block) {
-                if ($read) {
-                    $return_hash{"read"} = $key->{groups};
-                }
-                if ($post) {
-                    $return_hash{"post"} = $key->{groups};
-                }
-                return %return_hash;
-            }
-        }
-
-        if ($ip =~ /^$key->{block}$/) {
-            if ($read) {
-                $return_hash{"read"} = $key->{groups};
-            }
-            if ($post) {
-                $return_hash{"post"} = $key->{groups};
-            }
-            return %return_hash;
-        }
-
-        if ($host =~ /^$key->{block}$/) {
-            if ($read) {
-                $return_hash{"read"} = $key->{groups};
-            }
-            if ($post) {
-                $return_hash{"post"} = $key->{groups};
-            }
-            return %return_hash;
-        }
-    }
-
-    # If we fell through to here, nothing matched, so we should deny
-    # permissions.
-    return %return_hash;
-}
diff --git a/samples/nnrpd_access.py b/samples/nnrpd_access.py
deleted file mode 100644 (file)
index 23cd0c2..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-##  $Id: nnrpd_access.py 7906 2008-06-23 05:44:49Z iulius $
-##
-##  This is a sample access module for the Python nnrpd hook.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The perl_access: parameter in readers.conf is used to load this script.
-##
-##  An instance of ACCESS class is passed to nnrpd via the set_auth_hook()
-##  function imported from nnrpd.  The following methods of that class
-##  are known to nnrpd:
-##
-##  __init__()                  - Use this method to initialize your
-##                                general variables or open a common
-##                                database connection.  May be omitted.
-##  access_init()               - Init function specific to access
-##                                control.  May be omitted.
-##  access(attributes)          - Called when a python_access
-##                                statement is reached in the
-##                                processing of readers.conf.  Returns
-##                                a dictionary of values representing
-##                                statements to be included in an
-##                                access group.
-##  access_close()              - Called on nnrpd termination.  Save
-##                                your state variables or close a
-##                                database connection.  May be omitted.
-##
-##  If there is a problem with return codes from any of these methods, then nnrpd
-##  will die and syslog the exact reason.
-##
-##  There are also a few Python functions defined in nnrpd:
-##
-##  set_auth_hook()             - Called by nnrpd as this module is loaded.
-##                              It is used to pass a reference to an
-##                              instance of authentication class to nnrpd.
-##  syslog()                    - An equivalent replacement for regular syslog.
-##                              One consideration for using it is to
-##                              uniform nnrpd logging.
-
-##  Sample access class.  It defines all access methods known to nnrpd.
-class ACCESS:
-    """Provide access callbacks to nnrpd."""
-
-    def __init__(self):
-        """This is a good place to initialize variables or open a
-           database connection."""
-        syslog('notice', 'nnrpd access class instance created')
-
-    def access_init(self):
-        """Called when this script is initialized."""
-        pass
-
-    def access(self, attributes):
-        """Called when python_access: is encountered in readers.conf."""
-
-       # Just for debugging purposes.
-       syslog('notice', 'n_a access() invoked: hostname %s, ipaddress %s, interface %s, user %s' % (\
-               attributes['hostname'], \
-               attributes['ipaddress'], \
-               attributes['interface'], \
-               attributes['user']))
-
-       # Allow newsreading from specific host only.
-        if '127.0.0.1' == str(attributes['ipaddress']):
-            syslog('notice', 'authentication access by IP address succeeded')
-            return {'read':'*', 'post':'*'}
-        else:
-            syslog('notice', 'authentication access by IP address failed')
-            return {'read':'!*', 'post':'!*'}
-
-    def access_close(self):
-        """Called on nnrpd termination."""
-        pass
-
-
-##  The rest is used to hook up the access module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-myaccess = ACCESS()
-
-##  ...and try to hook up on nnrpd.  This would make auth object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(myaccess)
-    syslog('notice', "access module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for access method: %s" % errmsg[0])
diff --git a/samples/nnrpd_access_wrapper.pl.in b/samples/nnrpd_access_wrapper.pl.in
deleted file mode 100644 (file)
index 2a2a388..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Example wrapper nnrpd_access.pl for support of old perl authentication
-# scripts, by Erik Klavon.
-
-# This file contains a sample perl script which can be used to
-# duplicate the behavior of the old nnrpperlauth functionality. This
-# script only supports access control.
-
-# How to use this wrapper:
-# - append your old script to this file with two changes:
-# - rename the old "auth_init" sub to "old_auth_init"
-# - rename the old "authenticate" sub to "old_authenticate"
-
-
-# access
-# This sub modifies the global hash attributes so that it has all the
-# entries required in the old way of doing things, calls
-# old_authenticate, and creates a return hash with the right attributes.
-
-sub access {
-    # Comment this out if you don't need auth_init.
-    old_auth_init();
-
-    $attributes{type} = "connect";
-    my @connect_array = old_authenticate();
-    my %hash;
-
-    # handle max rate
-    if ($connect_array[4]) {
-        # Force perl to make a C string out of this integer, 
-        # or else bad things will happen. Sigh.
-        $hash{"max_rate"} = $connect_array[4] . "\0"; 
-    }
-
-    # handle read boolean, set to wildmat
-    if ($connect_array[1]) {
-        $hash{"read"} = $connect_array[3];
-    }
-
-    # handle post boolean, set to wildmat
-    if ($connect_array[2]) {
-        $hash{"post"} = $connect_array[3];
-    }
-
-    return %hash;    
-}
diff --git a/samples/nnrpd_access_wrapper.py b/samples/nnrpd_access_wrapper.py
deleted file mode 100644 (file)
index bc83012..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-##  $Id: nnrpd_access_wrapper.py 7899 2008-06-22 18:22:07Z iulius $
-##
-##  Example wrapper for support of old Python authentication scripts,
-##  by Erik Klavon. 
-##
-##  This file contains a sample Python script which can be used to
-##  duplicate the behaviour of the old nnrppythonauth functionality.
-##  This script only supports access control.
-##
-##  How to use this wrapper:
-##    - insert your authentication class into this file;
-##    - rename your authentication class OLDAUTH.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The use of this file is *discouraged*.
-
-##  Old AUTH class.
-##  Insert your old auth class here.
-##  Do not include the code which sets the hook.
-
-
-
-
-##  Wrapper ACCESS class.  It creates an instance of the old class and
-##  calls its methods.  Arguments and return values are munged as
-##  needed to fit the new way of doing things.
-
-class MYACCESS:
-    """Provide access callbacks to nnrpd."""
-    def access_init(self):
-        self.old = OLDAUTH()
-
-    def access(self, attributes):
-        attributes['type'] = buffer('connect')
-        perm = (self.old).authenticate(attributes)
-        result = dict([('users','*')])        
-        if perm[1] == 1:
-                result['read'] = perm[3]
-        if perm[2] == 1:
-                result['post'] = perm[3]
-        return result
-
-    def access_close(self):
-        (self.old).close()
-
-
-##  The rest is used to hook up the access module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-myaccess = MYACCESS()
-
-##  ...and try to hook up on nnrpd.  This would make access object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(myaccess)
-    syslog('notice', "access module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for access method: %s" % errmsg[0])
diff --git a/samples/nnrpd_auth.pl.in b/samples/nnrpd_auth.pl.in
deleted file mode 100644 (file)
index bce456f..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-##
-##  Sample code for the nnrpd Perl authentication hooks.
-##
-##  This file is loaded when a perl_auth: parameter is reached in
-##  readers.conf.  If it defines a sub named authenticate, that
-##  function will be called during processing of a perl_auth:
-##  parameter. Attributes about the connection are passed to the
-##  program in the %attributes global variable.  It should return an
-##  array with two elements:
-##
-##  1) NNTP response code.  Should be one of the codes from %authcodes
-##  below to not risk violating the protocol.  
-##  2) An error string to be passed to the client.
-##  Both elements are required.  If there is a problem, nnrpd will die
-##  and syslog the exact error.
-
-##  The code below uses a user database based on CDB_File. It is
-##  provided here as an example of an authentication script.
-
-##  This file cannot be run as a standalone script, although it would be
-##  worthwhile to add some code so that it could so that one could test the
-##  results of various authentication and connection queries from the
-##  command line.  The #! line at the top is just so that fixscript will
-##  work.
-
-use strict;
-use vars qw(%attributes %authcodes %users);
-
-# These codes are a widely implemented de facto standard.
-%authcodes = ('allowed' => 281, 'denied' => 502);
-
-# This sub should perform any initialization work that the
-# authentication stuff needs.
-sub auth_init {
-    require CDB_File;
-    tie (%users, 'CDB_File', $inn::pathdb . '/users.cdb')
-        or warn "Could not open $inn::pathdb/users.cdb for users: $!\n";
-}
-
-# This function is called for authentication requests.  For details on
-# all the information passed to it, see ~news/doc/hook-perl.
-sub authenticate {
-    return &checkuser();
-}
-
-# This function assumes that there's a database tied as %users that
-# contains, keyed by users, a tab-separated list of the password (in
-# crypt format), whether they can post, a wildmat matching what
-# newsgroups they have access to, and the number of bytes per second
-# they're allowed to use. This section of the code only accesses the
-# username and password fields. See the file nnrpd_access.pl for
-# access rights based on the other fields.
-sub checkuser {
-    my $user = $attributes{'username'};
-    my $pass = $attributes{'password'};
-
-    return ($authcodes{denied}, "No username given.")
-        unless defined $users{$user};
-
-    my ($password, $post, $speed, $subscription) = split(/\t/, $users{$user});
-    return ($authcodes{denied}, "Incorrect password.")
-        if (crypt($pass, $password) ne $password);
-
-    return ($authcodes{allowed}, "");
-}
diff --git a/samples/nnrpd_auth.py b/samples/nnrpd_auth.py
deleted file mode 100644 (file)
index 76ca010..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-##  $Id: nnrpd_auth.py 7906 2008-06-23 05:44:49Z iulius $
-##
-##  This is a sample authentication module for the Python nnrpd hook.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The perl_auth: parameter in readers.conf is used to load this script.
-##
-##  An instance of AUTH class is passed to nnrpd via the set_auth_hook()
-##  function imported from nnrpd.  The following methods of that class
-##  are known to nnrpd:
-##
-##  __init__()                  - Use this method to initialize your
-##                                general variables or open a common
-##                                database connection.  May be omitted.
-##  authen_init()               - Init function specific to
-##                                authentication.  May be omitted.
-##  authenticate(attributes)    - Called when a python_auth statement
-##                                is reached in the processing of
-##                                readers.conf.  Returns a response
-##                                code, an error string and an
-##                                optional string to appear in the
-##                                logs as the username.
-##  authen_close()              - Called on nnrpd termination.  Save
-##                                your state variables or close a database
-##                                connection.  May be omitted.
-##
-##  If there is a problem with return codes from any of these methods, then nnrpd
-##  will die and syslog the exact reason.
-##
-##  There are also a few Python functions defined in nnrpd:
-##
-##  set_auth_hook()             - Called by nnrpd as this module is loaded.
-##                              It is used to pass a reference to an
-##                              instance of authentication class to nnrpd.
-##  syslog()                    - An equivalent replacement for regular syslog.
-##                              One consideration for using it is to
-##                              uniform nnrpd logging.
-
-##  Sample authentication class.  It defines all auth methods known to nnrpd.
-class AUTH:
-    """Provide authentication callbacks to nnrpd."""
-
-    def __init__(self):
-        """This is a good place to initialize variables or open a
-           database connection."""
-
-        # Create a list of NNTP codes to respond on connect.
-        self.connectcodes = {   'READPOST':200,
-                                'READ':201,
-                                'AUTHNEEDED':480,
-                                'PERMDENIED':502
-        }
-
-        # Create a list of NNTP codes to respond on authentication.
-        self.authcodes = {  'ALLOWED':281,
-                            'DENIED':502
-        }
-
-        syslog('notice', 'nnrpd authentication class instance created')
-
-    def authen_init(self):
-        """Called when this script is initialized."""
-        pass
-
-    def authenticate(self, attributes):
-        """Called when python_auth: is encountered in readers.conf."""
-
-       # Just for debugging purposes.
-       syslog('notice', 'n_a authenticate() invoked: hostname %s, ipaddress %s, interface %s, user %s' % (\
-               attributes['hostname'], \
-               attributes['ipaddress'], \
-               attributes['interface'], \
-               attributes['user']))
-
-       # Do username password authentication.
-        if 'foo' == str(attributes['user'])  \
-          and 'foo' == str(attributes['pass']):
-            syslog('notice', 'authentication by username succeeded')
-            return (self.authcodes['ALLOWED'], 'No error', 'default_user')
-        else:
-            syslog('notice', 'authentication by username failed')
-            return (self.authcodes['DENIED'], 'Access Denied!')
-
-    def authen_close(self):
-        """Called on nnrpd termination."""
-        pass
-
-
-##  The rest is used to hook up the auth module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-myauth = AUTH()
-
-##  ...and try to hook up on nnrpd.  This would make auth object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(myauth)
-    syslog('notice', "authentication module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for authentication method: %s" % errmsg[0])
diff --git a/samples/nnrpd_auth_wrapper.pl.in b/samples/nnrpd_auth_wrapper.pl.in
deleted file mode 100644 (file)
index 50bd1e7..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Example wrapper nnrpd_auth.pl for support of old perl authentication
-# scripts, by Erik Klavon.
-
-# This file contains a sample perl script which can be used to
-# duplicate the behavior of the old nnrpperlauth functionality. This
-# script only supports authentication.
-
-# How to use this wrapper:
-# - append your old script to this file with two changes:
-# - rename the old "auth_init" sub to "old_auth_init"
-# - rename the old "authenticate" sub to "old_authenticate"
-
-
-# auth_init
-# This sub simply calls old_auth_init
-# Comment this out if you don't need auth_init
-
-sub auth_init {
-    old_auth_init();
-}
-
-
-# authenticate
-# This sub modifies the global hash attributes so that it has all the
-# entries required in the old way of doing things, calls
-# old_authenticate, and transforms the return array into the new
-# format.
-
-sub authenticate {
-    $attributes{type} = "authenticate";
-    my @auth_array = old_authenticate();
-    my @return_array;
-
-    # copy return code
-    $return_array[0] = $auth_array[0];
-
-    # simple error report
-    if ($auth_array[0] != 281) {
-        $return_array[1] = "Perl authentication error!";
-        return @return_array;
-    } else {
-        $return_array[1] = "";
-    }
-
-    return @return_array;
-}
diff --git a/samples/nnrpd_auth_wrapper.py b/samples/nnrpd_auth_wrapper.py
deleted file mode 100644 (file)
index d55d942..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-##  $Id: nnrpd_auth_wrapper.py 7899 2008-06-22 18:22:07Z iulius $
-##
-##  Example wrapper for support of old Python authentication scripts,
-##  by Erik Klavon.
-##
-##  This file contains a sample Python script which can be used to
-##  duplicate the behaviour of the old nnrppythonauth functionality.
-##  This script only supports authentication.
-##
-##  How to use this wrapper:
-##    - insert your authentication class into this file;
-##    - rename your authentication class OLDAUTH.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The use of this file is *discouraged*.
-
-##  Old AUTH class.
-##  Insert your old auth class here.
-##  Do not include the code which sets the hook.
-
-
-
-
-##  Wrapper AUTH class.  It creates an instance of the old class and
-##  calls its methods.  Arguments and return values are munged as
-##  needed to fit the new way of doing things.
-
-class MYAUTH:
-    """Provide auth callbacks to nnrpd."""
-    def authen_init(self):
-        self.old = OLDAUTH()
-
-    def authenticate(self, attributes):
-        attributes['type'] = buffer('authinfo')
-        perm = (self.old).authenticate(attributes)
-        err_str = "No error"
-        if perm[0] == 502:
-                err_str = "Python authentication error!"        
-        return (perm[0],err_str)                
-
-    def authen_close(self):
-        (self.old).close()
-
-
-##  The rest is used to hook up the auth module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-myauth = MYAUTH()
-
-##  ...and try to hook up on nnrpd.  This would make auth object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(myauth)
-    syslog('notice', "authentication module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for authentication method: %s" % errmsg[0])
diff --git a/samples/nnrpd_dynamic.py b/samples/nnrpd_dynamic.py
deleted file mode 100644 (file)
index 139f8b8..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-##  $Id: nnrpd_dynamic.py 7906 2008-06-23 05:44:49Z iulius $
-##
-##  This is a sample dynamic access module for the Python nnrpd hook.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The perl_dynamic: parameter in readers.conf is used to load this script.
-##
-##  An instance of DYNACCESS class is passed to nnrpd via the set_auth_hook()
-##  function imported from nnrpd.  The following methods of that class
-##  are known to nnrpd:
-##
-##  __init__()                  - Use this method to initialize your
-##                                general variables or open a common
-##                                database connection.  May be omitted.
-##  dynamic_init()              - Init function specific to
-##                                authentication.  May be omitted.
-##  dynamic(attributes)         - Called whenever a reader requests either
-##                                read or post access to a
-##                                newsgroup.  Returns None to grant
-##                                access, or a non-empty string (which
-##                                will be reported back to reader)
-##                                otherwise.
-##  dynamic_close()             - Called on nnrpd termination.  Save
-##                                your state variables or close a database
-##                                connection.  May be omitted.
-##
-##  If there is a problem with return codes from any of these methods, then nnrpd
-##  will die and syslog the exact reason.
-##
-##  There are also a few Python functions defined in nnrpd:
-##
-##  set_auth_hook()             - Called by nnrpd as this module is loaded.
-##                              It is used to pass a reference to an
-##                              instance of authentication class to nnrpd.
-##  syslog()                    - An equivalent replacement for regular syslog.
-##                              One consideration for using it is to
-##                              uniform nnrpd logging.
-
-##  Sample dynamic access class.  It defines all dynamic access methods known
-##  to nnrpd.
-class DYNACCESS:
-    """Provide dynamic access callbacks to nnrpd."""
-
-    def __init__(self):
-        """This is a good place to initialize variables or open a
-           database connection."""
-        syslog('notice', 'nnrpd dynamic access class instance created')
-
-    def dynamic_init(self):
-        """Called when this script is initialized."""
-        pass
-
-    def dynamic(self, attributes):
-        """Called when python_dynamic: is reached in the processing of
-           readers.conf and a reader requests either read or post
-           permission for particular newsgroup."""
-
-       # Just for debugging purposes.
-       syslog('notice', 'n_a dynamic() invoked against type %s, hostname %s, ipaddress %s, interface %s, user %s' % (\
-               attributes['type'], \
-               attributes['hostname'], \
-               attributes['ipaddress'], \
-               attributes['interface'], \
-               attributes['user']))
-
-       # Allow reading of any newsgroup but not posting.
-        if 'post' == str(attributes['type']):
-            syslog('notice', 'dynamic authorization access for post access denied')
-            return "no posting for you"
-        elif 'read' == str(attributes['type']):
-            syslog('notice', 'dynamic authorization access for read access granted')
-            return None
-        else:
-            syslog('notice', 'dynamic authorization access type is not known: %s' % attributes['type'])
-            return "Internal error";
-
-    def dynamic_close(self):
-        """Called on nnrpd termination."""
-        pass
-
-
-##  The rest is used to hook up the dynamic access module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-mydynaccess = DYNACCESS()
-
-##  ...and try to hook up on nnrpd.  This would make auth object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(mydynaccess)
-    syslog('notice', "dynamic access module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for dynamic access method: %s" % errmsg[0])
diff --git a/samples/nnrpd_dynamic_wrapper.py b/samples/nnrpd_dynamic_wrapper.py
deleted file mode 100644 (file)
index 6c30e9d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-##  $Id: nnrpd_dynamic_wrapper.py 7899 2008-06-22 18:22:07Z iulius $
-##
-##  Example wrapper for support of old Python authentication scripts,
-##  by Erik Klavon.
-##
-##  This file contains a sample Python script which can be used to
-##  duplicate the behaviour of the old nnrppythonauth functionality.
-##  This script only supports dynamic access control by group.
-##
-##  How to use this wrapper:
-##    - insert your authentication class into this file;
-##    - rename your authentication class OLDAUTH.
-##
-##  See the INN Python Filtering and Authentication Hooks documentation
-##  for more information.
-##  The use of this file is *discouraged*.
-
-##  Old AUTH class.
-##  Insert your old auth class here.
-##  Do not include the code which sets the hook.
-
-
-
-
-##  Wrapper DYNACCESS class.  It creates an instance of the old class and
-##  calls its methods.  Arguments and return values are munged as
-##  needed to fit the new way of doing things.
-
-class MYDYNACCESS:
-    """Provide dynamic access callbacks to nnrpd."""
-    def dynamic_init(self):
-        self.old = OLDAUTH()
-
-    def dynamic(self, attributes):
-        return (self.old).authorize(attributes)
-
-    def dynamic_close(self):
-        (self.old).close()
-
-
-##  The rest is used to hook up the dynamic access module on nnrpd.  It is unlikely
-##  you will ever need to modify this.
-
-##  Import functions exposed by nnrpd.  This import must succeed, or nothing
-##  will work!
-from nnrpd import *
-
-##  Create a class instance.
-mydynaccess = MYDYNACCESS()
-
-##  ...and try to hook up on nnrpd.  This would make auth object methods visible
-##  to nnrpd.
-try:
-    set_auth_hook(mydynaccess)
-    syslog('notice', "dynamic access module successfully hooked into nnrpd")
-except Exception, errmsg:
-    syslog('error', "Cannot obtain nnrpd hook for dynamic access method: %s" % errmsg[0])
diff --git a/samples/nntpsend.ctl b/samples/nntpsend.ctl
deleted file mode 100644 (file)
index f54a96c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-##  $Revision: 1165 $
-##  Control file for nntpsend.
-## Format:
-##     site:fqdn:max_size:[<args...>]
-##     <site>          The name used in the newsfeeds file for this site;
-##                     this determines the name of the batchfile, etc.
-##     <fqdn>          The fully-qualified domain name of the site,
-##                     passed as the parameter to innxmit.
-##     <size>          Size to truncate batchfile if it gets too big;
-##                     see shrinkfile(1).
-##     <args>          Other args to pass to innxmit
-##  Everything after the pound sign is ignored.
-#nsavax:erehwon.nsavax.gov::-S -t60
-#walldrug:walldrug.com:4m-1m:-T1800 -t300
-#kremvax:kremvax.cis:2m:
diff --git a/samples/ovdb.conf b/samples/ovdb.conf
deleted file mode 100644 (file)
index b97432a..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# The directory that overview will be stored in (the DB_HOME directory)
-# is set in inn.conf with the 'pathoverview' option.  Other parameters
-# for tuning ovdb are in this file.
-
-# Size of the memory pool cache, in Kilobytes.  The cache will have a
-# backing store file in the DB directory which will be at least as big.
-# In general, the bigger the cache, the better.  Use C<ovdb_stat -m> to see
-# cache hit percentages.  If they're less than 80%, try increasing the
-# cache size.  To make a change of this parameter take effect, shut down
-# and restart INN (be sure to kill all of the nnrpds when shutting down).
-# Default is 8000, which is adequate for small to medium sized servers.
-# Large servers will probably need at least 14000.
-#cachesize     8000
-
-# Overview data is split between this many files.  Currently,
-# innd will keep all of the files open, so don't set this too high
-# or innd may run out of file descriptors.  The nnrpds only open one
-# at a time, regardless.  May be set to one, or just a few, but only
-# do that if your OS supports large (>2G) files.  Changing this
-# parameter has no effect on an already-established database.
-#numdbfiles    32
-
-# If txn_nosync is set to false, BerkeleyDB flushes the log after every
-# transaction.  This minimizes the number of transactions that may be
-# lost in the event of a crash, but results in significantly degraded
-# performance.  Default is true.
-#txn_nosync    true
-
-# If useshm is set to true, BerkeleyDB will use shared memory instead
-# of mmap for its environment regions (cache, lock, etc).  With some
-# platforms, this may improve performance.  Default is false.
-# This parameter is ignored if you have BerkeleyDB 2.x
-#useshm                false
-
-# Sets the shared memory key used by BerkeleyDB when 'useshm' is true.
-# BerkeleyDB will create several (usually 5) shared memory segments,
-# using sequentially numbered keys starting with 'shmkey'.
-# Choose a key that does not conflict with any existing shared memory
-# segments on your system.  Default is 6400.  This parameter is only
-# used with BerkeleyDB 3.1 or newer.
-#shmkey                6400
-
-# Sets the page size for the DB files (in bytes).  Must be a power of 2.
-# Best choices are 4096 or 8192.  The default is 8192.
-# Changing this parameter has no effect on an already-established database.
-#pagesize      8192
-
-# Sets the minimum number of keys per page.  See the BerkeleyDB
-# documentation for more info.  Default is based on page size:
-#
-#     default_minkey = MAX(2, pagesize / 2048 - 1)
-#
-# The lowest allowed minkey is 2.  Setting minkey higher than the
-# default is not recommended, as it will cause the databases to have
-# a lot of overflow pages.
-# Changing this parameter has no effect on an already-established database.
-#minkey                3
-
-# Sets the BerkeleyDB "lk_max" parameter, which is the maxmium number
-# of locks that can exist in the database at the same time.  Default
-# is 4000.
-#maxlocks      4000
-
-# The nocompact parameter affects expireover's behavior.  The expireover
-# function in ovdb can do its job in one of two ways:  By simply deleting
-# expired records from the database; or by re-writing the overview records
-# into a different location leaving out the expired records.  The first
-# method is faster, but it leaves 'holes' that result in space that can
-# not immediately be reused.  The second method 'compacts' the records
-# by rewriting them.
-# 
-# If this parameter is set to 0, expireover will compact all newsgroups;
-# if set to 1, expireover will not compact any newsgroups; and if set to
-# a value greater than one, expireover will only compact groups that
-# have less than that number of articles.  Default is 1000.
-#
-# Experience has shown that compacting has minimal effect (other than 
-# making expireover take longer) so the default is now 1.  This parameter 
-# will probably be removed in the future.
-#nocompact     1
-
-# Normally, each nnrpd process directly accesses the BerkeleyDB environment.
-# The process of attaching to the database (and detaching when finished) is
-# fairly expensive, and can result in high loads in situations when there are
-# lots of reader connections of relatively short duration.
-# 
-# When the readserver parameter is "true", the nnrpds will access overview
-# via a helper server (ovdb_server -- which is started by ovdb_init).
-# Default is false.
-#readserver    false
-
-# This parameter is only used when 'readserver' is true.  It sets the number
-# of ovdb_server processes.  As each ovdb_server can process only one
-# transaction at a time, running more servers can improve reader response
-# times.  Default is 5.
-#numrsprocs    5
-
-# This parameter is only used when 'readserver' is true.  It sets a maximum
-# number of readers that a given ovdb_server process will serve at one time.
-# This means the maximum number of readers for all of the ovdb_server
-# processes is (numrsprocs * maxrsconn).  Default is 0, which means an
-# umlimited number of connections is allowed.
-#maxrsconn     0
-
diff --git a/samples/overview.fmt b/samples/overview.fmt
deleted file mode 100644 (file)
index e3cb43d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-##  $Revision: 573 $
-##  overview.fmt - format of news overview database
-##  Format
-##     <header>
-##     <header>:full
-##  header is a news article header, known by innd.  If ":full" appears,
-##  then header name will be prepended.  Order of lines is important!
-Subject:
-From:
-Date:
-Message-ID:
-References:
-Bytes:
-Lines:
-Xref:full
-#Keywords:full
diff --git a/samples/passwd.nntp b/samples/passwd.nntp
deleted file mode 100644 (file)
index 50cf3f5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-##  $Revision: 1165 $
-##  passwd.nntp - passwords for connecting to remote NNTP servers
-##  Format:
-##     <host>:<name>:<pass>[:<style>]
-##  Clients need only one entry, for where innd is running.  The
-##  server will have more entries for connecting to peers to feed them
-##  articles.
-##     <host>          Host this line is for.
-##     <name>          Name to use to authenticate with
-##     <pass>          Password to send, after sending name
-##     <style>         Optional authentication style, defaults to "authinfo"
-##  <name> and <pass> can be empty string; a peer innd doesn't need a
-##  <name>, for example.
-#news.foo.com:rsalz:martha
diff --git a/samples/radius.conf b/samples/radius.conf
deleted file mode 100644 (file)
index dd1d06c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# $Id: radius.conf 7556 2006-08-28 02:00:28Z eagle $
-#
-# Sample RADIUS configuration file for the RADIUS readers.conf
-# authenticator.  If you're not using that authenticator, this file is not
-# used.
-
-server radius {
-
-# Hostname of the RADIUS server.
-
-#radhost:       radius-server.example.com
-
-# Port to query on the RADIUS server.
-
-radport:        1645
-
-# Local hostname or IP address.
-#
-# The RADIUS server expects an IP address; a hostname will be translated
-# into an IP address with gethostbyname().  If not given, not included in
-# the request (not all RADIUS setups need this information).
-
-#lochost:       news.example.com
-
-# Local port of connection.
-#
-# The port the client we're authenticating is connecting to.  If not
-# given, defaults to 119.  You'll only need to set this if you're readers
-# are connecting on a non-standard port.
-
-#locport:       119
-
-# Shared secret with RADIUS server.
-#
-# Be careful not to use the '#' symbol in your secret, since in this
-# file that indicates the beginning of a comment.
-
-#secret:        SECRET-WORD
-
-# Prefix for username.
-#
-# Before given to the RADIUS server, usernames will be rewritten by
-# prepending the prefix, if given, and then appending the suffix, if
-# given.
-
-#prefix:        news-
-
-# Suffix for username.
-
-#suffix:        @example.com
-
-# Whether to ignore bad reply IP.
-#
-# If set to false, the RADIUS authenticator will check to ensure that the
-# response it receives is from the same IP address as it sent the request
-# to (for some added security).  If set to true, it will skip this
-# verification check (if your RADIUS server has multiple IP addresses or
-# if other odd things are going on, it may be perfectly normal for the
-# response to come from a different IP address).
-
-ignore-source:  false
-
-}
diff --git a/samples/readers.conf b/samples/readers.conf
deleted file mode 100644 (file)
index ed86f99..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-##  $Id: readers.conf 4371 2001-01-16 15:35:38Z rra $
-##
-##  readers.conf - Access control and configuration for nnrpd
-##
-##  Format:
-##     auth "<name>" {
-##             hosts: "<hostlist>"
-##             auth: "<authprog>"
-##             res: "<resprog>"
-##             default: "<identity>"
-##             default-domain: "<email-domain>"
-##     }
-##     access "<name>" {
-##             users: "<userlist>"
-##             newsgroups: "<newsgroups>"
-##             read: "<read>"
-##             post: "<post>"
-##             access: "<perm>"
-##     }
-##
-##  Other parameters are possible.  See readers.conf(5) for all the
-##  details.  Only one of newsgroups or read/post may be used in a single
-##  access group.
-##
-##  If the connecting host is not matched by any hosts: parameter of any
-##  auth group, it will be denied access.  auth groups assign an identity
-##  string to connections, access groups grant privileges to identity
-##  strings matched by their users: parameters.
-##
-##  In all cases, the last match found is used, so put defaults first.
-##
-##  For a news server that allows connections from anyone within a
-##  particular domain or IP address range, just uncomment the "local" auth
-##  group and the "local" access group below and adjust the hosts: and
-##  default: parameters of the auth group and the users: parameter of the
-##  access group for your local network and domain name.  That's all there
-##  is to it.
-##
-##  For more complicated configurations, read the comments on the examples
-##  and also see the examples and explanations in readers.conf(5).  The
-##  examples in readers.conf(5) include setups that require the user to
-##  log in with a username and password (the example in this file only
-##  uses simple host-based authentication).
-##
-##  NOTE: Unlike in previous versions of INN, nnrpd will now refuse any
-##  post from anyone to a moderated newsgroup that contains an Approved:
-##  header unless their access block has an access: key containing the
-##  "A" flag.  This is to prevent abuse of moderated groups, but it means
-##  that if you support any newsgroup moderators, you need to make sure
-##  to add such a line to the access group that affects them.  See the
-##  access group for localhost below for an example.
-
-# The only groups enabled by default (the rest of this file is
-# commented-out examples).  This assigns the identity of <localhost> to
-# the local machine
-
-auth "localhost" {
-    hosts: "localhost, 127.0.0.1, stdin"
-    default: "<localhost>"
-}
-
-# Grant that specific identity access to read and post to any newsgroup
-# and allow it to post articles with Approved: headers to moderated
-# groups.
-
-access "localhost" {
-    users: "<localhost>"
-    newsgroups: "*"
-    access: RPA
-}
-
-
-# This auth group matches all connections from example.com or machines in
-# the example.com domain and gives them the identity <local>@example.com.
-# Instead of using wildmat patterns to match machine names, you could also
-# put a wildmat pattern matching IP addresses or an IP range specified
-# using CIDR notation (like 10.10.10.0/24) here.
-
-#auth "local" {
-#    hosts: "*.example.com, example.com"
-#    default: "<local>@example.com"
-#}
-
-# This auth group matches a subset of machines and assigns connections
-# from there an identity of "<read>@example.com"; these systems should
-# only have read access, no posting privileges.
-
-#auth "read-only" {
-#    hosts: "*.newuser.example.com"
-#    default: "<read>@example.com"
-#}
-
-# This auth group matches the systems at a guest institution that should
-# be allowed to read the example.events.* hierarchy but nothing else.
-
-#auth "events-only" {
-#    hosts: "*.example.org"
-#    default: "<events-only>@example.org"
-#}
-
-# Finally, this auth group matches some particular systems which have been
-# abusing the server.  Note that it doesn't assign them an identity at
-# all; the "empty" identity created in this fashion won't match any users:
-# parameters.  Note also that it's last, so anything matching this entry
-# will take precedent over everything above it.
-
-#auth "abusers" {
-#    hosts: "badguy-dsl.example.com, kiosk.public-access.example.com"
-#}
-
-
-# Now for the access groups.  All of our access groups should have users:
-# parameters so there are no access groups that match connections without
-# an identity (such as are generated by the "abusers" entry above).
-# First, the default case of local users, who get to read and post to
-# everything.
-
-#access "local" {
-#    users: "<local>@example.com"
-#    newsgroups: "*"
-#}
-
-# Now, the read-only folks, who only get to read everything.
-
-#access "read-only" {
-#    users: "<read>@example.com"
-#    read: "*"
-#}
-
-# Finally, the events-only people who get to read and post but only to a
-# specific hierarchy.
-
-#access "events-only" {
-#    users: "<events-only>@example.org"
-#    newsgroups: "example.events.*"
-#}
diff --git a/samples/sasl.conf.in b/samples/sasl.conf.in
deleted file mode 100644 (file)
index 8f94375..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-tls_ca_path:           @prefix@/lib
-tls_cert_file:         @prefix@/lib/cert.pem
-tls_key_file:          @prefix@/lib/cert.pem
diff --git a/samples/startup.tcl b/samples/startup.tcl
deleted file mode 100644 (file)
index e11eeaf..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-##  $Id: startup.tcl 4353 2001-01-15 13:32:40Z rra $
-##
-##  Tcl filter initialization code
-##
-##  If you compile with Tcl support enabled, this file (even if empty) must
-##  exist as pathfilter/_PATH_TCL_STARTUP (as defined in paths.h).  This
-##  sample file defines the two functions that are called before and after
-##  reloading the filter code, but defines them as empty procs that do
-##  nothing.
-
-proc filter_before_reload {} {
-}
-
-proc filter_after_reload {} {
-}
diff --git a/samples/startup_innd.pl b/samples/startup_innd.pl
deleted file mode 100644 (file)
index 4148469..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-# 
-# RCSId:        $Id: startup_innd.pl 6312 2003-05-04 21:40:11Z rra $
-# Description: Sample startup code for Perl hooks in INN. This file, after
-#              it's installed in the right spot, will be loaded when
-#              innd starts up. The following functions should be defined
-#              by it (they don't have to be, in fact this file can be
-#              empty, but it must exist if you've compiled in Perl support).
-#
-#              sub filter_before_reload { ... }
-#                      Called before the filter definition file filter_innd.pl
-#                      is loaded (every time).
-#              sub filter_after_reload { ... }
-#                      Called after the filter definition file filter_innd.pl
-#                      is loaded (every time).
-#
-#              See the sample file filter_innd.pl for details on what it does.
-
-
-my $before_count = 1 ;
-# Gets no arguments, and its caller expects no return value.
-sub filter_before_reload {
-       if ($before_count == 1) {
-#              Do one thing
-#              print "First time (before)\n" ;
-               $before_count++ ;
-       } else {
-#              Do something else
-#              print "Time number $before_count (before)\n" ;
-               $before_count++ ;
-       }
-}
-
-my $after_count = 1 ;
-# Gets no arguments, and its caller expects no return value.
-sub filter_after_reload {
-       if ($after_count == 1) {
-#              Do one thing
-#              print "First time (after)\n" ;
-               $after_count++ ;
-       } else {
-#              Do another
-#              print "Time number $after_count (after)\n" ;
-               $after_count++ ;
-       }
-}
-
diff --git a/samples/storage.conf b/samples/storage.conf
deleted file mode 100644 (file)
index 41a6e13..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-##  $Id: storage.conf 6567 2003-12-27 04:18:33Z rra $
-##
-##  Rules for where INN should store incoming articles.
-##
-##  This file is used to determine which storage method articles are sent
-##  to to be stored and which storage class they are stored as.  Each
-##  method is described as follows:
-##
-##      method <methodname> {
-##          newsgroups: <wildmat>
-##          class: <storage class #>
-##          size: <minsize>[,<maxsize>]
-##          expires: <mintime>[,<maxtime>]
-##          options: <options>
-##      }
-##
-##  Only newsgroups, class, and (for CNFS, to specify the metacycbuff)
-##  options are required; the other keys are optional.  If any CNFS
-##  methods are configured, you will also need to set up cycbuff.conf.
-
-#  By default, store everything in tradspool.
-method tradspool {
-    newsgroups: *
-    class: 0
-}
-
-##  Here are some samples for a CNFS configuration.  This assumes that you
-##  have two metacycbuffs configured, one for text newsgroups and one for
-##  binaries.  Cancel messages, which tend to be very high-volume, are
-##  stored in the binary metacycbuff as well.  This assumes storeonxref is
-##  set to true in inn.conf.
-
-# Pick off the binary newsgroups first.
-#method cnfs {
-#    newsgroups: *.bina*,control.cancel
-#    class: 1
-#    options: BINARY
-#}
-
-# Put the remaining (text) groups in the other cycbuff.
-#method cnfs {
-#    newsgroups: *
-#    class: 2
-#    options: TEXT
-#}
diff --git a/samples/subscriptions b/samples/subscriptions
deleted file mode 100644 (file)
index 49109a2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-news.announce.newusers
-news.newusers.questions
-misc.test
-misc.test.moderated
-news.announce.newgroups
-news.answers
diff --git a/scripts/Makefile b/scripts/Makefile
deleted file mode 100644 (file)
index 3da914c..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-##  $Id: Makefile 7739 2008-04-06 09:38:31Z iulius $
-##
-##  Files that can be handled by fixscript (and need to be so handled) need
-##  a rule to build them from the .in version, and then all files need an
-##  installation rule.  Do the installation rules individually so as to
-##  avoid needless work if the files haven't changed.  We also need lists
-##  of files to build and files to install for the all and install rules.
-
-include ../Makefile.global
-
-top          = ..
-
-ALL           = innmail innreport innstat innupgrade innwatch rc.news \
-               scanlogs simpleftp tally.control writelog
-
-EXTRA         = inncheck innshellvars innshellvars.pl innshellvars.tcl \
-               news.daily
-
-INSTALLED     = $(D)$(PATHBIN)/inncheck                \
-               $(D)$(PATHBIN)/innmail          \
-               $(D)$(PATHBIN)/innreport        \
-               $(D)$(PATHBIN)/innstat          \
-               $(D)$(PATHBIN)/innupgrade       \
-               $(D)$(PATHBIN)/innwatch         \
-               $(D)$(PATHBIN)/news.daily       \
-               $(D)$(PATHBIN)/rc.news          \
-               $(D)$(PATHBIN)/scanlogs         \
-               $(D)$(PATHBIN)/simpleftp        \
-               $(D)$(PATHBIN)/tally.control    \
-               $(D)$(PATHBIN)/writelog         \
-               $(D)$(PATHLIB)/innreport_inn.pm \
-               $(D)$(PATHLIB)/innshellvars     \
-               $(D)$(PATHLIB)/innshellvars.pl  \
-               $(D)$(PATHLIB)/innshellvars.tcl
-
-all: $(ALL) $(EXTRA)
-
-install: all
-       for F in innmail innreport simpleftp ; do \
-           $(CP_XPUB) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for F in inncheck innstat innupgrade innwatch news.daily rc.news \
-                scanlogs tally.control writelog ; do \
-           $(CP_XPRI) $$F $D$(PATHBIN)/$$F ; \
-       done
-       for F in innreport_inn.pm innshellvars innshellvars.pl \
-                innshellvars.tcl ; do \
-           $(CP_RPUB) $$F $D$(PATHLIB)/$$F ; \
-       done
-
-clean:
-       rm -f $(ALL)
-
-clobber distclean: clean
-       rm -f $(EXTRA)
-
-depend:
-
-profiled: all
-
-$(EXTRA) $(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-
-##  Build rules.
-
-FIX             = $(FIXSCRIPT)
-
-innmail:       innmail.in       $(FIX) ; $(FIX) innmail.in
-innreport:     innreport.in     $(FIX) ; $(FIX) innreport.in
-innstat:       innstat.in       $(FIX) ; $(FIX) innstat.in
-innupgrade:    innupgrade.in    $(FIX) ; $(FIX) -i innupgrade.in
-innwatch:      innwatch.in      $(FIX) ; $(FIX) innwatch.in
-rc.news:       rc.news.in       $(FIX) ; $(FIX) rc.news.in
-scanlogs:      scanlogs.in      $(FIX) ; $(FIX) scanlogs.in
-simpleftp:     simpleftp.in     $(FIX) ; $(FIX) -i simpleftp.in
-tally.control: tally.control.in $(FIX) ; $(FIX) tally.control.in
-writelog:      writelog.in      $(FIX) ; $(FIX) writelog.in
diff --git a/scripts/inncheck.in b/scripts/inncheck.in
deleted file mode 100644 (file)
index aa73fbe..0000000
+++ /dev/null
@@ -1,937 +0,0 @@
-#!@_PATH_PERL@ --
-##  $Revision: 7748 $
-##  Sanity-check the configuration of an INN system
-##  by Brendan Kehoe <brendan@cygnus.com> and Rich $alz.
-
-require "@LIBDIR@/innshellvars.pl" ;
-
-$ST_MODE = 2;
-$ST_UID  = 4;
-$ST_GID  = 5;
-
-$newsuser = '@NEWSUSER@';
-$newsgroup = '@NEWSGRP@';
-
-##  We use simple names, mapping them to the real filenames only when
-##  we actually need a filename.
-%paths = (
-    'active',          "$inn::pathdb/active",
-    'archive',         "$inn::patharchive",
-    'badnews',         "$inn::pathincoming/bad",
-    'batchdir',                "$inn::pathoutgoing",
-    'control.ctl',     "$inn::pathetc/control.ctl",
-    'ctlprogs',                "$inn::pathcontrol",
-    'expire.ctl',      "$inn::pathetc/expire.ctl",
-    'history',         "$inn::pathdb/history",
-    'incoming.conf',   "$inn::pathetc/incoming.conf",
-    'inews',           "$inn::pathbin/inews",
-    'inn.conf',                "$inn::pathetc/inn.conf",
-    'innd',            "$inn::pathbin/innd",
-    'innddir',         "$inn::pathrun",
-    'inndstart',       "$inn::pathbin/inndstart",
-    'moderators',      "$inn::pathetc/moderators",
-    'most_logs',       "$inn::pathlog",
-    'newsbin',         "$inn::pathbin",
-    'newsboot',                "$inn::pathbin/rc.news",
-    'newsfeeds',       "$inn::pathetc/newsfeeds",
-    'overview.fmt',    "$inn::pathetc/overview.fmt",
-    'newsetc',         "$inn::pathetc",
-    'newslib',         "@LIBDIR@",
-    'nnrpd',           "$inn::pathbin/nnrpd",
-    'nntpsend.ctl',    "$inn::pathetc/nntpsend.ctl",
-    'oldlogs',         "$inn::pathlog/OLD",
-    'passwd.nntp',     "$inn::pathetc/passwd.nntp",
-    'readers.conf',    "$inn::pathetc/readers.conf",
-    'rnews',           "$inn::pathbin/rnews",
-    'rnewsprogs',      "$inn::pathbin/rnews.libexec",
-    'spooltemp',       "$inn::pathtmp",
-    'spool',           "$inn::patharticles",
-    'spoolnews',       "$inn::pathincoming"
-);
-
-##  The sub's that check the config files.
-%checklist = (
-    'active',          'active',
-    'control.ctl',     'control_ctl',
-    'expire.ctl',      'expire_ctl',
-    'incoming.conf',   'incoming_conf',
-    'inn.conf',                'inn_conf',
-    'moderators',      'moderators',
-    'newsfeeds',       'newsfeeds',
-    'overview.fmt',    'overview_fmt',
-    'nntpsend.ctl',    'nntpsend_ctl',
-    'passwd.nntp',     'passwd_nntp',
-    'readers.conf',    'readers_conf'
-);
-
-##  The modes of the config files we can check.
-%modes = (
-    'active',          @FILEMODE@,
-    'control.ctl',     0644,
-    'expire.ctl',      0644,
-    'incoming.conf',   0640,
-    'inn.conf',                0644,
-    'moderators',      0644,
-    'newsfeeds',       0644,
-    'overview.fmt',    0644,
-    'nntpsend.ctl',    0644,
-    'passwd.nntp',     0640,
-    'readers.conf',    0644
-);
-
-
-sub
-spacious
-{
-    local ($i);
-
-    chop;
-    study;
-    if ( /^#/ || /^$/ ) {
-       $i = 1;
-    } elsif ( /^\s/ ) {
-       print "$file:$line: starts with whitespace\n";
-       $i = 1;
-    } elsif ( /\s$/ ) {
-       print "$file:$line: ends with whitespace\n";
-       $i = 1;
-    }
-    $i;
-}
-\f
-##
-##  These are the functions that verify each individual file, called
-##  from the main code.  Each function gets <IN> as the open file, $line
-##  as the linecount, and $file as the name of the file.
-##
-
-
-##
-##  active
-##
-sub
-active
-{
-    local ($group, $hi, $lo, $f, $alias, %groups, %aliases);
-
-    input: while ( <IN> ) {
-       $line++;
-       unless ( ($group, $hi, $lo, $f) = /^([^ ]+) (\d+) (\d+) (.+)\n$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-
-       print "$file:$line: group `$group' already appeared\n"
-           if $groups{$group}++;
-       print "$file:$line: `$hi' <  '$lo'.\n"
-           if $hi < $lo && $lo != $hi + 1;
-
-       next input if $f =~ /^[jmynx]$/;
-       unless ( ($alias) = $f =~ /^=(.*)$/ ) {
-           print "$file:$line: bad flag `$f'.\n";
-           next input;
-       }
-       if ($alias eq "") {
-           print "$file:$line: empty alias.\n";
-           next input;
-       }
-       $aliases{$alias} = $line
-           unless defined $groups{$alias};
-    }
-    foreach $key ( keys %aliases ) {
-       print "$file:$aliases{$group} aliased to unknown group `$key'.\n"
-           unless defined $groups{$key};
-    }
-    1;
-}
-
-
-##
-##  control.ctl
-##
-%control'messages = (
-    'all',             1,
-    'checkgroups',     1,
-    'ihave',           1,
-    'newgroup',                1,
-    'rmgroup',         1,
-    'sendme',          1,
-    'sendsys',         1,
-    'senduuname',      1,
-    'version',         1,
-);
-%control'actions = (
-    'drop',            1,
-    'log',             1,
-    'mail',            1,
-    'doit',            1,
-    'doifarg',         1,
-    'verify',           1
-);
-
-sub
-control_ctl
-{
-    local ($msg, $from, $ng, $act);
-
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       unless ( ($msg, $from, $ng, $act) =
-                   /^([^:]+):([^:]+):([^:]+):(.+)$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-       if ( !defined $control'messages{$msg} ) {
-           print "$file:$line: unknown control message `$msg'.\n";
-           next input;
-       }
-       print "$file:$line: action for unknown control messages is `doit'.\n"
-           if $msg eq "default" && $act eq "doit";
-       print "$file:$line: empty from field.\n"
-           if $from eq "";
-       print "$file:$line: bad email address.\n"
-           if $from ne "*" && $from !~ /[@!]/;
-
-       ##  Perhaps check for conflicting rules, or warn about the last-match
-       ##  rule?  Maybe later...
-       print "$file:$line: may not match groups properly.\n"
-           if $ng ne "*" && $ng !~ /\./;
-       if ( $act !~ /([^=]+)(=.+)?/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-       $act =~ s/=.*//;
-       $act = "verify" if ($act =~ /^verify-.+/) ;
-       print "$file:$line: unknown action `$act'\n"
-           if !defined $control'actions{$act};
-    }
-    1;
-}
-
-
-##
-##  expire.ctl
-##
-sub
-expire_ctl
-{
-    local ($rem, $v, $def, $class, $pat, $flag, $keep, $default, $purge, $groupbaseexpiry);
-
-    $groupbaseexpiry = $inn::groupbaseexpiry;
-    $groupbaseexpiry =~ tr/A-Z/a-z/;
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       if ( ($v) = m@/remember/:(.+)@ ) {
-           print "$file:$line: more than one /remember/ line.\n"
-               if $rem++;
-           if ( $v !~ /[\d\.]+/ ) {
-               print "$file:$line: illegal value `$v' for remember.\n";
-               next input;
-           }
-           print "$file:$line: are you sure about your /remember/ value?\n"
-               ##  These are arbitrary "sane" values.
-               if $v != 0 && ($v > 60.0 || $v < 5.0);
-           next input;
-       }
-
-       ##  Could check for conflicting lines, but that's hard.
-       if ($groupbaseexpiry =~ /^true$/ || $groupbaseexpiry =~ /^yes$/ ||
-           $groupbaseexpiry =~ /^on$/) {
-           unless ( ($pat, $flag, $keep, $default, $purge) =
-            /^([^:])+:([^:]+):([\d\.]+|never):([\d\.]+|never):([\d\.]+|never)$/ ) {
-               print "$file:$line: malformed line.\n";
-               next input;
-           }
-           print "$file:$line: duplicate default line\n"
-               if $pat eq "*" && $flag eq "a" && $def++;
-           print "$file:$line: unknown modflag `$flag'\n"
-               if $flag !~ /[mMuUaAxX]/;
-       } else {
-           unless ( ($class, $keep, $default, $purge) =
-            /^(\d+):([\d\.]+|never):([\d\.]+|never):([\d\.]+|never)$/ ) {
-               print "$file:$line: malformed line.\n";
-               next input;
-           }
-           print "$file:$line: invalid class\n"
-               if $class < 0;
-       }
-       print "$file:$line: purge `$purge' younger than default `$default'.\n"
-           if $purge ne "never" && $default > $purge;
-       print "$file:$line: default `$default' younger than keep `$keep'.\n"
-           if $default ne "never" && $keep ne "never" && $keep > $default;
-    }
-    1;
-}
-
-
-##
-##  incoming.conf
-##
-sub
-incoming_conf
-{
-    1;
-}
-
-
-##
-##  inn.conf
-##
-sub
-inn_conf
-{
-    system ("$inn::pathbin/innconfval", '-C');
-
-#    if ( $k eq "domain" ) {
-#        print "$file:$line: domain (`$v') isn't local domain\n"
-#            if $fqdn =~ /[^\.]+\(\..*\)/ && $v ne $1;
-#        print "$file:$line: domain should not have a leading period\n"
-#            if $v =~ /^\./;
-#    } elsif ( $k eq "fromhost" ) {
-#        print "$file:$line: fromhost isn't a valid FQDN\n"
-#            if $v !~ /[\w\-]+\.[\w\-]+/;
-#    } elsif ( $k eq "moderatormailer" ) {
-#        # FIXME: shouldn't warn about blank lines if the
-#        # moderators file exists
-#        print "$file:$line: moderatormailer has bad address\n"
-#            if $v !~ /[\w\-]+\.[\w\-]+/ && $v ne "%s";
-#    } elsif ( $k eq "organization" ) {
-#        print "$file:$line: org is blank\n"
-#            if $v eq "";
-#    } elsif ( $k eq "pathhost" ) {
-#        print "$file:$line: pathhost has a ! in it\n"
-#            if $v =~ /!/;
-#    } elsif ( $k eq "pathalias" ) {
-#        print "$file:$line: pathalias has a ! in it\n"
-#            if $v =~ /!/;
-#    } elsif ( $k eq "pathcluster" ) {
-#        print "$file:$line: pathcluster has a ! in it\n"
-#            if $v =~ /!/;
-#    } elsif ( $k eq "server" ) {
-#        print "$file:$line: server (`$v') isn't local hostname\n"
-#            if $pedantic && $fqdn !~ /^$v/;
-#    }
-#
-#    if ( $key eq "moderatormailer" ) {
-#        printf "$file:$line: missing $key and no moderators file.\n"
-#            if ! -f $paths{"moderators"};
-#    }
-
-    1;
-}
-
-
-##
-##  moderators
-##
-sub
-moderators
-{
-    local ($k, $v);
-
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       unless ( ($k, $v) = /^([^:]+):(.+)$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-
-       if ( $k eq "" || $v eq "" ) {
-           print "$file:$line: missing field\n";
-           next input;
-       }
-       print "$file:$line: not an email address\n"
-           if $pedantic && $v !~ /[@!]/;
-       print "$file:$line: `$v' goes to local address\n"
-           if $pedantic && $v eq "%s";
-       print "$file:$line: more than one %s in address field\n"
-           if $v =~ /%s.*%s/;
-    }
-    1;
-}
-
-
-##
-##  newsfeeds
-##
-%newsfeeds'flags = (
-    '<',       '^\d+$',
-    '>',       '^\d+$',
-    'A',       '^[cCdeoOp]+$',
-    'B',       '^\d+(/\d+)?$',
-    'C',       '^\d+$',
-    'F',       '^.+$',
-    'G',       '^\d+$',
-    'H',       '^\d+$',
-    'I',       '^\d+$',
-    'N',       '^[mu]$',
-    'O',       '^\S+$',
-    'P',       '^\d+$',
-    'Q',       '^@?\d+(-\d+)?/\d+(_\d+)?$',
-    'S',       '^\d+$',
-    'T',       '^[cflmpx]$',
-    'W',       '^[befghmnpst*DGHNPOR]*$',
-);
-
-sub
-newsfeeds
-{
-    local ($next, $start, $me_empty, @muxes, %sites);
-    local ($site, $pats, $dists, $flags, $param, $type, $k, $v, $defsub);
-    local ($bang, $nobang, $prog, $dir);
-
-    input: while ( <IN> ) {
-       $line++;
-       next input if /^$/;
-       chop;
-       print "$file:$line: starts with whitespace\n"
-           if /^\s+/;
-
-       ##  Read continuation lines.
-       $start = $line;
-       while ( /\\$/ ) {
-           chop;
-           chop($next = <IN>);
-           $line++;
-           $next =~ s/^\s*//;
-           $_ .= $next;
-       }
-       next input if /^#/;
-       print "$file:$line: ends with whitespace\n"
-           if /\s+$/;
-
-        # Catch a variable setting.
-        if ( /^\$([A-Za-z0-9]+)=/ ) {
-            print "$file:$line: variable name too long\n"
-                if length ($1) > 31;
-            next input;
-        }
-
-       unless ( ($site, $pats, $flags, $param) =
-                   /^([^:]+):([^:]*):([^:]*):(.*)$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-
-       print "$file:$line: Newsfeed `$site' has whitespace in its name\n"
-           if $site =~ /\s/;
-       print "$file:$line: comma-space in site name\n"
-           if $site =~ m@, @;
-       print "$file:$line: comma-space in subscription list\n"
-           if $pats =~ m@, @;
-       print "$file:$line: comma-space in flags\n"
-           if $flags =~ m@, @;
-
-       print "$file:$start: ME has exclusions\n"
-           if $site =~ m@^ME/@;
-       print "$file:$start: multiple slashes in exclusions for `$site'\n"
-           if $site =~ m@/.*/@;
-       $site =~ s@([^/]*)/.*@$1@;
-       print "$site, "
-           if $verbose;
-
-       if ( $site eq "ME" ) {
-           $defsub = $pats;
-           $defsub =~ s@(.*)/.*@$1@;
-       } elsif  ( $defsub ne "" ) {
-           $pats = "$defsub,$pats";
-       }
-       print "$file:$start: Multiple slashes in distribution for `$site'\n"
-           if $pats =~ m@/.*/@;
-
-       if ( $site eq "ME" ) {
-           print "$file:$start: ME flags should be empty\n"
-               if $flags ne "";
-           print "$file:$start: ME param should be empty\n"
-               if $param ne "";
-           $me_empty = 1
-               if $pats !~ "/.+";
-       }
-
-       ##  If we don't have !junk,!control, give a helpful warning.
-#      if ( $site ne "ME" && $pats =~ /!\*,/ ) {
-#          print "$file:$start: consider adding !junk to $site\n"
-#              if $pats !~ /!junk/;
-#          print "$file:$start: consider adding !control to $site\n"
-#              if $pats !~ /!control/;
-#      }
-
-       ##  Check distributions.
-       if ( ($dists) = $pats =~ m@.*/(.*)@ ) {
-           $bang = $nobang = 0;
-           dist: foreach $d ( split(/,/, $dists) ) {
-               if ( $d =~ /^!/ ) {
-                   $bang++;
-               }
-               else {
-                   $nobang++;
-               }
-               print "$file:$start: questionable distribution `$d'\n"
-                   if $d !~ /^!?[a-z0-9-]+$/;
-           }
-           print "$file:$start: both ! and non-! distributions\n"
-               if $bang && $nobang;
-       }
-       $type = "f";
-       flag: foreach $flag ( split(/,/, $flags) ) {
-           ($k, $v) = $flag =~ /(.)(.*)/;
-           if ( !defined $newsfeeds'flags{$k} ) {
-               print "$file:$start: unknown flag `$flag'\n";
-               next flag;
-           }
-           if ( $v !~ /$newsfeeds'flags{$k}/ ) {
-               print "$file:$start: bad value `$v' for flag `$k'\n";
-               next flag;
-           }
-           $type = $v
-               if $k eq "T";
-       }
-
-       ##  Warn about multiple feeds.
-       if ( !defined $sites{$site} ) {
-           $sites{$site} = $type;
-       } elsif ( $sites{$site} ne $type ) {
-           print "$file:$start: feed $site multiple conflicting feeds\n";
-       }
-
-       if ( $type =~ /[cpx]/ ) {
-           $prog = $param;
-           $prog =~ s/\s.*//;
-           print "$file:$start: relative path for $site\n"
-               if $prog !~ m@^/@;
-           print "$file:$start: `$prog' is not executable for $site\n"
-               if ! -x $prog;
-       }
-       if ( $type eq "f" && $param =~ m@/@ ) {
-           $dir = $param;
-           $dir =~ s@(.*)/.*@$1@;
-           $dir = $paths{'batchdir'} . "/" . $dir
-               unless $dir =~ m@^/@;
-           print "$file:$start: directory `$dir' does not exist for $site\n"
-               if ! -d $dir;
-       }
-
-       ##  If multiplex target not known, add to multiplex list.
-       push(@muxes, "$start: undefined multiplex `$param'")
-           if $type eq "m" && !defined $sites{$param};
-    }
-
-    ##  Go through and make sure all referenced multiplex exist.
-    foreach (@muxes) {
-       print "$file:$_\n"
-           if /`(.*)'/ && !defined $sites{$1};
-    }
-    print "$file:0: warning you accept all incoming article distributions\n"
-       if !defined $sites{"ME"} || $me_empty;
-
-    print "done.\n"
-       if $verbose;
-    1;
-}
-
-
-##
-##  overview.fmt
-##
-#%overview_fmtheaders = (
-#    'Approved',               1,
-#    'Bytes',          1,
-#    'Control',                1,
-#    'Date',           1,
-#    'Distribution',   1,
-#    'Expires',                1,
-#    'From',           1,
-#    'Lines',          1,
-#    'Message-ID',     1,
-#    'Newsgroups',     1,
-#    'Path',           1,
-#    'References',     1,
-#    'Reply-To',               1,
-#    'Sender',         1,
-#    'Subject',                1,
-#    'Supersedes',     1,
-#);
-
-sub
-overview_fmt
-{
-    local ($header, $mode, $sawfull);
-
-    $sawfull = 0;
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       unless ( ($header, $mode) = /^([^:]+):([^:]*)$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-
-       #print "$file:$line: unknown header `$header'\n"
-       #    if !defined $overview_fmtheaders{$header};
-       if ( $mode eq "full" ) {
-           $sawfull++;
-       } elsif ( $mode eq "" ) {
-           print "$file:$line: short header `$header' appears after full one\n"
-               if $sawfull;
-       } else {
-           print "$file:$line: unknown mode `$mode'\n";
-       }
-    }
-    1;
-}
-
-
-##
-##  nntpsend.ctl
-##
-sub
-nntpsend_ctl
-{
-    local ($site, $fqdn, $flags, $f, $v);
-
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       ##  Ignore the size info for now.
-       unless ( ($site, $fqdn, $flags) =
-                   /^([\w\-\.]+):([^:]*):[^:]*:([^:]*)$/ ) {
-           print "$file:$line: malformed line.\n";
-           next input;
-       }
-       print "$file:$line: FQDN is empty for `$site'\n"
-           if $fqdn eq "";
-
-       next input if $flags eq "";
-       flag: foreach (split(/ /, $flags)) {
-           unless ( ($f, $v) = /^-([adrvtTpSP])(.*)$/ ) {
-               print "$file:$line: unknown argument for `$site'\n";
-               next flag;
-           }
-           print "$file:$line: unknown argument to option `$f': $flags\n"
-               if ( $f eq "t" || $f eq "T" || $f eq "P") && $v !~ /\d+/;
-       }
-    }
-    1;
-}
-
-
-##
-##  passwd.nntp
-##
-sub
-passwd_nntp
-{
-    local ($name, $pass);
-
-    input: while ( <IN> ) {
-       next input if &spacious($file, ++$line);
-
-       unless ( ($name, $pass) = /[\w\-\.]+:(.*):(.*)(:authinfo)?$/ ) {
-           next input;
-           print "$file:$line: malformed line.\n";
-       }
-       print "$file:$line: username/password must both be blank or non-blank\n"
-           if ( $name eq "" && $pass ne "" ) || ($name ne "" && $pass eq "");
-    }
-    1;
-}
-
-
-##
-##  readers.conf
-##
-sub
-readers_conf
-{
-    1;
-}
-\f
-
-##
-##  Routines to check permissions
-##
-
-##  Given a file F, check its mode to be M, and its ownership to be by the
-##  user U in the group G.  U and G have defaults.
-sub
-checkperm
-{
-    local ($f, $m, $u, $g) = ( @_, $newsuser, $newsgroup);
-    local (@sb, $owner, $group, $mode);
-
-    die "Internal error, undefined name in perm from ", (caller(0))[2], "\n"
-       if !defined $f;
-    die "Internal error, undefined mode in perm from ", (caller(0))[2], "\n"
-       if !defined $m;
-
-    if ( ! -e $f ) {
-       print "$pfx$f:0: missing\n";
-    }
-    else {
-       @sb = stat _;
-       $owner = (getpwuid($sb[$ST_UID]))[0];
-       $group = (getgrgid($sb[$ST_GID]))[0];
-       $mode  = $sb[$ST_MODE] & ~0770000;
-
-       ##  Ignore setgid bit on directories.
-       $mode &= ~0777000
-           if -d _;
-
-       if ( $owner ne $u ) {
-           print "$pfx$f:0: owned by $owner, should be $u\n";
-           print "chown $u $f\n"
-               if $fix;
-       }
-       if ( $group ne $g ) {
-           print "$pfx$f:0: in group $group, should be $g\n";
-           print "chgrp $g $f\n"
-               if $fix;
-       }
-       if ( $mode ne $m ) {
-           printf "$pfx$f:0: mode %o, should be %o\n", $mode, $m;
-           printf "chmod %o $f\n", $m
-               if $fix;
-       }
-    }
-}
-
-##  Return 1 if the Intersection of the files in the DIR and FILES is empty.
-##  Otherwise, report an error for each illegal file, and return 0.
-sub
-intersect
-{
-    local ($dir, @files) = @_;
-    local (@in, %dummy, $i);
-
-    if ( !opendir(DH, $dir) ) {
-       print "$pfx$dir:0: can't open directory\n";
-    }
-    else {
-       @in = grep($_ ne "." && $_ ne "..", readdir(DH));
-       closedir(DH);
-    }
-
-    $i = 1;
-    if ( scalar(@in) ) {
-       foreach ( @files ) {
-           $dummy{$_}++;
-       }
-       foreach ( grep ($dummy{$_} == 0, @in) ) {
-           print "$pfx$dir:0: ERROR: illegal file `$_' in directory\n";
-           $i = 0;
-       }
-    }
-    $i;
-}
-
-@directories = (
-    'archive', 'badnews', 'batchdir', 'ctlprogs', 'most_logs', 'newsbin',
-    'newsetc', 'newslib', 'oldlogs', 'rnewsprogs', 'spooltemp', 'spool', 'spoolnews'
-);
-@rnews_programs = (
-    'c7unbatch', 'decode', 'encode', 'gunbatch'
-);
-@newsbin_public = (
-    'archive', 'batcher', 'buffchan', 'convdate', 'cvtbatch', 'expire',
-    'filechan', 'getlist', 'grephistory', 'innconfval', 'innxmit',
-    'makehistory', 'nntpget', 'overchan', 'prunehistory', 'shlock',
-    'shrinkfile'
-);
-@newsbin_private = (
-    'ctlinnd', 'expirerm', 'inncheck', 'innstat', 'innwatch',
-    'news.daily', 'nntpsend', 'scanlogs', 'sendbatch',
-    'tally.control', 'writelog',
-    'send-ihave', 'send-nntp', 'send-uucp'
-);
-#@newslib_private_read = (
-#    'innlog.pl'
-#);
-
-## The modes for the various programs.
-%prog_modes = (
-    'inews',            @INEWSMODE@,
-    'innd',             0550,
-    'newsboot',                 0550,
-    'nnrpd',            0555,
-    'rnews',            @RNEWSMODE@,
-);
-
-##  Check the permissions of nearly every file in an INN installation.
-sub
-check_all_perms
-{
-    local ($rnewsprogs) = $paths{'rnewsprogs'};
-    local ($newsbin) = $paths{'newsbin'};
-    local ($newslib) = $paths{'newslib'};
-
-    foreach ( @directories ) {
-       &checkperm($paths{$_}, 0755);
-    }
-    &checkperm($paths{'innddir'}, 0750);
-    foreach ( keys %prog_modes ) {
-       &checkperm($paths{$_}, $prog_modes{$_});
-    }
-    &checkperm($paths{'inndstart'}, 04550, 'root', $newsgroup);
-    foreach ( keys %paths ) {
-       &checkperm($paths{$_}, $modes{$_})
-           if defined $modes{$_};
-    }
-    &checkperm($paths{'history'}, 0644);
-    # Commented out for now since it depends on the history type.
-    #&checkperm($paths{'history'} . ".dir", 0644);
-    #&checkperm($paths{'history'} . ".index", 0644);
-    #&checkperm($paths{'history'} . ".hash", 0644);
-    #foreach ( @newslib_private_read ) {
-    #   &checkperm("$newslib/$_", 0440);
-    #}
-    foreach ( @newsbin_private ) {
-       &checkperm("$newsbin/$_", 0550);
-    }
-    foreach ( @newsbin_public ) {
-       &checkperm("$newsbin/$_", 0555);
-    }
-    foreach ( @rnews_programs ) {
-       &checkperm("$rnewsprogs/$_", 0555);
-    }
-
-    ##  Also make sure that @rnews_programs are the *only* programs in there;
-    ##  anything else is probably someone trying to spoof rnews into being bad.
-    &intersect($rnewsprogs, @rnews_programs);
-
-    1;
-}
-
-\f
-##
-##  Parsing, main routine.
-##
-
-sub
-Usage
-{
-    local ($i) = 0;
-
-    print "Usage error: @_.\n";
-    print
-"Usage:
-       $program [-v] [-noperm] [-pedantic] [-perms [-fix] ] [-a|file...]
-File to check may be followed by \"=path\" to use the specified path.  All
-files are checked if -a is used or if -perms is not used.  Files that may
-be checked are:\n";
-    foreach ( sort(keys %checklist) ) {
-       printf "     %-20s", $_;
-       if ( ++$i == 3) {
-           print "\n";
-           $i = 0;
-       }
-    }
-    print "\n"
-       if $i;
-    exit 0;
-}
-
-
-sub
-parse_flags
-{
-    $all = 0;
-    $fix = 0;
-    $perms = 0;
-    $noperms = 0;
-    $verbose = 0;
-    @todo = ();
-
-    arg: foreach ( @ARGV ) {
-       if ( /-a/ ) {
-           $all++;
-           next arg;
-       }
-       if ( /^-v/ ) {
-           $verbose++;
-           next arg;
-       }
-       if ( /^-ped/ ) {
-           $pedantic++;
-           next arg;
-       }
-       if ( /^-f/ ) {
-           $fix++;
-           next arg;
-       }
-       if ( /^-per/ ) {
-           $perms++;
-           next arg;
-       }
-       if ( /^-noperm/ ) {
-           $noperms++;
-           next arg;
-       }
-       if ( /^-/ ) {
-           &Usage("Unknown flag `$_'");
-       }
-       if ( ($k, $v) = /(.*)=(.*)/ ) {
-           &Usage("Can't check `$k'")
-               if !defined $checklist{$k};
-           push(@todo, $k);
-           $paths{$k} = $v;
-           next arg;
-       }
-       &Usage("Can't check `$_'")
-           if !defined $checklist{$_};
-       push(@todo, $_);
-    }
-
-    &Usage("Can't use `-fix' without `-perm'")
-       if $fix && !$perms;
-    &Usage("Can't use `-noperm' with `-perm'")
-       if $noperms && $perms;
-    $pfx = $fix ? '# ' : '';
-
-    @todo = grep(defined $checklist{$_}, sort(keys %paths))
-       if $all || (scalar(@todo) == 0 && ! $perms);
-}
-
-
-$program = $0;
-$program =~ s@.*/@@;
-$| = 1;
-&parse_flags();
-action: foreach $workfile ( @todo ) {
-    $file = $paths{$workfile};
-    if ( ! -f $file ) {
-       print "$file:0: file missing\n";
-       next action;
-    }
-    print "Looking at $file...\n"
-       if $verbose;
-    if ( !open(IN, $file) ) {
-       print "$pfx$workfile:0: can't open $!\n";
-       next action;
-    }
-    &checkperm($file, $modes{$workfile})
-       if $noperms == 0 && !$perms && defined $modes{$workfile};
-    $line = 0;
-    eval "&$checklist{$workfile}" || warn "$@";
-    close(IN);
-}
-
-&check_all_perms()
-    if $perms;
-exit(0);
-
-if ( 0 ) {
-    &active();
-    &control_ctl();
-    &incoming_conf();
-    &expire_ctl();
-    &inn_conf();
-    &moderators();
-    &nntpsend_ctl();
-    &newsfeeds();
-    &overview_fmt();
-    &passwd_nntp();
-    &readers_conf();
-}
diff --git a/scripts/innmail.in b/scripts/innmail.in
deleted file mode 100644 (file)
index 7d980d8..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Fri, 25 Apr 1997 14:11:23 +0200
-# Project:      INN
-# File:         innmail.pl
-# RCSId:        $Id: innmail.in 2677 1999-11-15 06:33:13Z rra $
-# Description:  A simple replacement for UCB Mail to avoid nasty security
-#              problems. 
-# 
-
-$0 =~ s!.*/!! ;
-
-require 5.001 ;
-require 'getopts.pl' ;
-
-die "$0: No \$inn::mta  variable defined.\n" 
-    if ! defined ($inn::mta);
-
-$sm = $inn::mta ;
-
-die "$0: MTA path is not absolute\n" unless ($sm =~ m!^/!) ;
-
-$usage = "usage: $0 -s subject addresses\n\n" .
-    "Reads stdin for message body\n" ;
-
-&Getopts ("s:h") || die $usage ;
-
-die $usage if $opt_h ;
-
-if ( !$opt_s ) {
-    warn "No subject given. Hope that's ok\n" ;
-    $opt_s = "NO SUBJECT" ;
-} else {
-    $opt_s =~ s/\n+\Z//;
-}
-
-# fix up any addresses.
-foreach ( @ARGV ) {
-    s![^-a-zA-Z0-9+_.@%]!!g ;
-
-    push (@addrs,$_) if ($_ ne "") ;
-}
-
-die "$0: No addresses specified\n\n$usage" unless @addrs ;
-
-if ($sm =~ m!%s!) {
-    $sm = sprintf $sm,join (' ',@addrs);
-} else {
-    $sm .= " " . join(' ', @addrs);
-}
-
-@smarr = split(/\s+/,$sm);
-
-($t = $inn::mta) =~ s!\s.*!!;
-die "$0: MTA variable definition is changed after subsitution\n" 
-    if ($t ne $smarr[0]);
-
-die "$0: MTA excutable doesn't appear to exist: $smarr[0]\n"
-    if ! -x $smarr[0];
-
-# startup mta without using the shell
-$pid = open (MTA,"|-") ;
-if ($pid == 0) {
-    exec (@smarr) || die "$0: exec of $sm failed: $!\n" ;
-} elsif ($pid < 0) {
-    die "$0: Fork failed: $!\n" ;
-}
-
-print MTA "To: ", join (",\n\t",@addrs), "\n" ;
-print MTA "Subject: $opt_s\n" ;
-print MTA "\n" ;
-while (<STDIN>) {
-    print MTA $_ ;
-}
-close (MTA) ;
-exit ;
diff --git a/scripts/innreport.in b/scripts/innreport.in
deleted file mode 100644 (file)
index 241d10e..0000000
+++ /dev/null
@@ -1,2598 +0,0 @@
-#! /usr/bin/perl
-# fixscript will replace this line with require innshellvars.pl
-
-##########################################################################
-#
-#   innreport: Perl script to summarize news log files
-#              (with optional HTML output and graphs).
-#
-# version: 3.0.2
-#
-# Copyright (c) 1996-1999, Fabien Tassin (fta@sofaraway.org).
-#
-##########################################################################
-#
-# Usage: innreport -f config_file [-[no]options] logfile [logfile2 [...]]
-#   where options are:
-#     -h (or -help)      : this help page
-#     -html              : HTML output
-#     -v                 : display the version number of INNreport
-#     -f config_file     : name of the configuration file
-#     -config            : print INNreport configuration information
-#     -g                 : want graphs [default]
-#     -graph             : an alias for option -g
-#     -d directory       : directory for Web pages
-#     -dir directory     : an alias for option -d
-#     -p directory       : pictures path (file space)
-#     -path directory    : an alias for option -p
-#     -w directory       : pictures path (web space)
-#     -webpath directory : an alias for option -w
-#     -i                 : name of index page
-#     -index             : an alias for option -i
-#     -a                 : want to archive HTML results
-#     -archive           : an alias for option -a
-#     -c number          : how many report files to keep (0 = all)
-#     -cycle number      : an alias for option -c
-#     -s char            : separator for filename
-#     -separator char    : an alias for option -s
-#     -unknown           : Unknown entries from news log file
-#     -maxunrec          : Max number of unrecognized line to display
-#     -casesensitive     : Case sensitive
-#     -notdaily          : Never perform daily actions
-#
-# Use no in front of boolean options to unset them.
-# For example, "-html" is set by default. Use "-nohtml" to remove this
-# feature.
-#
-##########################################################################
-#
-# ABSOLUTELY NO WARRANTY WITH THIS PACKAGE. USE IT AT YOUR OWN RISKS.
-#
-# Note: You need the Perl graphic library GD.pm if you want the graphs.
-#       GD is available on all good CPAN ftp sites:
-#           ex: [CPAN_DIR]/authors/id/LDS/GD-1.1_.tar.gz (or greater)
-#         or directly to:
-#           <URL:http://www-genome.wi.mit.edu/pub/software/WWW/GD.html>
-#       Note : innreport will create PNG or GIF files depending upon
-#              the GD version.
-#
-# Documentation: for a short explaination of the different options, you
-#        can read the usage (obtained with the -h or -help switch).
-#
-# Install: - check the Perl location (first line). Require Perl 5.002
-#            or greater.
-#          - look at the parameters in the configuration file (section
-#            'default')
-#          - copy the configuration file into ${PATHETC}/innreport.conf
-#          - copy the INN module into ${PATHETC}/innreport_inn.pm
-#          - copy this script into ${PATHETC}/innreport
-#          - be sure that the news user can run it (chmod 755 or 750)
-#          - in "scanlog", comment the line containing innlog and add:
-#            ${PATHETC}/innreport -f ${PATHETC}/innreport.conf ${OLD_SYSLOG}
-#            or, if you want to change some options:
-#    ${PATHETC}/innreport -f ${PATHETC}/innreport.conf options ${OLD_SYSLOG}
-#
-# Report: please report bugs (preferably) to the INN mailing list
-#         (see README) or directly to the author (do not forget to
-#         include the result of the "-config" switch, the parameters
-#         passed on the command line and the INN version).
-#         Please also report unknown entries.
-#         Be sure your are using the latest version of this script before
-#         any report.
-#
-##########################################################################
-
-# Note: References to <ftp://ftp.sofaraway.org/pub/innreport/> have been
-# removed from the output because this site appears to no longer exist.  It
-# used to be the upstream source for innreport.  If there is a new site for
-# innreport releases, please notify the INN maintainers.
-
-# remember to add '-w' on the first line and to uncomment the 'use strict'
-# below before doing any changes to this file.
-
-use strict;
-
-## Do you want to create a Web page. Pick DO or DONT.
-my $HTML = "DO";
-
-## Do you want the graphs (need $HTML too). Pick DO or DONT.
-my $GRAPH = "DO";
-
-## Directory for the Web pages (used only if the previous line is active)
-my $HTML_dir = "$inn::pathhttp";
-
-## Directory for the pictures (need HTML support) in the file space
-my $IMG_dir = "$HTML_dir/pics";
-
-## Directory for the pictures (need HTML support) in the Web space
-## (can be relative or global)
-my $IMG_pth = "pics";
-
-## Do you want to archive HTML results (& pics) [ will add a date in each
-## name ]. Pick DO or DONT.
-my $ARCHIVE = "DO";
-
-## index page will be called:
-my $index = "index.html";
-
-## How many report files to keep (0 = all) (need $ARCHIVE).
-my $CYCLE = 0;
-
-## separator between hours-minutes-seconds in filenames
-## (normaly a ":" but some web-browsers (Lynx, MS-IE, Mosaic) can't read it)
-## Warning: never use "/". Use only a _valid_ filename char.
-my $SEPARATOR = ".";
-
-## Do you want the "Unknown entries from news log file" report. Pick DO or
-## DONT.
-my $WANT_UNKNOWN = "DO";
-
-## Max number of unrecognized lines to display (if $WANT_UNKNOWN)
-## (-1 = no limit)
-my $MAX_UNRECOGNIZED = 50;
-
-## Do you want to be case sensitive. Pick DO or DONT.
-my $CASE_SENSITIVE = "DO";
-
-## Some actions must only be performed daily (once for a log file).
-## (ex: unwanted.log with INN). Default value (DONT) means to perform
-## these actions each . Pick DO or DONT.
-my $NOT_DAILY = "DONT";
-
-###############################################
-## THERE'S NOTHING TO CHANGE AFTER THIS LINE ##
-###############################################
-
-my $version = "3.0.2";
-my %output; # content of the configuration file.
-my $DEBUG = 0; # set to 1 to verify the structure/content of the conf file.
-my $start_time = time;
-
-# Require Perl 5.002 or greater.
-require 5.002;
-use Getopt::Long;
-use vars qw/$HAVE_GD $GD_FORMAT/;
-
-my @old_argv = @ARGV;
-
-# Convert DO/DONT into boolean values.
-{
-  my $i;
-  foreach $i (\$HTML, \$GRAPH, \$ARCHIVE, \$WANT_UNKNOWN,
-              \$CASE_SENSITIVE, \$NOT_DAILY) {
-    $$i = $$i eq 'DO' ? 1 : 0 ;
-  }
-}
-
-my %ref;
-GetOptions (\%ref,
-          qw(-h -help
-             -html!
-             -config
-             -f=s
-             -g! -graph!
-             -d=s -dir=s
-             -p=s -path=s
-             -w=s -webpath=s
-              -i=s -index=s
-             -a! -archive!
-             -c=i -cycle=i
-             -s=s -separator=s
-             -unknown!
-             -html-unknown!
-             -maxunrec=i
-             -casesensitive!
-              -notdaily!
-             -v
-             ));
-
-&Version if $ref{'v'};
-
-&Decode_Config_File($ref{'f'}) if defined $ref{'f'};
-&Usage if $ref{'h'} || $ref{'help'} || !defined $ref{'f'};
-
-$HTML = 0 if defined $output{'default'}{'html'};
-$HTML = 1 if $output{'default'}{'html'} eq 'true';
-$HTML = 0 if defined $ref{'html'};
-$HTML = 1 if $ref{'html'};
-
-$GRAPH = 0 if defined $output{'default'}{'graph'};
-$GRAPH = 1 if $HTML && ($output{'default'}{'graph'} eq 'true');
-$GRAPH = 0 if defined $ref{'g'} || defined $ref{'graph'};
-$GRAPH = 1 if $HTML && ($ref{'g'} || $ref{'graph'});
-
-$HTML_dir = &GetValue ($output{'default'}{'html_dir'})
-  if defined $output{'default'}{'html_dir'};
-$HTML_dir = $ref{'d'} if defined $ref{'d'};
-$HTML_dir = $ref{'dir'} if defined $ref{'dir'};
-
-$IMG_pth = &GetValue ($output{'default'}{'img_dir'})
-  if defined $output{'default'}{'img_dir'};
-$IMG_pth = $ref{'w'} if defined $ref{'w'};
-$IMG_pth = $ref{'webpath'} if defined $ref{'webpath'};
-
-$IMG_dir = $HTML_dir . "/" . $IMG_pth
-  if (defined $output{'default'}{'img_dir'} ||
-       defined $ref{'w'} || defined $ref{'webpath'})
-      &&
-      (defined $output{'default'}{'html_dir'} ||
-       defined $ref{'d'} || defined $ref{'dir'});
-
-$IMG_dir = $ref{'p'} if defined $ref{'p'};
-$IMG_dir = $ref{'path'} if defined $ref{'path'};
-
-$index = &GetValue ($output{'default'}{'index'})
-  if defined $output{'default'}{'index'};
-$index = $ref{'i'} if defined $ref{'i'};
-$index = $ref{'index'} if defined $ref{'index'};
-
-$ARCHIVE = &GetValue ($output{'default'}{'archive'})
-  if defined $output{'default'}{'archive'};
-$ARCHIVE = $ARCHIVE eq 'true';
-$ARCHIVE = 0 if defined $ref{'a'} || defined $ref{'archive'};
-$ARCHIVE = 1 if ($ref{'a'} || $ref{'archive'}) && $HTML;
-$ARCHIVE = 0 unless $HTML;
-
-$CYCLE = &GetValue ($output{'default'}{'cycle'})
-  if defined $output{'default'}{'cycle'};
-$CYCLE = 0 if $CYCLE eq 'none';
-$CYCLE = $ref{'c'} if defined $ref{'c'};
-$CYCLE = $ref{'cycle'} if defined $ref{'cycle'};
-
-$SEPARATOR = &GetValue ($output{'default'}{'separator'})
-  if defined $output{'default'}{'separator'};
-$SEPARATOR = $ref{'s'} if defined $ref{'s'};
-$SEPARATOR = $ref{'separator'} if defined $ref{'separator'};
-
-if (defined $output{'default'}{'unknown'}) {
-  $WANT_UNKNOWN = &GetValue ($output{'default'}{'unknown'});
-  $WANT_UNKNOWN = $WANT_UNKNOWN eq 'true' ? 1 : 0;
-}
-$WANT_UNKNOWN = 0 if defined $ref{'unknown'};
-$WANT_UNKNOWN = 1 if $ref{'unknown'};
-
-my $WANT_HTML_UNKNOWN = $WANT_UNKNOWN;
-if (defined $output{'default'}{'html-unknown'}) {
-  $WANT_HTML_UNKNOWN = &GetValue ($output{'default'}{'html-unknown'});
-  $WANT_HTML_UNKNOWN = $WANT_HTML_UNKNOWN eq 'true' ? 1 : 0;
-}
-$WANT_HTML_UNKNOWN = 0 if defined $ref{'html-unknown'};
-$WANT_HTML_UNKNOWN = 1 if $ref{'html-unknown'};
-
-$NOT_DAILY = 0 if defined $ref{'notdaily'};
-$NOT_DAILY = 1 if $ref{'notdaily'};
-
-$MAX_UNRECOGNIZED = &GetValue ($output{'default'}{'max_unknown'})
-  if defined $output{'default'}{'max_unknown'};
-$MAX_UNRECOGNIZED = $ref{'maxunrec'} if defined ($ref{'maxunrec'});
-
-$CASE_SENSITIVE = &GetValue ($output{'default'}{'casesensitive'})
-  if defined $output{'default'}{'casesensitive'};
-$CASE_SENSITIVE = 1 if $CASE_SENSITIVE eq 'true';
-$CASE_SENSITIVE = 0 if defined $ref{'casesensitive'};
-$CASE_SENSITIVE = 1 if $ref{'casesensitive'};
-
-my $CLASS   = &GetValue ($output{'default'}{'module'});
-my $LIBPATH = &GetValue ($output{'default'}{'libpath'});
-
-umask 022;
-
-BEGIN {
-  eval "use GD;";
-  $HAVE_GD = $@ eq '';
-  if ($HAVE_GD) {
-    my $gd = new GD::Image(1,1);
-    $GD_FORMAT = "gif" if $gd->can('gif');
-    $GD_FORMAT = "png" if $gd->can('png');
-  }
-  $HAVE_GD;
-};
-undef $GRAPH unless $HTML;
-if ($GRAPH && !$::HAVE_GD) {
-  print "WARNING: can't make graphs as required.\n" .
-        "         Install GD.pm or disable this option.\n\n";
-  undef $GRAPH;
-}
-
-if ($HTML) {
-  if ($GRAPH) {
-    $IMG_dir = "." if defined $IMG_dir && $IMG_dir eq '';
-    $IMG_pth .= "/" if $IMG_pth;
-    $IMG_pth =~ s|/+|/|g;
-    $IMG_dir =~ s|/+|/|g;
-    unless (-w $IMG_dir) {
-      print "WARNING: can't write in \"$IMG_dir\" as required by -g " .
-       "switch.\n         Option -g removed. Please see the -p switch.\n\n";
-      undef $GRAPH;
-    }
-  }
-  $HTML_dir = "." if defined $HTML_dir && $HTML_dir eq '';
-  unless (-w $HTML_dir) {
-    print "WARNING: can't write in \"$HTML_dir\" as required by -html " .
-      "switch.\n         Option -html and -a removed. Please see the " .
-      "-d switch.\n\n";
-    undef $HTML;
-    $ARCHIVE = 0;
-  }
-}
-
-# Now, we are sure that HTML and graphs can be made if options are active.
-&Summary if defined $ref{'config'};
-
-my $unrecognize_max = 0;
-my @unrecognize;
-my ($total_line, $total_size) = (0, 0);
-my ($suffix, $HTML_output, %config, $first_date, $last_date,
-    %prog_type, %prog_size);
-
-my $HTML_header = '';
-my $HTML_footer = '';
-
-my $MIN = 1E10;
-my $MAX = -1;
-
-my $xmax = &GetValue ($output{'default'}{'graph_width'})   # Graph size..
-  if defined $output{'default'}{'graph_width'};
-$xmax = 550 unless $xmax;
-
-my $transparent = &GetValue ($output{'default'}{'transparent'})
-  if defined $output{'default'}{'transparent'};
-$transparent = (defined $transparent && $transparent eq 'true') ? 1 : 0;
-
-my $repeated = 1;
-
-my $first_date_cvt = $MIN;
-my $last_date_cvt = $MAX;
-
-
-#########################################################################
-my $s = sprintf "use lib qw($LIBPATH); use $CLASS;";
-eval $s;  # initialization
-die "Can't find/load $CLASS.pm : $@\n" if $@;
-
-my $save_line = <>;
-$_ = $save_line;
-local $^W = 0 if $] < 5.004; # to avoid a warning for each '+=' first use.
-LINE: while (!eof ()) {
-  $total_line++;
-  my $size = length;
-  $total_size += $size;
-
-  # Syslog optimization
-  if ($repeated) {
-    $repeated--;
-    $_ = $save_line;
-  }
-  else {
-    $_ = <>;
-    if ($_ =~ /last message repeated (\d+) times?$/o) {
-       $repeated = $1;
-       $_ = $save_line;
-    }
-    else {
-       $save_line = $_;
-    }
-  }
-
-  # skip empty lines
-  next LINE if $_ eq '';
-
-  my $res;
-  my ($day, $hour, $prog, $left) =
-    $_ =~ m/^(\S+\s+\S+) (\S+) \S+ (\S+): \[ID \d+ \S+\] (.*)$/o;
-  ($day, $hour, $prog, $left) =
-    $_ =~ m/^(\S+\s+\S+) (\S+) \S+ (\S+): (.*)$/o unless $day;
-  ($day, $hour, $prog, $left) =
-    $_ =~ m/^(\S+\s+\S+) (\S+) \d+ \S+ (\S+): (.*)$/o unless $day;
-
-  unless ($day) {
-    ($day, $hour, $res, $left) = $_ =~ m/^(\S+\s+\S+) (\S+)\.\d+ (\S+) (.*)$/o;
-    if ($day) {
-      my $cvtdate = &ConvDate ("$day $hour");
-      if ($cvtdate < $first_date_cvt) {
-       $first_date_cvt = $cvtdate;
-       $first_date = "$day $hour";
-      }
-      elsif ($cvtdate > $last_date_cvt) {
-       $last_date_cvt = $cvtdate;
-       $last_date = "$day $hour";
-      }
-      $prog = "inn";
-    }
-    else {
-      next if $_ =~ /^$/;
-      # Unrecognize line... skip
-      $unrecognize[$unrecognize_max] = $_
-       unless $unrecognize_max > $MAX_UNRECOGNIZED
-               && $MAX_UNRECOGNIZED > 0;
-      $unrecognize_max++;
-      next LINE;
-    }
-  }
-  else {
-    my $cvtdate = &ConvDate ("$day $hour");
-    if ($cvtdate < $first_date_cvt) {
-      $first_date_cvt = $cvtdate;
-      $first_date = "$day $hour";
-    }
-    elsif ($cvtdate > $last_date_cvt) {
-      $last_date_cvt = $cvtdate;
-      $last_date = "$day $hour";
-    }
-  }
-
-  ########
-  ## Program name
-  # word[7164] -> word
-  my ($pid) = $prog =~ s/\[(\d+)\]$//o;
-  # word: -> word
-  $prog =~ s/:$//o;
-  # wordX -> word   (where X is a digit)
-  $prog =~ s/\d+$//o;
-
-  $prog_type{$prog}++;
-  $prog_size{$prog} = 0 unless defined $prog_size{$prog}; # stupid warning :(
-  $prog_size{$prog} += $size;
-
-  # The "heart" of the tool.
-  {
-    no strict;
-    next LINE if
-      &{$CLASS."::collect"} ($day, $hour, $prog, $res, $left, $CASE_SENSITIVE);
-  }
-
-  $unrecognize[$unrecognize_max] = $_
-    unless $unrecognize_max > $MAX_UNRECOGNIZED
-           && $MAX_UNRECOGNIZED > 0;
-  $unrecognize_max++;
-}
-
-{
-  no strict;
-  &{$CLASS . "::adjust"} ($first_date, $last_date);
-}
-
-$| = 1;
-
-die "no data. Abort.\n" unless $total_line;
-
-my $sec_glob = &ConvDate ("$last_date") - &ConvDate ("$first_date");
-unless ($sec_glob) {
-  print "WARNING: bad date (\"$last_date\" or \"$first_date\")\n" .
-        "         Please, contact the author of innreport.\n";
-  $sec_glob = 24 * 60 * 60; # one day
-}
-
-$HTML_output = '';
-
-if ($HTML) {
-  # Create a new filename (unique and _sortable_)
-  if ($ARCHIVE) {
-    # The filename will contain the first date of the log or the current time.
-    my ($ts, $tm, $th, $dd, $dm, $dy) = localtime;
-    my ($m, $d, $h, $mn, $s) =
-      $first_date =~ /^(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
-    if ($m) {
-      my $ddm = (index "JanFebMarAprMayJunJulAugSepOctNovDec", $m) / 3;
-      # Adjust the year because syslog doesn't record it. We assume that
-      # it's the current year unless the last date is in the future.
-      my $ld = &ConvDate($last_date);
-      $dy-- if $ld > $ts + 60 * ($tm + 60 * ($th + 24 * ($dd - 1 +
-        substr("000031059090120151181212243273304334", $dm * 3, 3)))) ||
-        $ld < &ConvDate($first_date);
-      ($dm, $dd, $th, $tm, $ts) = ($ddm, $d, $h, $mn, $s);
-    }
-    $dm++; # because January = 0 and we prefer 1
-    $dy += 100 if $dy < 90; # Try to pacify the year 2000 !
-    $dy += 1900;
-    $suffix = sprintf ".%02d.%02d.%02d-%02d$SEPARATOR%02d$SEPARATOR%02d",
-                      $dy, $dm, $dd, $th, $tm, $ts;
-  }
-  else {
-    $suffix = '';
-  }
-  $HTML_output = "$HTML_dir" . "/news-notice" . "$suffix" . ".html";
-  $HTML_output =~ s|/+|/|g;
-  if (defined $output{'default'}{'html_header_file'}) {
-    my $file = &GetValue ($output{'default'}{'html_header_file'});
-    $file = $HTML_dir . "/" . $file;
-    open (F, $file) && do {
-      local $/ = undef;
-      $HTML_header = <F>;
-      close F;
-    };
-  }
-  if (defined $output{'default'}{'html_footer_file'}) {
-    my $file = &GetValue ($output{'default'}{'html_footer_file'});
-    $file = $HTML_dir . "/" . $file;
-    open (F, $file) && do {
-      local $/ = undef;
-      $HTML_footer = <F>;
-      close F;
-    };
-  }
-}
-
-&Write_all_results ($HTML_output, \%output);
-
-&Make_Index ($HTML_dir, $index, "news-notice$suffix.html", \%output)
-  if $HTML && $index;
-
-#====================================================================
-
-if ($ARCHIVE) {
-  # rotate html files
-  &Rotate ($CYCLE, $HTML_dir, "news-notice", ".html");
-
-  # rotate pictures
-  my $report;
-  foreach $report (@{$output{'_order_'}}) {
-    next if $report =~ m/^(default|index)$/;
-    next unless defined $output{$report}{'graph'};
-
-    my $i = 0;
-    while ($GRAPH && defined ${${$output{$report}{'graph'}}[$i]}{'type'}) {
-      my $name = $report . ($i ? $i : '');
-      &Rotate ($CYCLE, $IMG_dir, $name, '.' . $GD_FORMAT);
-      $i++;
-    }
-  }
-}
-
-# Code needed by INN only. It must be in innreport_inn.pm to keep things clean.
-if (!$NOT_DAILY && defined $output{'default'}{'unwanted_log'}) {
-  my $logfile = &GetValue ($output{'default'}{'unwanted_log'});
-  my $logpath = &GetValue ($output{'default'}{'logpath'});
-  {
-    no strict;
-    &{$CLASS . "::report_unwanted_ng"} ("$logpath/$logfile");
-  }
-}
-
-################
-# End of report.
-###################################################################
-
-######
-# Misc...
-
-# Compare 2 dates (+hour)
-sub DateCompare {
-  # ex: "May 12 06"   for May 12, 6:00am
-  local $[ = 0;
-  # The 2 dates are near. The range is less than a few days that's why we
-  # can cheat to determine the order. It is only important if one date
-  # is in January and the other in December.
-
-  my $date1 = substr ($a, 4, 2) * 24;
-  my $date2 = substr ($b, 4, 2) * 24;
-  $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a,0,3)) * 288;
-  $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b,0,3)) * 288;
-  if ($date1 - $date2 > 300 * 24) {
-    $date2 += 288 * 3 * 12;
-  }
-  elsif ($date2 - $date1 > 300 * 24) {
-    $date1 += 288 * 3 * 12;
-  }
-  $date1 += substr($a, 7, 2);
-  $date2 += substr($b, 7, 2);
-  $date1 - $date2;
-}
-
-
-# Convert: seconds to hh:mm:ss
-sub second2time {
-  my $temp;
-  my $t = shift;
-  # Hours
-  $temp = sprintf "%02d", $t / 3600;
-  my $chaine = "$temp:";
-  $t %= 3600;
-  # Min
-  $temp = sprintf "%02d", $t / 60;
-  $chaine .= "$temp:";
-  $t %= 60;
-  # Sec
-  $chaine .= sprintf "%02d", $t;
-  return $chaine;
-}
-
-# Convert: milliseconds to hh:mm:ss:mm
-sub ms2time {
-  my $temp;
-  my $t = shift;
-  # Hours
-  $temp = sprintf "%02d", $t / 3600000;
-  my $chaine = "$temp:";
-  $t %= 3600000;
-  # Min
-  $temp = sprintf "%02d", $t / 60000;
-  $chaine .= "$temp:";
-  $t %= 60000;
-  # Sec
-  $temp = sprintf "%02d", $t / 1000;
-  $chaine .= "$temp.";
-  $t %= 1000;
-  # Millisec
-  $chaine .= sprintf "%03d", $t;
-  return $chaine;
-}
-
-# Rotate the archive files..
-sub Rotate {
-  # Usage: &Rotate ($max_files, "$directory", "prefix", "suffix");
-  my ($max, $rep, $prefix, $suffix) = @_;
-  my ($file, $num, %files);
-  local ($a, $b);
-
-  return 1 unless $max;
-  opendir (DIR, "$rep") || die "Error: Cant open directory \"$rep\"\n";
-
-  FILE : while (defined ($file = readdir (DIR))) {
-    next FILE
-      unless $file =~ /^           # e.g. news-notice.1997.05.14-01:34:29.html
-                        $prefix          # Prefix : news-notice
-                        \.               # dot    : .
-                       (\d\d)?\d\d      # Year   : 1997 (or 97)
-                       \.               # dot    : .
-                       \d\d             # Month  : 05
-                       \.               # dot    : .
-                        \d\d             # Day    : 14
-                        -                # Separator : -
-                        \d\d             # Hour   : 01
-                        $SEPARATOR       # Separator : ":"
-                        \d\d             # Minute : 34
-                        $SEPARATOR       # Separator : ":"
-                        \d\d             # Second : 29
-                        $suffix          # Suffix : ".html"
-                        $/x;
-    $files{$file}++;
-  }
-  closedir DIR;
-  $num = 0;
-  foreach $file (sort {$b cmp $a} (keys (%files))) {
-    unlink "$rep/$file" if $num++ >= $max && -f "$rep/$file";
-  }
-  return 1;
-}
-
-# convert a date to a number of seconds
-sub ConvDate {
-  # usage: $num = &ConvDate ($date);
-  # date format is Aug 22 01:49:40
-  my $T = shift;
-  my ($m, $d, $h, $mn, $s) = $T =~ /^(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
-  my $out = $s + 60 * $mn + 3600 * $h + 86400 * ($d - 1);
-
-  $m = substr("000031059090120151181212243273304334",
-             index ("JanFebMarAprMayJunJulAugSepOctNovDec", $m), 3);
-  $out += $m * 86400;
-  return $out;
-}
-
-# Compare 2 filenames
-sub filenamecmp {
-  local $[ = 0;
-  my ($la, $lb) = ($a, $b);
-  my ($ya) = $la =~ m/news-notice\.(\d+)\./o;
-  $ya += 100  if $ya < 90; # Try to pacify the year 2000 !
-  $ya += 1900 if $ya < 1900; # xx -> xxxx
-  my ($yb) = $lb =~ m/news-notice\.(\d+)\./o;
-  $yb += 100  if $yb < 90; # Try to pacify the year 2000 !
-  $yb += 1900 if $yb < 1900; # xx -> xxxx
-
-  $la =~ s/news-notice\.(\d+)\./$ya\./;
-  $lb =~ s/news-notice\.(\d+)\./$yb\./;
-  $la =~ s/[\.\-\:html]//g;
-  $lb =~ s/[\.\-\:html]//g;
-
-  $lb <=> $la;
-}
-
-sub ComputeTotal {
-  my $h = shift;
-  my $total = 0;
-  my $key;
-  foreach $key (keys (%$h)) {
-    $total += $$h{$key};
-  }
-  $total;
-}
-
-sub ComputeTotalDouble {
-  my $h = shift;
-  my $total = 0;
-  my ($key1, $key2);
-  foreach $key1 (keys (%$h)) {
-    foreach $key2 (keys (%{$$h{$key1}})) {
-      $total += ${$$h{$key1}}{$key2};
-    }
-  }
-  $total;
-}
-
-# make an index for archive pages
-sub Make_Index {
-  my ($rep, $index, $filename, $data) = @_;
-  my %output = %$data;
-
-  $index =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-
-  # add requested data at the end of the database.
-  open (DATA, ">> $rep/innreport.db") || die "can't open $rep/innreport.db\n";
-  my $i = 0;
-  my $res = "$filename";
-  while (defined ${${$output{'index'}{'column'}}[$i]}{'value'}) {
-    my $data = &GetValue (${${$output{'index'}{'column'}}[$i]}{'value'});
-    $data =~ s/\n//sog;
-    my @list = split /\|/, $data;
-    my $val;
-    foreach $val (@list) {
-      $res .= ($val eq 'date' ? "|$first_date -- $last_date"
-                             : "|" . &EvalExpr($val));
-    }
-    $i++;
-  }
-  print DATA "$res\n";
-  close DATA;
-
-  # sort the database (reverse order), remove duplicates.
-  open (DATA, "$rep/innreport.db") || die "can't open $rep/innreport.db\n";
-  my %data;
-  while (<DATA>) {
-    m/^([^\|]+)\|(.*)$/o;
-    $data{$1} = $2;
-  }
-  close DATA;
-  open (DATA, "> $rep/innreport.db") || die "can't open $rep/innreport.db\n";
-  $i = 0;
-  foreach (sort {$b cmp $a} (keys %data)) {
-    print DATA "$_|$data{$_}\n" if $CYCLE == 0 || $i < $CYCLE;
-    $i++;
-  }
-  close DATA;
-
-  my $title = "Daily Usenet report";
-  $title = &GetValue ($output{'default'}{'title'})
-    if defined $output{'default'}{'title'};
-  $title =~ s/\\\"/\"/g;
-  my $Title = $title;
-  $Title =~ s/<.*?>//g;
-  my $body = '';
-  $body = &GetValue ($output{'default'}{'html_body'})
-    if defined $output{'default'}{'html_body'};
-  $body =~ s/\\\"/\"/go;
-  my $result = sprintf <<EOF;
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<HTML><HEAD>
-<TITLE>$Title: index</TITLE>
-</HEAD><BODY $body>
-$HTML_header
-<HR ALIGN=CENTER SIZE=\"4\" WIDTH=\"100%%\">
-<BR><CENTER><FONT SIZE=\"+2\">
-<B>$title - archives</B>
-</FONT></CENTER>
-<BR CLEAR=ALL>
-<HR ALIGN=CENTER SIZE=4 WIDTH=\"100%%\"><P>
-<CENTER>
-EOF
-
-  if ($GRAPH) {
-    my $i = 0;
-    while (defined ${${$output{'index'}{'graph'}}[$i]}{'title'}) {
-      my $title =  &GetValue (${${$output{'index'}{'graph'}}[$i]}{'title'});
-      my $filename = "index$i.$GD_FORMAT";
-      my $color_bg = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'color'});
-      my $unit     = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'unit'});
-      my $date_idx = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'value'});
-      $date_idx =~ s/^val(\d+)$/$1/o;
-      my @c = @{${${$output{'index'}{'graph'}}[$i]}{'data'}};
-      my $label_in  = &GetValue (${$c[0]}{'name'});
-      my $color_in  = &GetValue (${$c[0]}{'color'});
-      my $value_in  = &GetValue (${$c[0]}{'value'});
-      my $type_in   = 0;
-      $type_in = $value_in =~ s/^byte\((.*?)\)$/$1/o;
-      $value_in =~ s/^val(\d+)$/$1/o;
-      my $label_out = &GetValue (${$c[1]}{'name'});
-      my $color_out = &GetValue (${$c[1]}{'color'});
-      my $value_out = &GetValue (${$c[1]}{'value'});
-      my $type_out   = 0;
-      $type_out = $value_out =~ s/^byte\((.*?)\)$/$1/o;
-      $value_out =~ s/^val(\d+)$/$1/o;
-      my (%in, %out, %dates, $k);
-      foreach $k (keys (%data)) {
-       my @res = split /\|/, $data{$k};
-       my ($year) = $k =~ m/^news-notice\.(\d+)\.\d+\.\d+-\d+.\d+.\d+\.html/;
-       next unless $year; # bad filename.. strange.
-       my ($start, $end) =
-         $res[$date_idx - 1] =~ m/^(\w+\s+\d+ \S+) -- (\w+\s+\d+ \S+)$/o;
-       next unless $start; # bad date
-       $start = &ConvDate ($start);
-       $end = &ConvDate ($end);
-       # 31/12 - 1/1 ?
-       my $inc = $end < $start ? 1 : 0;
-       $start += (($year - 1970) * 365 +
-                  int (($year - 1968) / 4)) * 3600 * 24;
-       $year += $inc;
-       $end += (($year - 1970) * 365 + int (($year - 1968) / 4)) * 3600 * 24;
-       $in{$start} = $type_in ? &kb2i($res[$value_in - 1])
-                              : $res[$value_in - 1];
-       $out{$start} = $type_out ? &kb2i($res[$value_out - 1])
-                                : $res[$value_out - 1];
-       $dates{$start} = $end;
-      }
-      my ($xmax, $ymax) = (500, 170);
-      &Chrono ("$IMG_dir/$filename", $title, $color_bg, $xmax, $ymax,
-              \%in, \%out, \%dates, $label_in, $label_out,
-              $color_in, $color_out, $unit);
-      $result .= "<IMG WIDTH=\"$xmax\" HEIGHT=\"$ymax\" ";
-      $result .= "SRC=\"$IMG_pth$filename\" ALT=\"Graph\">\n";
-      $i++;
-    }
-    $result .= "<P>\n";
-  }
-  $i = 0;
-  $result .= "<TABLE BORDER=\"1\"><TR>";
-  my $temp = '';
-  while (defined ${${$output{'index'}{'column'}}[$i]}{'title'}) {
-    my $title = &GetValue (${${$output{'index'}{'column'}}[$i]}{'title'});
-    my $name = '';
-    $name = &GetValue (${${$output{'index'}{'column'}}[$i]}{'name'})
-      if defined ${${$output{'index'}{'column'}}[$i]}{'name'};
-    my @list = split /\|/, $name;
-    if ($name) {
-      $result .= sprintf "<TH COLSPAN=%d>$title</TH>", $#list + 1;
-    }
-    else {
-      $result .= "<TH ROWSPAN=\"2\">$title</TH>";
-    }
-    foreach (@list) {
-      $temp .= "<TH>$_</TH>";
-    }
-    $i++;
-  }
-  $result .= "</TR>\n<TR>$temp</TR>\n";
-
-  $i = 0;
-  foreach (sort {$b cmp $a} (keys %data)) {
-    if ($CYCLE == 0 || $i < $CYCLE) {
-      my @list = split /\|/, $data{$_};
-      my $str = "<TR><TD ALIGN=LEFT>";
-      $str .= "<A HREF=\"$_\">" if -e "$rep/$_";
-      $str .= shift @list;
-      $str .= "</A>" if -e "$rep/$_";;
-      $str .= "</TD>";
-      while (@list) {
-       $str .= "<TD ALIGN=RIGHT>";
-       my $t = shift @list;
-       $t =~ s/^\0+//o; # remove garbage, if any.
-       $str .= "$t</TD>";
-      }
-      $str .= "</TR>\n";
-      $result .= "$str";
-    }
-    $i++;
-  }
-  $result .= "</TABLE>\n</CENTER>\n<P><HR>";
-  $result .= "innreport $version (c) 1996-1999 ";
-  $result .= "by Fabien Tassin &lt;<A HREF=\"mailto:fta\@sofaraway.org\">";
-  $result .= "fta\@sofaraway.org</A>&gt;.\n";
-  if (defined ($output{'default'}{'footer'})) {
-    my ($t) = $output{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o;
-    $t =~ s/\\\"/\"/go;
-    $result .= "<BR>" . $t;
-  }
-  $result .= "$HTML_footer\n</BODY>\n</HTML>\n";
-  my $name = $rep . "/" . $index;
-  while ($name =~ m/\/\.\.\//o) {
-    $name =~ s|^\./||o;                 # ^./xxx        =>      ^xxx
-    $name =~ s|/\./|/|go;               # xxx/./yyy     =>      xxx/yyy
-    $name =~ s|/+|/|go;                 # xxx//yyy      =>      xxx/yyy
-    $name =~ s|^/\.\./|/|o;             # ^/../xxx      =>      ^/xxx
-    $name =~ s|^[^/]+/\.\./||o;         # ^xxx/../      =>      ^nothing
-    $name =~ s|/[^/]+/\.\./|/|go;       # /yyy/../      =>      /
-  }
-
-  open (INDEX, "> $name") || die "Error: Unable to create $name\n";
-  print INDEX $result;
-  close INDEX;
-  1;
-}
-
-sub Graph3d {
-  my $filename = shift;           # filename
-  my $title = shift;              # title
-  my $xmax = shift;               # width
-  my $n = shift;                  # Number of hash code tables
-
-  no strict;
-  my ($i, $k, $t);
-  my @val;
-  for $i (0 .. $n - 1) {
-    push @val, shift;           # hash code table
-  }
-  my $colors = shift;             # colors table
-  my $labels = shift;             # labels
-
-  my $max = 0;
-  my $max_size = 0;
-  my $size = 0;
-  foreach $k (sort keys (%{$val[0]})) {
-    $t = 0;
-    $size++;
-    for $i (0 .. $n - 1) {
-      $t += ${$val[$i]}{$k} if defined ${$val[$i]}{$k};
-    }
-    $max = $t if $max < $t;
-    $t = length "$k";
-    $max_size = $t if $max_size < $t;
-  }
-  $max = 1 unless $max;
-  $max_size *= gdSmallFont->width;
-
-  # relief
-  my ($rx, $ry) = (15, 5);
-
-  # margins
-  my ($mt, $mb) = (40, 40);
-  my $ml = $max_size > 30 ? $max_size + 8 : 30;
-
-  my $mr = 7 + (length "$max") * gdSmallFont->width;
-  $mr = 30 if $mr < 30;
-
-  # height of each bar
-  my $h = 12;
-
-  # difference between 2 bars
-  my $d = 25;
-
-  my $ymax = $size * $d + $mt + $mb;
-  my $image = new GD::Image ($xmax, $ymax);
-
-  my ($white, $black);
-  if (defined $output{'default'}{'graph_fg'}) {
-    my $t = $output{'default'}{'graph_fg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_fg'. Bad color.\n";
-    my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
-    $black = $image->colorAllocate (@c);
-  }
-  else {
-    $black = $image->colorAllocate (  0,   0,   0);
-  }
-  if (defined $output{'default'}{'graph_bg'}) {
-    my $t = $output{'default'}{'graph_bg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_bg'. Bad color.\n";
-    my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
-    $white = $image->colorAllocate (@c);
-  }
-  else {
-    $white = $image->colorAllocate (255, 255, 255);
-  }
-  $image->filledRectangle (0, 0, $xmax, $ymax, $white);
-  my @col;
-  for $i (0 .. $n - 1) {
-    $col[$i][0] = $image->colorAllocate
-      ($$colors[$i][0], $$colors[$i][1], $$colors[$i][2]);
-    $col[$i][1] = $image->colorAllocate
-      ($$colors[$i][0] * 3 / 4, $$colors[$i][1] * 3 / 4,
-       $$colors[$i][2] * 3 / 4);
-    $col[$i][2] = $image->colorAllocate
-      ($$colors[$i][0] * 2 / 3, $$colors[$i][1] * 2 / 3,
-       $$colors[$i][2] * 2 / 3);
-  }
-
-  $image->transparent ($white) if $transparent;
-
-  $image->rectangle (0, 0, $xmax - 1, $size * $d + $mt + $mb - 1, $black);
-  $image->line (0, $mt - 5, $xmax - 1, $mt - 5, $black);
-  for $i (0 .. $n - 1) {
-    $image->string (gdSmallFont, $i * $xmax / $n + $mt - 10 + $rx,
-                   ($mt - gdSmallFont->height) / 2, "$$labels[$i]", $black);
-    $image->filledRectangle ($i * $xmax / $n + 10, 8 + $ry / 2,
-                      $i * $xmax / $n + $mt - 10, $mt - 12, $col[$i][0]);
-    $image->rectangle ($i * $xmax / $n + 10, 8 + $ry / 2,
-                      $i * $xmax / $n + $mt - 10, $mt - 12, $black);
-    {
-      my $poly = new GD::Polygon;
-      $poly->addPt($i * $xmax / $n + 10, 8 + $ry / 2);
-      $poly->addPt($i * $xmax / $n + 10 + $rx / 2, 8);
-      $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, 8);
-      $poly->addPt($i * $xmax / $n + $mt - 10, 8 + $ry / 2);
-
-      $image->filledPolygon($poly, $col[$i][1]);
-      $image->polygon($poly, $black);
-    }
-    {
-      my $poly = new GD::Polygon;
-      $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, 8);
-      $poly->addPt($i * $xmax / $n + $mt - 10, 8 + $ry / 2);
-      $poly->addPt($i * $xmax / $n + $mt - 10, $mt - 12);
-      $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, $mt - 12 - $ry / 2);
-
-      $image->filledPolygon($poly, $col[$i][2]);
-      $image->polygon($poly, $black);
-    }
-  }
-  # Title
-  $image->string (gdMediumBoldFont, ($xmax - gdMediumBoldFont->width *
-                 (length "$title")) / 2, $ymax - gdMediumBoldFont->height - 7,
-                 "$title", $black);
-
-  my $e = $mt - $h + $d;
-  my $r = ($xmax - $ml - $mr - $rx) / $max;
-
-  # Axe Oz
-  $image->line ($ml + $rx, $mt, $ml + $rx, $size * $d + $mt - $ry, $black);
-  $image->line ($ml + $rx + $max * $r, $mt, $ml + $rx + $max * $r,
-               $size * $d + $mt - $ry, $black);
-  $image->line ($ml, $mt + $ry, $ml, $size * $d + $mt, $black);
-  # Axe Ox
-  $image->line ($ml + $rx, $size * $d + $mt - $ry,
-               $ml + $rx - 2 * $rx, $size * $d + $mt + $ry, $black);
-  # Axe Oy
-  $image->line ($ml + $rx, $size * $d + $mt - $ry,
-               $xmax - $mr / 2, $size * $d + $mt - $ry, $black);
-  $image->line ($ml, $size * $d + $mt,
-               $xmax - $mr - $rx, $size * $d + $mt, $black);
-
-  # Graduations..
-  my $nn = 10;
-  for $k (1 .. ($nn - 1)) {
-    $image->dashedLine ($ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                 $mt + 10, $ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                 $size * $d + $mt - $ry, $black);
-    $image->dashedLine ($ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                       $size * $d + $mt - $ry,
-                       $ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                       $size * $d + $mt, $black);
-    $image->line ($ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                       $size * $d + $mt,
-                       $ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
-                       $size * $d + $mt + 5, $black);
-    my $t = sprintf "%d%%", $k * 10;
-    $image->string (gdSmallFont, $ml + $k * ($xmax - $ml - $mr - $rx) / $nn -
-                   (length "$t") * gdSmallFont->width / 2,
-                   $size * $d + $mt + 6, "$t", $black);
-  }
-  {
-    my $t = sprintf "%d%%", 0;
-    $image->line ($ml, $size * $d + $mt, $ml, $size * $d + $mt + 5, $black);
-    $image->string (gdSmallFont, $ml - (length "$t") * gdSmallFont->width / 2,
-                   $size * $d + $mt + 6, "$t", $black);
-    $image->line ($xmax - $mr, $size * $d + $mt - $ry,
-                 $xmax - $mr - $rx, $size * $d + $mt, $black);
-    $image->line ($xmax - $mr - $rx, $size * $d + $mt,
-                 $xmax - $mr - $rx, $size * $d + $mt + 5, $black);
-    $t = sprintf "%d%%", 100;
-    $image->string (gdSmallFont, $xmax - $mr - $rx
-                   - (length "$t") * gdSmallFont->width / 2,
-                   $size * $d + $mt + 6, "$t", $black);
-  }
-  foreach $k (sort {${$val[0]}{$b} <=> ${$val[0]}{$a}} keys (%{$val[0]})) {
-    $image->string (gdSmallFont, $ml - (length "$k") * gdSmallFont->width - 3,
-                    $e + $h / 2 - gdSmallFont->height / 2, "$k", $black);
-    my $t = 0;
-    $image->line ($ml + ($t + ${$val[0]}{$k}) * $r + $rx - $rx, $e + $h,
-                  $ml + ($t + ${$val[0]}{$k}) * $r + $rx, $e - $ry + $h,
-                  $black);
-    for $i (0 .. $n - 1) {
-      next unless defined ${$val[$i]}{$k};
-      {
-       my $poly = new GD::Polygon;
-       $poly->addPt($ml + $t * $r, $e);
-       $poly->addPt($ml + $t * $r + $rx, $e - $ry);
-       $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry);
-        $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r, $e);
-
-        $image->filledPolygon($poly, $col[$i][1]);
-        $image->polygon($poly, $black);
-      }
-      unless (${$val[$i + 1]}{$k} || ${$val[$i]}{$k} == 0) {
-       my $poly = new GD::Polygon;
-       $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry);
-       $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx - $rx, $e);
-       $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx - $rx, $e + $h);
-       $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry + $h);
-
-       $image->filledPolygon($poly, $col[$i][2]);
-       $image->polygon($poly, $black);
-      }
-      $image->filledRectangle ($ml + $t * $r, $e,
-                              $ml + ($t + ${$val[$i]}{$k}) * $r, $e + $h,
-                               $col[$i][0]);
-      $image->rectangle ($ml + $t * $r, $e, $ml + ($t + ${$val[$i]}{$k}) * $r,
-                         $e + $h, $black);
-      $t += ${$val[$i]}{$k};
-    }
-    # total length (offered)
-    $image->filledRectangle ($ml + $t * $r + $rx + 3,
-                            $e - 2 - gdSmallFont->height / 2,
-                            $ml + $t * $r + $rx + 4 +
-                            gdSmallFont->width * length $t,
-                            $e - 6 + gdSmallFont->height / 2, $white);
-    $image->string (gdSmallFont, $ml + $t * $r + $rx + 5,
-                   $e - 3 - gdSmallFont->height / 2, "$t", $black);
-    # first value (accepted)
-    $image->filledRectangle ($ml + $t * $r + $rx + 3,
-                            $e - 4 + gdSmallFont->height / 2,
-                            $ml + $t * $r + $rx + 4 +
-                            gdSmallFont->width * length "${$val[0]}{$k}",
-                            $e - 2 + gdSmallFont->height, $white);
-    $image->string (gdSmallFont, $ml + $t * $r + $rx + 5,
-                   $e - 5 + gdSmallFont->height / 2, ${$val[0]}{$k}, $black);
-    $e += $d;
-  }
-  open (IMG, "> $filename") || die "Error: Can't open \"$filename\": $!\n";
-  if ($GD_FORMAT eq 'png') {
-    print IMG $image->png;
-  }
-  else {
-    print IMG $image->gif;
-  }
-  close IMG;
-  $ymax;
-}
-
-sub Histo {
-  my ($filename, $title, $xmax, $factor,
-      $labelx, $labely, $val1, $labels1) = @_;
-
-  no strict;
-  my $max = 0;
-  my $ymax = 300;
-  my $nb = 0;
-  # A hugly hack to convert hashes to lists..
-  # and to adjust the first and the last value...
-  # this function should be rewritten..
-  my (@a, @b, $kk);
-  foreach $kk (sort keys (%$val1))   {
-    if (defined $$val1{$kk}) {
-      $nb++;
-      # Arg... the following MUST be removed !!!!!!!!!
-      $$val1{$kk} = $$val1{$kk} / $innreport_inn::inn_flow_time{$kk} * 3600
-       if ($innreport_inn::inn_flow_time{$kk} != 3600) &&
-          ($innreport_inn::inn_flow_time{$kk} != 0);
-      push @a, $$val1{$kk};
-      $max = $$val1{$kk} if $$val1{$kk} > $max;
-      push @b, $$labels1{$kk};
-    }
-  }
-  return 0 unless $nb; # strange, no data.
-  my $val = \@a;
-  my $labels = \@b;
-  my ($i, $j);
-  my ($marginl, $marginr, $margint, $marginb, $shx, $shy);
-
-  my $image = new GD::Image($xmax, $ymax);
-  my ($white, $black);
-  if (defined $output{'default'}{'graph_fg'}) {
-    my $t = $output{'default'}{'graph_fg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_fg'. Bad color.\n";
-    my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
-    $black = $image->colorAllocate (@c);
-  }
-  else {
-    $black = $image->colorAllocate (  0,   0,   0);
-  }
-  if (defined $output{'default'}{'graph_bg'}) {
-    my $t = $output{'default'}{'graph_bg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_bg'. Bad color.\n";
-    my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
-    $white = $image->colorAllocate (@c);
-  }
-  else {
-    $white = $image->colorAllocate (255, 255, 255);
-  }
-  $image->filledRectangle (0, 0, $xmax, $ymax, $white);
-  my $gray  = $image->colorAllocate (128, 128, 128);
-  my $red   = $image->colorAllocate (255,   0,   0);
-  my $red2  = $image->colorAllocate (189,   0,   0);
-  my $red3  = $image->colorAllocate (127,   0,   0);
-  my $coltxt = $black;
-
-  $image->transparent ($white) if $transparent;
-
-  my $FontWidth = gdSmallFont->width;
-  my $FontHeight = gdSmallFont->height;
-
-  $marginl = 60;
-  $marginr = 30;
-  $margint = 60;
-  $marginb = 30;
-  $shx = 7;
-  $shy = 7;
-
-  $max = 1 unless $max;
-  my $part = 8;
-  $max /= $factor;
-
-  my $old_max = $max;
-  {
-    my $t = log ($max) / log 10;
-    $t = sprintf "%.0f", $t - 1;
-    $t = exp ($t * log 10);
-    $max = sprintf "%.0f", $max / $t * 10 + 0.4;
-    my $t2 = sprintf "%.0f", $max / $part;
-    unless ($part * $t2 == $max) {
-      while ($part * $t2 != $max) {
-       $max++;
-       $t2 = sprintf "%d", $max / $part;
-      }
-    }
-    $max = $max * $t / 10;
-  }
-
-  # Title
-  $image->string (gdMediumBoldFont,
-                 ($xmax - length ($title) * gdMediumBoldFont->width) / 2,
-                 ($margint - $shy - gdMediumBoldFont->height) / 2,
-                 $title, $coltxt);
-
-  # Labels
-  $image->string (gdSmallFont, $marginl / 2, $margint / 2, $labely, $coltxt);
-  $image->string (gdSmallFont, $xmax - $marginr / 2 -
-                 $FontWidth * length ($labelx), $ymax - $marginb / 2,
-                 $labelx, $coltxt);
-
-  # Max
-  $image->line ($marginl, $ymax - $marginb - $shy -
-               $old_max * ($ymax - $marginb - $margint - $shy) / $max,
-               $xmax - $marginr, $ymax - $marginb - $shy -
-               $old_max * ($ymax - $marginb - $margint - $shy) / $max, $red);
-  $image->line ($marginl, $ymax - $marginb - $shy -
-               $old_max * ($ymax - $marginb - $margint - $shy) / $max,
-               $marginl - $shx, $ymax - $marginb -
-               $old_max * ($ymax - $marginb - $margint - $shy) / $max, $red);
-
-  # Left
-  $image->line ($marginl - $shx, $margint + $shy,
-               $marginl - $shx, $ymax - $marginb, $coltxt);
-  $image->line ($marginl, $margint,
-               $marginl, $ymax - $marginb - $shy, $coltxt);
-  $image->line ($marginl, $margint,
-               $marginl - $shx, $margint + $shy, $coltxt);
-  $image->line ($marginl - $shx, $ymax - $marginb,
-               $marginl, $ymax - $marginb - $shy, $coltxt);
-
-  # Right
-  $image->line ($xmax - $marginr, $margint,
-               $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
-  $image->line ($xmax - $marginr - $shx, $ymax - $marginb,
-               $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
-
-  # Bottom
-  $image->line ($marginl - $shx, $ymax - $marginb,
-               $xmax - $marginr - $shx, $ymax - $marginb, $coltxt);
-  $image->line ($marginl, $ymax - $marginb - $shy,
-               $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
-  $image->fill ($xmax / 2, $ymax - $marginb - $shy / 2, $gray);
-
-  # Top
-  $image->line ($marginl, $margint,
-               $xmax - $marginr, $margint, $coltxt);
-  $image->setStyle ($coltxt, $coltxt, &GD::gdTransparent,
-                   &GD::gdTransparent, &GD::gdTransparent);
-  # Graduations
-  for ($i = 0; $i <= $part; $i++) {
-    $j = $max * $i / $part ;  # Warning to floor
-    # $j = ($max / $part) * ($i / 10000);
-    # $j *= 10000;
-
-    # Little hack...
-    $j = sprintf "%d", $j if $j > 100;
-
-    $image->line ($marginl - $shx - 3, $ymax - $marginb -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part,
-                 $marginl - $shx, $ymax - $marginb -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part, $coltxt);
-    $image->line ($marginl - $shx, $ymax - $marginb -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part,
-                 $marginl, $ymax - $marginb - $shy -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part, gdStyled);
-    $image->line ($marginl, $ymax - $marginb - $shy -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part,
-                 $xmax - $marginr, $ymax - $marginb - $shy -
-                 $i * ($ymax - $marginb - $margint - $shy) / $part, gdStyled);
-    $image->string (gdSmallFont,
-                   $marginl - $shx - $FontWidth * length ("$j") - 7,
-                   $ymax - $marginb -
-                   ($i) * ($ymax - $marginb - $margint - $shy) / ($part) -
-                   $FontHeight / 2, "$j", $coltxt);
-  }
-
-  # Graduation (right bottom corner)
-  $image->line ($xmax - $marginr - $shx, $ymax - $marginb,
-               $xmax - $marginr - $shx, $ymax - $marginb + 3, $coltxt);
-  # Bars
-  $i = 0;
-  my $w = ($xmax - $marginl - $marginr) / $nb;
-  my $k = $w / 5;
-  $$val[$nb - 1] = 0 unless $$val[$nb - 1];
-  foreach $j (@$val) {
-    my $MAX = 1;
-    if ($i++ <= $nb) {
-      # Graduation
-      $image->line ($marginl + ($i - 1) * $w - $shx, $ymax - $marginb,
-                   $marginl + ($i - 1) * $w - $shx, $ymax - $marginb + 3,
-                   $coltxt);
-      my $ii = sprintf "%d", $i / $MAX;
-      $image->string (gdSmallFont,
-                     $marginl + ($i - 0.5) * $w + 1 -
-                     ($FontWidth * length ($$labels[$i-1])) / 2 - $shx,
-                     $ymax - $marginb + 3, $$labels[$i-1], $coltxt)
-       unless ($w < $FontWidth * length ($$labels[$i-1]))
-               && ($i != $MAX * $ii);
-
-      # Right
-      my $poly = new GD::Polygon;
-      $poly->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-      $poly->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy);
-      $poly->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb);
-      $poly->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-
-      $image->filledPolygon($poly, $red3);
-      $image->polygon($poly, $coltxt);
-
-      # Front
-      $image->filledRectangle ($marginl + ($i - 1) * $w + $k - $shx,
-                  $ymax - $marginb -
-                  $j  / $factor * ($ymax - $marginb - $margint - $shy) / $max,
-                  $marginl + ($i) * $w - $k - $shx,
-                  $ymax - $marginb, $red);
-      $image->rectangle ($marginl + ($i - 1) * $w + $k - $shx,
-                  $ymax - $marginb -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max,
-                  $marginl + ($i) * $w - $k - $shx,
-                  $ymax - $marginb, $coltxt);
-      # Top
-      my $poly2 = new GD::Polygon;
-      $poly2->addPt($marginl + ($i - 1) * $w + $k, $ymax - $marginb - $shy -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-      $poly2->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-      $poly2->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-      $poly2->addPt($marginl + ($i - 1) * $w + $k - $shx, $ymax - $marginb -
-                  $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
-
-      $image->rectangle (0, 0, $xmax - 1, $ymax - 1, $coltxt);
-      $image->filledPolygon($poly2, $red2);
-      $image->polygon($poly2, $coltxt);
-    }
-  }
-
-  open (IMG, "> $filename") || die "Can't create '$filename'\n";
-  if ($GD_FORMAT eq 'png') {
-    print IMG $image->png;
-  }
-  else {
-    print IMG $image->gif;
-  }
-  close IMG;
-  1;
-}
-
-sub Chrono {
-  my $filename = shift;           # filename
-  my $title = shift;              # title
-  my $color_bg = shift;           # background color
-  my $xmax = shift;               # width
-  my $ymax = shift;               # height
-
-  my $in = shift;
-  my $out = shift;
-  my $dates = shift;
-
-  my $legend_in = shift;
-  my $legend_out = shift;
-
-  my $color_in = shift;
-  my $color_out = shift;
-
-  my $unit = shift;
-
-  my $key;
-  my $x_min = 1E30;
-  my $x_max = 0;
-  my $y_min = 0;
-  my $y_max;
-  my $y_max_in = 0;
-  my $y_max_out = 0;
-
-  foreach $key (sort keys %$dates) {
-    $x_min = $key if $x_min > $key;
-    $x_max = $$dates{$key} if $x_max < $$dates{$key};
-    my $t = $$out{$key} / ($$dates{$key} - $key);
-    $y_max_out = $t if $y_max_out < $t;
-    $t = $$in{$key} / ($$dates{$key} - $key);
-    $y_max_in = $t if $y_max_in < $t;
-  }
-  $y_max = $y_max_out > $y_max_in ? $y_max_out : $y_max_in;
-  my $factor = 1;
-  if ($y_max < 1) {
-    $factor = 60;
-    if ($y_max < 4 / 60) {
-      $y_max = 4 / 60;
-    }
-    else {
-      $y_max = int ($y_max * $factor) + 1;
-      $y_max += (4 - ($y_max % 4)) % 4;
-      $y_max /= $factor;
-    }
-  }
-  else {
-    $y_max = int ($y_max) + 1;
-    $y_max += (4 - ($y_max % 4)) % 4;
-  }
-
-  $unit .= "/" . ($factor == 60 ? "min" : "sec");
-
-  # min range is 4 weeks.
-  my $delta = $x_max - $x_min;
-  $x_min = $x_max - 3024000 if $delta < 3024000;
-  # between 4 weeks and one year, range is a year.
-  $x_min = $x_max - 31536000 if ($delta < 31536000 && $delta > 3024000);
-  # max range is 13 months
-  $x_min = $x_max - 34128000 if $delta > 34128000;
-  my $image = new GD::Image ($xmax, $ymax);
-  my ($white, $black);
-  if (defined $output{'default'}{'graph_fg'}) {
-    my $t = $output{'default'}{'graph_fg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_fg'. Bad color.\n";
-    my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
-    $black = $image->colorAllocate (@c);
-  }
-  else {
-    $black = $image->colorAllocate (  0,   0,   0);
-  }
-  if (defined $output{'default'}{'graph_bg'}) {
-    my $t = $output{'default'}{'graph_bg'};
-    $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-    $t =~ m/^[\da-fA-F]{6}$/o ||
-      die "Error in section 'default' section 'graph_bg'. Bad color.\n";
-    my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
-    $white = $image->colorAllocate (@c);
-  }
-  else {
-    $white = $image->colorAllocate (255, 255, 255);
-  }
-  my $bg;
-  if (defined $color_bg) {
-    $color_bg =~ m/^\#[\da-fA-F]{6}$/o ||
-      die "Error in section 'index'. Bad color $color_bg.\n";
-    my @c = map { hex $_ } ($color_bg =~ m/^\#(..)(..)(..)$/);
-    $bg = $image->colorAllocate (@c);
-  }
-  else {
-    $bg = $image->colorAllocate (255, 255, 206);
-  }
-  my $col_in;
-  if (defined $color_in) {
-    $color_in =~ m/^\#[\da-fA-F]{6}$/o ||
-      die "Error in section 'index'. Bad color $color_in.\n";
-    my @c = map { hex $_ } ($color_in =~ m/^\#(..)(..)(..)$/);
-    $col_in = $image->colorAllocate (@c);
-  }
-  else {
-    $col_in = $image->colorAllocate ( 80, 159, 207);
-  }
-  my $col_out;
-  my @col_out = (  0,   0, 255);
-  if (defined $color_out) {
-    $color_out =~ m/^\#[\da-fA-F]{6}$/o ||
-      die "Error in section 'index'. Bad color $color_out.\n";
-    my @c = map { hex $_ } ($color_out =~ m/^\#(..)(..)(..)$/);
-    $col_out = $image->colorAllocate (@c);
-    @col_out = @c;
-  }
-  else {
-    $col_out = $image->colorAllocate (@col_out);
-  }
-
-  my $white2  = $image->colorAllocate (255, 255, 255);
-  my $gray    = $image->colorAllocate (192, 192, 192);
-  my $red     = $image->colorAllocate (255,   0,   0);
-  my $coltxt  = $black;
-
-  my $size    = 22; # legend
-  # legend statistics
-  my ($max_in, $max_out) = (0, 0);         # min
-  my ($min_in, $min_out) = (1E10, 1E10);   # max
-  my ($t_in, $t_out) = (0, 0);             # time
-  my ($s_in, $s_out) = (0, 0);             # sum
-
-  $image->filledRectangle (0, 0, $xmax, $ymax, $gray);
-  $image->transparent ($gray) if $transparent;
-
-  my $FontWidth = gdSmallFont->width;
-  my $FontHeight = gdSmallFont->height;
-  $image->setStyle ($black, &GD::gdTransparent, &GD::gdTransparent);
-
-  my $marginl = 13 + $FontWidth * length (sprintf "%d", $y_max * $factor);
-  my $marginr = 15 + 4 * $FontWidth; # "100%"
-  my $margint = 2 * $FontHeight + gdMediumBoldFont->height;
-  my $marginb = 2 * $FontHeight + $size;
-  my $xratio = ($xmax - $marginl - $marginr) / ($x_max - $x_min);
-  my $yratio = ($ymax - $margint - $marginb) / ($y_max - $y_min);
-
-  my $frame = new GD::Polygon;
-  $frame->addPt(2, $margint - $FontHeight -3);
-  $frame->addPt($xmax - 2, $margint - $FontHeight -3);
-  $frame->addPt($xmax - 2, $ymax - 3);
-  $frame->addPt(2, $ymax - 3);
-  $image->filledPolygon($frame, $white2);
-  $image->polygon($frame, $black);
-
-  $image->filledRectangle ($marginl, $margint,
-                          $xmax - $marginr, $ymax - $marginb, $bg);
-  my $brush = new GD::Image(1, 2);
-  my $b_col = $brush->colorAllocate(@col_out);
-  $brush->line(0, 0, 0, 1, $b_col);
-  $image->setBrush($brush);
-  my ($old_x, $old_y_in, $old_y_out);
-  foreach $key (sort keys %$dates) {
-    next if $key < $x_min;
-    my $delta = $$dates{$key} - $key;
-    $min_in  = $$in{$key} / $delta  if $min_in  > $$in{$key} / $delta;
-    $max_in  = $$in{$key} / $delta  if $max_in  < $$in{$key} / $delta;
-    $min_out = $$out{$key} / $delta if $min_out > $$out{$key} / $delta;
-    $max_out = $$out{$key} / $delta if $max_out < $$out{$key} / $delta;
-    $t_in   += $delta;
-    $s_in   += $$in{$key};
-    $s_out  += $$out{$key};
-
-    my $tt_in  = $$in{$key} / ($$dates{$key} - $key) * $yratio;
-    my $tt_out = $$out{$key} / ($$dates{$key} - $key) * $yratio;
-    my $new_x = $marginl + ($key - $x_min) * $xratio;
-    $image->filledRectangle ($marginl + ($key - $x_min) * $xratio,
-                      $ymax - $marginb - $tt_in,
-                      $marginl + ($$dates{$key} - $x_min) * $xratio,
-                      $ymax - $marginb, $col_in);
-    if (defined $old_x) {
-      $old_x = $new_x if $old_x > $new_x;
-      my $poly = new GD::Polygon;
-      $poly->addPt($old_x, $old_y_in);
-      $poly->addPt($new_x, $ymax - $marginb - $tt_in);
-      $poly->addPt($new_x, $ymax - $marginb);
-      $poly->addPt($old_x, $ymax - $marginb);
-      $image->filledPolygon($poly, $col_in);
-    }
-    $image->line ($marginl + ($key - $x_min) * $xratio,
-                      $ymax - $marginb - $tt_out,
-                      $marginl + ($$dates{$key} - $x_min) * $xratio,
-                      $ymax - $marginb - $tt_out, &GD::gdBrushed);
-    $image->line ($old_x, $old_y_out, $new_x,
-                 $ymax - $marginb - $tt_out, $col_out) if defined $old_x;
-    $old_x = $marginl + ($$dates{$key} - $x_min) * $xratio;
-    $old_y_in  = $ymax - $marginb - $tt_in;
-    $old_y_out = $ymax - $marginb - $tt_out;
-  }
-  $t_out = $t_in;
-
-  # main frame
-  $image->rectangle ($marginl, $margint,
-                    $xmax - $marginr, $ymax - $marginb, $black);
-  # graduations
-  my $i;
-  foreach $i (0, 25, 50, 75, 100) {
-    my $t = $ymax - $margint - $marginb;
-    $image->line ($marginl, $ymax - $marginb - $i / 100 * $t,
-                 $xmax - $marginr, $ymax - $marginb - $i / 100 * $t,
-                 &GD::gdStyled);
-    $image->line ($xmax - $marginr, $ymax - $marginb - $i / 100 * $t,
-                 $xmax - $marginr + 3, $ymax - $marginb - $i / 100 * $t,
-                 $black);
-    $image->line ($marginl - 3, $ymax - $marginb - $i / 100 * $t,
-                 $marginl, $ymax - $marginb - $i / 100 * $t,
-                 $black);
-    $image->string (&GD::gdSmallFont, $xmax - $marginr + 8, - $FontHeight / 2 +
-                   $ymax - $marginb - $i / 100 * $t, "$i%", $black);
-    my $s = sprintf "%d", $y_max * $i / 100 * $factor;
-    $image->string (&GD::gdSmallFont, $marginl - 5 - $FontWidth * length $s,
-                   - $FontHeight / 2 +
-                   $ymax - $marginb - $i / 100 * $t, $s, $black);
-  }
-  ##
-  my $w = 604800;      # number of seconds in a week
-  my $y = 31536000;    # number of seconds in a 365 days year
-  my $mm = 2592000;    # number of seconds in a 30 days month
-  if ($x_max - $x_min <= 3024000) { # less than five weeks
-    # unit is a week
-    # 1/1/1990 is a monday. Use this as a basis.
-    my $d = 631152000; # number of seconds between 1/1/1970 and 1/1/1990
-    my $n = int ($x_min / $y);
-    my $t = $x_min - $n * $y - int (($n - 2) / 4) * 24 * 3600;
-    my $f = int ($t / $w);
-    $n = $d + int (($x_min - $d) / $w) * $w;
-    while ($n < $x_max) {
-      $t = $marginl + ($n - $x_min) * $xratio;
-      if ($n > $x_min) {
-       $image->line ($t, $margint, $t, $ymax - $marginb, &GD::gdStyled);
-       $image->line ($t, $ymax - $marginb, $t, $ymax - $marginb + 2, $black);
-      }
-      $image->string (&GD::gdSmallFont, $FontWidth * 7 / 2 + $t,
-                     $ymax - $marginb + 4, (sprintf "Week %02d", $f), $black)
-       if ($n + $w / 2 > $x_min) && ($n + $w / 2 < $x_max);
-      $f++;
-      $n += $w;
-      $t = int ($n / $y);
-      $f = 0
-       if $n - $y * $t - int (($t - 2) / 4) * 24 * 3600 < $w && $f > 50;
-    }
-    $d = 86400;    # 1 day
-    $n = int ($x_min / $y);
-    $t = $n * $y + int (($n - 2) / 4) * 24 * 3600;
-    $i = 0;
-    my $x;
-    while ($t < $x_max) {
-      $x = $marginl + ($t - $x_min) * $xratio;
-      $image->line ($x, $margint, $x, $ymax - $marginb + 2, $red)
-       if $t > $x_min;
-      $t += $mm;
-      $t += $d if $i == 0 || $i == 2 || $i == 4 ||
-                 $i == 6 || $i == 7 || $i == 9 || $i == 11; # 31 days months
-      if ($i == 1) {  # february ?
-       $t -= 2 * $d;
-       $t += $d unless (1970 + int ($t / $y)) % 4;
-      }
-      $i++;
-      $i = 0 if $i == 12; # Happy New Year !!
-    }
-  }
-  else {
-    # unit is a month
-    my $n = int ($x_min / $y);
-    my $t = $n * $y + int (($n - 2) / 4) * 24 * 3600;
-    my @m = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
-            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
-    my $d = 86400;    # 1 day
-    my $i = 0;
-    my $x;
-    while ($t < $x_max) {
-      $x = $marginl + ($t - $x_min) * $xratio;
-      if ($t > $x_min) {
-       $image->line ($x, $margint, $x, $ymax - $marginb, &GD::gdStyled);
-       $image->line ($x, $ymax - $marginb, $x,
-                     $ymax - $marginb + 2, $black);
-       $image->line ($x, $margint, $x, $ymax - $marginb, $red) unless $i;
-      }
-      $image->string (&GD::gdSmallFont,
-                     $mm * $xratio / 2 - $FontWidth * 3 / 2 +
-                     $x, $ymax - $marginb + 4, (sprintf "%s", $m[$i]),
-                     $black)
-       if ($t + 2 * $w > $x_min) && ($x_max > 2 * $w + $t);
-      $t += $mm;
-      $t += $d if ($i == 0 || $i == 2 || $i == 4 ||
-                  $i == 6 || $i == 7 || $i == 9 || $i == 11); # 31 days months
-      if ($i == 1) {  # february ?
-       $t -= 2 * $d;
-       $t += $d unless (1970 + int ($t / $y)) % 4;
-      }
-      $i++;
-      $i = 0 if $i == 12; # Happy New Year !!
-    }
-  }
-
-  # Add the little red arrow
-  my $poly = new GD::Polygon;
-  $poly->addPt($xmax - $marginr - 2, $ymax - $marginb - 3);
-  $poly->addPt($xmax - $marginr + 4, $ymax - $marginb);
-  $poly->addPt($xmax - $marginr - 2, $ymax - $marginb + 3);
-  $image->filledPolygon($poly, $red);
-
-  # Title
-  $image->string (&GD::gdMediumBoldFont,
-                 $xmax / 2 - $FontWidth * length ($title) / 2, 4,
-                 $title, $black);
-
-  # Legend
-  my $y_in = $ymax - $size - $FontHeight + 5;
-  $image->string (&GD::gdSmallFont, $marginl, $y_in, $legend_in, $col_in);
-  $image->string (&GD::gdSmallFont, $xmax / 4, $y_in,
-                 (sprintf "Min: %5.1f $unit", $min_in * $factor), $black);
-  $image->string (&GD::gdSmallFont, $xmax / 2, $y_in,
-               (sprintf "Avg: %5.1f $unit", $s_in / $t_in * $factor), $black);
-  $image->string (&GD::gdSmallFont, 3 * $xmax / 4, $y_in,
-                 (sprintf "Max: %5.1f $unit", $max_in * $factor), $black);
-
-  my $y_out = $ymax - $size + 5;
-  $image->string (&GD::gdSmallFont, $marginl, $y_out, $legend_out, $col_out);
-  $image->string (&GD::gdSmallFont, $xmax / 4, $y_out,
-                 (sprintf "Min: %5.1f $unit", $min_out * $factor), $black);
-  $image->string (&GD::gdSmallFont, $xmax / 2, $y_out,
-             (sprintf "Avg: %5.1f $unit", $s_out / $t_out * $factor), $black);
-  $image->string (&GD::gdSmallFont, 3 * $xmax / 4, $y_out,
-                 (sprintf "Max: %5.1f $unit", $max_out * $factor), $black);
-
-  open (IMG, "> $filename") || die "Error: Can't open \"$filename\": $!\n";
-  if ($GD_FORMAT eq 'png') {
-    print IMG $image->png;
-  }
-  else {
-    print IMG $image->gif;
-  }
-  close IMG;
-  return $ymax;
-}
-
-sub Write_all_results {
-  my $HTML_output = shift;
-  my $h = shift;
-  my $k;
-
-  my $title = $$h{'default'}{'title'} ?
-    $$h{'default'}{'title'} : "Daily Usenet report";
-  $title =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-  $title =~ s/\\\"/\"/go;
-  my $Title = $title;
-  $Title =~ s/<.*?>//go;
-  {
-    my $Title = $Title;
-    $Title =~ s/\&amp;/&/go;
-    $Title =~ s/\&lt;/</go;
-    $Title =~ s/\&gt;/>/go;
-    print "$Title from $first_date to $last_date\n\n";
-  }
-
-  if ($HTML) {
-    my $body = defined $output{'default'}{'html_body'} ?
-      $output{'default'}{'html_body'} : '';
-    $body =~ s/^\"\s*(.*?)\s*\"$/ $1/o;
-    $body =~ s/\\\"/\"/go;
-    open (HTML, "> $HTML_output") || die "Error: cant open $HTML_output\n";
-
-    print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n" .
-      "<HTML>\n<HEAD>\n<TITLE>$Title: $first_date</TITLE>\n" .
-      "<!-- innreport $version -->\n</HEAD>\n<BODY $body>\n" .
-      "$HTML_header\n<CENTER><H1>$title</H1>\n" .
-      "<H3>$first_date -- $last_date</H3>\n</CENTER>\n<P><HR><P>\n";
-
-    # Index
-    print HTML "<UL>\n";
-    foreach $k (@{$$h{'_order_'}}) {
-      next if $k =~ m/^(default|index)$/;
-      my ($data) = $$h{$k}{'data'} =~ m/^\"\s*(.*?)\s*\"$/o;
-      $data =~ s/^\%/\%$CLASS\:\:/ unless $data eq '%prog_type';
-      my %data;
-      { local $^W = 0; no strict; %data = eval $data }
-      my ($string) = $$h{$k}{'title'} =~ m/^\"\s*(.*?)\s*\"$/o;
-      $string =~ s/\s*:$//o;
-      my $want = 1;
-
-      ($want) = $$h{$k}{'skip'} =~ m/^\"?\s*(.*?)\s*\"?$/o
-       if defined $$h{$k}{'skip'};
-      $want = $want eq 'true' ? 0 : 1;
-      print HTML "<LI><A HREF=\"#$k\">$string</A>\n" if %data && $want;
-    }
-    print HTML "</UL><P><HR><P>\n";
-  }
-  if (@unrecognize && $WANT_UNKNOWN) {
-    my $mm = $#unrecognize;
-    print HTML "<A NAME=\"unrecognize\">" if $HTML && $WANT_HTML_UNKNOWN;
-    print "Unknown entries from news log file:\n";
-    print HTML "<STRONG>Unknown entries from news log file:</STRONG></A><P>\n"
-      if $HTML && $WANT_HTML_UNKNOWN;
-    $mm = $MAX_UNRECOGNIZED - 1
-      if $MAX_UNRECOGNIZED > 0 && $mm > $MAX_UNRECOGNIZED - 1;
-    if ($mm < $unrecognize_max && $unrecognize_max > 0) {
-      printf HTML "First %d / $unrecognize_max lines (%3.1f%%)<BR>\n", $mm + 1,
-        ($mm + 1) / $unrecognize_max * 100 if $HTML && $WANT_HTML_UNKNOWN;
-      printf "First %d / $unrecognize_max lines (%3.1f%%)\n", $mm + 1,
-        ($mm + 1) / $unrecognize_max * 100;
-    }
-
-    my $l;
-    for $l (0 .. $mm) {
-      chomp $unrecognize[$l];     # sometimes, the last line need a CR
-      print "$unrecognize[$l]\n"; # so, we always add one
-      if ($HTML && $WANT_HTML_UNKNOWN) {
-       $unrecognize[$l] =~ s/&/\&amp;/g;
-       $unrecognize[$l] =~ s/</\&lt;/g;
-       $unrecognize[$l] =~ s/>/\&gt;/g;
-       print HTML "$unrecognize[$l]<BR>\n";
-      }
-    }
-    print "\n";
-    print HTML "<P><HR><P>\n" if $HTML && $WANT_HTML_UNKNOWN;
-  }
-
-  close HTML if $HTML;
-  foreach $k (@{$$h{'_order_'}}) {
-    next if $k =~ m/^(default|index)$/;
-    &Write_Results($HTML_output, $k, $h);
-  }
-  if ($HTML) {
-    open (HTML, ">> $HTML_output") || die "Error: cant open $HTML_output\n";
-    print HTML <<EOT;
-innreport $version (c) 1996-1999 by Fabien Tassin
-&lt;<A HREF="mailto:fta\@sofaraway.org">fta\@sofaraway.org</A>&gt;.
-EOT
-    if (defined $$h{'default'}{'footer'}) {
-      my ($t) = $$h{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o;
-      $t =~ s/\\\"/\"/go;
-      print HTML "<BR>" . $t;
-    }
-    print HTML "\n$HTML_footer";
-    printf HTML "\n<!-- Running time: %s -->", second2time(time - $start_time);
-    print HTML "\n</BODY>\n</HTML>\n";
-    close HTML;
-  }
-}
-
-sub Write_Results {
-  my $HTML_output = shift;
-  my $report = shift;
-  my $data = shift;
-  my %output = %$data;
-  return 0 unless defined $output{$report}; # no data to write
-  return 0 if defined $output{$report}{'skip'} &&
-              $output{$report}{'skip'} =~ m/^true$/io;
-  my ($TEXT, $HTML, $DOUBLE);
-
-  # Need a text report ?
-  $TEXT = defined $output{$report}{'text'} ? $output{$report}{'text'} :
-    (defined $output{'default'}{'text'} ? $output{'default'}{'text'} : '');
-  die "Error in config file. Field 'text' is mandatory.\n" unless $TEXT;
-  $TEXT = ($TEXT =~ m/^true$/io) ? 1 : 0;
-
-  # Need an html report ?
-  if ($HTML_output) {
-    $HTML = defined $output{$report}{'html'} ? $output{$report}{'html'} :
-      (defined $output{'default'}{'html'} ? $output{'default'}{'html'} : '');
-    die "Error in config file. Field 'html' is mandatory.\n" unless $HTML;
-    $HTML = ($HTML =~ m/^true$/io) ? 1 : 0;
-  }
-  # Double table ?
-  $DOUBLE = defined $output{$report}{'double'} ?
-    $output{$report}{'double'} : 0;
-  $DOUBLE = ($DOUBLE =~ m/^true$/io) ? 1 : 0;
-
-  # Want to truncate the report ?
-  my $TOP = defined $output{$report}{'top'} ? $output{$report}{'top'} : -1;
-  my $TOP_HTML = defined $output{$report}{'top_html'} ?
-                   $output{$report}{'top_html'} : $TOP;
-  my $TOP_TEXT = defined $output{$report}{'top_text'} ?
-                   $output{$report}{'top_text'} : $TOP;
-
-  my (%h, %d, $h);
-  {
-    my $t = $output{$report}{'data'} ||
-      die "Error in section $report. Need a 'data' field.\n";
-    $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-    $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
-    %d = eval $t;
-    return unless %d; # nothing to report. exit.
-    return unless keys (%d); # nothing to report. exit.
-  }
-  {
-    my $t = defined $output{$report}{'sort'} ? $output{$report}{'sort'} :
-      "\$a cmp \$b";
-    $t =~ s/\n/ /smog;
-    $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-    $t =~ s/([\$\%\@])/$1${CLASS}\:\:/go;
-    $t =~ s/([\$\%\@])${CLASS}\:\:(prog_(?:size|type)|key|num)/$1$2/go;
-    $t =~ s/\{\$${CLASS}\:\:(a|b)\}/\{\$$1\}/go;
-    $t =~ s/\$${CLASS}\:\:(a|b)/\$$1/go;
-    $h = $t;
-  }
-
-  if ($HTML) {
-    open (HTML, ">> $HTML_output") || die "Error: cant open $HTML_output\n";
-  }
-  print "\n" if $TEXT;
-  my ($key, $key1, $key2);
-  if (defined $output{$report}{'title'}) {
-    my $t = $output{$report}{'title'};
-    $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-    if ($HTML) {
-      print HTML "<A NAME=\"$report\">";
-      my $html = $t;
-      $html =~ s/(:?)$/ [Top $TOP_HTML]$1/o if $TOP_HTML > 0;
-      $html =~ s|^(.*)$|<STRONG>$1</STRONG>|;
-      print HTML "$html</A>\n<P>\n<CENTER>\n<TABLE BORDER=\"1\">\n";
-    }
-    $t =~ s/(:?)$/ [Top $TOP_TEXT]$1/o if $TOP_TEXT > 0;
-    print "$t\n" if $TEXT;
-  }
-  my $numbering = 0;
-  $numbering = 1 if defined $output{$report}{'numbering'} &&
-                    $output{$report}{'numbering'} =~ m/^true$/o;
-  my $i;
-  my $s = '';
-  my $html = '';
-  my $first = 0;
-
-  foreach $i (@{$output{$report}{'column'}}) {
-    my ($v1, $v2);
-
-    my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
-    $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
-    my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
-    $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
-
-    $v1 = defined ($$i{'format_name'}) ? $$i{'format_name'} :
-      (defined ($$i{'format'}) ? $$i{'format'} : "%s");
-    $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-    $v2 = $$i{'name'};
-    $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-    $s .= sprintf $v1 . " ", $v2 if $wtext && !($DOUBLE && $first == 1);
-    if ($HTML && $whtml) {
-      my $v1 = $v1;
-      $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?(\w)/\%$1/g;
-      my $temp = $first ? "CENTER" : "LEFT";
-      $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
-      $html .= sprintf "<TH ALIGN=\"$temp\">$v1</TH>", $v2;
-    }
-    $first++;
-  }
-  $s =~ s/\s*$//;
-  print "$s\n" if $TEXT;
-  $s = '';
-  if ($HTML) {
-    print HTML "<TR>$html</TR>\n<TR><TD></TD></TR>\n";
-    $html = '';
-  }
-  my $num = 0;
-  my $done;
-  if ($DOUBLE) {
-    my $num_d = 0;
-    foreach $key1 (sort keys (%d)) {
-      $done = 0;
-      $num = 0;
-      $num_d++;
-      $s = '';
-      $html = '';
-      my @res;
-      foreach $key2 (sort {$d{$key1}{$b} <=> $d{$key1}{$a}}
-                    keys (%{$d{$key1}})) {
-       my $first = 0;
-       $num++;
-       foreach $i (@{$output{$report}{'column'}}) {
-         my ($v1, $v2, $p);
-
-         my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
-         $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
-         my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
-         $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
-
-         # is it the primary key ?
-         $p = 0;
-         $p = 1 if defined $$i{'primary'} && $$i{'primary'} =~ m/true/;
-
-         # format
-         $v1 = defined ($$i{'format'}) ? $$i{'format'} : "%s";
-         $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-
-         # value
-         $v2 = $$i{'value'};
-         $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         my $r ='';
-         if ($v2) {
-           $r = &EvalExpr ($v2, $key2, $num, $key1);
-           die "Error in section $report column $$i{'name'}. " .
-             "Invalid 'value' value.\n" unless defined $r;
-         }
-         $res[$first] += $r if $v1 =~ m/\%-?(?:\d+(?:\.\d+)?)?d/o;
-         if ($p) {
-           $s .= sprintf $v1. "\n", $r unless $done || !$wtext;
-           if ($HTML && $whtml) {
-             if ($done) {
-               $html .= "<TD></TD>";
-             }
-             else {
-               $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-               $html .= $numbering ? "<TH ALIGN=\"CENTER\">$num_d</TH>" : '';
-               #  unless $first;
-               $html .= sprintf "<TD ALIGN=\"LEFT\">$v1</TD></TR>\n", $r;
-               $html .= "<TR><TD></TD>";
-             }
-           }
-         }
-         else {
-           if ($wtext) {
-             $s .= "  " if $first == 1;
-             $s .= sprintf $v1 . " ", $r;
-           }
-           if ($HTML && $whtml) {
-             $html .= $numbering ? "<TD></TD>" : '' if $first == 1;
-             $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-             my $temp = $first > 1 ? "RIGHT" : "LEFT";
-             $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
-           }
-         }
-         $done = 1 if $p;
-         $first++;
-       }
-       $s =~ s/\s*$//;
-       $s =~ s/\\n/\n/g;
-       print "$s\n" if $TEXT && ($num <= $TOP_TEXT || $TOP_TEXT == -1);
-       if ($HTML && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
-         $html =~ s/\\n//g;
-         print HTML "<TR>$html</TR>\n";
-       }
-       $s = '';
-       $html = '';
-      }
-      $first = 0;
-      $s = '';
-      $html = '';
-      if ($TOP_TEXT != -1 && $TOP_HTML != -1) {
-       foreach $i (@{$output{$report}{'column'}}) {
-         if (defined $$i{'primary'} && $$i{'primary'} =~ m/true/o) {
-           $first++;
-           $s .= '  ';
-           $html .= "<TD></TD>" if $HTML;
-           $html .= "<TD></TD>" if $HTML && $numbering;
-           next;
-         }
-         my ($v1, $v2);
-         $v1 = defined ($$i{'format_total'}) ? $$i{'format_total'} :
-           (defined ($$i{'format'}) ? $$i{'format'} : "%s");
-         $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         my $r = $first == 1 ? $num : $res[$first];
-         $s .= sprintf $v1 . " ", $r;
-         if ($HTML) {
-           my $temp = $first > 1 ? "RIGHT" : "LEFT";
-           $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-           $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first > 1;
-           $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
-         }
-         $first++;
-       }
-       $s =~ s/\s*$//;
-       $s =~ s/\\n//g;
-       print "$s\n" if $TEXT;
-       print HTML "<TR>$html</TR>\n" if $HTML;
-      }
-    }
-    print "\n" if $TEXT;
-    print HTML "<TR><TD></TD></TR>\n" if $HTML;
-    $first = 0;
-    $num = $num_d;
-    $s = '';
-    $html = '';
-    foreach $i (@{$output{$report}{'column'}}) {
-      my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
-      $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
-      my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
-      $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
-
-      my ($v1, $v2);
-      $v1 = defined $$i{'format_total'} ? $$i{'format_total'} :
-       (defined $$i{'format'} ? $$i{'format'} : "%s");
-      $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-      $v2 = $$i{'total'} ||
-       die "Error in section $report column $$i{'name'}. " .
-         "Need a 'total' field.\n";
-      $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-      my $r = '';
-      if ($v2) {
-       $r = &EvalExpr ($v2, $key2, $num, 1);
-       die "Error in section $report column $$i{'name'}. " .
-         "Invalid 'total' value.\n" unless defined $r;
-      }
-      $s .= sprintf $v1 . " ", $r if $wtext && $first != 1;
-      if ($HTML && $whtml) {
-       my $temp = $first ? "RIGHT" : "LEFT";
-       $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
-       $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-       $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first;
-       $html .= $first == 1 ? "<TD></TD>" :
-                sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
-      }
-      $first++;
-    }
-    $s =~ s/\s*$//;
-    $s =~ s/\\n//g;
-    print "$s\n" if $TEXT;
-    print HTML "<TR>$html</TR>\n</TABLE>\n</CENTER>\n<P>\n<HR>\n" if $HTML;
-  }
-  else {
-    # foreach $key (sort { local $^W = 0; no strict; eval $h } (keys (%d)))
-    foreach $key ((eval "sort {local \$^W = 0; no strict; $h} (keys (%d))")) {
-      next unless defined $key;
-      next unless defined $d{$key}; # to avoid problems after some undef()
-      $num++;
-      next unless $num <= $TOP_HTML || $TOP_HTML == -1 ||
-                 $num <= $TOP_TEXT || $TOP_TEXT == -1;
-      my $first = 0;
-      foreach $i (@{$output{$report}{'column'}}) {
-       my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
-       $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
-       my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
-       $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
-
-       my ($v1, $v2);
-       $v1 = defined ($$i{'format'}) ? $$i{'format'} : "%s";
-       $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-       $v2 = $$i{'value'};
-       $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-       my $r ='';
-       if ($v2) {
-         $r = &EvalExpr ($v2, $key, $num);
-         die "Error in section $report column $$i{'name'}. " .
-           "Invalid 'value' value.\n" unless defined $r;
-       }
-       $s .= sprintf $v1 . " ", $r
-         if $wtext && (($num <= $TOP_TEXT) || ($TOP_TEXT == -1));
-       if ($HTML && $whtml && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
-         $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-         $html .= "<TH ALIGN=\"CENTER\">$num</TH>" if $numbering && !$first;
-         my $temp = $first ? "RIGHT" : "LEFT";
-         $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
-       }
-       $first++;
-      }
-      $s =~ s/\s*$//;
-      print "$s\n" if $TEXT && ($num <= $TOP_TEXT || $TOP_TEXT == -1);
-      $s = '';
-      if ($HTML && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
-       print HTML "<TR>$html</TR>\n";
-       $html = '';
-      }
-    }
-    print "\n" if $TEXT;
-    print HTML "<TR><TD></TD></TR>\n" if $HTML;
-    $first = 0;
-    foreach $i (@{$output{$report}{'column'}}) {
-      my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
-      $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
-      my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
-      $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
-
-      my ($v1, $v2);
-      $v1 = defined ($$i{'format_total'}) ? $$i{'format_total'} :
-       (defined ($$i{'format'}) ? $$i{'format'} : "%s");
-      $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-      $v2 = $$i{'total'} ||
-       die "Error in section $report column $$i{'name'}. " .
-         "Need a 'total' field.\n";
-      $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-      my $r = '';
-      if ($v2) {
-       $r = &EvalExpr ($v2, $key, $num);
-       die "Error in section $report column $$i{'name'}. " .
-         "Invalid 'total' value.\n" unless defined $r;
-      }
-      $s .= sprintf $v1 . " ", $r if $wtext;
-      if ($HTML && $whtml) {
-       $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
-       my $temp = $first ? "RIGHT" : "LEFT";
-       $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
-       $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first;
-       $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
-      }
-      $first++;
-    }
-    $s =~ s/\s*$//;
-    print "$s\n" if $TEXT;
-    if ($HTML) {
-      print HTML "<TR>$html</TR>\n";
-      print HTML "</TABLE>\n</CENTER><P>\n";
-
-      my $i = 0;
-      while ($GRAPH && defined ${${$output{$report}{'graph'}}[$i]}{'type'}) {
-       my $type = ${${$output{$report}{'graph'}}[$i]}{'type'};
-        my ($title) = ${${$output{$report}{'graph'}}[$i]}{'title'} =~
-                      m/^\"\s*(.*?)\s*\"$/o;
-        if ($type eq 'histo3d') {
-         my (@values, @colors, @labels);
-         my $num = 0;
-         my $j;
-         foreach $j (@{${${$output{$report}{'graph'}}[$i]}{'data'}}) {
-           $num++;
-           my ($h) = $$j{'value'} =~ m/^\"\s*(.*?)\s*\"$/o;
-           my %hh;
-           $h =~ s/^\%/\%$CLASS\:\:/ unless $h eq '%prog_type';
-           { local $^W = 0; no strict; %hh = eval $h }
-           push @values, \%hh;
-           my ($t) = $$j{'name'} =~ m/^\"\s*(.*?)\s*\"$/o;
-           push @labels, $t;
-           $t = $$j{'color'} ||
-             die "Error in section $report section 'graph'. " .
-               "No color specified for 'value' $$j{'value'}.\n";
-           $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
-           $t =~ m/^[\da-fA-F]{6}$/o ||
-             die "Error in section $report section 'graph'. " .
-               "Bad color for 'value' $$j{'value'}.\n";
-           my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
-           push @colors, \@c;
-         }
-         $suffix = '' unless defined $suffix;
-         my $s = ($i ? $i : '') . $suffix;
-         print HTML "<CENTER><IMG ALT=\"$title\" ";
-         close HTML;
-         my $y = &Graph3d ("$IMG_dir/$report$s.$GD_FORMAT",
-                   $title, $xmax, $num, @values, \@colors, \@labels);
-         open (HTML, ">> $HTML_output") ||
-           die "Error: cant open $HTML_output\n";
-         print HTML "WIDTH=\"$xmax\" HEIGHT=\"$y\" ";
-         print HTML "SRC=\"$IMG_pth$report$s.$GD_FORMAT\"></CENTER>\n";
-       }
-        elsif ($type eq 'histo') {
-         my (%values, %labels);
-         my $factor =
-           ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'factor'}
-             || die "Error in section $report section 'graph'. " .
-              "No factor specified for 'value' " .
-              ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'} .
-              ".\n";
-         $factor =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         my $labelx =
-           ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'name'}
-            || die "Error in section $report section 'graph'. " .
-              "No name specified for value.\n";
-         $labelx =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         my $labely =
-           ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'}
-            || die "Error in section $report section 'graph'. " .
-              "No name specified for value.\n";
-         $labely =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         my $t = ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'value'}
-            || die "Error in section $report section 'graph'. " .
-              "No 'value' specified for " .
-              ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'name'} .
-              ".\n";
-         $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
-         { local $^W = 0; no strict; %labels = eval $t }
-
-         $t = ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'value'} ||
-            die "Error in section $report section 'graph'. " .
-              "No 'value' specified for " .
-              ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'} .
-              ".\n";
-         $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
-         $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
-         { local $^W = 0; no strict; %values = eval $t }
-         my $s = ($i ? $i : '') . $suffix;
-         {
-           my $r;
-           close HTML;
-           $r = &Histo ("$IMG_dir/$report$s.$GD_FORMAT", $title, $xmax,
-                        $factor, $labelx, $labely, \%values, \%labels);
-           open (HTML, ">> $HTML_output") ||
-             die "Error: cant open $HTML_output\n";
-           print HTML "<CENTER><IMG ALT=\"$title\" WIDTH=\"$xmax\" " .
-             "SRC=\"$IMG_pth$report$s.$GD_FORMAT\"></CENTER>\n" if $r;
-         }
-       }
-        elsif ($type eq 'piechart') {
-         print "Sorry, graph type 'piechart' not supported yet..\n";
-       }
-        else {
-         die "Error in section $report section 'graph'. " .
-           "Invalid 'type' value.\n"
-       }
-       $i++;
-       print HTML "<P>\n";
-      }
-      print HTML "\n<HR>\n";
-    }
-  }
-  close HTML if $HTML;
-}
-
-sub EvalExpr {
-  my $v = shift;
-  my ($key, $num, $key1) = @_;
-  my $key2;
-
-  $v =~ s/\n/ /smog;
-  $v =~ s/^\"(.*?)\"$/$1/o;
-  if ($key1) {
-    $key2 = $key;
-    $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%/$1&ComputeTotalDouble\(\\%/og;
-  }
-  else {
-    $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%/$1&ComputeTotal\(\\%/og;
-    # $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%([^\)]*)\)/$1&ComputeTotal\("$2"\)/og;
-  }
-  $v =~ s/([^a-zA-Z_\-]?)bytes\s*\(\s*/$1&NiceByte\(/og;
-  $v =~ s/([^a-zA-Z_\-]?)time\s*\(\s*/$1&second2time\(/og;
-  $v =~ s/([^a-zA-Z_\-]?)time_ms\s*\(\s*/$1&ms2time\(/og;
-  # $v =~ s/([\$\%\@])/$1${CLASS}\:\:/og;
-  $v =~ s/([\$\%\@])([^{\s\d])/$1${CLASS}\:\:$2/og;
-  $v =~ s/([\$\%\@])${CLASS}\:\:(prog_(?:size|type)|key|sec_glob|num)/$1$2/og;
-  my $r;
-  # eval { local $^W = 0; no strict; ($r) = eval $v; };
-  eval " local \$^W = 0; no strict; (\$r) = $v; ";
-  $r = 0 unless defined $r;
-  $r;
-}
-
-sub NiceByte {
-  my $size = shift;
-  my $t;
-
-  $size = 0 unless defined $size;
-  $t = $size / 1024 / 1024 / 1024 > 1 ?
-    sprintf "%.1f GB", $size / 1024 / 1024 / 1024 :
-      ($size / 1024 / 1024 > 1 ? sprintf "%.1f MB", $size / 1024 / 1024 :
-       sprintf "%.1f KB", $size / 1024);
-  return $t;
-}
-
-sub kb2i {
-  my $s = shift;
-  my ($i, $u) = $s =~ m/^(\S+) (\S+)$/;
-  $i *= 1024 * 8 if $u =~ m/MB/o;
-  $i *= 1024 * 1024 * 8 if $u =~ m/GB/o;
-  return $i;
-}
-
-sub Decode_Config_File {
-  my $file = shift;
-  my ($line, $section);
-  my $linenum = 0;
-  my $info;
-  my @list;
-  open (FILE, "$file") || die "Can\'t open config file \"$file\". Abort.\n";
-  while (defined ($line = <FILE>)) {
-    $linenum++;
-    last if eof (FILE);
-    ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-    die "Error in $file line $linenum: must be 'section' instead of '$info'\n"
-      unless ($info eq 'section');
-    ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-    die "Error in $file line $linenum: invalid section name '$info'\n"
-      unless $info =~ /^\w+$/;
-    print "section $info {\n" if $DEBUG;
-    $section = $info;
-    ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-    die "Error in $file line $linenum: must be a '{' instead of '$info'\n"
-      unless ($info eq '{');
-    ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-    push @list, $section;
-    while ($info ne '}') { # it is a block
-      last if eof (FILE);
-      my $keyword = $info;
-      ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-      my $value = $info;
-      if ($info eq '{') { # it is a sub-block
-       my @a;
-       $output{$section}{$keyword} = \@a unless $output{$section}{$keyword};
-       my %hash;
-       print "\t$keyword {\n" if $DEBUG;
-       ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-       my @sublist; # to store the "data" blocks
-
-       while ($info ne '}') {
-         last if eof (FILE);
-         my $subkeyword = $info;
-         ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-         my $subvalue = $info;
-         if ($info eq '{') {
-           # it is a sub-sub-block
-           my %subhash;
-           print "\t\t$subkeyword {\n" if $DEBUG;
-           my @b;
-           $hash{$subkeyword} = \@b unless ${hash}{$subkeyword};
-           ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-           while ($info ne '}') {
-             last if eof (FILE);
-             my $subsubkeyword = $info;
-             ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-             my $subsubvalue = $info;
-             if ($info eq '{') {
-               die "Error in $file line $linenum: too many blocks.\n";
-             }
-             else {
-               ($info, $linenum, $line) =
-                 &read_conf ($linenum, $line, \*FILE);
-               die "Error in $file line $linenum: must be a ';' instead " .
-                 "of '$info'\n" unless ($info eq ';');
-               print "\t\t\t$subsubkeyword\t$subsubvalue;\n" if $DEBUG;
-               $subhash{$subsubkeyword} = $subsubvalue;
-               ($info, $linenum, $line) =
-                 &read_conf ($linenum, $line, \*FILE);
-             }
-           }
-           ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-           die "Error in $file line $linenum: must be a ';' instead of " .
-             "'$info'\n" unless $info eq ';';
-           push @{$hash{$subkeyword}} , \%subhash;
-            ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-           print "\t\t};\n" if $DEBUG;
-         }
-         else {
-           ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-           die "Error in $file line $linenum: must be a ';' instead " .
-             "of '$info'\n" unless $info eq ';';
-           print "\t\t$subkeyword\t$subvalue;\n" if $DEBUG;
-           $hash{$subkeyword} = $subvalue;
-           ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-         }
-       }
-       ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-        die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
-         unless $info eq ';';
-       push @{$output{$section}{$keyword}}, \%hash;
-       ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-       print "\t};\n" if $DEBUG;
-      }
-      else {
-       ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-        die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
-         unless $info eq ';';
-       print "\t$keyword\t$value;\n" if $DEBUG;
-       $output{$section}{$keyword} = $value;
-       ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-      }
-    }
-    die "Error in $file line $linenum: must be a '}' instead of '$info'\n"
-      unless $info eq '}';
-    ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
-    die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
-      unless $info eq ';';
-    print "};\n\n" if $DEBUG;
-  }
-  close FILE;
-  $output{'_order_'} = \@list;
-}
-
-sub read_conf {
-  my ($linenum, $line, $file) = @_;
-  *FILE = *$file;
-
-  $line =~ s,^\s+,,o;            # remove useless blanks
-  $line =~ s,^(\#|//).*$,,o;     # remove comments (at the beginning)
-  while (($line =~ m/^$/o || $line =~ m/^\"[^\"]*$/o) && !(eof (FILE))) {
-    $line .= <FILE>;             # read one line
-    $linenum++;
-    $line =~ s,^\s*,,om;         # remove useless blanks
-    $line =~ s,^(\#|//).*$,,om;  # remove comments (at the beginning)
-  }
-  $line =~ s/^(                  # at the beginning
-              [{};]             # match '{', '}', or ';'
-             |                  # OR
-              \"                # a double quoted string
-                (?:\\.|[^\"\\])*
-               \"
-             |                  # OR
-               [^{};\"\s]+       # a word
-             )\s*//mox;
-  my $info = $1;
-  if (defined $info && $info) {
-    chomp $info;
-  }
-  else {
-    warn "Syntax error in conf file line $linenum.\n";
-  }
-  return ($info, $linenum, $line);
-}
-
-sub GetValue {
-  my $v = shift;
-  my ($r) = $v =~ m/^(?:\"\s*)?(.*?)(?:\s*\")?$/so;
-  return $r;
-}
-
-sub Usage {
-  my ($base) = $0 =~ /([^\/]+)$/;
-  print "Usage: $base -f innreport.conf [-[no]options]\n";
-  print "  where options are:\n";
-  print "    -h (or -help)       this help page\n";
-  print "    -v                  display the version number of INNreport\n";
-  print "    -config             print INNreport configuration information\n";
-  print "    -html               HTML output";
-  print " [default]" if ($HTML);
-  print "\n";
-  print "    -g                  want graphs";
-  print " [default]" if ($GRAPH);
-  print "\n";
-  print "    -graph              an alias for option -g\n";
-  print "    -d directory        directory for Web pages";
-  print "\n                        [default=$HTML_dir]"
-    if (defined ($HTML_dir));
-  print "\n";
-  print "    -dir directory      an alias for option -d\n";
-  print "    -p directory        pictures path (file space)";
-  print "\n                        [default=$IMG_dir]"
-    if (defined ($IMG_dir));
-  print "\n";
-  print "    -path directory     an alias for option -p\n";
-  print "    -w directory        pictures path (web space)";
-  print " [default=$IMG_pth]" if (defined ($IMG_pth));
-  print "\n";
-  print "    -webpath directory  an alias for option -w\n";
-  print "\n";
-  print "    -i file             Name of index file";
-  print " [default=$index]" if (defined ($index));
-  print "\n";
-  print "    -index file         an alias for option -i\n";
-  print "    -a                  want to archive HTML results";
-  print " [default]" if ($ARCHIVE);
-  print "\n";
-  print "    -archive            an alias for option -a\n";
-  print "    -c number           how many report files to keep (0 = all)\n";
-  print "                        [default=$CYCLE]"
-    if (defined ($CYCLE));
-  print "\n";
-  print "    -cycle number       an alias for option -c\n";
-  print "    -s char             separator for filename";
-  print " [default=\"$SEPARATOR\"]\n";
-  print "    -separator char     an alias for option -s\n";
-  print "    -unknown            \"Unknown entries from news log file\"\n";
-  print "                        report";
-  print " [default]" if ($WANT_UNKNOWN);
-  print "\n";
-  print "    -html-unknown       Same as above, but in generated HTML output.";
-  print " [default]" if ($WANT_UNKNOWN);
-  print "\n";
-  print "    -maxunrec           Max number of unrecognized lines to display\n";
-  print "                        [default=$MAX_UNRECOGNIZED]"
-    if (defined ($MAX_UNRECOGNIZED));
-  print "\n";
-  print "    -notdaily           Never perform daily actions";
-  print " [default]" if $NOT_DAILY;
-  print "\n";
-  print "    -casesensitive      Case sensitive";
-  print " [default]" if ($CASE_SENSITIVE);
-  print "\n\n";
-  print "Use no in front of boolean options to unset them.\n";
-  print "For example, \"-html\" is set by default. Use \"-nohtml\" to remove this\n";
-  print "feature.\n";
-  exit 0;
-}
-
-sub Version {
-  print "\nThis is INNreport version $version\n\n";
-  print "Copyright 1996-1999, Fabien Tassin <fta\@sofaraway.org>\n";
-  exit 0;
-}
-
-sub Summary {
-  use Config;
-
-  # Convert empty arguments into null string ("")
-  my $i = 0;
-  foreach (@old_argv) {
-    $old_argv[$i] = '""' if $_ eq '';
-    $i++;
-  }
-
-  # Display the summary
-  print "\nSummary of my INNreport (version $version) configuration:\n";
-  print "  General options:\n";
-  print "    command line='@old_argv' (please, check this value)\n";
-  print "    html=" . ($HTML?"yes":"no") . ", graph=" .
-                      ($GRAPH?"yes":"no") . ", haveGD=" .
-                      ($::HAVE_GD?"yes":"no") . "\n";
-  print "    archive=" . ($ARCHIVE?"yes":"no") .
-                      ", cycle=$CYCLE, separator=\"" . $SEPARATOR . "\"\n";
-  print "    case_sensitive=" .
-                      ($CASE_SENSITIVE?"yes":"no") . ", want_unknown=" .
-                     ($WANT_UNKNOWN?"yes":"no") .
-                      ", max_unrecog=$MAX_UNRECOGNIZED\n";
-  print "  Paths:\n";
-  print "    html_dir=$HTML_dir\n";
-  print "    img_dir=$IMG_dir\n";
-  print "    img_pth=$IMG_pth\n";
-  print "    index=$index\n";
-  print "  Platform:\n";
-  print "    perl version $::Config{baserev} "
-            . "patchlevel $::Config{patchlevel} "
-            . "subversion $::Config{subversion}\n";
-  print "    libperl=$::Config{libperl}, useshrplib=$::Config{useshrplib}, "
-       . "bincompat3=$::Config{bincompat3}\n";
-  print "    osname=$::Config{osname}, osvers=$::Config{osvers}, "
-        . "archname=$::Config{archname}\n";
-  print "    uname=$::Config{myuname}\n\n";
-
-  exit 0;
-}
-
-######################### End of File ##########################
diff --git a/scripts/innreport_inn.pm b/scripts/innreport_inn.pm
deleted file mode 100644 (file)
index 4043f3e..0000000
+++ /dev/null
@@ -1,2227 +0,0 @@
-##########################################################
-# INN module for innreport (3.*).
-#
-# Sample file tested with INN 2.4, 2.3, 2.2, 1.7.2 and 1.5.1
-#
-# (c) 1997-1999 by Fabien Tassin <fta@sofaraway.org>
-# version 3.0.2
-##########################################################
-
-# TODO: add the map file.
-
-package innreport_inn;
-
-my $MIN = 1E10;
-my $MAX = -1;
-
-my %ctlinnd = ('a', 'addhist',     'D', 'allow',
-              'b', 'begin',       'c', 'cancel',
-              'u', 'changegroup', 'd', 'checkfile',
-              'e', 'drop',        'f', 'flush',
-              'g', 'flushlogs',   'h', 'go',
-              'i', 'hangup',      's', 'mode',
-              'j', 'name',        'k', 'newgroup',
-              'l', 'param',       'm', 'pause',
-              'v', 'readers',     't', 'refile',
-              'C', 'reject',      'o', 'reload',
-              'n', 'renumber',    'z', 'reserve',
-              'p', 'rmgroup',     'A', 'send',
-              'q', 'shutdown',    'B', 'signal',
-              'r', 'throttle',    'w', 'trace',
-              'x', 'xabort',      'y', 'xexec',
-              'E', 'logmode',     'F', 'feedinfo',
-              'T', 'filter',      'P', 'perl',);
-
-my %timer_names = (idle     => 'idle',
-                   hishave  => 'history lookup',
-                   hisgrep  => 'history grep',
-                   hiswrite => 'history write',
-                   hissync  => 'history sync',
-                   nntpread => 'nntp read',
-                   artparse => 'article parse',
-                   artclean => 'article cleanup',
-                   artwrite => 'article write',
-                   artcncl  => 'article cancel',
-                   artlog   => 'article logging',
-                   sitesend => 'site send',
-                   overv    => 'overview write',
-                   perl     => 'perl filter',
-                   python   => 'python filter',
-                   datamove => 'data move'
-);
-
-my %innfeed_timer_names = (
-                   'idle'    => 'idle',
-                  'blstats' => 'backlog stats',
-                  'stsfile' => 'status file',
-                  'newart'  => 'article new',
-                  'prepart' => 'article prepare',
-                  'readart' => 'article read',
-                  'read'    => 'data read',
-                  'write'   => 'data write',
-                  'cb'      => 'callbacks',
-);
-
-my %nnrpd_timer_names = (
-                   'idle'    => 'idle',
-                   'newnews' => 'newnews',
-);
-
-# init innd timer
-foreach (values %timer_names) {
-  $innd_time_min{$_} = $MIN;
-  $innd_time_max{$_} = $MAX;
-  $innd_time_time{$_} = 0;   # to avoid a warning... Perl < 5.004
-  $innd_time_num{$_} = 0;    # ...
-}
-$innd_time_times = 0;        # ...
-
-# init innfeed timer
-foreach (values %innfeed_timer_names) {
-  $innfeed_time_min{$_} = $MIN;
-  $innfeed_time_max{$_} = $MAX;
-  $innfeed_time_time{$_} = 0;   # to avoid a warning... Perl < 5.004
-  $innfeed_time_num{$_} = 0;    # ...
-}
-$innfeed_time_times = 0;        # ...
-
-# init nnrpd timer
-foreach (values %nnrpd_timer_names) {
-  $nnrpd_time_min{$_} = $MIN;
-  $nnrpd_time_max{$_} = $MAX;
-  $nnrpd_time_time{$_} = 0;   # to avoid a warning... Perl < 5.004
-  $nnrpd_time_num{$_} = 0;    # ...
-}
-$nnrpd_time_times = 0;        # ...
-
-# collect: Used to collect the data.
-sub collect {
-  my ($day, $hour, $prog, $res, $left, $CASE_SENSITIVE) = @_;
-
-  return 1 if $left =~ /Reading config from (\S+)$/o;
-
-  ########
-  ## inn (from the "news" log file - not from "news.notice")
-  ##
-  if ($prog eq "inn") {
-    # accepted article
-    if ($res =~ m/[\+j]/o) {
-      $hour =~ s/:.*$//o;
-      $inn_flow{"$day $hour"}++;
-      $inn_flow_total++;
-
-      # Memorize the size. This can only be done with INN >= 1.5xx and
-      # DO_LOG_SIZE = DO.
-
-      # server <msg-id> size [feeds]
-      # or
-      # server <msg-id> (filename) size [feeds]
-
-      my ($s) = $left =~ /^\S+ \S+ (?:\(\S+\) )?(\d+)(?: |$)/o;
-      if ($s) {
-       $inn_flow_size{"$day $hour"} += $s;
-       $inn_flow_size_total += $s;
-      }
-      return 1;
-    }
-
-    # 437 Duplicate article
-    if ($left =~ /(\S+) <[^>]+> 437 Duplicate(?: article)?$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_duplicate{$server}++;
-      return 1;
-    }
-    # 437 Unapproved for
-    if ($left =~ /(\S+) <[^>]+> 437 Unapproved for \"([^\"]+)\"$/o) {
-      my ($server, $group) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_unapproved{$server}++;
-      $inn_unapproved_g{$group}++;
-      return 1;
-    }
-    # 437 Too old -- ...
-    if ($left =~ /(\S+) <[^>]+> 437 Too old -- /o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_tooold{$server}++;
-      return 1;
-    }
-    # 437 Unwanted site ... in path
-    if ($left =~ /(\S+) <[^>]+> 437 Unwanted site (\S+) in path$/o) {
-      my ($server, $site) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_uw_site{$server}++;
-      $inn_site_path{$site}++;
-      return 1;
-    }
-    # 437 Unwanted newsgroup "..."
-    if ($left =~ /(\S+) <[^>]+> 437 Unwanted newsgroup \"(\S+)\"$/o) {
-      my ($server, $group) = ($1, $2);
-      ($group) = split(/,/, $group);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_uw_ng_s{$server}++;
-      $inn_uw_ng{$group}++;
-      return 1;
-    }
-    # 437 Unwanted distribution "..."
-    if ($left =~ /(\S+) <[^>]+> 437 Unwanted distribution \"(\S+)\"$/o) {
-      my ($server, $dist) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_uw_dist_s{$server}++;
-      $inn_uw_dist{$dist}++;
-      return 1;
-    }
-    # 437 Linecount x != y +- z
-    if ($left =~ /(\S+) <[^>]+> 437 Linecount/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $inn_linecount{$server}++;
-      return 1;
-    }
-    # 437 No colon-space in "xxxx" header
-    if ($left =~ /(\S+) <[^>]+> 437 No colon-space in \"[^\"]+\" header/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $innd_others{$server}++;
-      $innd_no_colon_space{$server}++;
-      return 1;
-    }
-    # 437 Article posted in the future -- "xxxxx"
-    if ($left =~ /(\S+) <[^>]+> 437 Article posted in the future -- \"[^\"]+\"/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_posted_future{$server}++;
-      $innd_others{$server}++;
-      $inn_badart{$server}++;
-      return 1;
-    }
-    # 437 article includes "....."
-    if ($left =~ /(\S+) <[^>]+> 437 article includes/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_strange_strings{$server}++;
-      $innd_others{$server}++;
-      $inn_badart{$server}++;
-      return 1;
-    }
-    # Cancelling <...>
-    if ($left =~ /(\S+) <[^>]+> Cancelling/o) {
-      return 1;
-    }
-    # all others are just counted as "Other"
-    if ($left =~ /(\S+) /o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $inn_badart{$server}++;
-      $innd_others{$server}++;
-      return 1;
-    }
-  }
-
-  ########
-  ## innd
-  if ($prog eq "innd") {
-    ## Note for innd logs:
-    ## there's a lot of entries detected but still not used
-    ## (because of a lack of interest).
-
-    # think it's a dotquad
-    return 1 if $left =~ /^think it\'s a dotquad$/o;
-    if ($left =~ /^SERVER /o) {
-      # SERVER perl filtering enabled
-      return 1 if $left =~ /^SERVER perl filtering enabled$/o;
-      # SERVER perl filtering disabled
-      return 1 if $left =~ /^SERVER perl filtering disabled$/o;
-      # SERVER Python filtering enabled
-      return 1 if $left =~ /^SERVER Python filtering enabled$/o;
-      # SERVER Python filtering disabled
-      return 1 if $left =~ /^SERVER Python filtering disabled$/o;
-      # SERVER cancelled +id
-      return 1 if $left =~ /^SERVER cancelled /o;
-    }
-    # Python filter
-    return 1 if $left =~ /^defined python methods$/o;
-    return 1 if $left =~ /^reloading pyfilter$/o;
-    return 1 if $left =~ /^reloaded pyfilter OK$/o;
-    return 1 if $left =~ /^python interpreter initialized OK$/o;
-    return 1 if $left =~ /^python method \w+ not found$/o; 
-    return 1 if $left =~ /^python: First load, so I can do initialization stuff\.$/o;
-    return 1 if $left =~ /^python: filter_before_reload executing\.\.\.$/o;
-    return 1 if $left =~ /^python: I\'m just reloading, so skip the formalities\.$/o;
-    return 1 if $left =~ /^python: spamfilter successfully hooked into INN$/o;
-    return 1 if $left =~ /^python: state change from \w+ to \w+ - /o;
-    return 1 if $left =~ /^python: filter_close running, bye!$/o;
-    # rejecting[perl]
-    if ($left =~ /^rejecting\[perl\] <[^>]+> \d+ (.*)/o) {
-      $innd_filter_perl{$1}++;
-      return 1;
-    }
-    # rejecting[python]
-    if ($left =~ /^rejecting\[python\] <[^>]+> \d+ (.*)/o) {
-      $innd_filter_python{$1}++;
-      return 1;
-    }
-    # closed lost
-    return 1 if $left =~ /^\S+ closed lost \d+/o;
-    # new control command
-    if ($left =~ /^ctlinnd command (\w)(:.*)?/o) {
-      my $command = $1;
-      my $cmd = $ctlinnd{$command};
-      $cmd = $command unless $cmd;
-      return 1 if $cmd eq 'flush'; # to avoid a double count
-      $innd_control{"$cmd"}++;
-      return 1;
-    }
-    # old control command (by letter)
-    if ($left =~ /^(\w)$/o) {
-      my $command = $1;
-      my $cmd = $ctlinnd{$command};
-      $cmd = $command unless $cmd;
-      return 1 if $cmd eq 'flush'; # to avoid a double count
-      $innd_control{"$cmd"}++;
-      return 1;
-    }
-    # old control command (letter + reason)
-    if ($left =~ /^(\w):.*$/o) {
-      my $command = $1;
-      my $cmd = $ctlinnd{$command};
-      $cmd = $command unless $cmd;
-      return 1 if $cmd eq 'flush'; # to avoid a double count
-      $innd_control{"$cmd"}++;
-      return 1;
-    }
-    # opened
-    return 1 if $left =~ /\S+ opened \S+:\d+:file$/o;
-    # buffered
-    return 1 if $left =~ /\S+ buffered$/o;
-    # spawned
-    return 1 if $left =~ /\S+ spawned \S+:\d+:proc:\d+$/o;
-    return 1 if $left =~ /\S+ spawned \S+:\d+:file$/o;
-    # running
-    return 1 if $left =~ /\S+ running$/o;
-    # sleeping
-    if ($left =~ /(\S+):\d+:proc:\d+ sleeping$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_blocked{$server}++;
-      return 1;
-    }
-    # blocked sleeping
-    if ($left =~ /(\S+):\d+:proc:\d+ blocked sleeping/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_blocked{$server}++;
-      return 1;
-    }
-    if ($left =~ /(\S+):\d+ blocked sleeping/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_blocked{$server}++;
-      return 1;
-    }
-    # restarted
-    return 1 if $left =~ m/^\S+ restarted$/o;
-    # starting
-    return 1 if $left =~ m/^\S+ starting$/o;
-    # readclose
-    return 1 if $left =~ m/^\S+:\d+ readclose+$/o;
-    # rejected 502
-    if ($left =~ m/^(\S+) rejected 502$/) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_no_permission{$server}++;
-      return 1;
-    }
-    # rejected 505
-    if ($left =~ m/^(\S+) rejected 505$/) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_too_many_connects_per_minute{$server}++;
-      return 1;
-    }
-    # connected
-    if ($left =~ /^(\S+) connected \d+/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_connect{$server}++;
-      return 1;
-    }
-    # closed (with times)
-    if ($left =~ /(\S+):\d+ closed seconds (\d+) accepted (\d+) refused (\d+) rejected (\d+) duplicate (\d+) accepted size (\d+) duplicate size (\d+)(?: rejected size (\d+))?$/o) {
-      my ($server, $seconds, $accepted, $refused, $rejected, $duplicate, $accptsize, $dupsize) =
-       ($1, $2, $3, $4, $5, $6, $7, $8);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_seconds{$server} += $seconds;
-      $innd_accepted{$server} += $accepted;
-      $innd_refused{$server} += $refused;
-      $innd_rejected{$server} += $rejected;
-      $innd_stored_size{$server} += $accptsize;
-      $innd_duplicated_size{$server} += $dupsize;
-      return 1;
-    } elsif ($left =~ /(\S+):\d+ closed seconds (\d+) accepted (\d+) refused (\d+) rejected (\d+)$/o) {
-      # closed (with times)
-      my ($server, $seconds, $accepted, $refused, $rejected) =
-       ($1, $2, $3, $4, $5);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_seconds{$server} += $seconds;
-      $innd_accepted{$server} += $accepted;
-      $innd_refused{$server} += $refused;
-      $innd_rejected{$server} += $rejected;
-      return 1;
-    }
-    # closed (without times (?))
-    return 1 if $left =~ m/\S+ closed$/o;
-    # closed (for a cancel feed - MODE CANCEL)
-    return 1 if $left =~ m/localhost:\d+ closed seconds \d+ cancels \d+$/o;
-    # checkpoint
-    return 1 if $left =~ m/^\S+:\d+ checkpoint /o;
-    # if ($left =~ /(\S+):\d+ checkpoint seconds (\d+) accepted (\d+)
-    #     refused (\d+) rejected (\d+)$/) {
-    #   # Skipped...
-    #   my ($server, $seconds, $accepted, $refused, $rejected) =
-    #      ($1, $2, $3, $4, $5);
-    #   $innd_seconds{$server} += $seconds;
-    #   $innd_accepted{$server} += $accepted;
-    #   $innd_refused{$server} += $refused;
-    #   $innd_rejected{$server} += $rejected;
-    #   return 1;
-    # }
-
-    # flush
-    if ($left =~ /(\S+) flush$/o) {
-      $innd_control{"flush"}++;
-      return 1;
-    }
-    # flush-file
-    if ($left =~ /flush_file/) {
-       $innd_control{"flush_file"}++;
-       return 1;
-     }
-    # too many connections from site
-    if ($left =~ /too many connections from (\S+)/o) {
-      $innd_max_conn{$1}++;
-      return 1;
-    }
-    # overview exit 0 elapsed 23 pid 28461
-    return 1 if $left =~ m/\S+ exit \d+ .*$/o;
-    # internal rejecting huge article
-    if ($left =~ /(\S+) internal rejecting huge article/o) {
-      my $server = $1;
-      $server =~ s/:\d+$//o;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innd_huge{$server}++;
-      return 1;
-    }
-    # internal closing free channel
-    if ($left =~ /(\S+) internal closing free channel/o) {
-      $innd_misc{"Free channel"}++;
-      return 1;
-    }
-    # internal (other)
-    return 1 if $left =~ /\S+ internal/o;
-    # wakeup
-    return 1 if $left =~ /\S+ wakeup$/o;
-    # throttle
-    if ($left =~ /(\S+) throttled? /) {
-      $innd_control{"throttle"}++;
-      return 1;
-    }
-    # profile timer
-    # ME time X nnnn X(X) [...]
-    # The exact timers change from various versions of INN, so try to deal
-    # with this in a general fashion.
-    if ($left =~ m/^\S+\s+                         # ME
-                  time\s(\d+)\s+                  # time
-                   ((?:\S+\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\s(\d+)\s+                  # time
-                   ((?:\S+\s\d+\(\d+\)\s*)+)       # timer values
-                   $/ox) {
-      $innfeed_time_times += $1;
-      my $timers = $2;
-
-      while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) {
-        my $name = $innfeed_timer_names{$1} || $1;
-        my $average = $2 / ($3 || 1);
-        $innfeed_time_time{$name} += $2;
-        $innfeed_time_num{$name} += $3;
-        $innfeed_time_min{$name} = $average
-          if ($3 && $innfeed_time_min{$name} > $average);
-        $innfeed_time_max{$name} = $average
-          if ($3 && $innfeed_time_max{$name} < $average);
-      }
-      return 1;
-    }
-    # xxx grabbing external tape file
-    return 1 if $left =~ m/ grabbing external tape file/o;
-    # hostChkCxns - maxConnections was
-    return 1 if $left =~ m/hostChkCxns - maxConnections was /o;
-    # cxnsleep
-    return 1 if $left =~ m/\S+ cxnsleep .*$/o;
-    # idle
-    return 1 if $left =~ m/\S+ idle tearing down connection$/o;
-    # remote
-    return 1 if $left =~ m/\S+ remote .*$/o;
-    # spooling
-    return 1 if $left =~ m/\S+ spooling no active connections$/o;
-    # ME articles total
-    return 1 if $left =~ m/(?:SERVER|ME) articles total \d+ bytes \d+/o;
-    # ME articles active
-    return 1 if $left =~ m/(?:SERVER|ME) articles active \d+ bytes \d+/o;
-    # connect : Connection refused
-    return 1 if $left =~ m/connect : Connection refused/o;
-    # connect : Network is unreachable
-    return 1 if $left =~ m/connect : Network is unreachable/o;
-    # connect : Address family not supported by protocol
-    return 1 if $left =~ m/connect : Address family not supported by protocol/o;
-    # connect : No route to host
-    return 1 if $left =~ m/connect : No route to host/o;
-    # connection vanishing
-    return 1 if $left =~ m/connection vanishing/o;
-    # can't resolve hostname
-    return 1 if $left =~ m/can\'t resolve hostname/o;
-    # new hand-prepared backlog file
-    return 1 if $left =~ m/new hand-prepared backlog file/o;
-    # flush re-connect failed
-    return 1 if $left =~ m/flush re-connect failed/o;
-    # internal QUIT while write pending
-    return 1 if $left =~ m/internal QUIT while write pending/o;
-    # ME source lost . Exiting
-    return 1 if $left =~ m/(?:SERVER|ME) source lost . Exiting/o;
-    # ME starting innfeed (+version & date)
-    return 1 if $left =~ m/(?:SERVER|ME) starting (?:innfeed|at)/o;
-    # ME finishing at (date)
-    return 1 if $left =~ m/(?:SERVER|ME) finishing at /o;
-    # mode no-CHECK entered
-    return 1 if $left =~ m/mode no-CHECK entered/o;
-    # mode no-CHECK exited
-    return 1 if $left =~ m/mode no-CHECK exited/o;
-    # closed
-    return 1 if $left =~ m/^(\S+) closed$/o;
-    # global (+ seconds offered accepted refused rejected missing)
-    return 1 if $left =~ m/^(\S+) global/o;
-    # idle connection still has articles
-    return 1 if $left =~ m/^(\S+) idle connection still has articles$/o;
-    # missing article for IHAVE-body
-    return 1 if $left =~ m/^(\S+) missing article for IHAVE-body$/o;
-    # cannot continue
-    return 1 if $left =~ m/^cannot continue/o;
-    if ($left =~ /^(?:SERVER|ME)/o) {
-      # ME dropping articles into ...
-      return 1 if $left =~ / dropping articles into /o;
-      # ME dropped ...
-      return 1 if $left =~ / dropped /o;
-      # ME internal bad data in checkpoint file
-      return 1 if $left =~ m/ internal bad data in checkpoint/o;
-      # ME two filenames for same article
-      return 1 if $left =~ m/ two filenames for same article/o;
-      # ME unconfigured peer
-      return 1 if $left =~ m/ unconfigured peer/o;
-      # exceeding maximum article size
-      return 1 if $left =~ m/ exceeding maximum article byte/o;
-      # no space left on device errors
-      return 1 if $left =~ m/ ioerr fclose/o;
-      return 1 if $left =~ m/ lock failed for host/o;
-      return 1 if $left =~ m/ lock file pid-write/o;
-      return 1 if $left =~ m/ locked cannot setup peer/o;
-      return 1 if $left =~ m/ received shutdown signal/o;
-      # unconfigured peer
-      return 1 if $left =~ m/ unconfigured peer/o;
-      # ME lock
-      return 1 if $left =~ m/ lock/o;
-      # ME exception: getsockopt (0): Socket operation on non-socket
-      return 1 if $left =~ m/ exception: getsockopt /o;
-      # ME config aborting fopen (...) Permission denied
-      return 1 if $left =~ m/ config aborting fopen /o;
-      # ME cant chmod innfeed.pid....
-      return 1 if $left =~ m/ cant chmod \S+\/innfeed.pid/o;
-      return 1 if $left =~ m/ tape open failed /o;
-      return 1 if $left =~ m/ oserr open checkpoint file:/o;
-      # ME finishing (quickly)
-      return 1 if $left =~ m/\(quickly\) /o;
-      # ME config: value of streaming is not a boolean
-      return 1 if $left =~ m/config: value of \S+ is not/o;
-    }
-    # hostChkCxn - now: x.xx, prev: x.xx, abs: xx, curr: x
-    return 1 if $left =~ m/ hostChkCxn - now/o;
-    # loading path_to_config_file/innfeed.conf
-    return 1 if $left =~ m/loading /o;
-    # Finnaly, to avoid problems with strange error lines, ignore them.
-    #return 1 if ($left =~ /ME /);
-  }
-  ########
-  ## innxmit
-  if ($prog eq "innxmit") {
-    # 437 Duplicate article
-    if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) 437 Duplicate article$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_duplicate{$server}++;
-      return 1;
-    }
-    # 437 Unapproved for
-    if ($left =~ /(\S+) rejected [^\s]+ \(.*\) 437 Unapproved for \"(.*?)\"$/o) {
-      my ($server, $group) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_unapproved{$server}++;
-      $innxmit_unapproved_g{$group}++;
-      return 1;
-    }
-    # 437 Too old -- ...
-    if ($left =~ /(\S+) rejected [^\s]+ \(.*\) 437 Too old -- \".*?\"$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_tooold{$server}++;
-      return 1;
-    }
-    # 437 Unwanted site ... in path
-    if ($left =~
-      /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted site (\S+) in path$/o) {
-      my ($server, $site) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_uw_site{$server}++;
-      # $innxmit_site_path{$site}++;
-      return 1;
-    }
-    # 437 Unwanted newsgroup "..."
-    if ($left =~
-      /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted newsgroup \"(\S+)\"$/o) {
-      my ($server, $group) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_uw_ng_s{$server}++;
-      $innxmit_uw_ng{$group}++;
-      return 1;
-    }
-    # 437 Unwanted distribution "..."
-    if ($left =~
-      /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted distribution \"(\S+)\"$/o) {
-      my ($server, $dist) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_uw_dist_s{$server}++;
-      $innxmit_uw_dist{$dist}++;
-      return 1;
-    }
-    # xx rejected foo.bar/12345 (foo/bar/12345) 437 Unwanted distribution "..."
-    if ($left =~ /^(\S+) rejected .* 437 Unwanted distribution \"(\S+)\"$/o) {
-      my ($server, $dist) = ($1, $2);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_uw_dist_s{$server}++;
-      $innxmit_uw_dist{$dist}++;
-      return 1;
-    }
-    # 437 Linecount x != y +- z
-    if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) 437 Linecount/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_badart{$server}++;
-      $innxmit_linecount{$server}++;
-      return 1;
-    }
-    # 437 Newsgroup name illegal -- "xxx"
-    if ($left =~ /(\S+) rejected .* 437 Newsgroup name illegal -- "[^\"]*"$/) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_others{$server}++;
-      $innxmit_badart{$server}++;
-      return 1;
-    }
-    # Streaming retries
-    return 1 if ($left =~ /\d+ Streaming retries$/o);
-    # ihave failed
-    if ($left =~ /(\S+) ihave failed/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_ihfail{$server} = 1;
-      if ($left = /436 \S+ NNTP \S+ out of space/o) {
-       $innxmit_nospace{$server}++;
-       return 1;
-      }
-      if ($left = /400 \S+ space/o) {
-       $innxmit_nospace{$server}++;
-       return 1;
-      }
-      if ($left = /400 Bad file/o) {
-       $innxmit_crefused{$server}++;
-       return 1;
-      }
-      if ($left = /480 Transfer permission denied/o) {
-       $innxmit_crefused{$server}++;
-       return 1;
-      }
-    }
-    # stats (new format)
-    if ($left =~
-      /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) accsize (\d+) rejsize (\d+)$/o) {
-      my ($server, $offered, $accepted, $refused, $rejected, $missing, $accbytes, $rejbytes) =
-       ($1, $2, $3, $4, $5, $6, $7, $8);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_offered{$server} += $offered;
-      $innxmit_offered{$server} -= $innxmit_ihfail{$server}
-        if ($innxmit_ihfail{$server});
-      $innxmit_accepted{$server} += $accepted;
-      $innxmit_refused{$server} += $refused;
-      $innxmit_rejected{$server} += $rejected;
-      $innxmit_missing{$server} += $missing;
-      $innxmit_accepted_size{$server} += $accbytes;
-      $innxmit_rejected_size{$server} += $rejbytes;
-      $innxmit_site{$server}++;
-      $innxmit_ihfail{$server} = 0;
-      return 1;
-    }
-    # stats
-    if ($left =~
-      /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+)$/o) {
-      my ($server, $offered, $accepted, $refused, $rejected) =
-       ($1, $2, $3, $4, $5);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_offered{$server} += $offered;
-      $innxmit_offered{$server} -= $innxmit_ihfail{$server}
-        if ($innxmit_ihfail{$server});
-      $innxmit_accepted{$server} += $accepted;
-      $innxmit_refused{$server} += $refused;
-      $innxmit_rejected{$server} += $rejected;
-      $innxmit_site{$server}++;
-      $innxmit_ihfail{$server} = 0;
-      return 1;
-    }
-    # times
-    if ($left =~ /(\S+) times user (\S+) system (\S+) elapsed (\S+)$/o) {
-      my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_times{$server} += $elapsed;
-      return 1;
-    }
-    # connect & no space
-    if ($left =~ /(\S+) connect \S+ 400 No space/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_nospace{$server}++;
-      $innxmit_site{$server}++;
-      return 1;
-    }
-    # connect & NNTP no space
-    if ($left =~ /(\S+) connect \S+ 400 \S+ out of space/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_nospace{$server}++;
-      $innxmit_site{$server}++;
-      return 1;
-    }
-    # connect & loadav
-    if ($left =~ /(\S+) connect \S+ 400 loadav/o) {
-      my $server = $1;
-      if ($left =~ /expir/i) {
-       $server = lc $server unless $CASE_SENSITIVE;
-       $innxmit_expire{$server}++;
-       $innxmit_site{$server}++;
-       return 1;
-      }
-    }
-    # connect 400 (other)
-    if ($left =~ /(\S+) connect \S+ 400/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_crefused{$server}++;
-      $innxmit_site{$server}++;
-      return 1;
-    }
-    # connect failed
-    if ($left =~ /(\S+) connect failed/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_cfail_host{$server}++;
-      $innxmit_site{$server}++;
-      return 1;
-    }
-    # authenticate failed
-    if ($left =~ /(\S+) authenticate failed/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_afail_host{$server}++;
-      $innxmit_site{$server}++;
-      return 1;
-    }
-    # xxx ihave failed 400 loadav [innwatch:hiload] yyy gt zzz
-    if ($left =~ /^(\S+) ihave failed 400 loadav/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $innxmit_hiload{$server}++;
-      return 1;
-    }
-    # ihave failed
-    return 1 if ($left =~ /\S+ ihave failed/o);
-    # requeued (....) 436 No space
-    return 1 if ($left =~ /\S+ requeued \S+ 436 No space/o);
-    # requeued (....) 400 No space
-    return 1 if ($left =~ /\S+ requeued \S+ 400 No space/o);
-    # requeued (....) 436 Can't write history
-    return 1 if ($left =~ /\S+ requeued \S+ 436 Can\'t write history/o);
-    # unexpected response code
-    return 1 if ($left =~ /unexpected response code /o);
-  }
-
-  ########
-  ## nntplink
-  if ($prog eq "nntplink") {
-    $left =~ s/^(\S+):/$1/;
-    # EOF
-    if ($left =~ /(\S+) EOF /o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_eof{$server}++;
-      return 1;
-    }
-    # Broken pipe
-    if ($left =~ /(\S+) Broken pipe$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_bpipe{$server}++;
-      return 1;
-    }
-    # already running - won't die
-    return 1 if $left =~ /\S+ nntplink.* already running /o;
-    # connection timed out
-    if ($left =~ /(\S+) connection timed out/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_bpipe{$server}++;
-      return 1;
-    }
-    # greeted us with 400 No space
-    if ($left =~ /(\S+) greeted us with 400 No space/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_nospace{$server}++;
-      return 1;
-    }
-    # greeted us with 400 loadav
-    if ($left =~ /(\S+) greeted us with 400 loadav/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_hiload{$server}++;
-      return 1;
-    }
-    # greeted us with 400 (other)
-    if ($left =~ /(\S+) greeted us with 400/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      if ($left =~ /expir/i) {
-       $nntplink_expire{$server}++;
-      } else {
-       $nntplink_fail{$server}++;
-      }
-      return 1;
-    }
-    # greeted us with 502
-    if ($left =~ /(\S+) greeted us with 502/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_auth{$server}++;
-      return 1;
-    }
-    # sent authinfo
-    if ($left =~ /(\S+) sent authinfo/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_auth{$server}++;
-      return 1;
-    }
-    # socket()
-    if ($left =~ /(\S+) socket\(\): /o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_sockerr{$server}++;
-      return 1;
-    }
-    # select()
-    if ($left =~ /(\S+) select\(\) /o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_site{$server}++;
-      $nntplink_selecterr{$server}++;
-      return 1;
-    }
-    # sent IHAVE
-    if ($left =~ /(\S+) sent IHAVE/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_ihfail{$server}++;
-      if (($left =~ / 436 /) && ($left =~ / out of space /)) {
-       $nntplink_fake_connects{$server}++;
-       $nntplink_nospace{$server}++;
-      }
-      return 1;
-    }
-    # article .... failed(saved): 436 No space
-    if ($left =~ /(\S+) .* failed\(saved\): 436 No space$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_nospace{$server}++;
-      return 1;
-    }
-    # article .. 400 No space left on device writing article file -- throttling
-    if ($left =~ /(\S+) .* 400 No space left on device writing article file -- throttling$/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_nospace{$server}++;
-      return 1;
-    }
-    # stats
-    if ($left =~ /(\S+) stats (\d+) offered (\d+) accepted (\d+) rejected (\d+) failed (\d+) connects$/o) {
-      my ($server, $offered, $accepted, $rejected, $failed, $connects) =
-       ($1, $2, $3, $4, $5, $6);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_offered{$server} += $offered - $nntplink_ihfail{$server}++;
-      $nntplink_accepted{$server} += $accepted;
-      $nntplink_rejected{$server} += $rejected;
-      $nntplink_failed{$server} += $failed;
-      $nntplink_connects{$server} += $connects;
-      $nntplink_ihfail{$server} = 0;
-      if ($nntplink_fake_connects{$server}) {
-       $nntplink_site{$server} += $nntplink_fake_connects{$server};
-       $nntplink_fake_connects{$server} = 0;
-      } else {
-       $nntplink_site{$server}++;
-      }
-      return 1;
-    }
-    # xmit
-    if ($left =~ /(\S+) xmit user (\S+) system (\S+) elapsed (\S+)$/o) {
-      my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_times{$server} += $elapsed;
-      return 1;
-    }
-    # xfer
-    return 1 if $left =~ /\S+ xfer/o;
-    # Links down .. x hours
-    if ($left =~ /(\S+) Links* down \S+ \d+/o) {
-      # Collected but not used
-      # my $server = $1;
-      # $server = lc $server unless $CASE_SENSITIVE;
-      # $nntplink_down{$server} += $hours;
-      return 1;
-    }
-    # 503 Timeout
-    if ($left =~ /^(\S+) \S+ \S+ \S+ 503 Timeout/o) {
-      # Collected but not used
-      # my $server = $1;
-      # $server = lc $server unless $CASE_SENSITIVE;
-      # $nntplink_timeout{$server}++;
-      return 1;
-    }
-    # read() error while reading reply
-    if ($left =~ /^(\S+): read\(\) error while reading reply/o) {
-      my $server = $1;
-      $server = lc $server unless $CASE_SENSITIVE;
-      $nntplink_failed{$server}++;
-      return 1;
-    }
-    # Password file xxxx not found
-    return 1 if $left =~ /^\S+ Password file \S+ not found/;
-    # No such
-    return 1 if $left =~ /^\S+ \S+ \S+ No such/;
-    # already running
-    return 1 if $left =~ /^\S+ \S+ already running/;
-    # error reading version from datafile
-    return 1 if $left =~ /error reading version from datafile/;
-  }
-  ########
-  ## nnrpd
-  if ($prog =~ /^nnrpd(?:-ssl)?$/)
-  {
-    # Fix a small bug of nnrpd (inn 1.4*)
-    $left =~ s/^ /\? /o;
-    # Another bug (in INN 1.5b1)
-    return 1 if $left =~ /^\020\002m$/o; # ^P^Bm
-    # bad_history at num for <ref>
-    return 1 if $left =~ /bad_history at \d+ for /o;
-    # timeout short
-    return 1 if $left =~ /\S+ timeout short$/o;
-    # < or > + (blablabla)
-    return 1 if $left =~ /^\S+ [\<\>] /o;
-    # cant opendir ... I/O error
-    return 1 if $left =~ /\S+ cant opendir \S+ I\/O error$/o;
-    # perl filtering enabled
-    return 1 if $left =~ /perl filtering enabled$/o;
-    # Python filtering enabled
-    return 1 if $left =~ /Python filtering enabled$/o;
-    return 1 if $left =~ /^python interpreter initialized OK$/o;
-    return 1 if $left =~ /^python method \S+ not found$/o;
-    return 1 if $left =~ /^python authenticate method succeeded, return code \d+, error string /o;
-    return 1 if $left =~ /^python access method succeeded$/o;
-    return 1 if $left =~ /^python dynamic method \(\w+ access\) succeeded, refusion string: /o;
-    return 1 if $left =~ /^python: .+ module successfully hooked into nnrpd$/o;
-    return 1 if $left =~ /^python: nnrpd .+ class instance created$/o;
-    return 1 if $left =~ /^python: n_a authenticate\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o;
-    return 1 if $left =~ /^python: n_a access\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o;
-    return 1 if $left =~ /^python: n_a dynamic\(\) invoked against type \S+, hostname \S+, ipaddress \S+, interface \S+, user /o;
-    return 1 if $left =~ /^python: authentication by username succeeded$/o;
-    return 1 if $left =~ /^python: authentication by username failed$/o;
-    return 1 if $left =~ /^python: authentication access by IP address succeeded$/o;
-    return 1 if $left =~ /^python: authentication access by IP address failed$/o;
-    return 1 if $left =~ /^python: dynamic access module successfully hooked into nnrpd$/o;
-    return 1 if $left =~ /^python: dynamic authorization access for read access granted$/o;
-    return 1 if $left =~ /^python: dynamic authorization access type is not known: /o;
-    # connect
-    if ($left =~ /(\S+) (\([0-9a-fA-F:.]*\) )?connect$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_connect{$dom}++;
-      $nnrpd_connect{$cust}++;
-      return 1;
-    }
-    # group
-    if ($left =~ /(\S+) group (\S+) (\d+)$/o) {
-      my ($cust, $group, $num) = ($1, $2, $3);
-      if ($num) {
-       $nnrpd_group{$group} += $num;
-       my ($hierarchy) = $group =~ /^([^\.]+).*$/o;
-       $nnrpd_hierarchy{$hierarchy} += $num;
-      }
-      return 1;
-    }
-    # post failed
-    if ($left =~ /(\S+) post failed (.*)$/o) {
-      my ($cust, $error) = ($1, $2);
-      $nnrpd_post_error{$error}++;
-      return 1;
-    }
-    # post ok
-    return 1 if $left =~ /\S+ post ok/o;
-    # posts
-    if ($left =~ /(\S+) posts received (\d+) rejected (\d+)$/o) {
-      my ($cust, $received, $rejected) = ($1, $2, $3);
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_post_ok{$dom} += $received;
-      $nnrpd_dom_post_rej{$dom} += $rejected;
-      $nnrpd_post_ok{$cust} += $received;
-      $nnrpd_post_rej{$cust} += $rejected;
-      return 1;
-    }
-    # noperm post without permission
-    if ($left =~ /(\S+) noperm post without permission/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_post_rej{$dom} ++;
-      $nnrpd_post_rej{$cust} ++;
-      return 1;
-    }
-    # no_permission
-    if ($left =~ /(\S+) no_(permission|access)$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_no_permission{$cust}++;
-      $nnrpd_dom_no_permission{$dom}++;
-      return 1;
-    }
-    # bad_auth
-    if ($left =~ /(\S+) bad_auth$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_no_permission{$dom}++;
-      $nnrpd_no_permission{$cust}++;
-      return 1;
-    }
-    # Authentication failure
-    # User not known to the underlying authentication module
-    return 1 if $left =~ / ckpasswd: pam_authenticate failed: /o;
-    return 1 if $left =~ / ckpasswd: user .+ unknown$/o;
-    # authinfo
-    if ($left =~ /\S+ user (\S+)$/o) {
-      my $user = $1;
-      $nnrpd_auth{$user}++;
-      return 1;
-    }
-    # unrecognized + command
-    if ($left =~ /(\S+) unrecognized (.*)$/o) {
-      my ($cust, $error) = ($1, $2);
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $error = "_null command_" if ($error !~ /\S/);
-      $error =~ s/^(xmotd) .*$/$1/i if ($error =~ /^xmotd .*$/i);
-      $nnrpd_dom_unrecognized{$dom}++;
-      $nnrpd_unrecognized{$cust}++;
-      $nnrpd_unrecogn_cmd{$error}++;
-      return 1;
-    }
-    # exit
-    if ($left =~ /(\S+) exit articles (\d+) groups (\d+)$/o) {
-      my ($cust, $articles, $groups) = ($1, $2, $3);
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust) || '?';
-      $nnrpd_connect{$cust}++, $nnrpd_dom_connect{$dom}++ if $cust eq '?';
-      $nnrpd_groups{$cust} += $groups;
-      $nnrpd_dom_groups{$dom} += $groups;
-      $nnrpd_articles{$cust} += $articles;
-      $nnrpd_dom_articles{$dom} += $articles;
-      return 1;
-    }
-    # times
-    if ($left =~ /(\S+) times user (\S+) system (\S+) idle (\S+) elapsed (\S+)$/o) {
-      my ($cust, $user, $system, $idle, $elapsed) = ($1, $2, $3, $4, $5);
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_times{$cust} += $elapsed;
-      $nnrpd_resource_user{$cust} += $user;
-      $nnrpd_resource_system{$cust} += $system;
-      $nnrpd_resource_idle{$cust} += $idle;
-      $nnrpd_resource_elapsed{$cust} += $elapsed;
-      $nnrpd_dom_times{$dom} += $elapsed;
-      return 1;
-    }
-    # artstats
-    if ($left =~ /(\S+) artstats get (\d+) time (\d+) size (\d+)$/o) {
-      my ($cust, $articles, $time, $bytes) = ($1, $2, $3, $4);
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_bytes{$cust} += $bytes;
-      $nnrpd_dom_bytes{$dom} += $bytes;
-      return 1;
-    }
-    # timeout
-    if ($left =~ /(\S+) timeout$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_timeout{$dom}++;
-      $nnrpd_timeout{$cust}++;
-      return 1;
-    }
-    # timeout in post
-    if ($left =~ /(\S+) timeout in post$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_timeout{$dom}++;
-      $nnrpd_timeout{$cust}++;
-      return 1;
-    }
-    # can't read: Connection timed out
-    if ($left =~ /(\S+) can\'t read: Connection timed out$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_timeout{$dom}++;
-      $nnrpd_timeout{$cust}++;
-      return 1;
-    }
-    # can't read: Operation timed out
-    if ($left =~ /(\S+) can\'t read: Operation timed out$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_timeout{$dom}++;
-      $nnrpd_timeout{$cust}++;
-      return 1;
-    }
-    # can't read: Connection reset by peer
-    if ($left =~ /(\S+) can\'t read: Connection reset by peer$/o) {
-      my $cust = $1;
-      $cust = lc $cust unless $CASE_SENSITIVE;
-      my $dom = &host2dom($cust);
-      $nnrpd_dom_reset_peer{$dom}++;
-      $nnrpd_reset_peer{$cust}++;
-      return 1;
-    }
-    # can't read: Network is unreachable
-    return 1 if $left =~ /(\S+) can\'t read: Network is unreachable$/o;
-    # gethostbyaddr: xxx.yyy.zzz != a.b.c.d
-    if ($left =~ /^gethostbyaddr: (.*)$/o) {
-      my $msg = $1;
-      $nnrpd_gethostbyaddr{$msg}++;
-      return 1;
-    }
-    # cant gethostbyaddr
-    if ($left =~ /\? cant gethostbyaddr (\S+) .*$/o) {
-      my $ip = $1;
-      $nnrpd_gethostbyaddr{$ip}++;
-      return 1;
-    }
-    # cant getpeername
-    if ($left =~ /\? cant getpeername/o) {
-      # $nnrpd_getpeername++;
-      $nnrpd_gethostbyaddr{"? (can't getpeername)"}++;
-      return 1;
-    }
-    # can't getsockname
-    return 1 if $left =~ /^\S+ can\'t getsockname$/o;
-    # reverse lookup failed
-    return 1 if $left =~ /^\? reverse lookup for \S+ failed: .* -- using IP address for access$/o;
-    # profile timer
-    # ME time X nnnn X(X) [...]
-    # The exact timers change from various versions of INN, so try to deal
-    # with this in a general fashion.
-    if ($left =~ m/^\S+\s+                         # ME
-                  time\s(\d+)\s+                  # time
-                   ((?:\S+\s\d+\(\d+\)\s*)+)       # timer values
-                   $/ox) {
-      $nnrpd_time_times += $1;
-      my $timers = $2;
-
-      while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) {
-        my $name = $nnrpd_timer_names{$1} || $1;
-        my $average = $2 / ($3 || 1);
-        $nnrpd_time_time{$name} += $2;
-        $nnrpd_time_num{$name} += $3;
-        if ($3) {
-          my $min = $nnrpd_time_min{$name};
-          $nnrpd_time_min{$name} = $average
-            if (defined($min) && $min > $average);
-          my $max = $nnrpd_time_max{$name};
-          $nnrpd_time_max{$name} = $average
-            if (defined($max) && $max < $average);
-        }
-      }
-      return 1;
-    }
-    # ME dropping articles into ...
-    return 1 if $left =~ /ME dropping articles into /o;
-    # newnews (interesting but ignored till now)
-    return 1 if $left =~ /^\S+ newnews /o;
-    # cant fopen (ignored too)
-    return 1 if $left =~ /^\S+ cant fopen /o;
-    # can't read: No route to host
-    return 1 if $left =~ /can\'t read: No route to host/o;
-    # can't read: Broken pipe
-    return 1 if $left =~ /can\'t read: Broken pipe/o;
-    # eof in post
-    return 1 if $left =~ /^\S+ eof in post$/o;
-    # ioctl: ...
-    return 1 if $left =~ /^ioctl: /o;
-    # other stats
-    return 1 if $left =~ /^\S+ overstats count \d+ hit \d+ miss \d+ time \d+ size \d+ dbz \d+ seek \d+ get \d+ artcheck \d+$/o;
-    # starttls
-    return 1 if $left =~ /^starttls: \S+ with cipher \S+ \(\d+\/\d+ bits\) no authentication$/o;
-  }
-  ########
-  ## inndstart
-  if ($prog eq "inndstart") {
-    # cant bind Address already in use
-    # cant bind Permission denied
-    return 1 if $left =~ /cant bind /o;
-    # cant setgroups Operation not permitted
-    return 1 if $left =~ /cant setgroups /o;
-  }
-  ########
-  ## overchan
-  if ($prog eq "overchan") {
-    # times
-    if ($left =~ /timings (\d+) arts (\d+) of (\d+) ms$/o) {
-      my ($articles, $work_time, $run_time) = ($1, $2, $3);
-      # ??? What to do with numbers
-      return 1;
-    }
-  }
-  ########
-  ## batcher
-  if ($prog eq "batcher") {
-    # times
-    if ($left =~ /(\S+) times user (\S+) system (\S+) elapsed (\S+)$/o) {
-      my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
-      $server = lc $server unless $CASE_SENSITIVE;
-      # $batcher_user{$server} += $user;
-      # $batcher_system{$server} += $system;
-      $batcher_elapsed{$server} += $elapsed;
-      return 1;
-    }
-    # stats
-    if ($left =~ /(\S+) stats batches (\d+) articles (\d+) bytes (\d+)$/o) {
-      my ($server, $batches, $articles, $bytes) = ($1, $2, $3, $4);
-      $server = lc $server unless $CASE_SENSITIVE;
-      $batcher_offered{$server} += $batches;
-      $batcher_articles{$server} += $articles;
-      $batcher_bytes{$server} += $bytes;
-      return 1;
-    }
-  }
-  ########
-  ## rnews
-  if ($prog eq "rnews") {
-    # rejected connection
-    if ($left =~ /rejected connection (.*)$/o) {
-      $rnews_rejected{$1}++;
-      return 1;
-    }
-    # cant open_remote
-    if ($left =~ /(cant open_remote .*)$/o) {
-      $rnews_rejected{$1}++;
-      return 1;
-    }
-    # rejected 437 Unwanted newsgroup
-    if ($left =~ /rejected 437 Unwanted newsgroup \"(.*)\"$/o) {
-      $rnews_bogus_ng{$1}++;
-      return 1;
-    }
-    # rejected 437 Unapproved for "xx"
-    if ($left =~ /rejected 437 Unapproved for \"(.*)\"$/o) {
-      $rnews_unapproved{$1}++;
-      return 1;
-    }
-    # rejected 437 Unwanted distribution
-    if ($left =~ /rejected 437 Unwanted distribution (.*)$/o) {
-      $rnews_bogus_dist{$1}++;
-      return 1;
-    }
-    # rejected 437 Bad "Date"
-    if ($left =~ /rejected 437 Bad \"Date\" (.*)$/o) {
-      $rnews_bogus_date{$1}++;
-      return 1;
-    }
-    # rejected 437 Article posted in the future
-    if ($left =~ /rejected 437 Article posted in the future -- \"(.*)\"$/o) {
-      $rnews_bogus_date{"(future) $1"}++;
-      return 1;
-    }
-    # rejected 437 Too old -- "..."
-    if ($left =~ /rejected 437 Too old -- (.*)$/o) {
-      $rnews_too_old++;
-      return 1;
-    }
-    # rejected 437 Linecount...
-    if ($left =~ /rejected 437 (Linecount) \d+ \!= \d+/o) {
-      $rnews_linecount++;
-      return 1;
-    }
-    # rejected 437 Duplicate
-    if ($left =~ /rejected 437 Duplicate$/o) {
-      $rnews_duplicate++;
-      return 1;
-    }
-    # rejected 437 Duplicate article
-    if ($left =~ /rejected 437 (Duplicate article)/o) {
-      $rnews_duplicate++;
-      return 1;
-    }
-    # rejected 437 No colon-space ...
-    if ($left =~ /rejected 437 No colon-space in \"(.*)\" header$/o) {
-      $rnews_no_colon_space++;
-      return 1;
-    }
-    # duplicate <msg-id> path..
-    if ($left =~ /^duplicate /o) {
-      $rnews_duplicate++;
-      return 1;
-    }
-    # offered <msg-id> feed
-    if ($left =~ /^offered \S+ (\S+)/o) {
-      my $host = $1;
-      $host = lc $host unless $CASE_SENSITIVE;
-      # Small hack used to join article spooled when innd is throttle.
-      # In this situation, the hostname is a 8 hex digits string
-      # To avoid confusions with real feeds, the first character is forced
-      # to be a '3' or a '4' (will work between 9/7/1995 and 13/7/2012).
-      $host = "Local postings" if $host =~ /^[34][0-9a-f]{7}$/;
-      $rnews_host{$host}++;
-      return 1;
-    }
-    # rejected 437 ECP rejected
-    return 1 if $left =~ m/rejected 437 ECP rejected/o;
-    # rejected 437 "Subject" header too long
-    return 1 if $left =~ m/header too long/o;
-    # rejected 437 Too long line in header 1163 bytes
-    return 1 if $left =~ m/rejected 437 Too long line in header/o;
-    # rejected 437 Too many newsgroups (meow)
-    return 1 if $left =~ m/rejected 437 Too many newsgroups/o;
-    # rejected 437 Space before colon in "<a" header
-    return 1 if $left =~ m/rejected 437 Space before colon in/o;
-    # rejected 437 EMP (phl)
-    return 1 if $left =~ m/rejected 437 EMP/o;
-    # rejected 437 Scoring filter (8)
-    return 1 if $left =~ m/rejected 437 Scoring filter/o;
-    # bad_article missing Message-ID
-    return 1 if $left =~ m/bad_article missing Message-ID/o;
-    # cant unspool saving to xxx
-    return 1 if $left =~ m/cant unspool saving to/o;
-  }
-
-  ###########
-  ## ncmspool
-  if ($prog eq "ncmspool") {
-    # <article> good signature from foo@bar.com
-    if ($left =~ /good signature from (.*)/o) {
-      $nocem_goodsigs{$1}++;
-      $nocem_totalgood++;
-      $nocem_lastid = $1;
-      return 1;
-    }
-    # <article> bad signature from foo@bar.com
-    if ($left =~ /bad signature from (.*)/o) {
-      $nocem_badsigs{$1}++;
-      $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1});
-      $nocem_totalbad++;
-      $nocem_lastid = $1;
-      return 1;
-    }
-    # <article> contained 123 new 456 total ids
-    if ($left =~ /contained (\d+) new (\d+) total ids/o) {
-      $nocem_newids += $1;
-      $nocem_newids{$nocem_lastid} += $1;
-      $nocem_totalids += $2;
-      $nocem_totalids{$nocem_lastid} += $2;
-      return 1;
-    }
-    return 1;
-  }
-
-  ########
-  ## nocem
-  if ($prog eq "nocem") {
-    if ($left =~ /processed notice .* by (.*) \((\d+) ids,/o) {
-      $nocem_goodsigs{$1}++;
-      $nocem_totalgood++;
-      $nocem_lastid = $1;
-      $nocem_newids += $2;
-      $nocem_newids{$nocem_lastid} += $2;
-      $nocem_totalids += $2;
-      $nocem_totalids{$nocem_lastid} += $2;
-      return 1;
-    }
-    if ($left =~ /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;
-  }
-
-  ###########
-  ## controlchan
-  if ($prog eq "controlchan") {
-    # loaded /x/y/z/foo.pl
-    return 1 if $left =~ m/^loaded /;
-    # starting
-    return 1 if $left =~ m/^starting/;
-    # skipping rmgroup x@y (pgpverify failed) in <foo@bar>
-    if ($left =~ m/^skipping \S+ (\S+) \(pgpverify failed\) in /) {
-      $controlchan_skippgp{$1}++;
-      $controlchan_who{$1}++;
-      return 1;
-    }
-    if ($left =~ m/^control_(sendme|ihave), [^,]+, (\S+), doit,/o) {
-      if ($1 eq "sendme") {
-       $controlchan_sendme_site{$2}++;
-      } else {
-       $controlchan_ihave_site{$2}++;
-      }
-      return 1;
-    }
-    # control_XXgroup, foo.bar [moderated] who who /x/y/12, peer, action, 1
-    #
-    # Various other random junk can end up in the moderated field, like y,
-    # unmoderated, m, etc. depending on what the control message says.  It
-    # can even have multiple words, which we still don't handle.
-    if ($left =~ m/^control_(\S+),    # type of msg
-                  \s(?:\S+)?          # newsgroup name
-                  (\s\S+)?            # optional
-                  \s(\S+)             # e-mail
-                  \s\S+               # e-mail
-                  \s\S+,              # filename
-                  \s\S+,              # server
-                  \s([^=,]+(?:=\S+)?),            # action
-                  \s*(.*)             # code
-                  /x) {
-      if ($1 eq 'newgroup') {
-       $controlchan_new{$3}++;
-      } elsif ($1 eq 'rmgroup') {
-       $controlchan_rm{$3}++;
-      } else {
-       $controlchan_other{$3}++;
-      }
-      $controlchan_who{$3}++;
-      $controlchan_ok{$3} += $5;
-      my $action = $4;
-      my $email = $3;
-      $action =~ s/=.*//;
-      $controlchan_doit{$email}++ if $action eq 'doit';
-      return 1;
-    }
-    # checkgroups processed (no change or not)
-    return 1 if $left =~ /^checkgroups by \S+ processed/o;
-  }
-
-  ###########
-  ## crosspost
-  if ($prog eq "crosspost") {
-    # seconds 1001 links 3182 0 symlinks 0 0 mkdirs 0 0
-    # missing 13 toolong 0 other 0
-    if ($left =~ /^seconds\ (\d+)
-                  \ links\ (\d+)\ (\d+)
-                  \ symlinks\ (\d+)\ (\d+)
-                  \ mkdirs\ (\d+)\ (\d+)
-                  \ missing\ (\d+)
-                  \ toolong\ (\d+)
-                  \ other\ (\d+)
-                $/ox) {
-      $crosspost_time += $1;
-      $crosspost{'Links made'} += $2;
-      $crosspost{'Links failed'} += $3;
-      $crosspost{'Symlinks made'} += $4;
-      $crosspost{'Symlinks failed'} += $5;
-      $crosspost{'Mkdirs made'} += $6;
-      $crosspost{'Mkdirs failed'} += $7;
-      $crosspost{'Files missing'} += $8;
-      $crosspost{'Paths too long'} += $9;
-      $crosspost{'Others'} += $10;
-      return 1;
-    }
-  }
-
-  ###########
-  ## cnfsstat
-  if ($prog eq "cnfsstat") {
-    # Class ALT for groups matching "alt.*" article size min/max: 0/1048576
-    # Buffer T3, len: 1953  Mbytes, used: 483.75 Mbytes (24.8%)   0 cycles
-    if ($left =~ m|^Class\ (\S+)\ for\ groups\ matching\ \S+
-                    (\ article\ size\ min/max:\ \d+/\d+)?
-                    \ Buffer\ (\S+),
-                    \ len:\ ([\d.]+)\s+Mbytes,
-                    \ used:\ ([\d.]+)\ Mbytes\ \(\s*[\d.]+%\)
-                    \s+(\d+)\ cycles\s*
-                 $|ox) {
-      my ($class, $buffer, $size, $used, $cycles) = ($1, $3, $4, $5, $6);
-      my ($h, $m, $s) = $hour =~ m/^(\d+):(\d+):(\d+)$/;
-      my $time = $h * 3600 + $m * 60 + $s;
-      $size *= 1024 * 1024;
-      $used *= 1024 * 1024;
-      $cnfsstat{$buffer} = $class;
-
-      # If the size changed, invalidate all of our running fill rate stats.
-      if (!exists($cnfsstat_size{$buffer}) ||  $size != $cnfsstat_size{$buffer}) {
-        delete $cnfsstat_rate{$buffer};
-        delete $cnfsstat_samples{$buffer};
-        delete $cnfsstat_time{$buffer};
-        $cnfsstat_size{$buffer} = $size;
-      }
-      elsif ($cnfsstat_time{$buffer}) {
-        # We want to gather the rate at which cycbuffs fill.  Store a
-        # running total of bytes/second and a total number of samples.
-        # Ideally we'd want a weighted average of those samples by the
-        # length of the sample period, but we'll ignore that and assume
-        # cnfsstat runs at a roughly consistent interval.
-        my ($period, $added);
-        $period = $time - $cnfsstat_time{$buffer};
-        $period = 86400 - $cnfsstat_time{$buffer} + $time if $period <= 0;
-        $added = $used - $cnfsstat_used{$buffer};
-        if ($cycles > $cnfsstat_cycles{$buffer}) {
-          $added += $size * ($cycles - $cnfsstat_cycles{$buffer});
-        }
-        if ($added > 0) {
-          $cnfsstat_rate{$buffer} += $added / $period;
-          $cnfsstat_samples{$buffer}++;
-        }
-      }
-      $cnfsstat_used{$buffer} = $used;
-      $cnfsstat_cycles{$buffer} = $cycles;
-      $cnfsstat_time{$buffer} = $time;
-      return 1;
-    }
-  }
-
-  # Ignore following programs :
-  return 1 if ($prog eq "uxfxn");
-  return 1 if ($prog eq "beverage");
-  return 1 if ($prog eq "newsx");
-  return 1 if ($prog eq "demmf");
-  return 1 if ($prog eq "nnnn");
-  return 1 if ($prog eq "slurp");
-  return 0;
-}
-
-#################################
-# Adjust some values..
-
-sub adjust {
-  my ($first_date, $last_date) = @_;
-
-  my $nnrpd_doit = 0;
-  my $curious;
-
-  {
-    my $serv;
-    if (%nnrpd_connect) {
-      my $c = keys (%nnrpd_connect);
-      foreach $serv (keys (%nnrpd_connect)) {
-       my $dom = &host2dom($serv);
-       if ($nnrpd_no_permission{$serv}) {
-         $nnrpd_dom_connect{$dom} -= $nnrpd_connect{$serv}
-           if defined $nnrpd_dom_connect{$dom} && defined $nnrpd_connect{$serv};
-         $nnrpd_dom_groups{$dom}  -= $nnrpd_groups{$serv}
-           if defined $nnrpd_dom_groups{$dom} && defined $nnrpd_groups{$serv};
-         $nnrpd_dom_times{$dom}   -= $nnrpd_times{$serv}
-           if defined $nnrpd_dom_times{$dom};
-         $nnrpd_connect{$serv} -= $nnrpd_no_permission{$serv};
-         $nnrpd_groups{$serv} -= $nnrpd_no_permission{$serv}
-           if defined $nnrpd_groups{$serv};
-         delete $nnrpd_connect{$serv} unless $nnrpd_connect{$serv};
-         delete $nnrpd_groups{$serv}  unless $nnrpd_groups{$serv};
-         delete $nnrpd_times{$serv}   unless $nnrpd_times{$serv};
-         delete $nnrpd_usr_times{$serv}   unless $nnrpd_usr_times{$serv};
-         delete $nnrpd_sys_times{$serv}   unless $nnrpd_sys_times{$serv};
-         delete $nnrpd_dom_connect{$dom} unless $nnrpd_dom_connect{$dom};
-         delete $nnrpd_dom_groups{$dom}  unless $nnrpd_dom_groups{$dom};
-         delete $nnrpd_dom_times{$dom}   unless $nnrpd_dom_times{$dom};
-         $c--;
-       }
-       $nnrpd_doit++
-         if $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv};
-      }
-      undef %nnrpd_connect unless $c;
-    }
-    foreach $serv (keys (%nnrpd_groups)) {
-      $curious = "ok" unless $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv} ||
-       $nnrpd_articles{$serv};
-    }
-  }
-
-  # Fill some hashes
-  {
-    my $key;
-    foreach $key (keys (%innd_connect)) {
-      $innd_offered{$key} = ($innd_accepted{$key} || 0)
-       + ($innd_refused{$key} || 0)
-       + ($innd_rejected{$key} || 0);
-      $innd_offered_size{$key} = ($innd_stored_size{$key} || 0)
-       + ($innd_duplicated_size{$key} || 0);
-    }
-
-
-    # adjust min/max of innd timer stats.
-    if (%innd_time_min) {
-      foreach $key (keys (%innd_time_min)) {
-       $innd_time_min{$key} = 0 if ($innd_time_min{$key} == $MIN);
-       $innd_time_max{$key} = 0 if ($innd_time_max{$key} == $MAX);
-
-       #$innd_time_min{$key} /= 1000;
-       #$innd_time_max{$key} /= 1000;
-      }
-    }
-    if (%innfeed_time_min) {
-      foreach $key (keys (%innfeed_time_min)) {
-        $innfeed_time_min{$key} = 0 if ($innfeed_time_min{$key} == $MIN);
-        $innfeed_time_max{$key} = 0 if ($innfeed_time_max{$key} == $MAX);
-      }
-    }
-    if (%nnrpd_time_min) {
-      foreach $key (keys (%nnrpd_time_min)) {
-        $nnrpd_time_min{$key} = 0 if ($nnrpd_time_min{$key} == $MIN);
-        $nnrpd_time_max{$key} = 0 if ($nnrpd_time_max{$key} == $MAX);
-      }
-    }
-    # remove the innd timer stats if not used.
-    unless ($innd_time_times) {
-      undef %innd_time_min;
-      undef %innd_time_max;
-      undef %innd_time_num;
-      undef %innd_time_time;
-    }
-    # same thing for innfeed timer
-    unless ($innfeed_time_times) {
-      undef %innfeed_time_min;
-      undef %innfeed_time_max;
-      undef %innfeed_time_num;
-      undef %innfeed_time_time;
-    }
-    # same thing for nnrpd timer
-    unless ($nnrpd_time_times) {
-      undef %nnrpd_time_min;
-      undef %nnrpd_time_max;
-      undef %nnrpd_time_num;
-      undef %nnrpd_time_time;
-    }
-
-    # adjust the crosspost stats.
-    if (%crosspost) {
-      foreach $key (keys (%crosspost)) {
-       $crosspost_times{$key} = $crosspost_time ?
-         sprintf "%.2f", $crosspost{$key} / $crosspost_time * 60 : "?";
-      }
-    }
-  }
-
-  if (%inn_flow) {
-    my ($prev_dd, $prev_d, $prev_h) = ("", -1, -1);
-    my $day;
-    foreach $day (sort datecmp keys (%inn_flow)) {
-      my ($r, $h) = $day =~ /^(.*) (\d+)$/;
-      my $d = index ("JanFebMarAprMayJunJulAugSepOctNovDec",
-                    substr ($r,0,3)) / 3 * 31 + substr ($r, 4, 2);
-      $prev_h = $h if ($prev_h == -1);
-      if ($prev_d == -1) {
-       $prev_d = $d;
-       $prev_dd = $r;
-      }
-      if ($r eq $prev_dd) { # Same day and same month ?
-       if ($h != $prev_h) {
-         if ($h == $prev_h + 1) {
-           $prev_h++;
-         }
-         else {
-           my $j;
-           for ($j = $prev_h + 1; $j < $h; $j++) {
-             my $t = sprintf "%02d", $j;
-             $inn_flow{"$r $t"} = 0;
-           }
-           $prev_h = $h;
-         }
-       }
-      }
-      else {
-       my $j;
-       # then end of the first day...
-       for ($j = ($prev_h == 23) ? 24 : $prev_h + 1; $j < 24; $j++) {
-         my $t = sprintf "%02d", $j;
-         $inn_flow{"$prev_dd $t"} = 0;
-       }
-
-       # all the days between (if any)
-       # well, we can forget them as it is supposed to be a tool
-       # launched daily.
-
-       # the beginning of the last day..
-       for ($j = 0; $j < $h; $j++) {
-         my $t = sprintf "%02d", $j;
-         $inn_flow{"$r $t"} = 0;
-       }
-       $prev_dd = $r;
-       $prev_d = $d;
-       $prev_h = $h;
-      }
-    }
-    my $first = 1;
-    my (%hash, %hash_time, %hash_size, $date, $delay);
-    foreach $day (sort datecmp keys (%inn_flow)) {
-      my ($r, $h) = $day =~ /^(.*) (\d+)$/o;
-      if ($first) {
-       $first = 0;
-       my ($t) = $first_date =~ m/:(\d\d:\d\d)$/o;
-       $date = "$day:$t - $h:59:59";
-       $t =~ m/(\d\d):(\d\d)/o;
-       $delay = 3600 - $1 * 60 - $2;
-      }
-      else {
-       $date = "$day:00:00 - $h:59:59";
-       $delay = 3600;
-      }
-      $hash{$date} = $inn_flow{$day};
-      $hash_size{$date} = $inn_flow_size{$day};
-      $inn_flow_labels{$date} = $h;
-      $hash_time{$date} = $delay;
-    }
-    my ($h, $t) = $last_date =~ m/ (\d+):(\d\d:\d\d)$/o;
-    my ($h2) = $date =~ m/ (\d+):\d\d:\d\d /o;
-    my $date2 = $date;
-    $date2 =~ s/$h2:59:59$/$h:$t/;
-    $hash{$date2} = $hash{$date};
-    delete $hash{"$date"};
-    $hash_size{$date2} = $hash_size{$date};
-    delete $hash_size{"$date"};
-    $t =~ m/(\d\d):(\d\d)/o;
-    $hash_time{$date2} = $hash_time{$date} - ($h2 == $h) * 3600 + $1 * 60 + $2;
-    delete $hash_time{"$date"};
-    $inn_flow_labels{$date2} = $h;
-    %inn_flow = %hash;
-    %inn_flow_time = %hash_time;
-    %inn_flow_size = %hash_size;
-  }
-
-  if (%innd_bad_ihave) {
-    my $key;
-    my $msg = 'Bad ihave control messages received';
-    foreach $key (keys %innd_bad_ihave) {
-      $innd_misc_stat{$msg}{$key} = $innd_bad_ihave{$key};
-    }
-  }
-  if (%innd_bad_msgid) {
-    my $key;
-    my $msg = 'Bad Message-ID\'s offered';
-    foreach $key (keys %innd_bad_msgid) {
-      $innd_misc_stat{$msg}{$key} = $innd_bad_msgid{$key};
-    }
-  }
-  if (%innd_bad_sendme) {
-    my $key;
-    my $msg = 'Ignored sendme control messages received';
-    foreach $key (keys %innd_bad_sendme) {
-      $innd_misc_stat{$msg}{$key} = $innd_bad_sendme{$key};
-    }
-  }
-  if (%innd_bad_command) {
-    my $key;
-    my $msg = 'Bad command received';
-    foreach $key (keys %innd_bad_command) {
-      $innd_misc_stat{$msg}{$key} = $innd_bad_command{$key};
-    }
-  }
-  if (%innd_bad_newsgroup) {
-    my $key;
-    my $msg = 'Bad newsgroups received';
-    foreach $key (keys %innd_bad_newsgroup) {
-      $innd_misc_stat{$msg}{$key} = $innd_bad_newsgroup{$key};
-    }
-  }
-  if (%innd_posted_future) {
-    my $key;
-    my $msg = 'Article posted in the future';
-    foreach $key (keys %innd_posted_future) {
-      $innd_misc_stat{$msg}{$key} = $innd_posted_future{$key};
-    }
-  }
-  if (%innd_no_colon_space) {
-    my $key;
-    my $msg = 'No colon-space in header';
-    foreach $key (keys %innd_no_colon_space) {
-      $innd_misc_stat{$msg}{$key} = $innd_no_colon_space{$key};
-    }
-  }
-  if (%innd_huge) {
-    my $key;
-    my $msg = 'Huge articles';
-    foreach $key (keys %innd_huge) {
-      $innd_misc_stat{$msg}{$key} = $innd_huge{$key};
-    }
-  }
-  if (%innd_blocked) {
-    my $key;
-    my $msg = 'Blocked server feeds';
-    foreach $key (keys %innd_blocked) {
-      $innd_misc_stat{$msg}{$key} = $innd_blocked{$key};
-    }
-  }
-  if (%innd_strange_strings) {
-    my $key;
-    my $msg = 'Including strange strings';
-    foreach $key (keys %innd_strange_strings) {
-      $innd_misc_stat{$msg}{$key} = $innd_strange_strings{$key};
-    }
-  }
-  if (%rnews_bogus_ng) {
-    my $key;
-    my $msg = 'Unwanted newsgroups';
-    foreach $key (keys %rnews_bogus_ng) {
-      $rnews_misc{$msg}{$key} = $rnews_bogus_ng{$key};
-    }
-  }
-  if (%rnews_bogus_dist) {
-    my $key;
-    my $msg = 'Unwanted distributions';
-    foreach $key (keys %rnews_bogus_dist) {
-      $rnews_misc{$msg}{$key} = $rnews_bogus_dist{$key};
-    }
-  }
-  if (%rnews_unapproved) {
-    my $key;
-    my $msg = 'Articles unapproved';
-    foreach $key (keys %rnews_unapproved) {
-      $rnews_misc{$msg}{$key} = $rnews_unapproved{$key};
-    }
-  }
-  if (%rnews_bogus_date) {
-    my $key;
-    my $msg = 'Bad Date';
-    foreach $key (keys %rnews_bogus_date) {
-      $rnews_misc{$msg}{$key} = $rnews_bogus_date{$key};
-    }
-  }
-
-  $rnews_misc{'Too old'}{'--'} = $rnews_too_old if $rnews_too_old;
-  $rnews_misc{'Bad linecount'}{'--'} = $rnews_linecount if $rnews_linecount;
-  $rnews_misc{'Duplicate articles'}{'--'} = $rnews_duplicate
-    if $rnews_duplicate;
-  $rnews_misc{'No colon-space'}{'--'} = $rnews_no_colon_space
-    if $rnews_no_colon_space;
-
-  if (%nnrpd_groups) {
-    my $key;
-    foreach $key (keys (%nnrpd_connect)) {
-      unless ($nnrpd_groups{"$key"} || $nnrpd_post_ok{"$key"} ||
-             $nnrpd_articles{"$key"}) {
-       $nnrpd_curious{$key} = $nnrpd_connect{$key};
-       undef $nnrpd_connect{$key};
-      }
-    }
-  }
-}
-
-sub report_unwanted_ng {
-  my $file = shift;
-  open (FILE, "$file") && do {
-    while (<FILE>) {
-      my ($c, $n) = $_ =~ m/^\s*(\d+)\s+(.*)$/;
-      next unless defined $n;
-      $n =~ s/^newsgroup //o; # for pre 1.8 logs
-      $inn_uw_ng{$n} += $c;
-    }
-    close (FILE);
-  };
-
-  unlink ("${file}.old");
-  rename ($file, "${file}.old");
-
-  open (FILE, "> $file") && do {
-    my $g;
-    foreach $g (sort {$inn_uw_ng{$b} <=> $inn_uw_ng{$a}} (keys (%inn_uw_ng))) {
-      printf FILE "%d %s\n", $inn_uw_ng{$g}, $g;
-    }
-    close (FILE);
-    chmod(0660, "$file");
-  };
-  unlink ("${file}.old");
-}
-
-###########################################################################
-
-# Compare 2 dates (+hour)
-sub datecmp {
-  # ex: "May 12 06"   for May 12, 6:00am
-  local($[) = 0;
-  # The 2 dates are near. The range is less than a few days that's why we
-  # can cheat to determine the order. It is only important if one date
-  # is in January and the other in December.
-
-  my($date1) = substr($a, 4, 2) * 24;
-  my($date2) = substr($b, 4, 2) * 24;
-  $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a,0,3)) * 288;
-  $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b,0,3)) * 288;
-  if ($date1 - $date2 > 300 * 24) {
-    $date2 += 288 * 3 * 12;
-  }
-  elsif ($date2 - $date1 > 300 * 24) {
-    $date1 += 288 * 3 * 12;
-  }
-  $date1 += substr($a, 7, 2);
-  $date2 += substr($b, 7, 2);
-  $date1 - $date2;
-}
-
-sub host2dom {
-  my $host = shift;
-
-  $host =~ m/^[^\.]+(.*)/;
-  $host =~ m/^[\d\.]+$/ ? "unresolved" : $1 ? "*$1" : "?";
-}
-
-1;
diff --git a/scripts/innshellvars.in b/scripts/innshellvars.in
deleted file mode 100644 (file)
index 4833b4d..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!@_PATH_SH@
-##  $Revision: 7466 $
-##  Set up any and all shell variables that an INN shell script
-##  might need.  Also sets umask.
-
-## NOTE: When adding stuff here, add the corresponding variables to 
-## innshellvars.pl and innshellvars.tcl and innshellvars.csh
-
-eval `@prefix@/bin/innconfval -s`
-
-NEWSHOME=${PATHNEWS}
-SPOOLBASE=${PATHSPOOL}
-MOST_LOGS=${PATHLOG}
-export NEWSHOME SPOOL MOST_LOGS
-
-NEWSBIN=${PATHBIN}
-NEWSETC=${PATHETC}
-NEWSLIB=@LIBDIR@
-INNDDIR=${PATHRUN}
-LOCKS=${PATHRUN}
-export NEWSBIN NEWSETC INNDDIR NEWSHOME
-
-ERRLOG=${MOST_LOGS}/errlog
-LOG=${MOST_LOGS}/news
-
-ARCHIVEDIR=${PATHARCHIVE}
-SPOOL=${PATHARTICLES}
-BATCH=${PATHOUTGOING}
-INCOMING=${PATHINCOMING}
-OVERVIEWDIR=${PATHOVERVIEW}
-SPOOLNEWS=${PATHINCOMING}
-BADNEWS=${PATHINCOMING}/bad
-
-ACTIVE=${PATHDB}/active
-ACTIVETIMES=${PATHDB}/active.times
-CTLFILE=${NEWSETC}/control.ctl
-CTLWATCH=${NEWSETC}/innwatch.ctl
-HISTORY=${PATHDB}/history
-NEWACTIVE=${PATHDB}/active.tmp
-NEWSFEEDS=${NEWSETC}/newsfeeds
-NEWSGROUPS=${PATHDB}/newsgroups
-OLDACTIVE=${PATHDB}/active.old
-PATH_MOTD=${NEWSETC}/motd.news
-EXPIRECTL=${NEWSETC}/expire.ctl
-LOCALGROUPS=${NEWSETC}/localgroups
-
-CONTROLPROGS=${PATHCONTROL}
-INNCONFVAL=${NEWSBIN}/innconfval
-INND=${NEWSBIN}/innd
-INNDSTART=${NEWSBIN}/inndstart
-INNWATCH=${NEWSBIN}/innwatch
-INEWS=${NEWSBIN}/inews
-RNEWS=${NEWSBIN}/rnews
-PERL_STARTUP_INND=${PATHFILTER}/startup_innd.pl
-PERL_FILTER_INND=${PATHFILTER}/filter_innd.pl
-PERL_FILTER_NNRPD=${PATHFILTER}/filter_nnrpd.pl
-PYTHON_FILTER_INND=${PATHFILTER}/filter_innd.py
-PATH_PYTHON_INN_MODULE=${PATHFILTER}/INN.py
-PATH_TCL_STARTUP=${PATHFILTER}/startup.tcl
-PATH_TCL_FILTER=${PATHFILTER}/filter.tcl
-
-DAILY=${LOCKS}/LOCK.news.daily
-
-NEWSCONTROL=${INNDDIR}/control
-NNTPCONNECT=${INNDDIR}/nntpin
-SERVERPID=${INNDDIR}/innd.pid
-INNWSTATUS=${INNDDIR}/innwatch.status
-WATCHPID=${INNDDIR}/innwatch.pid
-
-AWK=@_PATH_AWK@
-SED=@_PATH_SED@
-INNDF=${NEWSBIN}/inndf
-EGREP=@_PATH_EGREP@
-PERL=@_PATH_PERL@
-GPGV=@PATH_GPGV@
-PGP=@_PATH_PGP@
-SORT="@_PATH_SORT@"
-GETFTP="@GETFTP@"
-UUX=@_PATH_UUX@
-
-COMPRESS=@COMPRESS@
-GZIP=@GZIP@
-UNCOMPRESS="@UNCOMPRESS@"
-LOG_COMPRESS=@LOG_COMPRESS@
-Z=@LOG_COMPRESSEXT@
-
-if [ "$OVMETHOD" = "ovdb" ]; then
-    DB_HOME="${PATHOVERVIEW}"
-    export DB_HOME
-fi
-
-TEMPSOCK=`basename ${INNDDIR}/ctlinndXXXXXX | ${SED} -e 's/XXXXXX$/*/'`
-TEMPSOCKDIR=`echo ${INNDDIR}/ctlinndXXXXXX | ${SED} -e 's@/[^/]*$@@'`
-
-HAVE_UUSTAT=@HAVE_UUSTAT@
-
-NEWSMASTER=@NEWSMASTER@
-NEWSUSER=@NEWSUSER@
-NEWSGROUP=@NEWSGRP@
-
-TMPDIR=${PATHTMP}; export TMPDIR;
-
-SPOOLTEMP=${PATHTMP}
-
-NEWSLBIN=${NEWSHOME}/local
-export NEWSLBIN
-
-umask @NEWSUMASK@
-
-PATH=${NEWSLBIN}:${NEWSBIN}:${PATH}:/bin:/usr/bin:/usr/ucb
-export PATH
-
-HOME=$PATHNEWS
-export HOME
diff --git a/scripts/innshellvars.pl.in b/scripts/innshellvars.pl.in
deleted file mode 100644 (file)
index 422b61a..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-# 
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Sat, 24 Aug 1996 22:08:19 +0200
-# Project:      INN 
-# File:         innshellvars.pl
-# RCSId:        $Id: innshellvars.pl.in 7466 2005-12-12 03:04:08Z eagle $
-# Description:  Set up any and all variables that an INN perl script
-#               might need.
-
-package inn ;
-
-eval `@prefix@/bin/innconfval -p`;
-
-$newshome = $pathnews;
-$newslib = "@LIBDIR@";
-$spooldir = $pathspool;
-$most_logs = $pathlog;
-
-$errlog = "${most_logs}/errlog" ;
-$log = "${most_logs}/news" ;
-
-$spool = $patharticles;
-$overviewdir = $pathoverview;
-$archivedir = $patharchive;
-$badnews = "$pathincoming/bad";
-$spoolnews = $pathincoming;
-$batch = $pathoutgoing;
-$incoming = $pathincoming;
-
-$locks = $pathrun;
-$newsbin = $pathbin;
-$innddir = $pathrun;
-$newsetc = $pathetc;
-$newslbin = "$pathnews/local";
-
-$active = "${pathdb}/active" ;
-$activetimes = "${pathdb}/active.times" ;
-$ctlfile = "${newsetc}/control.ctl" ;
-$ctlwatch = "${newsetc}/innwatch.ctl" ;
-$history = "${pathdb}/history" ;
-$newactive = "${pathdb}/active.tmp" ;
-$newsfeeds = "${newsetc}/newsfeeds" ;
-$newsgroups = "${pathdb}/newsgroups" ;
-$oldactive = "${pathdb}/active.old" ;
-$path_motd = "${newsetc}/motd.news" ;
-$localgroups = "$newsetc/localgroups" ;
-$expirectl = "${newsetc}/expire.ctl" ;
-
-$controlprogs = $pathcontrol;
-$inews = "${newsbin}/inews" ;
-$innconfval = "${newsbin}/innconfval" ;
-$innd = "${newsbin}/innd" ;
-$inndstart = "${newsbin}/inndstart" ;
-$innwatch = "${newsbin}/innwatch" ;
-$rnews = "${newsbin}/rnews" ;
-$perl_startup_innd = "$pathfilter/startup_innd.pl" ;
-$perl_filter_innd = "$pathfilter/filter_innd.pl" ;
-$perl_filter_nnrpd = "$pathfilter/filter_nnrpd.pl" ;
-$python_filter_innd = "$pathfilter/filter_innd.py" ;
-$path_python_inn_module ="$pathfilter/INN.py" ;
-$path_tcl_startup = "$pathfilter/startup.tcl" ;
-$path_tcl_filter = "$pathfilter/filter.tcl" ;
-
-$daily = "${locks}/LOCK.news.daily" ;
-
-$newscontrol = "${innddir}/control" ;
-$nntpconnect = "${innddir}/nntpin" ;
-$serverpid = "${innddir}/innd.pid" ;
-$innwstatus = "${innddir}/innwatch.status" ;
-$watchpid = "${innddir}/innwatch.pid" ;
-
-$awk = "@_PATH_AWK@" ;
-$sed = "@_PATH_SED@" ;
-$inndf = "${newsbin}/inndf" ;
-$egrep = "@_PATH_EGREP@" ;
-$gpgv = "@PATH_GPGV@" ;
-$perl = "@_PATH_PERL@" ;
-$pgp = "@_PATH_PGP@" ;
-$sort = "@_PATH_SORT@" ;
-$getftp = "@GETFTP@" ;
-$uux = "@_PATH_UUX@" ;
-
-$compress = "@COMPRESS@" ;
-$gzip = "@GZIP@" ;
-$uncompress = "@UNCOMPRESS@" ;
-$log_compress = "@LOG_COMPRESS@" ;
-$z = "@LOG_COMPRESSEXT@" ;
-
-if ($ovmethod && $ovmethod eq "ovdb") {
-    $ENV{'DB_HOME'} = $pathoverview;
-}
-
-($tempsock = "${innddir}/ctlinndXXXXXX") =~ s!.*/(.*)XXXXXX$!$1*! ;
-($tempsockdir = "${innddir}/ctlinndXXXXXX") =~ s!/[^/]*$!! ;
-
-$have_uustat = ("@HAVE_UUSTAT@" eq "DO" ? 1 : 0) ;
-
-$newsmaster = '@NEWSMASTER@' ;
-$newsuser = '@NEWSUSER@' ;
-$newsgroup = '@NEWSGRP@' ;
-
-$ENV{'TMPDIR'} = $pathtmp;
-$tmpdir = $pathtmp;
-$spooltemp = $pathtmp;
-
-$umask = @NEWSUMASK@ ;
-
-$syslog_facility = lc("@SYSLOG_FACILITY@");
-$syslog_facility =~ s/log_//;
-
-$ENV{'PATH'} ||= '';
-$ENV{'PATH'} = "${newslbin}:${newsbin}:$ENV{'PATH'}:/bin:/usr/bin:/usr/ucb" ;
-
-$ENV{'HOME'} = ${pathnews};
-
-1 ;
diff --git a/scripts/innshellvars.tcl.in b/scripts/innshellvars.tcl.in
deleted file mode 100644 (file)
index c5e2dea..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-# -*- tcl -*-
-#
-# Author:       James Brister <brister@vix.com> -- berkeley-unix --
-# Start Date:   Sat, 24 Aug 1996 23:45:34 +0200
-# Project:      INN
-# File:         innshellvars.tcl
-# RCSId:        $Id: innshellvars.tcl.in 7466 2005-12-12 03:04:08Z eagle $
-# Description:  Set up any and all variables that an INN tcl script
-#               might need.
-
-eval `@prefix@/bin/innconfval -t`
-
-set inn_newshome "$inn_pathnews"
-set inn_newslib "@LIBDIR@"
-set inn_spooldir "$inn_pathspool"
-set inn_most_logs "$inn_pathlog"
-
-set inn_errlog "${inn_most_logs}/errlog"
-set inn_log "${inn_most_logs}/news"
-
-set inn_batch "${inn_pathoutgoing}"
-set inn_incoming "${inn_pathincoming}"
-set inn_spool "${inn_patharticles}"
-set inn_overviewdir "${inn_pathoverview}"
-set inn_archivedir "${inn_patharchive}"
-set inn_badnews "${inn_pathincoming}/bad"
-set inn_spoolnews "${inn_pathincoming}"
-
-set inn_newslbin "${inn_newshome}/local"
-set inn_innddir "${inn_pathrun}"
-set inn_locks "${inn_pathrun}"
-set inn_newsbin "${inn_pathbin}"
-set inn_newsetc "${inn_newshome}/etc"
-
-set inn_active "${inn_pathdb}/active"
-set inn_activetimes "${inn_pathdb}/active.times"
-set inn_ctlfile "${inn_newsetc}/control.ctl"
-set inn_ctlwatch "${inn_newsetc}/innwatch.ctl"
-set inn_history "${inn_pathdb}/history"
-set inn_newactive "${inn_pathdb}/active.tmp"
-set inn_newsfeeds "${inn_newsetc}/newsfeeds"
-set inn_newsgroups "${inn_pathdb}/newsgroups"
-set inn_oldactive "${inn_pathdb}/active.old"
-set inn_localgroups "${inn_newsetc}/localgroups"
-set inn_expirectl "${inn_newsetc}/expire.ctl"
-set inn_path_motd "${inn_newsetc}/motd.news"
-
-set inn_daily "${inn_locks}/locks/LOCK.news.daily"
-
-set inn_inews "${inn_newsbin}/inews"
-set inn_innconfval "${inn_newsbin}/innconfval"
-set inn_innd "${inn_newsbin}/innd"
-set inn_inndstart "${inn_newsbin}/inndstart"
-set inn_innwatch "${inn_newsbin}/innwatch"
-set inn_rnews "${inn_newsbin}/rnews"
-set inn_controlprogs "${inn_pathcontrol}/control"
-set inn_perl_startup_innd "${inn_pathfilter}/startup_innd.pl"
-set inn_perl_filter_innd "${inn_pathfilter}/filter_innd.pl"
-set inn_perl_filter_nnrpd "${inn_pathfilter}/filter_nnrpd.pl"
-set inn_python_filter_innd "${pathfilter}/filter_innd.py"
-set inn_path_python_inn_module "${pathfilter}/INN.py"
-set inn_path_tcl_startup "${inn_pathfilter}/startup.tcl"
-set inn_path_tcl_filter "${inn_pathfilter}/filter.tcl"
-
-set inn_newscontrol "${inn_innddir}/control"
-set inn_nntpconnect "${inn_innddir}/nntpin"
-set inn_innwstatus "${inn_innddir}/innwatch.status"
-set inn_watchpid "${inn_innddir}/innwatch.pid"
-set inn_serverpid "${inn_innddir}/innd.pid"
-
-set inn_awk "@_PATH_AWK@"
-set inn_sed "@_PATH_SED@"
-set inn_perl "@_PATH_PERL@"
-set inn_gpgv "@PATH_GPGV@"
-set inn_pgp "@_PATH_PGP@"
-set inn_inndf "${inn_newsbin}/inndf"
-set inn_egrep "@_PATH_EGREP@"
-set inn_sort "@_PATH_SORT@"
-set inn_getftp "@GETFTP@"
-set inn_uux "@_PATH_UUX@"
-
-set inn_compress "@COMPRESS@"
-set inn_gzip "@GZIP@"
-set inn_uncompress "@UNCOMPRESS@"
-set inn_log_compress "@LOG_COMPRESS@"
-set inn_z "@LOG_COMPRESSEXT@"
-
-set inn_tempsock [ eval exec basename ${inn_innddir}/ctlinndXXXXXX | $inn_sed -e {s/XXXXXX$/*/} ]
-set inn_tempsockdir [ exec echo ${inn_innddir}/ctlinndXXXXXX | $inn_sed -e {s@/[^/]*$@@} ]
-
-set inn_have_uustat [ expr { "@HAVE_UUSTAT@" == "DO" ? 1 : 0 } ]
-
-set inn_newsmaster "@NEWSMASTER@"
-set inn_newsuser "@NEWSUSER@"
-set inn_newsgroup "@NEWSGRP@"
-
-set env(TMPDIR) "$inn_pathtmp"
-set inn_tmpdir "$inn_pathtmp"
-set inn_spooltemp "$inn_pathtmp"
-
-scan "@NEWSUMASK@" "%o" inn_umask
-
-set env(PATH) "$inn_newslbin:$inn_newsbin:$env(PATH):/bin:/usr/bin:/usr/ucb"
-
-set env(HOME) "$inn_pathnews"
diff --git a/scripts/innstat.in b/scripts/innstat.in
deleted file mode 100644 (file)
index 2c16d07..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 6994 $
-##  Display status of INN.
-##  Written by Landon Curt Noll <chongo@toad.com>.
-
-SYSLOG_CRIT=news.crit
-SYSLOG_ERR=news.err
-SYSLOG_NOTICE=news.notice
-SYSLOGS="${SYSLOG_CRIT} ${SYSLOG_ERR} ${SYSLOG_NOTICE}"
-
-##  Set up the list of log files.
-LOGS="${SYSLOGS}"
-if [ -f "${MOST_LOGS}/`basename ${ERRLOG}`" ]; then
-    LOGS="${LOGS} `basename ${ERRLOG}`"
-else
-    LOGS="${LOGS} ${ERRLOG}"
-fi
-if [ -f "${MOST_LOGS}/`basename ${LOG}`" ]; then
-    LOGS="${LOGS} `basename ${LOG}`"
-else
-    LOGS="${LOGS} ${LOG}"
-fi
-
-##  Show INND status.
-echo 'Server status:'
-ctlinnd mode 2>&1
-
-##  Show disk usage.  You might have to change this.
-echo ''
-echo 'Disk usage:'
-${INNDF} ${SPOOL} ${OVERVIEWDIR} ${PATHETC} ${INCOMING} ${BATCH} \
-       ${PATHDB} ${MOST_LOGS} | sort -u
-
-##  Show size of batch files.
-echo ''
-echo 'Batch file sizes:'
-( cd ${BATCH}; ls -Cs | sed 1d )
-
-##  Show size of log files.
-echo ''
-echo 'Log file sizes:'
-( cd ${MOST_LOGS}; ls -Cs ${LOGS} *.log 2>&1 )
-
-##  Show the lock files
-echo ''
-(      cd ${LOCKS}
-       set -$- LOCK.*
-       if [ -f "$1" ]; then
-               echo 'Lock files:'
-               ls -C LOCK.* 2>&1
-       else
-               echo 'Innwatch is not running'
-       fi
-)
-
-echo ''
-echo 'Server connections:'
-ctlinnd -t60 name '' 2>&1 \
-  | ${PERL} -ne '
-     next if m/(^((rem|local)conn|control)|:proc|:file):/;
-     s/^(\S+):(\d+):.*:.*:.*$/${1}:${2}/;
-     m/^(\S+):(\d+)$/;
-     $c{$1} = [] unless $c{$1};
-     @l = @{$c{$1}};
-     push @l, $2;
-     $c{$1} = [@l];
-     $m++;
-     END {
-       $n = 0;
-       foreach $f (sort {$#{$c{$b}} <=> $#{$c{$a}}} keys %c) {
-          printf "%-35.35s %3d  (%s", $f, 1 + $#{$c{$f}}, "@{$c{$f}})\n";
-          $n++;
-       }
-       printf "\n%-35s %3d\n", "TOTAL: $n", $m;
-     }'
-
diff --git a/scripts/innupgrade.in b/scripts/innupgrade.in
deleted file mode 100644 (file)
index ea9251f..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-#! /usr/bin/perl
-
-##  $Id: innupgrade.in 6458 2003-09-03 02:58:51Z rra $
-##
-##  Convert INN configuration files to the current syntax.
-##
-##  Intended to be run during a major version upgrade, this script tries to
-##  convert existing INN configuration files to the syntax expected by the
-##  current version, if that's changed.
-##
-##  Note that this script cannot use innshellvars.pl, since loading that file
-##  requires innconfval be able to parse inn.conf, and until this script runs,
-##  inn.conf may not be valid.
-##
-##  Currently handles the following conversions:
-##
-##   * Clean up inn.conf for the new parser in INN 2.4.
-##   * Add the hismethod parameter to inn.conf if not found.
-
-require 5.003;
-
-use strict;
-use vars qw(%FIXES);
-use subs qw(fix_inn_conf);
-
-use Getopt::Long qw(GetOptions);
-
-# The mappings of file names to fixes.
-%FIXES = ('inn.conf' => \&fix_inn_conf);
-
-# Clean up inn.conf for the new parser in INN 2.4.  Null keys (keys without
-# values) need to be commented out since they're no longer allowed (don't just
-# remove them entirely since people may want them there as examples), and
-# string values must be quoted if they contain any special characters.  Takes
-# a reference to an array containing the contents of the file, a reference to
-# an array into which the output should be put, and the file name for error
-# reporting.
-sub fix_inn_conf {
-    my ($input, $output, $file) = @_;
-    my $line = 0;
-    my ($raw, $hismethod);
-    local $_;
-    for $raw (@$input) {
-        $_ = $raw;
-        $line++;
-        if (/^\s*\#/ || /^\s*$/) {
-            push (@$output, $_);
-            next;
-        }
-        chomp;
-        unless (/^(\s*)(\S+):(\s*)(.*)/) {
-            warn "$file:$line: cannot parse line: $_\n";
-            push (@$output, $_);
-            next;
-        }
-        my ($indent, $key, $space, $value) = ($1, $2, $3, $4);
-        if ($value eq '') {
-            push (@$output, "#$_\n");
-            next;
-        }
-        $hismethod = 1 if $key eq 'hismethod';
-        $value =~ s/\s+$//;
-        if ($value =~ /[\s;\"<>\[\]\\{}]/ && $value !~ /^\".*\"\s*$/) {
-            $value =~ s/([\"\\])/\\$1/g;
-            $value = '"' . $value . '"';
-        }
-        push (@$output, "$indent$key:$space$value\n");
-    }
-
-    # Add a setting of hismethod if one wasn't present in the original file.
-    unless ($hismethod) {
-        push (@$output, "\n# Added by innupgrade\nhismethod: hisv6\n");
-    }
-}
-
-# Upgrade a particular file.  Open the file, read it into an array, and then
-# run the fix function on it.  If the fix function generates different output
-# than the current contents of the file, change the file.
-sub upgrade_file {
-    my ($file, $function) = @_;
-    open (INPUT, $file) or die "$file: cannot open: $!\n";
-    my @input = <INPUT>;
-    close INPUT;
-    my @output;
-    &$function (\@input, \@output, $file);
-    if (join ('', @input) ne join ('', @output)) {
-        if (-e "$file.OLD") {
-            if (-t STDIN) {
-                print "$file.OLD already exists, overwrite (y/N)? ";
-                my $answer = <STDIN>;
-                if ($answer !~ /y/i) {
-                    die "$file: backup $file.OLD already exists, aborting\n";
-                }
-            } else {
-                die "$file: backup $file.OLD already exists\n";
-            }
-        }
-        print "Updating $file, old version saved as $file.OLD\n";
-        my ($user, $group) = (stat $file)[4,5];
-        open (OUTPUT, "> $file.new.$$")
-            or die "$file: cannot create $file.new.$$: $!\n";
-        print OUTPUT @output;
-        close OUTPUT or die "$file: cannot flush new file: $!\n";
-        unless (link ($file, "$file.OLD")) {
-            rename ($file, "$file.OLD")
-                or die "$file: cannot rename to $file.OLD: $!\n";
-        }
-        if ($> == 0) {
-            if (defined ($user) && defined ($group)) {
-                chown ($user, $group, "$file.new.$$")
-                    or warn "$file: cannot chown $file.new.$$: $!\n";
-            } else {
-                warn "$file: cannot find owner and group of $file\n";
-            }
-        }
-        rename ("$file.new.$$", $file)
-            or die "$file: cannot replace with $file.new.$$: $!\n";
-    }
-}
-
-# Upgrade a directory.  Scan the directory for files that have upgrade rules
-# defined and for each one of those, try running the upgrade rule.
-sub upgrade_directory {
-    my $directory = shift;
-    chdir $directory or die "Can't chdir to $directory: $!\n";
-    opendir (DIR, ".") or die "Can't opendir $directory: $!\n";
-    for (readdir DIR) {
-        if ($FIXES{$_}) {
-            upgrade_file ($_, $FIXES{$_});
-        }
-    }
-    closedir DIR;
-}
-
-
-# The main routine.  Parse command-line options to figure out what we're
-# doing.
-my ($file, $type);
-Getopt::Long::config ('bundling');
-GetOptions ('file|f=s' => \$file,
-            'type|t=s' => \$type) or exit 1;
-if ($file) {
-    my $basename = $file;
-    $basename =~ s%.*/%%;
-    $type ||= $basename;
-    if (!$FIXES{$type}) { die "No upgrade rules defined for $basename\n" }
-    upgrade_file ($file, $FIXES{$type});
-} else {
-    if (@ARGV != 1) { die "Usage: innupgrade <directory>\n" }
-    my $directory = shift;
-    upgrade_directory ($directory);
-}
diff --git a/scripts/innwatch.in b/scripts/innwatch.in
deleted file mode 100644 (file)
index 06cf95b..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 2677 $
-##  Watch the state of the system relative to the news subsystem.
-##  As controlled by the control file, when space or inodes are almost
-##  exhausted innd is throttled, or paused, similarly if the load is
-##  too high - when conditions revert to normal, innd is restarted.
-##  No logging is done here, watch for syslog reports from innd.
-##  Written by Mike Cooper <mcooper@usc.edu>.
-##  Extensively modified by <kre@munnari.oz.au>.
-##  Watch a log file and send mail when it gets new output by
-##     Steve Groom <stevo@elroy.Jpl.Nasa.Gov>
-##  Steve's extensions merged in innwatch by
-##     <Christophe.Wolfhugel@grasp.insa-lyon.fr>
-
-PROGNAME=innwatch
-LOCK=${LOCKS}/LOCK.${PROGNAME}
-DAILY=${LOCKS}/LOCK.news.daily
-##  Where to put the timestamp file (directory and filename).
-TIMESTAMP=${LOCKS}/${PROGNAME}.time
-
-##  Logfile to watch. Comment out if no logwatch.
-LOGFILE=${MOST_LOGS}/news.crit
-
-## Default value in case there is no definition in inn.conf
-: ${INNWATCHPAUSELOAD:=1500}
-: ${INNWATCHHILOAD:=2000}
-: ${INNWATCHLOLOAD:=1000}
-: ${INNWATCHSPOOLSPACE:=8000}
-: ${INNWATCHBATCHSPACE:=800}
-: ${INNWATCHLIBSPACE:=25000}
-: ${INNWATCHSPOOLNODES:=200}
-: ${INNWATCHSLEEPTIME:=600}
-
-##  Parse JCL.
-while [ $# -gt 0 ] ; do
-    case X"$1" in
-    X-f)
-       FILE=$2
-       shift
-       ;;
-    X-f*)
-       FILE=`expr "$1" : '-s\(.*\)'`
-       ;;
-    X-l)
-       LOGFILE=$2
-       shift
-       ;;
-    X-l*)
-       LOGFILE=`expr "$1" : '-s\(.*\)'`
-       ;;
-    X-t)
-       INNWATCHSLEEPTIME=$2
-       shift
-       ;;
-    X-t*)
-       INNWATCHSLEEPTIME=`expr "$1" : '-t\(.*\)'`
-       ;;
-    X--)
-       shift
-       break
-       ;;
-    X-*)
-       echo "${PROGNAME}:  Unknown flag $1" 1>&2
-       exit 1
-       ;;
-    *)
-       break
-       ;;
-    esac
-    shift
-done
-
-##  Process arguments.
-if [ $# -ne 0 ] ; then
-    echo "Usage:  ${PROGNAME} [flags]" 1>&2
-    exit 1
-fi
-
-trap '' 2
-
-##  Anyone else there?
-shlock -p $$ -f ${LOCK} || {
-    echo "${PROGNAME}: [$$] locked by [`cat ${LOCK}`]"
-    exit 0
-}
-
-trap 'rm -f ${LOCK} ${WATCHPID} ; exit 1' 1 3 15
-echo "$$" > ${WATCHPID}
-
-##  The reason why we turned INND off, and its, and our current state.
-REASON=''
-INND=''
-STATE=''
-
-trap '(
-       echo "${PROGNAME} waiting for INND to start (pid: $$)"
-       date
-    ) >${INNWSTATUS}' 2
-
-##  We need to remember the process ID of innd, in case one exits
-##  But we need to wait for innd to start before we can do that
-while PID=`cat ${SERVERPID} 2>/dev/null`; test -z "${PID}"; do
-    sleep ${INNWATCHSLEEPTIME}
-done
-
-trap '(
-       if [ -z "${STATE}" ]; then
-           echo "${PROGNAME} state RUN interval ${INNWATCHSLEEPTIME} pid $$"
-       else
-           echo "${PROGNAME} state ${STATE} interval ${INNWATCHSLEEPTIME} pid $$"
-       fi
-       if [ -z "${INND}" ]; then
-           X=GO
-       else
-           X="${INND}"
-       fi
-       test -n "${REASON}" && X="${X}: ${REASON}"
-       echo "INND state ${X}"
-       date
-    ) >${INNWSTATUS}' 2
-
-cd ${SPOOL}
-
-NEXTSLEEP=1
-HASEXITED=false
-
-while { sleep ${NEXTSLEEP} & wait; } ; : ; do
-    NEXTSLEEP=${INNWATCHSLEEPTIME}
-
-    ##  If news.daily is running, idle:  we don't want to change the
-    ##  status of anything while news.daily may be depending on what we
-    ##  have done.
-    test -f "${DAILY}" && continue
-
-    ## Check to see if INND is running.
-    ## Notify NEWSMASTER if it has stopped or just restarted.
-    if ctlinnd -s -t 120 mode 2>/dev/null ; then
-       ${HASEXITED} && {
-           HASEXITED=false
-           ${MAILCMD} -s "INND is now running" ${NEWSMASTER} </dev/null
-       }
-    else
-       ${HASEXITED} || {
-           HASEXITED=true
-           ${MAILCMD} -s "INND is NOT running" ${NEWSMASTER} </dev/null
-       }
-       continue
-    fi
-
-    ##  If innd has exited & restarted, put the new one into the
-    ##  same state the old one was in
-
-    nPID=`cat ${SERVERPID} 2>/dev/null`
-    test -n "${nPID}" -a "${PID}" -ne "${nPID}" && {
-       test -n "${INND}" -a "${INND}" != go && ctlinnd -s "${INND}" "${REASON}"
-       PID="${nPID}"
-    }
-
-    VALUE=0
-    PREVEXP=''
-
-    exec 3<&0
-    exec 0<${CTLWATCH}
-
-    LINE=0
-    while read line ; do
-       LINE=`expr ${LINE} + 1`
-       test -z "$line" && continue
-
-       ##  The first character on the line is the field delimiter,
-       ##  except '#' which marks the line as a comment
-       delim=`expr "${line}" : '\(.\).*'`
-       test "X${delim}" = 'X#' && continue
-
-       ##  Parse the line into seven fields, and assign them to local vars.
-       ##  You're welcome to work out what's going on with quoting in
-       ##  the next few lines if you feel inclined.
-       eval `trap '' 2; echo "${line}" \
-               | ${SED} -e "s/'/'\"'\"'/g" \
-                   -e "s/[     ]*\\\\${delim}[         ]*/\\\\${delim}/g" \
-               | ${AWK} -F"${delim}" '{ print  "LAB='"'"'" $2 "'"'"'", \
-                                               "CND='"'"'" $3 "'"'"'", \
-                                               "EXP='"'"'" $4 "'"'"'", \
-                                               "TST='"'"'" $5 "'"'"'", \
-                                               "LIM=" $6, \
-                                               "CMD='"'"'" $7 "'"'"'", \
-                                               "CMT='"'"'" $8 "'"'"'" }'`
-
-       ##  If there's no label, the label is the line number.
-       test -z "${LAB}" && LAB=${LINE}
-
-       ##  Should we act on this line?  We will if one (or more) of the
-       ##  specified conditions is satisfied.
-       for X in a b; do        # meaningless trash because we have no goto
-           if [ -z "${CND}" ]; then
-               X=-
-           else
-               X="${CND}"
-           fi
-           set -$- X ${X}; shift
-           for cnd
-           do
-               case "${cnd}" in
-               -)
-                   test -n "${STATE}" -a "X${STATE}" != "X${LAB}" && continue
-                   ;;
-               +)
-                   test -n "${STATE}" && continue
-                   ;;
-               '*')
-                   ;;
-               -*)
-                   test "X-${STATE}" = "X${cnd}" && continue
-                   ;;
-               *)
-                   test "X${STATE}" != "X${cnd}" && continue;
-                   ;;
-               esac
-               break 2;        # OK, continue with this line
-           done
-           continue 2;         # No, skip it.
-       done
-
-       ##  Evaluate the expression, if there is one, and if that works.
-       if [ -z "${EXP}" -o "${EXP}" = "${PREVEXP}" ] \
-        || { PREVEXP="${EXP}"; VALUE=`trap '' 2;eval "${EXP}"`; }; then
-           ##  If innd is running, and test "succeeds", stop it.
-           case "${CMD}" in
-           throttle|pause)
-               OK=n
-               ;;
-           *)
-               OK=y
-               ;;
-           esac
-
-           if [ \( -z "${STATE}" -o "${STATE}" != "${LAB}" -o "${OK}" = y \) \
-                   -a "${VALUE}" "-${TST}" "${LIM}" ] ; then
-               R="${CMT} [${PROGNAME}:${LAB}] ${VALUE} ${TST} ${LIM}"
-               O=
-               case "${CMD}" in
-               throttle)
-                   case "${STATE}" in
-                   ''|go)
-                       REASON="${R}"
-                       ;;
-                   *)
-                       ;;
-                   esac
-                   O="${LAB}"
-                   ARG="${REASON}"
-                   ;;
-               pause)
-                   O="${LAB}"
-                   REASON="${R}"
-                   ARG="${REASON}"
-                   ;;
-               shutdown)
-                   ARG="${R}"
-                   ;;
-               flush)
-                   ARG=''
-                   O="${STATE}"
-                   ARG="${REASON}"
-                   ;;
-               go)
-                   ARG="${REASON}"
-                   NEXTSLEEP=1
-                   REASON=''
-                   ;;
-               exit)
-                   exit 0
-                   ;;
-               *)
-                   break
-                   ;;
-               esac
-
-               ctlinnd -s "${CMD}" "${ARG}" && STATE="${O}" && INND="${CMD}"
-               break
-
-           ##  Otherwise, if innd is not running, and reverse test succeeds
-           ##  restart it.
-           elif [ "${STATE}" = "${LAB}" -a \
-                   \( "${CMD}" = "throttle" -o "${CMD}" = pause \) -a \
-                   ! "${VALUE}" "-${TST}" "${LIM}" ] ; then
-               ctlinnd -s go "${REASON}"
-               STATE=''
-               REASON=''
-               INND=''
-
-               ##  If we have started innd, run all tests again quickly in
-               ##  case there is some other condition that should stop it.
-               NEXTSLEEP=1
-               break
-           fi
-       fi
-
-    done
-
-    exec 0<&3
-    exec 3<&-
-
-    if [ -n "${LOGFILE}" -a -f "${LOGFILE}" ]; then
-       if [ ! -f ${TIMESTAMP} ]; then
-           DOIT=${LOGFILE}
-       else
-           # use ls to print most recently modified file first.
-           # If that's ${LOGFILE}, it's changed since the last pass.
-           DOIT="`ls -t ${TIMESTAMP} ${LOGFILE} | ${SED} -e 1q | grep ${LOGFILE}`"
-       fi
-
-       # If the file has been modified more recently than the timestamp,
-       # and the file has length greater than 0, send the warning.
-       if [ -n "${DOIT}" -a -s ${LOGFILE} ]; then
-           date >${TIMESTAMP}
-           (
-               ls -l ${LOGFILE}
-               echo "-----"
-               ctlinnd -t120 mode
-               echo "-----"
-               cat ${LOGFILE}
-           ) 2>&1 \
-            | sed -e 's/^~/~~/' \
-           | ${MAILCMD} -s "${PROGNAME} warning: messages in ${LOGFILE}" \
-               ${NEWSMASTER}
-       fi
-    fi
-
-done
-
-rm -f ${LOCK}
diff --git a/scripts/news.daily.in b/scripts/news.daily.in
deleted file mode 100644 (file)
index 2abb9be..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-#!@_PATH_SH@
-##  $Revision: 5999 $
-##  Daily news maintenance.
-##  Optional arguments:
-##     expdir=xxx      Directory in which to build new history file
-##     tmpdir=xxx      Working directory for `sort' and such
-##     expirectl=xxx   Use xxx as expire.ctl file
-##     flags=xxx       Pass xxx flags to expire
-##     lowmark         Create and use a lowmark file
-##     noexpire        Do not expire
-##     noexplog        Do not log expire output
-##     nologs          Do not scan logfiles
-##     nomail          Do not capture and mail output
-##     norenumber      Do not renumber the active file
-##     norm            Do not remove certain old files
-##     norotate        Do not rotate logfiles
-##     nostat          Do not run innstat
-##     notdaily        Not a daily run, and therefore implies nologs.
-##     delayrm         Delay unlink files, then do it quicker (expire -z)
-##     /full/path      Path to a program to run before expiring
-
-. @LIBDIR@/innshellvars
-
-EXPLOG=${MOST_LOGS}/expire.log
-INNSTAT=${PATHBIN}/innstat
-HOSTNAME=`hostname`
-DATE=`date`
-TAGGEDHASH=@DO_DBZ_TAGGED_HASH@
-SORT=sort
-
-##  If your expire does not pause or throttle innd, enable this next line:
-#MESSAGE="Expiration script $$"
-##  Renumber all at once, or in steps?  Set to the delay if steps (that
-##  may take a long time!).
-RENUMBER=
-
-PROGNAME=news.daily
-LOCK=${LOCKS}/LOCK.${PROGNAME}
-
-##  Set defaults.
-DAILY=true
-DOEXPIRE=true
-DOEXPLOG=true
-DOEXPIREOVER=false
-DOLOGS=true
-DOMAIL=true
-DORENUMBER=true
-DORM=true
-DOSTAT=true
-EXPIRECTL=
-EXPDIR=
-EXPIREFLAGS="-v1"
-EXPIREOVER=expireover
-LOWMARKFILE=
-RMFILE=
-
-HISTDIR="`dirname ${HISTORY}`"
-TOUT=600   # timeout value for ctlinnd commands
-if [ -z "${HISTDIR}" -o X"." = X"${HISTDIR}" -o ! -d "${HISTDIR}" ]; then
-    if [ -d "${PATHETC}/hist" ]; then
-       HISTDIR="${PATHETC}/hist"
-    else
-       HISTDIR="${PATHETC}"
-    fi
-fi
-if [ "${ENABLEOVERVIEW}" = "true" ]; then
-    DOEXPIREOVER=true
-    RMFILE=${MOST_LOGS}/expire.rm
-fi
-
-EXPIREOVERFLAGS=
-PROGRAMS=
-POSTPROGRAMS=
-REASON=
-SCANARG=
-DOGROUPBASEEXPIRY=false
-
-if [ "${GROUPBASEEXPIRY}" = "true" ]; then
-    if [ "${ENABLEOVERVIEW}" = "true" ]; then
-       DOGROUPBASEEXPIRY=true
-    else
-       DOEXPIREOVER=false
-       RMFILE=
-    fi
-fi
-
-##  Parse JCL.
-for I
-do
-    case "X$I" in
-    Xdelayrm)
-       RMFILE=${MOST_LOGS}/expire.rm
-       ;;
-    Xexpctl=*)
-       EXPIRECTL=`expr "${I}" : 'expctl=\(.*\)'`
-       case ${EXPIRECTL} in
-       /*)
-           ;;
-       *)
-           EXPIRECTL=`/bin/pwd`/${EXPIRECTL}
-           ;;
-       esac
-       ;;
-    Xexpdir=*)
-       EXPDIR=`expr "${I}" : 'expdir=\(.*\)'`
-       ;;
-    Xtmpdir=*)
-       TMPDIR=`expr "${I}" : 'tmpdir=\(.*\)'`
-       ;;
-    Xexpireover)
-       DOEXPIREOVER=true
-       RMFILE=${MOST_LOGS}/expire.rm
-       ;;
-    Xexpireoverflags=*)
-       EXPIREOVERFLAGS=`expr "${I}" : 'expireoverflags=\(.*\)'`
-       ;;
-    Xflags=*)
-       EXPIREFLAGS=`expr "${I}" : 'flags=\(.*\)'`
-       ;;
-    Xlowmark)
-       LOWMARKFILE=${MOST_LOGS}/expire.lowmark
-       DORENUMBER=false
-       ;;
-    Xnotdaily)
-        DAILY=false
-       DOLOGS=false
-       ;;
-    Xnoexpire)
-       DOEXPIRE=false
-       ;;
-    Xnoexpireover)
-       DOEXPIREOVER=false
-       RMFILE=
-       ;;
-    Xnoexplog)
-       DOEXPLOG=false
-       ;;
-    Xnologs)
-       DOLOGS=false
-       ;;
-    Xnomail)
-       DOMAIL=false
-       MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/'"
-       ;;
-    Xnonn)
-       # Ignore this.
-       ;;
-    Xnorenumber)
-       DORENUMBER=false
-       ;;
-    Xnorm)
-       DORM=false
-       ;;
-    Xnorotate)
-       SCANARG="${SCANARG} norotate"
-       ;;
-    Xnostat)
-       DOSTAT=false
-       ;;
-    X/*)
-       PROGRAMS="${PROGRAMS} ${I}"
-       ;;
-    Xpostexec=*)
-       POSTEXEC=`expr "${I}" : 'postexec=\(.*\)'`
-       POSTPROGRAMS="${POSTPROGRAMS} ${POSTEXEC}"
-       ;;
-    *)
-       echo "Unknown flag ${I}" 1>&2
-       exit 1
-       ;;
-    esac
-done
-
-##
-## Setup mail subject and command
-##
-if ${DAILY} ; then
-   MAILSUBJ="${HOSTNAME} Daily Usenet report for ${DATE}"
-else
-   MAILSUBJ="${HOSTNAME} intermediate usenet report for ${DATE}"
-fi
-MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/' | \
-    ${MAILCMD} -s '$MAILSUBJ' ${NEWSMASTER}"
-
-#
-#      Sanity check. Shouldn't we just bail out here with an error
-#      instead of trying to patch things up?
-#
-${DOEXPIRE} || {
-    EXPDIR=
-    RMFILE=
-}
-
-test -n "${EXPDIR}" && {
-       test -z "${REASON}" && REASON="Expiring $$ on ${EXPDIR}"
-       EXPIREFLAGS="${EXPIREFLAGS} '-d${EXPDIR}' '-r${REASON}'"
-}
-
-test -n "${RMFILE}" && {
-       if ${DOGROUPBASEEXPIRY} ; then
-           EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -z${RMFILE}"
-       else
-           EXPIREFLAGS="${EXPIREFLAGS} -z${RMFILE}"
-       fi
-    }
-
-test -n "${LOWMARKFILE}" && {
-       EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -Z${LOWMARKFILE}"
-}
-
-
-if ${DOMAIL} ; then
-    ##  Try to get a temporary file.
-    TEMP=${TMPDIR}/doex$$
-    test -f ${TEMP} && {
-       echo "Temporary file ${TEMP} exists" | eval ${MAIL}
-       exit 1
-    }
-    touch ${TEMP}
-    chmod 0660 ${TEMP}
-    exec 3>&1 >${TEMP} 2>&1
-fi
-
-cd ${PATHETC}
-
-##  Show the status of the news system.
-${DOSTAT} && {
-    ${INNSTAT}
-    echo ''
-}
-
-##  Lock out others.
-trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-shlock -p $$ -f ${LOCK} || {
-    ( echo "$0: Locked by `cat ${LOCK}`"; ${INNSTAT} ) | eval ${MAIL}
-    exit 1
-}
-
-##  Run any user programs.
-if [ -n "${PROGRAMS}" ] ; then
-    for P in ${PROGRAMS} ; do
-       echo ''
-       echo "${P}:"
-       eval ${P}
-    done
-fi
-
-${DOLOGS} && {
-    echo ''
-    scanlogs ${SCANARG}
-}
-
-# group-based expiry (delete expired overview first)
-if [ ${DOGROUPBASEEXPIRY} = true -a ${DOEXPIREOVER} = true ] ; then
-    if ${DOEXPLOG}; then
-       echo "${EXPIREOVER} start `date`: (${EXPIREOVERFLAGS})" >>${EXPLOG}
-    fi
-    ( cd ${HISTDIR} ; exec 2>&1 ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" ) \
-        >>${EXPLOG}
-    if ${DOEXPLOG}; then
-       echo "${EXPIREOVER} end `date`" >>${EXPLOG}
-    fi
-    test -n "${LOWMARKFILE}" && {
-       echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})"   >>${EXPLOG}
-       ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
-       echo "lowmarkrenumber end `date`"                       >>${EXPLOG}
-       rm -f ${MOST_LOGS}/expire.lastlowmark
-       mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
-    }
-    test -n "${RMFILE}" -a -s "${RMFILE}" && {
-       mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$
-
-       test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}"      
-       ${SORT} -u -o ${RMFILE} ${RMFILE}
-       if ${DOEXPLOG}; then
-           echo "      expirerm start `date`" >>${EXPLOG}
-       fi
-       expirerm ${RMFILE}
-       if ${DOEXPLOG}; then
-           echo "      expirerm end `date`" >>${EXPLOG}
-       fi
-    }
-    DOEXPIREOVER=false
-fi
-
-##  The heart of the matter:  prologs, expire, epilogs.
-if ${DOEXPIRE} ; then
-
-    ## Wait to be fairly certain innwatch is not in the middle of a pass
-    ## Since we're locked, innwatch will pause now till we're done
-    sleep 30
-
-    ##  See if we're throttled for lack of space.
-    SERVERMODE=`ctlinnd -t $TOUT mode 2>/dev/null | ${SED} 1q`
-    case "${SERVERMODE}" in
-    'Server paused'*'[innwatch:'*)
-       ## If paused, by innwatch, then turn pause into throttle
-       ## as we're going to stay that way for a while now
-       ctlinnd -t $TOUT -s throttle \
-           "`expr \"${SERVERMODE}\" : 'Server paused \(.*\)'`" || {
-           ( echo "$0: Cannot throttle while innwatch paused";
-             ${INNSTAT} ) | eval ${MAIL}
-           exit 1
-       }
-    esac
-    case "${SERVERMODE}" in
-    *space*" -- throttling")
-       echo "${SERVERMODE} -- trying to recover"
-       THROTTLED=true
-       EXPIREFLAGS="${EXPIREFLAGS} -n"
-       MESSAGE=
-       ;;
-    *"[innwatch:"*)
-       echo "${SERVERMODE} -- pressing on"
-       THROTTLED=false
-       EXPIREFLAGS="${EXPIREFLAGS} -n"
-       MESSAGE=
-       DORENUMBER=false
-       ;;
-    *)
-       THROTTLED=false
-       ;;
-    esac
-
-    ##  Throttle server if we need to.
-    if [ -n "${MESSAGE}" ] ; then
-       ctlinnd -t $TOUT -s -t120 throttle "${MESSAGE}" 2>&1 || {
-           ( echo "$0: Cannot throttle news"; ${INNSTAT} ) | eval ${MAIL}
-           exit 1
-       }
-    fi
-
-    #
-    #  Get rid of an old expire RMFILE since news.daily locks itself and
-    #  we would not get here if another instance were still running.
-    #        
-    if [ -n "${RMFILE}" ] ; then
-        rm -f ${RMFILE}
-    fi
-
-    ##  Actual expire the articles (finally!).
-    test -n "${EXPIRECTL}" && EXPIREFLAGS="${EXPIREFLAGS} ${EXPIRECTL}"
-    if ${DOEXPLOG}; then
-       echo "expire begin `date`: (${EXPIREFLAGS})"            >>${EXPLOG}
-       ( cd ${HISTDIR}; exec 2>&1 ; eval expire "${EXPIREFLAGS}" ) \
-           | ${SED} -e '/No such file or directory/d' \
-                    -e 's/^/    /' >>${EXPLOG}
-       echo "expire end `date`"                                >>${EXPLOG}
-    else
-       eval expire "${EXPIREFLAGS}" 2>&1 | grep -v 'No such file or directory'
-    fi
-
-    ##  If built on another filesystem, move history files.
-    if [ -n "${EXPDIR}" ] ; then
-       if [ ! -f ${EXPDIR}/history.n -o ! -f ${EXPDIR}/history.n.done ] ; then
-           ( echo "$0: No new history files"; ${INNSTAT} ) | eval ${MAIL}
-           exit 1
-       fi
-       cp /dev/null ${HISTORY}
-       mv -f ${EXPDIR}/history.n ${HISTORY}
-       mv -f ${EXPDIR}/history.n.dir ${HISTORY}.dir
-       if [ X${TAGGEDHASH} = XDO ] ; then
-           mv -f ${EXPDIR}/history.n.pag ${HISTORY}.pag
-       else
-           mv -f ${EXPDIR}/history.n.index ${HISTORY}.index
-           mv -f ${EXPDIR}/history.n.hash ${HISTORY}.hash
-       fi
-       rm -f ${EXPDIR}/history.n.done
-
-       case "${EXPIREFLAGS}" in
-       *-n*)
-           ;;
-       *)
-           MESSAGE="${REASON}"
-           ;;
-       esac
-    fi
-
-    ##  Restart the server if we need to.
-    if ${THROTTLED} || test -n "${MESSAGE}" ; then
-       ctlinnd -t "$TOUT" -s go "${MESSAGE}" 2>&1 || {
-           ( echo "$0: Cannot unthrottle news"; ${INNSTAT} ) | eval ${MAIL}
-           exit 1
-       }
-    fi
-    if ${DOEXPLOG}; then
-       echo "  all done `date`" >>${EXPLOG}
-    fi
-fi
-
-##  Remove old sockets.
-${DORM} &&
-    find ${TEMPSOCKDIR} -name "${TEMPSOCK}" -mtime +2 -exec rm -f '{}' ';'
-
-##  Did we became throttled during the run?
-SERVERMODE=`ctlinnd mode 2>/dev/null | ${SED} 1q`
-case "${SERVERMODE}" in
-*space*" -- throttling")
-    ##  We did, try to unthrottle the server.
-    echo "${SERVERMODE} -- trying to recover"    
-    ctlinnd -s go ""
-    ;;
-esac
-
-##  Release the lock now, everything below this must be able to withstand
-##  simultaneous news.daily's running.   We do this so innwatch can start
-##  monitoring again asap after the expire is done -- removing the
-##  articles isn't critical, nor is the renumber.
-rm ${LOCK}
-
-## Remove the articles that are supposed to go
-if [ ${DOEXPIRE} = true -a ${DOGROUPBASEEXPIRY} != true ] ; then
-    test -n "${RMFILE}" -a -s "${RMFILE}" && {
-       mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$
-
-       test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}"      
-       ${SORT} -u -o ${RMFILE} ${RMFILE}
-       if ${DOEXPLOG}; then
-           echo "      expirerm start `date`" >>${EXPLOG}
-       fi
-       expirerm ${RMFILE}
-       if ${DOEXPLOG}; then
-           echo "      expirerm end `date`" >>${EXPLOG}
-       fi
-       ${DOEXPIREOVER} && {
-           if ${DOEXPLOG}; then
-               echo "  ${EXPIREOVER} start `date`" >>${EXPLOG}
-           fi
-           ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
-             grep -v 'No such file or directory'
-           DOEXPIREOVER=false
-           if ${DOEXPLOG}; then
-               echo "  ${EXPIREOVER} end `date`" >>${EXPLOG}
-           fi
-       }
-       test -n "${LOWMARKFILE}" && {
-           echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})"   >>${EXPLOG}
-           ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
-           echo "lowmarkrenumber end `date`"                       >>${EXPLOG}
-           rm -f ${MOST_LOGS}/expire.lastlowmark
-           mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
-       }
-    }
-    # expire overview lines for files we just removed
-    if ${DOEXPIREOVER}; then
-       if ${DOEXPLOG}; then
-           echo "      ${EXPIREOVER} start `date`" >>${EXPLOG}
-       fi
-       ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
-           grep -v 'No such file or directory'
-       DOEXPIREOVER=false
-       if ${DOEXPLOG}; then
-           echo "      ${EXPIREOVER} end `date`" >>${EXPLOG}
-       fi
-       test -n "${LOWMARKFILE}" && {
-           echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})"   >>${EXPLOG}
-           ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
-           echo "lowmarkrenumber end `date`"                       >>${EXPLOG}
-           rm -f ${MOST_LOGS}/expire.lastlowmark
-           mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
-       }
-    fi
-fi
-# in case noexpire expireover
-if ${DOEXPIREOVER}; then
-    if ${DOEXPLOG}; then
-       echo "  ${EXPIREOVER} start `date`" >>${EXPLOG}
-    fi
-    ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
-       grep -v 'No such file or directory'
-    if ${DOEXPLOG}; then
-       echo "  ${EXPIREOVER} end `date`" >>${EXPLOG}
-    fi
-    test -n "${LOWMARKFILE}" && {
-       echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})"   >>${EXPLOG}
-       ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
-       echo "lowmarkrenumber end `date`"                           >>${EXPLOG}
-       rm -f ${MOST_LOGS}/expire.lastlowmark
-       mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
-    }
-fi
-
-##  Renumber the active file.
-if ${DORENUMBER} ; then
-    echo ''
-    echo 'Renumbering active file.'
-    if [ -z "${RENUMBER}" ] ;then
-       ctlinnd -s -t`wc -l <${ACTIVE}` renumber '' 2>&1
-    else
-       while read GROUP hi lo flag ; do
-           ctlinnd -s renumber ${GROUP} 2>&1
-           sleep ${RENUMBER}
-       done <${ACTIVE}
-    fi
-fi
-
-##  Display expire log messages
-if ${DOMAIL} ; then
-    if [ -s ${EXPLOG} ] ; then
-           echo Expire messages:
-           cat ${EXPLOG}
-           echo ---------
-           echo ''
-    fi
-fi
-
-##  Show the status of the news system after expiration.
-${DOSTAT} && {
-    echo 'Post expiration status:' ; echo ''
-    ${INNSTAT}
-    echo ''
-}
-
-##  Mail the report.
-if ${DOMAIL} ; then
-    # Stop using the temp file, and mail captured output.
-    exec 1>&3 2>&1 3>&-
-    MAIL="${MAILCMD} -s \"${MAILSUBJ}\" ${NEWSMASTER}"
-    test -s ${TEMP} && cat ${TEMP} | ${SED} -e 's/^~/~~/' | eval ${MAIL}
-    rm -f ${TEMP}
-fi
-
-##  Run any user programs.
-if [ -n "${POSTPROGRAMS}" ] ; then
-    for P in ${POSTPROGRAMS} ; do
-       echo ''
-       echo "${P}:"
-       eval ${P}
-    done
-fi
-
-##  All done
-if ${DAILY} ; then
-    date >${PATHDB}/.news.daily
-fi
-${RNEWS} -U
-exit 0
diff --git a/scripts/rc.news.in b/scripts/rc.news.in
deleted file mode 100644 (file)
index 59eb7fe..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 7435 $
-##  News boot script.  Runs as "news" user.  Requires inndstart be
-##  setuid root.  Run from rc.whatever as:
-##     su news -c /path/to/rc.news >/dev/console
-##
-##  Or to stop INN:
-##     su news -c '/path/to/rc.news stop'
-
-waitforpid()
-{
-    i=12
-    while [ $i -gt 0 ];
-    do
-        kill -0 $1 2>/dev/null || break
-       sleep 5
-       printf "."
-       i=`expr $i - 1`
-    done
-    printf "\n"
-}
-
-case X"$1" in
-Xstop)
-    # Stop cnfsstat (if running)
-    if [ -f ${PATHRUN}/cnfsstat.pid ]; then
-       kill `cat ${PATHRUN}/cnfsstat.pid`
-       rm -f ${PATHRUN}/cnfsstat.pid
-    fi
-
-    # Stop innwatch (if running)
-    if [ -f $WATCHPID ]; then
-       kill `cat $WATCHPID`
-       rm -f $WATCHPID
-    fi
-
-    printf "Stopping innd: "
-    ${PATHBIN}/ctlinnd throttle 'rc.news stop'
-    ${PATHBIN}/ctlinnd shutdown 'rc.news stop'
-
-    # wait for innd to exit (up to 60 sec)
-    pid=`cat ${SERVERPID} 2>/dev/null`
-    if [ "$pid" != "" ]; then
-       waitforpid $pid
-    else
-       printf "\n"
-    fi
-
-    # Turn off ovdb support procs, and close the DB environment
-    if [ "$OVMETHOD" = "ovdb" -a -f ${PATHRUN}/ovdb_server.pid ]; then
-       pid=`cat ${PATHRUN}/ovdb_server.pid 2>/dev/null`
-       if [ "$pid" != "" ]; then
-           printf "Stopping ovdb_server: "
-           kill $pid
-           waitforpid $pid
-       fi
-    fi
-    if [ "$OVMETHOD" = "ovdb" -a -f ${PATHRUN}/ovdb_monitor.pid ]; then
-       pid=`cat ${PATHRUN}/ovdb_monitor.pid 2>/dev/null`
-       if [ "$pid" != "" ]; then
-           printf "Stopping ovdb_monitor: "
-           kill $pid
-           waitforpid $pid
-       fi
-    fi
-
-    if [ -f ${PATHBIN}/rc.news.local ]; then
-        ${PATHBIN}/rc.news.local stop
-    fi
-
-    # Delete all of the PID files that we know about to avoid having them
-    # stick around after a fresh start.
-    rm -f ${PATHRUN}/cnfsstat.pid $WATCHPID $SERVERPID
-    rm -f ${PATHRUN}/ovdb_server.pid ${PATHRUN}/ovdb_monitor.pid
-
-    exit 0
-;;
-esac
-
-##  Pick ${INND} or ${INNDSTART}
-WHAT=${INNDSTART}
-
-MAIL="${MAILCMD} -s 'Boot-time Usenet warning on `hostname`' ${NEWSMASTER}"
-
-##  RFLAG is set below; set INNFLAGS in inn.conf(5)
-RFLAG=""
-
-##  Clean shutdown or already running?
-if [ -f ${SERVERPID} ] ; then
-    if kill -0 `cat ${SERVERPID}` 2>/dev/null; then
-       echo 'INND is running'
-       exit 0
-    fi
-    echo 'INND:  PID file exists -- unclean shutdown!'
-    RFLAG="-r"
-fi
-
-if [ ! -f ${PATHDB}/.news.daily ] ; then
-    case `find ${PATHBIN}/innd -mtime +1 -print 2>/dev/null` in
-    "")
-       ;;
-    *)
-       echo 'No .news.daily file; need to run news.daily?' | eval ${MAIL}
-       ;;
-    esac
-else
-    case `find ${PATHDB}/.news.daily -mtime +1 -print 2>/dev/null` in
-    "")
-       ;;
-    *)
-       echo 'Old .news.daily file; need to run news.daily?' | eval ${MAIL}
-       ;;
-    esac
-fi
-
-##  Active file recovery.
-if [ ! -s ${ACTIVE} ] ; then
-    if [ -s ${NEWACTIVE} ] ; then
-       mv ${NEWACTIVE} ${ACTIVE}
-    else
-       if [ -s ${OLDACTIVE} ] ; then
-           cp ${OLDACTIVE} ${ACTIVE}
-       else
-           echo 'INND:   No active file!'
-           exit 1
-       fi
-    fi
-    RFLAG="-r"
-    # You might want to rebuild the DBZ database, too:
-    #cd ${PATHDB} \
-    #          && makehistory -r \
-    #          && mv history.n.dir history.dir \
-    #          && mv history.n.index history.index \
-    #          && mv history.n.hash history.hash
-fi
-
-##  Remove temporary batchfiles and lock files.
-( cd ${BATCH} && rm -f bch* )
-( cd ${LOCKS} && rm -f LOCK* )
-( cd ${TEMPSOCKDIR} && rm -f ${TEMPSOCK} )
-rm -f ${NEWSCONTROL} ${NNTPCONNECT} ${SERVERPID}
-
-## Initialize ovdb.  Must be done before starting innd.
-if [ "$OVMETHOD" = "ovdb" ]; then
-    echo 'Starting ovdb.'
-    ovdb_init || {
-       echo "Can't initialize ovdb (check news.err for OVDB messages)"
-       exit 1
-    }
-    sleep 1
-fi
-
-##  Start the show.
-echo 'Starting innd.'
-eval ${WHAT} ${RFLAG} ${INNFLAGS}
-
-# Gee, looks like lisp, doesn't it?
-${DOINNWATCH} && {
-    echo "Scheduled start of ${INNWATCH}."
-    ( sleep 60 ; ${INNWATCH} ) > /dev/null &
-}
-
-${DOCNFSSTAT} && {
-    echo "Scheduled start of cnfsstat."
-    ( sleep 60 ; ${PATHBIN}/cnfsstat -s -l -P ) > /dev/null &
-}
-
-RMFILE=${MOST_LOGS}/expire.rm
-for F in ${RMFILE} ${RMFILE}.*; do
-    if [ -f $F -a -s $F ] ; then
-       echo "Removing articles from pre-downtime expire run (${F})."
-       (
-           echo 'System shut down during expire.' \
-               'Unlinking articles listed in'
-           echo ${F}
-       ) | eval ${MAIL}
-       ${PATHBIN}/expirerm ${F}
-    fi
-done &
-
-# Run any additional local startup commands.
-if [ -f ${PATHBIN}/rc.news.local ] ; then
-    ${PATHBIN}/rc.news.local start
-fi
diff --git a/scripts/scanlogs.in b/scripts/scanlogs.in
deleted file mode 100644 (file)
index 6101899..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 7770 $
-##  Summarize INN log files.
-##  Optional arguments:
-##     norotate        Do not rotate logfiles
-
-##  If you get an error from this line:
-##     sh -c 'egrep "`ls /etc`" /dev/null'
-##  then get a better egrep, like the FSF one.
-
-##  Directory where old log files are kept.
-OLD=${MOST_LOGS}/OLD
-##  If you want to archive the active file, enable this line.
-ACTIVEFILE=${ACTIVE}
-##  Number of lines of error in each category to report.
-TOP=${TOP-20}
-##  NN log file.
-NN=${PATHETC}/nn/Log
-
-##  Where these programs, if used, write their logs.
-##  We also have to find innfeed's log file.
-INNFEEDLOG=`${AWK} '{gsub(/:|#/, " & ")} {if ($1 == "log-file" && $2 == ":") print $3}' ${PATHETC}/innfeed.conf`
-INNFEED=
-for F in "${INNFEEDLOG}" ; do
-    test -f "${MOST_LOGS}/${F}" && INNFEED="${INNFEED} ${MOST_LOGS}/${F}"
-done
-test -z "${INNFEED}" && test -f ${MOST_LOGS}/innfeed.log && INNFEED="${MOST_LOGS}/innfeed.log"
-
-
-##  Where nntpsend, if used, writes its log information.
-NNTPSEND=${MOST_LOGS}/nntpsend.log
-SENDNNTP=${MOST_LOGS}/send-nntp.log
-SENDUUCP=${MOST_LOGS}/send-uucp.log
-LIVEFILES="${INNFEED} ${NNTPSEND} ${SENDNNTP} ${SENDUUCP}"
-##  Where news.daily places expire output, unless noexplog was used.
-EXPLOG=${MOST_LOGS}/expire.log
-
-##  If you divide your news syslog into separate files, list them here.
-SYSLOG_CRIT=${MOST_LOGS}/news.crit
-SYSLOG_ERR=${MOST_LOGS}/news.err
-SYSLOG_NOTICE=${MOST_LOGS}/news.notice
-SYSLOGS="${SYSLOG_CRIT} ${SYSLOG_ERR} ${SYSLOG_NOTICE}"
-
-##  Where tally control and unwanted processors are found.
-TALLY_CONTROL=${PATHBIN}/tally.control
-TALLY_UNWANTED=${PATHBIN}/tally.unwanted
-UNWANTED_LOG=${MOST_LOGS}/unwanted.log
-CONTROL_LOG=${MOST_LOGS}/control.log
-CONTROL_DATA=
-test -f ${MOST_LOGS}/newgroup.log && CONTROL_DATA=${MOST_LOGS}/newgroup.log
-test -f ${MOST_LOGS}/rmgroup.log \
-       && CONTROL_DATA="${CONTROL_DATA} ${MOST_LOGS}/rmgroup.log"
-
-##  Build up the list of log files to process.
-LOGS="${ERRLOG} ${EXPLOG} ${LOG} ${ACTIVEFILE} ${SYSLOGS} ${UNWANTED_LOG}"
-
-for F in ${LIVEFILES} ; do
-    test -n "${F}" -a -f "${F}" && LOGS="${LOGS} ${F}"
-done
-
-test -n "${CONTROL_DATA}" && LOGS="${LOGS} ${CONTROL_LOG}"
-for F in checkgroups default ihave newgroup rmgroup sendme sendsys \
-       senduuname version miscctl badcontrol failedpgp badpgp; do
-    test -f ${MOST_LOGS}/${F}.log && LOGS="${LOGS} ${MOST_LOGS}/${F}.log"
-done
-
-PROGNAME=scanlogs
-LOCK=${LOCKS}/LOCK.${PROGNAME}
-
-##  Set defaults.
-ROTATE=true
-
-##  Parse JCL.
-for I
-do
-    case "X${I}" in
-    Xnonn)
-       # Ignore this.
-       ;;
-    Xnorotate)
-       ROTATE=false
-       ;;
-    *)
-       echo "Unknown flag ${I}" 1>&2
-       exit 1
-       ;;
-    esac
-done
-
-##  Make sure every log exists.
-for F in ${LOGS} ; do
-    test ! -f ${F} && touch ${F}
-done
-
-##  Temporary files.
-T=${TMPDIR}/scan$$
-PROBS=${TMPDIR}/scanlog$$
-trap "rm -f ${T} ${PROBS}; exit 0" 0 1 2 3 15
-
-##  Rotate the logs?
-if ${ROTATE} ; then
-    ##  Lock out others.
-    shlock -p $$ -f ${LOCK} || {
-       echo "$0: Locked by `cat ${LOCK}`"
-       exit 1
-    }
-    trap "rm -f ${T} ${PROBS} ${LOCK}; exit 0" 1 2 3 15
-
-    HERE=`pwd`
-    cd ${MOST_LOGS}
-    test ! -d ${OLD} && mkdir ${OLD}
-
-    ctlinnd -s logmode
-    PAUSED=false
-    ctlinnd -s pause "Flushing log and syslog files" 2>&1 && PAUSED=true
-    OUTPUT=`ctlinnd flushlogs 2>&1`
-    if [ "$OUTPUT" != "Ok" -a "$OUTPUT" != "In debug mode" ]; then
-       echo "$OUTPUT"
-       echo 'Cannot flush logs.'
-       rm -f ${LOCK}
-       exit 1
-    fi
-
-    ##  Make sure these .old files exist, in case innd is down.
-    for F in ${LOG} ${ERRLOG} ${EXPLOG} ; do
-       if [ ! -f ${F}.old ]; then
-           rm -f ${F}.old
-           cp ${F} ${F}.old
-           cat /dev/null >${F}
-       fi
-    done
-
-    ##  Copy syslog files, truncating old inode since syslog has it open.
-    for F in ${SYSLOGS}; do
-       rm -f ${F}.old
-       cp ${F} ${F}.old
-       cat /dev/null >${F}
-    done
-    ctlinnd -s logmode
-
-    ##  Make a copy of the active file.
-    if [ -n ${ACTIVEFILE} ] ; then
-       BASE=`basename ${ACTIVEFILE}`
-       rm -f ${OLD}/${BASE}.old
-       cp ${ACTIVEFILE} ${OLD}/${BASE}.old
-    fi
-
-    ##  These are live files, so use link rather than copy.
-    for F in ${LIVEFILES} ; do
-       if [ -f ${F} ]; then
-           rm -f ${F}.old ${F}.new
-           ln ${F} ${F}.old
-           touch ${F}.new
-           chmod 0660 ${F}.new
-           mv ${F}.new ${F}
-       fi
-    done
-
-    ##  Tally control messages if we logged them.
-    test -n "${CONTROL_DATA}" && cat ${CONTROL_DATA} | ${TALLY_CONTROL}
-
-    ${PAUSED} && ctlinnd -s go "Flushing log and syslog files" 2>&1
-
-    cd ${OLD}
-    for F in ${LOGS}; do
-       ##  Process the current (just-flushed) log
-       BASE=`basename ${F}`
-       rm -f ${OLD}/${BASE}
-       case ${F} in
-       ${SYSLOG_CRIT}|${ERRLOG}|${EXPLOG}|${LOG}|${SYSLOG_NOTICE})
-           ##  Make a link that can be deleted (since if not rotating
-           ##  we delete the copy that is made in ${TMPDIR}).
-           mv ${F}.old ${OLD}/${BASE}
-           rm -f ${OLD}/${BASE}.0
-           ln ${OLD}/${BASE} ${OLD}/${BASE}.0
-           ;;
-       ${ACTIVEFILE})
-           mv ${BASE}.old ${OLD}/${BASE}
-           ;;
-       ${SYSLOG_ERR})
-           mv ${F}.old ${OLD}/${BASE}
-           ;;
-       ${UNWANTED_LOG})
-           ##  Rotate and compress the file.
-           BASE=`basename ${F}`
-           if [ ! -f ${BASE} -a -f ../${BASE} ]; then
-               cp ../${BASE} ${BASE}
-               chmod 0440 ${BASE}
-           fi
-           if [ -f ${BASE} ]; then
-               ${LOG_COMPRESS} <${BASE} >${BASE}.0${Z} && rm -f ${BASE}
-               chmod 0440 ${BASE}.0${Z}
-
-               ##  Do rotation.
-               if [ X${LOGCYCLES} = X ]; then       
-                   LOGCYCLES=3
-               fi
-               EXT=${LOGCYCLES}
-               rm -f ${BASE}.${LOGCYCLES}${Z}
-               while [ ${EXT} -gt 0 ] ; do
-                   NEXT=${EXT}
-                   EXT=`expr ${EXT} - 1`
-                   test -f ${BASE}.${EXT}${Z} \
-                       && rm -f ${BASE}.${NEXT}${Z} \
-                       && mv ${BASE}.${EXT}${Z} ${BASE}.${NEXT}${Z}
-               done
-           fi
-           ##  Innreport assumes where unwanted.log exists, so leave it
-           ##  and process later.
-           ;;
-       *)
-           if [ -f ${F}.old ]; then
-               mv ${F}.old ${OLD}/${BASE}
-           else
-               rm -f ${OLD}/${BASE} ${F}.new
-               touch ${F}.new
-               chmod 0660 ${F}.new
-               ln ${F} ${F}.old
-               mv ${F}.new ${F}
-               mv ${F}.old ${OLD}/${BASE}
-           fi
-           ;;
-       esac
-    done
-    cd ${HERE}
-else
-    ##  Don't use the real OLD directory, instead use TMPDIR
-    OLD=${TMPDIR}
-
-    ##  Make a snapshot of what we need for below.
-    ctlinnd -s pause "Snapshot log and syslog files" 2>&1
-    for F in ${SYSLOG_CRIT} ${ERRLOG} ${EXPLOG} ${LOG} ${SYSLOG_NOTICE} ; do
-       BASE=`basename ${F}`
-       rm -f ${OLD}/${BASE}.0
-       cp ${F} ${OLD}/${BASE}.0
-    done
-    ctlinnd -s go "Snapshot log and syslog files" 2>&1
-fi
-
-##
-##  We now (finally!) have copies of the log files where we need them.
-##
-
-##  Display syslog critical messages.
-BASE=`basename ${SYSLOG_CRIT}`
-OLD_SYSLOG=${OLD}/${BASE}.0
-if [ -s ${OLD_SYSLOG} ] ; then
-    echo Syslog critical messages:
-    cat ${OLD_SYSLOG}
-    echo ---------
-    echo ''
-fi
-rm -f ${OLD_SYSLOG}
-
-##  Display error log.
-BASE=`basename ${ERRLOG}`
-OLD_ERRLOG=${OLD}/${BASE}.0
-if [ -s ${OLD_ERRLOG} ] ; then
-    echo Error log:
-    cat ${OLD_ERRLOG}
-    echo ---------
-    echo ''
-fi
-rm -f ${OLD_ERRLOG}
-
-##  Scan for various problems in articles we were offered or sent...
-BASE=`basename ${LOG}`
-OLD_LOG=${OLD}/${BASE}.0
-
-##  and summarize syslog information.
-BASE=`basename ${SYSLOG_NOTICE}`
-OLD_SYSLOG=${OLD}/${BASE}.0
-if [ -s ${OLD_SYSLOG} -o -s ${OLD_LOG} ] ; then
-    ${PATHBIN}/innreport -f ${PATHETC}/innreport.conf ${OLD_SYSLOG} ${OLD_LOG}
-    echo ---------
-    echo ''
-fi
-rm -f ${OLD_LOG} ${OLD_SYSLOG}
-if ${ROTATE} ; then
-    BASE=`basename ${UNWANTED_LOG}`
-    if [ -f ${UNWANTED_LOG}.old ]; then
-       mv ${UNWANTED_LOG}.old ${OLD}/${BASE}
-    else
-       rm -f ${OLD}/${BASE}
-       cp ${UNWANTED_LOG} ${OLD}/${BASE}
-       chmod 0660 ${OLD}/${BASE}
-    fi
-fi
-
-OLD_SYSLOG=${OLD}/${EXPLOG}.0
-rm -f ${EXPLOG}
-
-##  Compress and rotate the logs.
-if ${ROTATE} ; then
-    cd ${OLD}
-    if [ X${LOGCYCLES} = X ]; then       
-        LOGCYCLES=3
-    fi
-    for F in ${LOGS} ; do
-       ##  Skip if it's unwanted.log, since it's already rotated
-       if [ ${F} = ${UNWANTED_LOG} ]; then
-           continue
-       fi
-       ##  Skip if file doesn't exist.
-       BASE=`basename ${F}`
-       test -f ${BASE} || continue
-
-       ##  Compress the file.
-       ${LOG_COMPRESS} <${BASE} >${BASE}.0${Z} && rm -f ${BASE}
-       chmod 0440 ${BASE}.0${Z}
-
-       ##  Do rotation.
-       EXT=${LOGCYCLES}
-       rm -f ${BASE}.${LOGCYCLES}${Z}
-       while [ ${EXT} -gt 0 ] ; do
-           NEXT=${EXT}
-           EXT=`expr ${EXT} - 1`
-           test -f ${BASE}.${EXT}${Z} \
-               && rm -f ${BASE}.${NEXT}${Z} \
-               && mv ${BASE}.${EXT}${Z} ${BASE}.${NEXT}${Z}
-       done
-    done
-
-    ##  Remove lock.
-    rm -f ${LOCK}
-fi
-
-##  All done.
-exit 0
diff --git a/scripts/simpleftp.in b/scripts/simpleftp.in
deleted file mode 100644 (file)
index ef133bc..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#! /usr/bin/perl -w
-
-# simpleftp - Rudimentary FTP client.
-#
-# Author: David Lawrence <tale@isc.org>.
-#         Rewritten by Julien Elie <julien@trigofacile.com> to use Net::FTP.
-#
-# Fetch files to the local machine based on URLs on the command line.
-# INN's configure searches for ncftp, wget, linx, et caetera,
-# but they're all system add-ons, so this is provided.
-#
-# Perl 5 is already required by other parts of INN; it only took a half hour
-# to write this, so this was the easiest way to go for a backup plan.
-#
-# This script is nowhere near as flexible as libwww.  If you really need
-# that kind of power, get libwww and use it.  This is just sufficient for what
-# INN needed.
-
-use strict;
-use Net::FTP;
-use Sys::Hostname;
-
-$0 =~ s(.*/)();
-
-my $usage = "Usage: $0 ftp-URL ...\n";
-
-@ARGV
-  or die $usage;
-
-for (@ARGV) {
-  m(^ftp://)
-    or die $usage;
-}
-
-my ($lasthost, $ftp);
-
-# This will keep track of how many _failed_.
-my $exit = @ARGV;
-
-for (@ARGV) {
-  my ($host, $path) = m%^ftp://([^/]+)(/.+)%;
-  my $user = 'anonymous';
-  my $pass = (getpwuid($<))[0] . '@' . hostname;
-  my $port = 21;
-
-  unless (defined $host && defined $path) {
-    warn "$0: bad URL: $_\n";
-    next;
-  }
-
-  if ($host =~ /(.*):(.*)\@(.*)/) {
-    $user = $1;
-    $pass = $2;
-    $host = $3;
-  }
-
-  if ($host =~ /(.*):(.*)/) {
-    $port = $1;
-    $host = $2;
-  }
-
-  if (defined $lasthost && $host ne $lasthost) {
-    $ftp->quit;
-    $lasthost = undef;
-  }
-
-  unless (defined $lasthost) {
-    $ftp = Net::FTP->new($host, Port => $port)
-      or next;
-    $ftp->login($user, $pass)
-      or next;
-  }
-
-  my $localfile = $path;
-  $path =~ s([^/]+$)();
-  $localfile =~ s(.*/)();
-
-  $ftp->cwd($path)
-    or next;
-  $ftp->get($localfile)
-    or next;
-
-  $exit--;
-  $lasthost = $host;
-}
-
-$ftp->quit
-  if defined $lasthost;
-
-exit $exit;
diff --git a/scripts/tally.control.in b/scripts/tally.control.in
deleted file mode 100644 (file)
index 3e49ce5..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 2677 $
-##  Tally/update the newgroup/rmgroup control log.
-##  Merge in a log that contains newgroup/rmgroup control messages so that
-##  the "control.log" file is updated to contain the new counts of how
-##  often each group has been newgroup'd or rmgroup'd.  This is run by
-##  scanlogs, which prepares this from the control-message handlers if
-##  control.ctl specifies logging.
-
-CONTROL=${MOST_LOGS}/control.log
-CONTROL_NEW=${CONTROL}.new
-CONTROL_OLD=${CONTROL}.old
-
-PROGNAME=`basename $0`
-LOCK=${LOCKS}/LOCK.${PROGNAME}
-
-##  Lock.
-trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
-shlock -f ${LOCK} -p $$ || {
-    echo "$0: cannot lock ${LOCK}" 1>&2
-    exit 1
-}
-
-##  Prepare the files.
-if [ ! -f ${CONTROL} ]; then
-    touch ${CONTROL}
-    chmod 0660 ${CONTROL}
-fi
-rm -f ${CONTROL_NEW} ${CONTROL_OLD}
-ln ${CONTROL} ${CONTROL_OLD}
-touch ${CONTROL_NEW}
-chmod 0660 ${CONTROL_NEW}
-
-##  Grab the data.
-${SED} -n -e 's/[       ][      ]*/ /g' -e 's/^ \(Control:.*\)$/1 \1/p' \
-    | cat - ${CONTROL} \
-    | ${SED} -e 's/ /#/g' -e 's/\([0-9][0-9]*\)#\(.*\)/\1 \2/' \
-    | ${AWK} 'BEGIN {
-           ctl[0]=0;
-       }
-       {
-           ctl[$2] += $1;
-       }
-       END {
-           for (line in ctl) {
-               if (line != 0) {
-                   print ctl[line], line;
-               }
-           }
-       }' \
-    | tr '#' ' ' \
-    | sort -n -r >${CONTROL_NEW}
-mv -f ${CONTROL_NEW} ${CONTROL}
-
-##  All done.
-rm -f ${LOCK}
-exit 0
diff --git a/scripts/writelog.in b/scripts/writelog.in
deleted file mode 100644 (file)
index a177ec6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#! /bin/sh
-# fixscript will replace this line with code to load innshellvars
-
-##  $Revision: 2677 $
-##  Write a log file entry, by either mailing it or writing it safely.
-##  Usage:
-##     writelog name text... <input
-##  where
-##     name    is 'mail' to mail it, or filename to append to.
-
-MAXTRY=60
-
-##  Parse arguments.
-if [ $# -lt 2 ] ; then
-    echo "usage: $0 'logfile|mail' message ..." 1>&2
-    exit 1
-fi
-LOGFILE="$1"
-shift
-MESSAGE="$@"
-
-##  Handle the easy cases.
-case "X${LOGFILE}" in
-X/dev/null)
-    exit 0
-    ;;
-Xmail)
-    sed -e 's/^~/~~/' | ${MAILCMD} -s "${MESSAGE}" ${NEWSMASTER}
-    exit 0
-    ;;
-esac
-
-##  We're sending to a file.
-LOCK=${LOCKS}/LOCK.`basename ${LOGFILE}`
-
-##  Remember our PID, in case while is a sub-shell.
-PID=$$
-TRY=0
-
-export LOCK MAXTRY PID LOGFILE ARTICLE MESSAGE TRY
-while [ ${TRY} -lt ${MAXTRY} ]; do
-    shlock -p ${PID} -f ${LOCK} && break
-    sleep 2
-    TRY=`expr ${TRY} + 1`
-done
-
-##  If we got the lock, update the file; otherwise, give up.
-if [ ${TRY} -lt ${MAXTRY} ]; then
-    echo "${MESSAGE}" >>${LOGFILE}
-    ${SED} -e 's/^/    /' >>${LOGFILE}
-    echo "" >>${LOGFILE}
-    rm -f ${LOCK}
-else
-    ##  This goes to errlog, usually.
-    echo "$0: Cannot grab lock ${LOCK}, held by:" `cat ${LOCK}` 1>&2
-fi
diff --git a/site/Makefile b/site/Makefile
deleted file mode 100644 (file)
index e81d9eb..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-##  $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/site/getsafe.sh b/site/getsafe.sh
deleted file mode 100644 (file)
index 4f123fb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh 
-##  $Revision: 847 $
-##
-##  Safely get a file from the samples directory.  Usage:
-##     getsafe <sample> <localfile>
-case $# in
-2)
-    ;;
-*)
-    echo "Can't get INN sample file:  wrong number of arguments." 1>&2
-    exit 1
-    ;;
-esac
-
-SRC=$1
-DEST=$2
-
-##  Try RCS.
-if [ -f RCS/${DEST},v ] ; then
-    echo "Note: ${SRC} has changed; please compare."
-    test -f ${DEST} && exit 0
-    exec co -q ${DEST}
-fi
-
-##  Try SCCS.
-if [ -f SCCS/s.${DEST} ] ; then
-    echo "Note: ${SRC} has changed; please compare."
-    test -f ${DEST} && exit 0
-    exec sccs get -s ${DEST}
-fi
-
-##  File exist locally?
-if [ -f ${DEST} ] ; then
-    cmp ${SRC} ${DEST}
-    if [ $? -eq 0 ] ; then
-       touch ${DEST}
-       exit 0
-    fi
-    echo "${SRC} has changed; please update ${DEST}"
-    exit 1
-fi
-
-echo Using sample version of ${DEST}
-cp ${SRC} ${DEST}
-
-exit 0
diff --git a/storage/Make.methods b/storage/Make.methods
deleted file mode 100644 (file)
index fc84d6c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is automatically generated by buildconfig
-
-METHOD_SOURCES  = buffindexed/buffindexed.c cnfs/cnfs.c ovdb/ovdb.c \
-                  timecaf/caf.c timecaf/timecaf.c timehash/timehash.c \
-                  tradindexed/tdx-cache.c tradindexed/tdx-data.c \
-                  tradindexed/tdx-group.c tradindexed/tradindexed.c \
-                  tradspool/tradspool.c trash/trash.c
-EXTRA_SOURCES   = tradindexed/tdx-util.c
-PROGRAMS        = tradindexed/tdx-util
-
-
-##  Included from buffindexed/ovmethod.mk
-
-# This rule requires a compiler that supports -o with -c.  Since it's normally
-# used by developers, that should be acceptable.
-buffindexed/buffindexed_d.o: buffindexed/buffindexed.c
-       $(CC) $(CFLAGS) -DBUFF_DEBUG -c -o $@ buffindexed/buffindexed.c
-
-buffindexed/debug: buffindexed/buffindexed_d.o libstorage.$(EXTLIB) $(LIBHIST)
-       $(LIBLD) $(LDFLAGS) -o $@ buffindexed/buffindexed_d.o \
-           $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
-
-
-##  Included from tradindexed/ovmethod.mk
-
-tradindexed/tdx-util.o: tradindexed/tdx-util.c
-       $(CC) $(CFLAGS) -c -o $@ tradindexed/tdx-util.c
-
-tradindexed/tdx-util: tradindexed/tdx-util.o libstorage.$(EXTLIB) $(LIBHIST)
-       $(LIBLD) $(LDFLAGS) -o $@ tradindexed/tdx-util.o \
-           $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
diff --git a/storage/Makefile b/storage/Makefile
deleted file mode 100644 (file)
index 770bd23..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-##  $Id: Makefile 7727 2008-04-06 07:59:46Z iulius $
-
-include ../Makefile.global
-
-top          = ..
-CFLAGS       = $(GCFLAGS) -I. $(BERKELEY_DB_CFLAGS)
-
-SOURCES              = expire.c interface.c methods.c ov.c overdata.c ovmethods.c \
-               $(METHOD_SOURCES)
-OBJECTS              = $(SOURCES:.c=.o)
-LOBJECTS      = $(OBJECTS:.o=.lo)
-
-.SUFFIXES: .lo
-
-all: library programs
-
-# Included here after the all target, since additional rules are defined in
-# Make.methods to be sure that we recurse properly to build the methods.
-include Make.methods
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' all
-
-install: all
-       $(LI_XPUB) libstorage.$(EXTLIB) $D$(PATHLIB)/libstorage.$(EXTLIB)
-       for F in $(PROGRAMS) ; do \
-           $(LI_XPRI) $$F $D$(PATHBIN)/`basename $$F` ; \
-       done
-
-library: libstorage.$(EXTLIB)
-
-programs: $(PROGRAMS)
-
-clobber clean distclean:
-       rm -f *.o *.lo */*.o */*.lo libstorage.la libstorage.a
-       rm -f $(PROGRAMS) libstorage_pure_*.a .pure
-       rm -f buildconfig methods.c methods.h ovmethods.c ovmethods.h
-       rm -f profiled libstorage$(PROFSUFFIX).a
-       rm -rf .libs */.libs
-
-tags ctags: $(SOURCES)
-       $(CTAGS) $(SOURCES) ../include/*.h ../include/inn/*.h
-
-$(FIXSCRIPT):
-       @echo Run configure before running make.  See INSTALL for details.
-       @exit 1
-
-libstorage.la: $(OBJECTS) $(LIBINN)
-       $(LIBLD) $(LDFLAGS) -o $@ $(LOBJECTS) \
-           $(LIBINN) $(EXTSTORAGELIBS) $(LIBS) \
-           -rpath $(PATHLIB) -version-info 2:0:0
-
-libstorage.a: $(OBJECTS)
-       ar r $@ $(OBJECTS)
-       $(RANLIB) libstorage.a
-
-# Make.methods is included in the distribution tarball since some non-GNU
-# makes can't deal with including a non-existent file, so don't depend on
-# it.  The dependencies aren't entirely accurate; you really want to re-run
-# buildconfig each time a new subdirectory is added to the directory.  But
-# adding a dependency on . is a bit too non-portable for my taste and causes
-# too many rebuilds.
-Make.methods methods.h ovmethods.c ovmethods.h methods.c: buildconfig
-       ./buildconfig
-
-buildconfig: buildconfig.in $(FIXSCRIPT)
-       $(FIXSCRIPT) -i buildconfig.in
-
-.c.o .c.lo:
-       $(LIBCC) $(CFLAGS) $(CCOUTPUT)
-
-ovtest:        ov.c libstorage.$(EXTLIB) $(LIBINN)
-       $(CC) $(CFLAGS) -D_TEST_ -o ovtest ov.c \
-           libstorage.$(EXTLIB) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
-
-$(LIBINN):      ; (cd ../lib ; $(MAKE))
-$(LIBHIST):    ; (cd ../history ; $(MAKE))
-
-
-##  Profiling.  The rules are a bit brute-force, but good enough.
-
-profiled: libstorage$(PROFSUFFIX).a
-       date >$@
-
-libstorage$(PROFSUFFIX).a: $(SOURCES)
-       rm -f $(OBJECTS)
-       $(MAKEPROFILING) libstorage.a
-       mv libstorage.a libstorage$(PROFSUFFIX).a
-       $(RANLIB) libstorage$(PROFSUFFIX).a
-       rm -f $(OBJECTS)
-
-
-##  Dependencies.  Default list, below, is probably good enough.
-
-depend:        Makefile $(SOURCES) $(EXTRA_SOURCES)
-       $(MAKEDEPEND) '$(CFLAGS)' $(SOURCES) $(EXTRA_SOURCES)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-expire.o: expire.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ovinterface.h ../include/storage.h ../include/inn/history.h \
-  ../include/paths.h
-interface.o: interface.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/conffile.h ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/wire.h interface.h ../include/storage.h \
-  ../include/libinn.h methods.h ../include/paths.h
-methods.o: methods.c interface.h ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/storage.h \
-  ../include/config.h methods.h cnfs/cnfs.h timecaf/timecaf.h \
-  ../include/config.h interface.h timehash/timehash.h ../include/config.h \
-  interface.h tradspool/tradspool.h ../include/config.h interface.h \
-  trash/trash.h ../include/config.h interface.h
-ov.o: ov.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ovinterface.h ../include/storage.h ../include/inn/history.h ovmethods.h
-overdata.o: overdata.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/inn/buffer.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h ../include/inn/qio.h \
-  ../include/inn/wire.h ../include/inn/vector.h ../include/libinn.h \
-  ovinterface.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../include/storage.h ../include/inn/history.h \
-  ../include/paths.h
-ovmethods.o: ovmethods.c ovinterface.h ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/ov.h \
-  ../include/storage.h ../include/config.h ../include/inn/history.h \
-  ../include/inn/defines.h ../include/storage.h ../include/inn/history.h \
-  buffindexed/buffindexed.h ovdb/ovdb.h tradindexed/tradindexed.h \
-  ../include/config.h ../include/ov.h ../include/storage.h
-buffindexed/buffindexed.o: buffindexed/buffindexed.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ../include/paths.h ovinterface.h ../include/config.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ../include/storage.h \
-  buffindexed/buffindexed.h
-cnfs/cnfs.o: cnfs/cnfs.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h \
-  ../include/portable/time.h ../include/inn/innconf.h \
-  ../include/inn/defines.h interface.h ../include/config.h \
-  ../include/storage.h ../include/libinn.h methods.h interface.h \
-  ../include/paths.h ../include/inn/wire.h ../include/inn/mmap.h \
-  cnfs/cnfs.h cnfs/cnfs-private.h
-ovdb/ovdb.o: ovdb/ovdb.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/socket.h ../include/config.h \
-  ../include/portable/time.h ../include/conffile.h \
-  ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/paths.h \
-  ../include/storage.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ovinterface.h ../include/config.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ovdb/ovdb.h ovdb/ovdb-private.h
-timecaf/caf.o: timecaf/caf.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h timecaf/caf.h
-timecaf/timecaf.o: timecaf/timecaf.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/portable/mmap.h ../include/config.h timecaf/caf.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/wire.h \
-  ../include/libinn.h methods.h interface.h ../include/config.h \
-  ../include/storage.h timecaf/timecaf.h interface.h ../include/paths.h
-timehash/timehash.o: timehash/timehash.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/wire.h \
-  ../include/libinn.h methods.h interface.h ../include/config.h \
-  ../include/storage.h ../include/paths.h timehash/timehash.h interface.h
-tradindexed/tdx-cache.o: tradindexed/tdx-cache.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/hashtab.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/storage.h \
-  tradindexed/tdx-private.h
-tradindexed/tdx-data.o: tradindexed/tdx-data.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/history.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h \
-  ../include/inn/mmap.h ../include/libinn.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ovinterface.h \
-  ../include/config.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../include/storage.h tradindexed/tdx-private.h \
-  tradindexed/tdx-structure.h
-tradindexed/tdx-group.o: tradindexed/tdx-group.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/hashtab.h ../include/inn/defines.h \
-  ../include/inn/innconf.h ../include/inn/messages.h \
-  ../include/inn/mmap.h ../include/inn/qio.h ../include/inn/vector.h \
-  ../include/libinn.h ../include/paths.h tradindexed/tdx-private.h \
-  ../include/storage.h tradindexed/tdx-structure.h
-tradindexed/tradindexed.o: tradindexed/tradindexed.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/innconf.h ../include/inn/defines.h \
-  ../include/inn/messages.h ../include/libinn.h ../include/ov.h \
-  ../include/storage.h ../include/inn/history.h ../include/storage.h \
-  tradindexed/tdx-private.h tradindexed/tdx-structure.h \
-  tradindexed/tradindexed.h
-tradspool/tradspool.o: tradspool/tradspool.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/portable/mmap.h ../include/config.h \
-  ../include/inn/innconf.h ../include/inn/defines.h ../include/inn/qio.h \
-  ../include/inn/wire.h ../include/libinn.h ../include/paths.h methods.h \
-  interface.h ../include/config.h ../include/storage.h \
-  tradspool/tradspool.h interface.h
-trash/trash.o: trash/trash.c ../include/config.h ../include/inn/defines.h \
-  ../include/inn/system.h ../include/clibrary.h ../include/config.h \
-  ../include/libinn.h methods.h interface.h ../include/config.h \
-  ../include/storage.h trash/trash.h interface.h
-tradindexed/tdx-util.o: tradindexed/tdx-util.c ../include/config.h \
-  ../include/inn/defines.h ../include/inn/system.h ../include/clibrary.h \
-  ../include/config.h ../include/inn/buffer.h ../include/inn/defines.h \
-  ../include/inn/history.h ../include/inn/innconf.h \
-  ../include/inn/messages.h ../include/inn/vector.h ../include/libinn.h \
-  ../include/ov.h ../include/storage.h ../include/inn/history.h \
-  ovinterface.h ../include/config.h ../include/ov.h ../include/storage.h \
-  ../include/inn/history.h ../include/paths.h tradindexed/tdx-private.h \
-  ../include/storage.h tradindexed/tdx-structure.h
diff --git a/storage/buffindexed/buffindexed.c b/storage/buffindexed/buffindexed.c
deleted file mode 100644 (file)
index a5498e8..0000000
+++ /dev/null
@@ -1,2275 +0,0 @@
-/*  $Id: buffindexed.c 7602 2007-02-10 22:19:49Z eagle $
-**
-**  Overview buffer and index method.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <syslog.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "ov.h"
-#include "paths.h"
-#include "ovinterface.h"
-#include "storage.h"
-
-#include "buffindexed.h"
-
-#define        OVBUFF_MAGIC    "ovbuff"
-
-/* ovbuff header */
-#define        OVBUFFMASIZ     8
-#define        OVBUFFNASIZ     16
-#define        OVBUFFLASIZ     16
-#define        OVBUFFPASIZ     64
-
-#define        OVMAXCYCBUFFNAME        8
-
-#define        OV_HDR_PAGESIZE 16384
-#define        OV_BLOCKSIZE    8192
-#define        OV_BEFOREBITF   (1 * OV_BLOCKSIZE)
-#define        OV_FUDGE        1024
-
-/* ovblock pointer */
-typedef struct _OV {
-  unsigned int blocknum;
-  short                index;
-} OV;
-
-/* ovbuff header */
-typedef struct {
-  char magic[OVBUFFMASIZ];
-  char path[OVBUFFPASIZ];
-  char indexa[OVBUFFLASIZ];    /* ASCII version of index */
-  char lena[OVBUFFLASIZ];      /* ASCII version of len */
-  char totala[OVBUFFLASIZ];    /* ASCII version of total */
-  char useda[OVBUFFLASIZ];     /* ASCII version of used */
-  char freea[OVBUFFLASIZ];     /* ASCII version of free */
-  char updateda[OVBUFFLASIZ];  /* ASCII version of updated */
-} OVBUFFHEAD;
-
-/* ovbuff info */
-typedef struct _OVBUFF {
-  unsigned int         index;                  /* ovbuff index */
-  char                 path[OVBUFFPASIZ];      /* Path to file */
-  int                  magicver;               /* Magic version number */
-  int                  fd;                     /* file descriptor for this
-                                                  ovbuff */
-  off_t                len;                    /* Length of writable area, in
-                                                  bytes */
-  off_t                base;                   /* Offset (relative to byte
-                                                   0 of file) to base block */
-  unsigned int         freeblk;                /* next free block number no
-                                                  freeblk left if equals
-                                                  totalblk */
-  unsigned int         totalblk;               /* number of total blocks */
-  unsigned int         usedblk;                /* number of used blocks */
-  time_t               updated;                /* Time of last update to
-                                                  header */
-  void *               bitfield;               /* Bitfield for ovbuff block in
-                                                  use */
-  bool                 needflush;              /* true if OVBUFFHEAD is needed
-                                                  to be flushed */
-  struct _OVBUFF       *next;                  /* next ovbuff */
-  int                  nextchunk;              /* next chunk */
-#ifdef OV_DEBUG
-  struct ov_trace_array        *trace;
-#endif /* OV_DEBUG */
-} OVBUFF;
-
-typedef struct _OVINDEXHEAD {
-  OV           next;           /* next block */
-  ARTNUM       low;            /* lowest article number in the index */
-  ARTNUM       high;           /* highest article number in the index */
-} OVINDEXHEAD;
-
-typedef struct _OVINDEX {
-  ARTNUM       artnum;         /* article number */
-  unsigned int blocknum;       /* overview data block number */
-  short                index;          /* overview data block index */
-  TOKEN                token;          /* token for this article */
-  off_t         offset;                /* offset from the top in the block */
-  int          len;            /* length of the data */
-  time_t       arrived;        /* arrived time of article */
-  time_t       expires;        /* expire time of article */
-} OVINDEX;
-
-#define OVINDEXMAX     ((OV_BLOCKSIZE-sizeof(OVINDEXHEAD))/sizeof(OVINDEX))
-
-typedef struct _OVBLOCK {
-  OVINDEXHEAD  ovindexhead;            /* overview index header */
-  OVINDEX      ovindex[OVINDEXMAX];    /* overview index */
-} OVBLOCK;
-
-typedef struct _OVBLKS {
-  OVBLOCK      *ovblock;
-  void *       addr;
-  int          len;
-  OV           indexov;
-} OVBLKS;
-
-/* Data structure for specifying a location in the group index */
-typedef struct {
-    int                 recno;             /* Record number in group index */
-} GROUPLOC;
-
-#ifdef OV_DEBUG
-struct ov_trace        {
-  time_t       occupied;
-  time_t       freed;
-  GROUPLOC     gloc;
-};
-
-#define        OV_TRACENUM 10
-struct ov_trace_array {
-  int                  max;
-  int                  cur;
-  struct ov_trace      *ov_trace;
-};
-
-struct ov_name_table {
-  char                 *name;
-  int                  recno;
-  struct ov_name_table *next;
-};
-
-static struct ov_name_table *name_table = NULL;
-#endif /* OV_DEBUG */
-
-#define GROUPHEADERHASHSIZE (16 * 1024)
-#define GROUPHEADERMAGIC    (~(0xf1f0f33d))
-
-typedef struct {
-  int          magic;
-  GROUPLOC     hash[GROUPHEADERHASHSIZE];
-  GROUPLOC     freelist;
-} GROUPHEADER;
-
-/* The group is matched based on the MD5 of the grouname. This may prove to
-   be inadequate in the future, if so, the right thing to do is to is
-   probably just to add a SHA1 hash into here also.  We get a really nice
-   benefit from this being fixed length, we should try to keep it that way.
-*/
-typedef struct {
-  HASH         hash;           /* MD5 hash of the group name */
-  HASH         alias;          /* If not empty then this is the hash of the
-                                  group that this group is an alias for */
-  ARTNUM       high;           /* High water mark in group */
-  ARTNUM       low;            /* Low water mark in group */
-  int          count;          /* Number of articles in group */
-  int          flag;           /* Posting/Moderation Status */
-  time_t       expired;        /* When last expiry */
-  time_t       deleted;        /* When this was deleted, 0 otherwise */
-  GROUPLOC     next;           /* Next block in this chain */
-  OV           baseindex;      /* base index buff */
-  OV           curindex;       /* current index buff */
-  int          curindexoffset; /* current index offset for this ovbuff */
-  ARTNUM       curhigh;        /* High water mark in group */
-  ARTNUM       curlow;         /* Low water mark in group */
-  OV           curdata;        /* current offset for this ovbuff */
-  off_t         curoffset;     /* current offset for this ovbuff */
-} GROUPENTRY;
-
-typedef struct _GIBLIST {
-  OV                   ov;
-  struct _GIBLIST      *next;
-} GIBLIST;
-
-typedef struct _GDB {
-  OV           datablk;
-  void *       addr;
-  void *       data;
-  int          len;
-  bool         mmapped;
-  struct _GDB  *next;
-} GROUPDATABLOCK;
-
-typedef struct {
-  char                 *group;
-  int                  lo;
-  int                  hi;
-  int                  cur;
-  bool                 needov;
-  GROUPLOC             gloc;
-  int                  count;
-  GROUPDATABLOCK       gdb;    /* used for caching current block */
-} OVSEARCH;
-
-#define GROUPDATAHASHSIZE      25
-
-static GROUPDATABLOCK  *groupdatablock[GROUPDATAHASHSIZE];
-
-typedef enum {PREPEND_BLK, APPEND_BLK} ADDINDEX;
-typedef enum {SRCH_FRWD, SRCH_BKWD} SRCH;
-
-#define        _PATH_OVBUFFCONFIG      "buffindexed.conf"
-
-static char LocalLogName[] = "buffindexed";
-static long            pagesize = 0;
-static OVBUFF          *ovbufftab;
-static int              GROUPfd;
-static GROUPHEADER      *GROUPheader = NULL;
-static GROUPENTRY       *GROUPentries = NULL;
-static int              GROUPcount = 0;
-static GROUPLOC         GROUPemptyloc = { -1 };
-#define        NULLINDEX       (-1)
-static OV              ovnull = { 0, NULLINDEX };
-typedef unsigned long  ULONG;
-static ULONG           onarray[64], offarray[64];
-static int             longsize = sizeof(long);
-static bool            Nospace;
-static bool            Needunlink;
-static bool            Cutofflow;
-static bool            Cache;
-static OVSEARCH                *Cachesearch;
-
-static int ovbuffmode;
-
-static GROUPLOC GROUPnewnode(void);
-static bool GROUPremapifneeded(GROUPLOC loc);
-static void GROUPLOCclear(GROUPLOC *loc);
-static bool GROUPLOCempty(GROUPLOC loc);
-static bool GROUPlockhash(enum inn_locktype type);
-static bool GROUPlock(GROUPLOC gloc, enum inn_locktype type);
-static off_t GROUPfilesize(int count);
-static bool GROUPexpand(int mode);
-static void *ovopensearch(char *group, int low, int high, bool needov);
-static void ovclosesearch(void *handle, bool freeblock);
-static OVINDEX *Gib;
-static GIBLIST *Giblist;
-static int     Gibcount;
-
-#ifdef MMAP_MISSES_WRITES
-/* With HP/UX, you definitely do not want to mix mmap-accesses of
-   a file with read()s and write()s of the same file */
-static off_t mmapwrite(int fd, void *buf, off_t nbyte, off_t offset) {
-  int          pagefudge, len;
-  off_t         mmapoffset;
-  void *       addr;
-
-  pagefudge = offset % pagesize;
-  mmapoffset = offset - pagefudge;
-  len = pagefudge + nbyte;
-
-  if ((addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, mmapoffset)) == MAP_FAILED) {
-    return -1;
-  }
-  memcpy(addr+pagefudge, buf, nbyte);
-  munmap(addr, len);
-  return nbyte;
-}
-#endif /* MMAP_MISSES_WRITES */
-
-static bool ovparse_part_line(char *l) {
-  char         *p;
-  struct stat  sb;
-  off_t         len, base;
-  int          tonextblock;
-  OVBUFF       *ovbuff, *tmp = ovbufftab;
-
-  /* ovbuff partition name */
-  if ((p = strchr(l, ':')) == NULL || p - l <= 0 || p - l > OVMAXCYCBUFFNAME - 1) {
-    syslog(L_ERROR, "%s: bad index in line '%s'", LocalLogName, l);
-    return false;
-  }
-  *p = '\0';
-  ovbuff = xmalloc(sizeof(OVBUFF));
-  ovbuff->index = strtoul(l, NULL, 10);
-  for (; tmp != (OVBUFF *)NULL; tmp = tmp->next) {
-    if (tmp->index == ovbuff->index) {
-      syslog(L_ERROR, "%s: dupulicate index in line '%s'", LocalLogName, l);
-      free(ovbuff);
-      return false;
-    }
-  }
-  l = ++p;
-
-  /* Path to ovbuff partition */
-  if ((p = strchr(l, ':')) == NULL || p - l <= 0 || p - l > OVBUFFPASIZ - 1) {
-    syslog(L_ERROR, "%s: bad pathname in line '%s'", LocalLogName, l);
-    free(ovbuff);
-    return false;
-  }
-  *p = '\0';
-  memset(ovbuff->path, '\0', OVBUFFPASIZ);
-  strlcpy(ovbuff->path, l, OVBUFFPASIZ);
-  if (stat(ovbuff->path, &sb) < 0) {
-    syslog(L_ERROR, "%s: file '%s' does not exist, ignoring '%d'",
-           LocalLogName, ovbuff->path, ovbuff->index);
-    free(ovbuff);
-    return false;
-  }
-  l = ++p;
-
-  /* Length/size of symbolic partition in KB */
-  len = strtoul(l, NULL, 10) * (off_t) 1024;
-  /*
-  ** The minimum article offset will be the size of the bitfield itself,
-  ** len / (blocksize * 8), plus however many additional blocks the OVBUFFHEAD
-  ** external header occupies ... then round up to the next block.
-  */
-  base = len / (OV_BLOCKSIZE * 8) + OV_BEFOREBITF;
-  tonextblock = OV_HDR_PAGESIZE - (base & (OV_HDR_PAGESIZE - 1));
-  ovbuff->base = base + tonextblock;
-  if (S_ISREG(sb.st_mode) && (len != sb.st_size || ovbuff->base > sb.st_size)) {
-    if (len != sb.st_size)
-      syslog(L_NOTICE, "%s: length mismatch '%lu' for index '%d' (%lu bytes)",
-        LocalLogName, (unsigned long) len, ovbuff->index,
-        (unsigned long) sb.st_size);
-    if (ovbuff->base > sb.st_size)
-      syslog(L_NOTICE, "%s: length must be at least '%lu' for index '%d' (%lu bytes)",
-        LocalLogName, (unsigned long) ovbuff->base, ovbuff->index,
-        (unsigned long) sb.st_size);
-    free(ovbuff);
-    return false;
-  }
-  ovbuff->len = len;
-  ovbuff->fd = -1;
-  ovbuff->next = (OVBUFF *)NULL;
-  ovbuff->needflush = false;
-  ovbuff->bitfield = NULL;
-  ovbuff->nextchunk = 1;
-
-  if (ovbufftab == (OVBUFF *)NULL)
-    ovbufftab = ovbuff;
-  else {
-    for (tmp = ovbufftab; tmp->next != (OVBUFF *)NULL; tmp = tmp->next);
-    tmp->next = ovbuff;
-  }
-  return true;
-}
-
-/*
-** ovbuffread_config() -- Read the overview partition/file configuration file.
-*/
-
-static bool ovbuffread_config(void) {
-  char         *path, *config, *from, *to, **ctab = (char **)NULL;
-  int          ctab_free = 0;  /* Index to next free slot in ctab */
-  int          ctab_i;
-
-  path = concatpath(innconf->pathetc, _PATH_OVBUFFCONFIG);
-  config = ReadInFile(path, NULL);
-  if (config == NULL) {
-    syslog(L_ERROR, "%s: cannot read %s", LocalLogName, path);
-    free(config);
-    free(path);
-    return false;
-  }
-  free(path);
-  for (from = to = config; *from; ) {
-    if (*from == '#') {        /* Comment line? */
-      while (*from && *from != '\n')
-       from++; /* Skip past it */
-      from++;
-      continue;        /* Back to top of loop */
-    }
-    if (*from == '\n') {       /* End or just a blank line? */
-      from++;
-      continue;                /* Back to top of loop */
-    }
-    if (ctab_free == 0)
-      ctab = xmalloc(sizeof(char *));
-    else
-      ctab = xrealloc(ctab, (ctab_free + 1) * sizeof(char *));
-    /* If we're here, we've got the beginning of a real entry */
-    ctab[ctab_free++] = to = from;
-    while (1) {
-      if (*from && *from == '\\' && *(from + 1) == '\n') {
-       from += 2;      /* Skip past backslash+newline */
-       while (*from && isspace((int)*from))
-         from++;
-       continue;
-      }
-      if (*from && *from != '\n')
-       *to++ = *from++;
-      if (*from == '\n') {
-       *to++ = '\0';
-       from++;
-       break;
-      }
-      if (! *from)
-       break;
-    }
-  }
-  for (ctab_i = 0; ctab_i < ctab_free; ctab_i++) {
-    if (!ovparse_part_line(ctab[ctab_i])) {
-      free(config);
-      free(ctab);
-      return false;
-    }
-  }
-  free(config);
-  free(ctab);
-  if (ovbufftab == (OVBUFF *)NULL) {
-    syslog(L_ERROR, "%s: no buffindexed defined", LocalLogName);
-    return false;
-  }
-  return true;
-}
-
-static char hextbl[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-                       'a', 'b', 'c', 'd', 'e', 'f'};
-
-static char *offt2hex(off_t offset, bool leadingzeros) {
-  static char  buf[24];
-  char *p;
-
-  if (sizeof(off_t) <= 4) {
-    snprintf(buf, sizeof(buf), (leadingzeros) ? "%016lx" : "%lx", offset);
-  } else {
-    int        i;
-
-    for (i = 0; i < OVBUFFLASIZ; i++)
-      buf[i] = '0';    /* Pad with zeros to start */
-    for (i = OVBUFFLASIZ - 1; i >= 0; i--) {
-      buf[i] = hextbl[offset & 0xf];
-      offset >>= 4;
-    }
-  }
-  if (!leadingzeros) {
-    for (p = buf; *p == '0'; p++)
-           ;
-    if (*p != '\0')
-      return p;
-    else
-      return p - 1;    /* We converted a "0" and then bypassed all the zeros */
-  } else
-    return buf;
-}
-
-static off_t hex2offt(char *hex) {
-  if (sizeof(off_t) <= 4) {
-    unsigned long rpofft;
-
-    sscanf(hex, "%lx", &rpofft);
-    return rpofft;
-  } else {
-    char               diff;
-    off_t      n = 0;
-
-    for (; *hex != '\0'; hex++) {
-      if (*hex >= '0' && *hex <= '9')
-       diff = '0';
-      else if (*hex >= 'a' && *hex <= 'f')
-       diff = 'a' - 10;
-      else if (*hex >= 'A' && *hex <= 'F')
-       diff = 'A' - 10;
-      else {
-       /*
-       ** We used to have a syslog() message here, but the case
-       ** where we land here because of a ":" happens, er, often.
-       */
-       break;
-      }
-      n += (*hex - diff);
-      if (isalnum((int)*(hex + 1)))
-       n <<= 4;
-    }
-    return n;
-  }
-}
-
-static void ovreadhead(OVBUFF *ovbuff) {
-  OVBUFFHEAD   rpx;
-  char         buff[OVBUFFLASIZ+1];
-
-  memcpy(&rpx, ovbuff->bitfield, sizeof(OVBUFFHEAD));
-  strncpy(buff, rpx.useda, OVBUFFLASIZ);
-  buff[OVBUFFLASIZ] = '\0';
-  ovbuff->usedblk = (unsigned int)hex2offt((char *)buff);
-  strncpy(buff, rpx.freea, OVBUFFLASIZ);
-  buff[OVBUFFLASIZ] = '\0';
-  ovbuff->freeblk = (unsigned int)hex2offt((char *)buff);
-  return;
-}
-
-static void ovflushhead(OVBUFF *ovbuff) {
-  OVBUFFHEAD   rpx;
-
-  if (!ovbuff->needflush)
-    return;
-  memset(&rpx, 0, sizeof(OVBUFFHEAD));
-  ovbuff->updated = time(NULL);
-  strncpy(rpx.magic, OVBUFF_MAGIC, strlen(OVBUFF_MAGIC));
-  strncpy(rpx.path, ovbuff->path, OVBUFFPASIZ);
-  /* Don't use sprintf() directly ... the terminating '\0' causes grief */
-  strncpy(rpx.indexa, offt2hex(ovbuff->index, true), OVBUFFLASIZ);
-  strncpy(rpx.lena, offt2hex(ovbuff->len, true), OVBUFFLASIZ);
-  strncpy(rpx.totala, offt2hex(ovbuff->totalblk, true), OVBUFFLASIZ);
-  strncpy(rpx.useda, offt2hex(ovbuff->usedblk, true), OVBUFFLASIZ);
-  strncpy(rpx.freea, offt2hex(ovbuff->freeblk, true), OVBUFFLASIZ);
-  strncpy(rpx.updateda, offt2hex(ovbuff->updated, true), OVBUFFLASIZ);
-  memcpy(ovbuff->bitfield, &rpx, sizeof(OVBUFFHEAD));
-  mmap_flush(ovbuff->bitfield, ovbuff->base);
-  ovbuff->needflush = false;
-  return;
-}
-
-static bool ovlock(OVBUFF *ovbuff, enum inn_locktype type) {
-  return inn_lock_range(ovbuff->fd, type, true, 0, sizeof(OVBUFFHEAD));
-}
-
-static bool ovbuffinit_disks(void) {
-  OVBUFF       *ovbuff = ovbufftab;
-  char         buf[64];
-  OVBUFFHEAD   *rpx;
-  int          i, fd;
-  off_t         tmpo;
-
-  /*
-  ** Discover the state of our ovbuffs.  If any of them are in icky shape,
-  ** duck shamelessly & return false.
-  */
-  for (; ovbuff != (OVBUFF *)NULL; ovbuff = ovbuff->next) {
-    if (ovbuff->fd < 0) {
-      if ((fd = open(ovbuff->path, ovbuffmode & OV_WRITE ? O_RDWR : O_RDONLY)) < 0) {
-       syslog(L_ERROR, "%s: ERROR opening '%s' : %m", LocalLogName, ovbuff->path);
-       return false;
-      } else {
-       close_on_exec(fd, true);
-       ovbuff->fd = fd;
-      }
-    }
-    if ((ovbuff->bitfield =
-        mmap(NULL, ovbuff->base, ovbuffmode & OV_WRITE ? (PROT_READ | PROT_WRITE) : PROT_READ,
-             MAP_SHARED, ovbuff->fd, (off_t) 0)) == MAP_FAILED) {
-      syslog(L_ERROR,
-              "%s: ovinitdisks: mmap for %s offset %d len %lu failed: %m",
-              LocalLogName, ovbuff->path, 0, (unsigned long) ovbuff->base);
-      return false;
-    }
-    rpx = (OVBUFFHEAD *)ovbuff->bitfield;
-    ovlock(ovbuff, INN_LOCK_WRITE);
-    if (strncmp(rpx->magic, OVBUFF_MAGIC, strlen(OVBUFF_MAGIC)) == 0) {
-       ovbuff->magicver = 1;
-       if (strncmp(rpx->path, ovbuff->path, OVBUFFPASIZ) != 0) {
-         syslog(L_ERROR, "%s: Path mismatch: read %s for buffindexed %s",
-                  LocalLogName, rpx->path, ovbuff->path);
-         ovbuff->needflush = true;
-       }
-       strncpy(buf, rpx->indexa, OVBUFFLASIZ);
-        buf[OVBUFFLASIZ] = '\0';
-       i = hex2offt(buf);
-       if (i != ovbuff->index) {
-           syslog(L_ERROR, "%s: Mismatch: index '%d' for buffindexed %s",
-                  LocalLogName, i, ovbuff->path);
-           ovlock(ovbuff, INN_LOCK_UNLOCK);
-           return false;
-       }
-       strncpy(buf, rpx->lena, OVBUFFLASIZ);
-        buf[OVBUFFLASIZ] = '\0';
-       tmpo = hex2offt(buf);
-       if (tmpo != ovbuff->len) {
-           syslog(L_ERROR, "%s: Mismatch: read 0x%s length for buffindexed %s",
-                  LocalLogName, offt2hex(tmpo, false), ovbuff->path);
-           ovlock(ovbuff, INN_LOCK_UNLOCK);
-           return false;
-       }
-       strncpy(buf, rpx->totala, OVBUFFLASIZ);
-        buf[OVBUFFLASIZ] = '\0';
-       ovbuff->totalblk = hex2offt(buf);
-       strncpy(buf, rpx->useda, OVBUFFLASIZ);
-        buf[OVBUFFLASIZ] = '\0';
-       ovbuff->usedblk = hex2offt(buf);
-       strncpy(buf, rpx->freea, OVBUFFLASIZ);
-        buf[OVBUFFLASIZ] = '\0';
-       ovbuff->freeblk = hex2offt(buf);
-       ovflushhead(ovbuff);
-       Needunlink = false;
-    } else {
-       ovbuff->totalblk = (ovbuff->len - ovbuff->base)/OV_BLOCKSIZE;
-       if (ovbuff->totalblk < 1) {
-         syslog(L_ERROR, "%s: too small length '%lu' for buffindexed %s",
-           LocalLogName, (unsigned long) ovbuff->len, ovbuff->path);
-         ovlock(ovbuff, INN_LOCK_UNLOCK);
-         return false;
-       }
-       ovbuff->magicver = 1;
-       ovbuff->usedblk = 0;
-       ovbuff->freeblk = 0;
-       ovbuff->updated = 0;
-       ovbuff->needflush = true;
-       syslog(L_NOTICE,
-               "%s: No magic cookie found for buffindexed %d, initializing",
-               LocalLogName, ovbuff->index);
-       ovflushhead(ovbuff);
-    }
-#ifdef OV_DEBUG
-    ovbuff->trace = xcalloc(ovbuff->totalblk, sizeof(ov_trace_array));
-#endif /* OV_DEBUG */
-    ovlock(ovbuff, INN_LOCK_UNLOCK);
-  }
-  return true;
-}
-
-static int ovusedblock(OVBUFF *ovbuff, int blocknum, bool set_operation, bool setbitvalue) {
-  off_t         longoffset;
-  int          bitoffset;      /* From the 'left' side of the long */
-  ULONG                bitlong, mask;
-
-  longoffset = blocknum / (sizeof(long) * 8);
-  bitoffset = blocknum % (sizeof(long) * 8);
-  bitlong = *((ULONG *) ovbuff->bitfield + (OV_BEFOREBITF / sizeof(long))
-               + longoffset);
-  if (set_operation) {
-    if (setbitvalue) {
-      mask = onarray[bitoffset];
-      bitlong |= mask;
-    } else {
-      mask = offarray[bitoffset];
-      bitlong &= mask;
-    }
-    *((ULONG *) ovbuff->bitfield + (OV_BEFOREBITF / sizeof(long))
-      + longoffset) = bitlong;
-    return 2;  /* XXX Clean up return semantics */
-  }
-  /* It's a read operation */
-  mask = onarray[bitoffset];
-  /* return bitlong & mask; doesn't work if sizeof(ulong) > sizeof(int) */
-  if ( bitlong & mask ) return 1; else return 0;
-}
-
-static void ovnextblock(OVBUFF *ovbuff) {
-  int          i, j, last, lastbit, left;
-  ULONG                mask = 0x80000000;
-  ULONG                *table;
-
-  last = ovbuff->totalblk/(sizeof(long) * 8);
-  if ((left = ovbuff->totalblk % (sizeof(long) * 8)) != 0) {
-    last++;
-  }
-  table = ((ULONG *) ovbuff->bitfield + (OV_BEFOREBITF / sizeof(long)));
-  for (i = ovbuff->nextchunk ; i < last ; i++) {
-    if (i == last - 1 && left != 0) {
-      for (j = 1 ; j < left ; j++) {
-       mask |= mask >> 1;
-      }
-      if ((table[i] & mask) != mask)
-       break;
-    } else {
-      if ((table[i] ^ ~0) != 0)
-       break;
-    }
-  }
-  if (i == last) {
-    for (i = 0 ; i < ovbuff->nextchunk ; i++) {
-      if ((table[i] ^ ~0) != 0)
-        break;
-    }
-    if (i == ovbuff->nextchunk) {
-      ovbuff->freeblk = ovbuff->totalblk;
-      return;
-    }
-  }
-  if ((i - 1) >= 0 && (last - 1 == i) && left != 0) {
-    lastbit = left;
-  } else {
-    lastbit = sizeof(long) * 8;
-  }
-  for (j = 0 ; j < lastbit ; j++) {
-    if ((table[i] & onarray[j]) == 0)
-      break;
-  }
-  if (j == lastbit) {
-    ovbuff->freeblk = ovbuff->totalblk;
-    return;
-  }
-  ovbuff->freeblk = i * sizeof(long) * 8 + j;
-  ovbuff->nextchunk = i + 1;
-  if (i == last)
-    ovbuff->nextchunk = 0;
-  return;
-}
-
-static OVBUFF *getovbuff(OV ov) {
-  OVBUFF       *ovbuff = ovbufftab;
-  for (; ovbuff != (OVBUFF *)NULL; ovbuff = ovbuff->next) {
-    if (ovbuff->index == ov.index)
-      return ovbuff;
-  }
-  return NULL;
-}
-
-#ifdef OV_DEBUG
-static OV ovblocknew(GROUPENTRY *ge) {
-#else
-static OV ovblocknew(void) {
-#endif /* OV_DEBUG */
-  static OVBUFF        *ovbuffnext = NULL;
-  OVBUFF       *ovbuff;
-  OV           ov;
-#ifdef OV_DEBUG
-  int          recno;
-  struct ov_trace_array *trace;
-#endif /* OV_DEBUG */
-
-  if (ovbuffnext == NULL)
-    ovbuffnext = ovbufftab;
-  for (ovbuff = ovbuffnext ; ovbuff != (OVBUFF *)NULL ; ovbuff = ovbuff->next) {
-    ovlock(ovbuff, INN_LOCK_WRITE);
-    ovreadhead(ovbuff);
-    if (ovbuff->totalblk != ovbuff->usedblk && ovbuff->freeblk == ovbuff->totalblk) {
-      ovnextblock(ovbuff);
-    }
-    if (ovbuff->totalblk == ovbuff->usedblk || ovbuff->freeblk == ovbuff->totalblk) {
-      /* no space left for this ovbuff */
-      ovlock(ovbuff, INN_LOCK_UNLOCK);
-      continue;
-    }
-    break;
-  }
-  if (ovbuff == NULL) {
-    for (ovbuff = ovbufftab ; ovbuff != ovbuffnext ; ovbuff = ovbuff->next) {
-      ovlock(ovbuff, INN_LOCK_WRITE);
-      ovreadhead(ovbuff);
-      if (ovbuff->totalblk == ovbuff->usedblk || ovbuff->freeblk == ovbuff->totalblk) {
-       /* no space left for this ovbuff */
-       ovlock(ovbuff, INN_LOCK_UNLOCK);
-       continue;
-      }
-      break;
-    }
-    if (ovbuff == ovbuffnext) {
-      Nospace = true;
-      return ovnull;
-    }
-  }
-#ifdef OV_DEBUG
-  recno = ((char *)ge - (char *)&GROUPentries[0])/sizeof(GROUPENTRY);
-  if (ovusedblock(ovbuff, ovbuff->freeblk, false, true)) {
-    syslog(L_FATAL, "%s: 0x%08x trying to occupy new block(%d, %d), but already occupied", LocalLogName, recno, ovbuff->index, ovbuff->freeblk);
-    buffindexed_close();
-    abort();
-  }
-  trace = &ovbuff->trace[ovbuff->freeblk];
-  if (trace->ov_trace == NULL) {
-    trace->ov_trace = xcalloc(OV_TRACENUM, sizeof(struct ov_trace));
-    trace->max = OV_TRACENUM;
-  } else if (trace->cur + 1 == trace->max) {
-    trace->max += OV_TRACENUM;
-    trace->ov_trace = xrealloc(trace->ov_trace, trace->max * sizeof(struct ov_trace));
-    memset(&trace->ov_trace[trace->cur], '\0', sizeof(struct ov_trace) * (trace->max - trace->cur));
-  }
-  if (trace->ov_trace[trace->cur].occupied != 0) {
-    trace->cur++;
-  }
-  trace->ov_trace[trace->cur].gloc.recno = recno;
-  trace->ov_trace[trace->cur].occupied = time(NULL);
-#endif /* OV_DEBUG */
-  ov.index = ovbuff->index;
-  ov.blocknum = ovbuff->freeblk;
-  ovusedblock(ovbuff, ov.blocknum, true, true);
-  ovnextblock(ovbuff);
-  ovbuff->usedblk++;
-  ovbuff->needflush = true;
-  ovflushhead(ovbuff);
-  ovlock(ovbuff, INN_LOCK_UNLOCK);
-  ovbuffnext = ovbuff->next;
-  if (ovbuffnext == NULL)
-    ovbuffnext = ovbufftab;
-  return ov;
-}
-
-#ifdef OV_DEBUG
-static void ovblockfree(OV ov, GROUPENTRY *ge) {
-#else
-static void ovblockfree(OV ov) {
-#endif /* OV_DEBUG */
-  OVBUFF       *ovbuff;
-#ifdef OV_DEBUG
-  int          recno;
-  struct ov_trace_array *trace;
-#endif /* OV_DEBUG */
-
-  if (ov.index == NULLINDEX)
-    return;
-  if ((ovbuff = getovbuff(ov)) == NULL)
-    return;
-  ovlock(ovbuff, INN_LOCK_WRITE);
-#ifdef OV_DEBUG
-  recno = ((char *)ge - (char *)&GROUPentries[0])/sizeof(GROUPENTRY);
-  if (!ovusedblock(ovbuff, ov.blocknum, false, false)) {
-    syslog(L_FATAL, "%s: 0x%08x trying to free block(%d, %d), but already freed", LocalLogName, recno, ov.index, ov.blocknum);
-    buffindexed_close();
-    abort();
-  }
-  trace = &ovbuff->trace[ov.blocknum];
-  if (trace->ov_trace == NULL) {
-    trace->ov_trace = xcalloc(OV_TRACENUM, sizeof(struct ov_trace));
-    trace->max = OV_TRACENUM;
-  } else if (trace->cur + 1 == trace->max) {
-    trace->max += OV_TRACENUM;
-    trace->ov_trace = xrealloc(trace->ov_trace, trace->max * sizeof(struct ov_trace));
-    memset(&trace->ov_trace[trace->cur], '\0', sizeof(struct ov_trace) * (trace->max - trace->cur));
-  }
-  if (trace->ov_trace[trace->cur].freed != 0) {
-    trace->cur++;
-  }
-  trace->ov_trace[trace->cur].freed = time(NULL);
-  trace->ov_trace[trace->cur].gloc.recno = recno;
-  trace->cur++;
-#endif /* OV_DEBUG */
-  ovusedblock(ovbuff, ov.blocknum, true, false);
-  ovreadhead(ovbuff);
-  if (ovbuff->freeblk == ovbuff->totalblk)
-    ovbuff->freeblk = ov.blocknum;
-  ovbuff->usedblk--;
-  ovbuff->needflush = true;
-  ovflushhead(ovbuff);
-  ovlock(ovbuff, INN_LOCK_UNLOCK);
-  return;
-}
-
-bool buffindexed_open(int mode) {
-  char         *groupfn;
-  struct stat  sb;
-  int          i, flag = 0;
-  static int   uninitialized = 1;
-  ULONG                on, off;
-
-  if (uninitialized) {
-    on = 1;
-    off = on;
-    off ^= ULONG_MAX;
-    for (i = (longsize * 8) - 1; i >= 0; i--) {
-      onarray[i] = on;
-      offarray[i] = off;
-      on <<= 1;
-      off = on;
-      off ^= ULONG_MAX;
-    }
-    uninitialized = 0;
-  }
-  ovbuffmode = mode;
-  if (pagesize == 0) {
-    pagesize = getpagesize();
-    if (pagesize == -1) {
-      syslog(L_ERROR, "%s: getpagesize failed: %m", LocalLogName);
-      pagesize = 0;
-      return false;
-    }
-    if ((pagesize > OV_HDR_PAGESIZE) || (OV_HDR_PAGESIZE % pagesize)) {
-      syslog(L_ERROR, "%s: OV_HDR_PAGESIZE (%d) is not a multiple of pagesize (%ld)", LocalLogName, OV_HDR_PAGESIZE, pagesize);
-      return false;
-    }
-  }
-  memset(&groupdatablock, '\0', sizeof(groupdatablock));
-  if (!ovbuffread_config()) {
-    return false;
-  }
-  Needunlink = true;
-  if (!ovbuffinit_disks()) {
-    return false;
-  }
-
-  groupfn = concatpath(innconf->pathdb, "group.index");
-  if (Needunlink && unlink(groupfn) == 0) {
-    syslog(L_NOTICE, "%s: all buffers are brandnew, unlink '%s'", LocalLogName, groupfn);
-  }
-  GROUPfd = open(groupfn, ovbuffmode & OV_WRITE ? O_RDWR | O_CREAT : O_RDONLY, 0660);
-  if (GROUPfd < 0) {
-    syslog(L_FATAL, "%s: Could not create %s: %m", LocalLogName, groupfn);
-    free(groupfn);
-    return false;
-  }
-
-  if (fstat(GROUPfd, &sb) < 0) {
-    syslog(L_FATAL, "%s: Could not fstat %s: %m", LocalLogName, groupfn);
-    free(groupfn);
-    close(GROUPfd);
-    return false;
-  }
-  if (sb.st_size > sizeof(GROUPHEADER)) {
-    if (mode & OV_READ)
-      flag |= PROT_READ;
-    if (mode & OV_WRITE) {
-      /*
-       * Note: below mapping of groupheader won't work unless we have
-       * both PROT_READ and PROT_WRITE perms.
-       */
-      flag |= PROT_WRITE|PROT_READ;
-    }
-    GROUPcount = (sb.st_size - sizeof(GROUPHEADER)) / sizeof(GROUPENTRY);
-    if ((GROUPheader = (GROUPHEADER *)mmap(0, GROUPfilesize(GROUPcount), flag,
-       MAP_SHARED, GROUPfd, 0)) == (GROUPHEADER *) -1) {
-      syslog(L_FATAL, "%s: Could not mmap %s in buffindexed_open: %m", LocalLogName, groupfn);
-      free(groupfn);
-      close(GROUPfd);
-      return false;
-    }
-    GROUPentries = (GROUPENTRY *)((char *)GROUPheader + sizeof(GROUPHEADER));
-  } else {
-    GROUPcount = 0;
-    if (!GROUPexpand(mode)) {
-      free(groupfn);
-      close(GROUPfd);
-      return false;
-    }
-  }
-  close_on_exec(GROUPfd, true);
-
-  free(groupfn);
-  Cutofflow = false;
-
-  return true;
-}
-
-static GROUPLOC GROUPfind(char *group, bool Ignoredeleted) {
-  HASH         grouphash;
-  unsigned int i;
-  GROUPLOC     loc;
-
-  grouphash = Hash(group, strlen(group));
-  memcpy(&i, &grouphash, sizeof(i));
-
-  loc = GROUPheader->hash[i % GROUPHEADERHASHSIZE];
-  GROUPremapifneeded(loc);
-
-  while (!GROUPLOCempty(loc)) {
-    if (GROUPentries[loc.recno].deleted == 0 || Ignoredeleted) {
-      if (memcmp(&grouphash, &GROUPentries[loc.recno].hash, sizeof(HASH)) == 0) {
-       return loc;
-      }
-    }
-    loc = GROUPentries[loc.recno].next;
-  }
-  return GROUPemptyloc;
-}
-
-bool buffindexed_groupstats(char *group, int *lo, int *hi, int *count, int *flag) {
-  GROUPLOC     gloc;
-
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    return false;
-  }
-  GROUPlock(gloc, INN_LOCK_READ);
-  if (lo != NULL)
-    *lo = GROUPentries[gloc.recno].low;
-  if (hi != NULL)
-    *hi = GROUPentries[gloc.recno].high;
-  if (count != NULL)
-    *count = GROUPentries[gloc.recno].count;
-  if (flag != NULL)
-    *flag = GROUPentries[gloc.recno].flag;
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-  return true;
-}
-
-static void setinitialge(GROUPENTRY *ge, HASH grouphash, char *flag, GROUPLOC next, ARTNUM lo, ARTNUM hi) {
-  ge->hash = grouphash;
-  if (lo != 0)
-    ge->low = lo;
-  ge->high = hi;
-  ge->expired = ge->deleted = ge->count = 0;
-  ge->flag = *flag;
-  ge->baseindex = ge->curindex = ge->curdata = ovnull;
-  ge->curindexoffset = ge->curoffset = 0;
-  ge->next = next;
-}
-
-bool buffindexed_groupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag) {
-  unsigned int i;
-  HASH         grouphash;
-  GROUPLOC     gloc;
-  GROUPENTRY   *ge;
-#ifdef OV_DEBUG
-  struct ov_name_table *ntp;
-#endif /* OV_DEBUG */
-
-  gloc = GROUPfind(group, true);
-  if (!GROUPLOCempty(gloc)) {
-    ge = &GROUPentries[gloc.recno];
-    if (GROUPentries[gloc.recno].deleted != 0) {
-      grouphash = Hash(group, strlen(group));
-      setinitialge(ge, grouphash, flag, ge->next, lo, hi);
-    } else {
-      ge->flag = *flag;
-    }
-    return true;
-  }
-  grouphash = Hash(group, strlen(group));
-  memcpy(&i, &grouphash, sizeof(i));
-  i = i % GROUPHEADERHASHSIZE;
-  GROUPlockhash(INN_LOCK_WRITE);
-  gloc = GROUPnewnode();
-  ge = &GROUPentries[gloc.recno];
-  setinitialge(ge, grouphash, flag, GROUPheader->hash[i], lo, hi);
-  GROUPheader->hash[i] = gloc;
-#ifdef OV_DEBUG
-  ntp = xmalloc(sizeof(struct ov_name_table));
-  memset(ntp, '\0', sizeof(struct ov_name_table));
-  ntp->name = xstrdup(group);
-  ntp->recno = gloc.recno;
-  if (name_table == NULL)
-    name_table = ntp;
-  else {
-    ntp->next = name_table;
-    name_table = ntp;
-  }
-#endif /* OV_DEBUG */
-  GROUPlockhash(INN_LOCK_UNLOCK);
-  return true;
-}
-
-static off_t GROUPfilesize(int count) {
-  return ((off_t) count * sizeof(GROUPENTRY)) + sizeof(GROUPHEADER);
-}
-
-/* Check if the given GROUPLOC refers to GROUPENTRY that we don't have mmap'ed,
-** if so then see if the file has been grown by another writer and remmap
-*/
-static bool GROUPremapifneeded(GROUPLOC loc) {
-  struct stat  sb;
-
-  if (loc.recno < GROUPcount)
-    return true;
-
-  if (fstat(GROUPfd, &sb) < 0)
-    return false;
-
-  if (GROUPfilesize(GROUPcount) >= sb.st_size)
-    return true;
-
-  if (GROUPheader) {
-    if (munmap((void *)GROUPheader, GROUPfilesize(GROUPcount)) < 0) {
-      syslog(L_FATAL, "%s: Could not munmap group.index in GROUPremapifneeded: %m", LocalLogName);
-      return false;
-    }
-  }
-
-  GROUPcount = (sb.st_size - sizeof(GROUPHEADER)) / sizeof(GROUPENTRY);
-  GROUPheader = (GROUPHEADER *)mmap(0, GROUPfilesize(GROUPcount),
-                                    PROT_READ | PROT_WRITE, MAP_SHARED, GROUPfd, 0);
-  if (GROUPheader == (GROUPHEADER *) -1) {
-    syslog(L_FATAL, "%s: Could not mmap group.index in GROUPremapifneeded: %m", LocalLogName);
-    return false;
-  }
-  GROUPentries = (GROUPENTRY *)((char *)GROUPheader + sizeof(GROUPHEADER));
-  return true;
-}
-
-/* This function does not need to lock because it's callers are expected to do so */
-static bool GROUPexpand(int mode) {
-  int  i;
-  int  flag = 0;
-
-  if (GROUPheader) {
-    if (munmap((void *)GROUPheader, GROUPfilesize(GROUPcount)) < 0) {
-      syslog(L_FATAL, "%s: Could not munmap group.index in GROUPexpand: %m", LocalLogName);
-      return false;
-    }
-  }
-  GROUPcount += 1024;
-  if (ftruncate(GROUPfd, GROUPfilesize(GROUPcount)) < 0) {
-    syslog(L_FATAL, "%s: Could not extend group.index: %m", LocalLogName);
-    return false;
-  }
-  if (mode & OV_READ)
-    flag |= PROT_READ;
-  if (mode & OV_WRITE) {
-    /*
-     * Note: below check of magic won't work unless we have both PROT_READ
-     * and PROT_WRITE perms.
-     */
-    flag |= PROT_WRITE|PROT_READ;
-  }
-  GROUPheader = (GROUPHEADER *)mmap(0, GROUPfilesize(GROUPcount),
-                                    flag, MAP_SHARED, GROUPfd, 0);
-  if (GROUPheader == (GROUPHEADER *) -1) {
-    syslog(L_FATAL, "%s: Could not mmap group.index in GROUPexpand: %m", LocalLogName);
-    return false;
-  }
-  GROUPentries = (GROUPENTRY *)((char *)GROUPheader + sizeof(GROUPHEADER));
-  if (GROUPheader->magic != GROUPHEADERMAGIC) {
-    GROUPheader->magic = GROUPHEADERMAGIC;
-    GROUPLOCclear(&GROUPheader->freelist);
-    for (i = 0; i < GROUPHEADERHASHSIZE; i++)
-      GROUPLOCclear(&GROUPheader->hash[i]);
-  }
-  /* Walk the new entries from the back to the front, adding them to the freelist */
-  for (i = GROUPcount - 1; (GROUPcount - 1024) <= i; i--) {
-    GROUPentries[i].next = GROUPheader->freelist;
-    GROUPheader->freelist.recno = i;
-  }
-  return true;
-}
-
-static GROUPLOC GROUPnewnode(void) {
-  GROUPLOC     loc;
-
-  /* If we didn't find any free space, then make some */
-  if (GROUPLOCempty(GROUPheader->freelist)) {
-    if (!GROUPexpand(ovbuffmode)) {
-      return GROUPemptyloc;
-    }
-  }
-  assert(!GROUPLOCempty(GROUPheader->freelist));
-  loc = GROUPheader->freelist;
-  GROUPheader->freelist = GROUPentries[GROUPheader->freelist.recno].next;
-  return loc;
-}
-
-bool buffindexed_groupdel(char *group) {
-  GROUPLOC     gloc;
-  GROUPENTRY   *ge;
-
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    return true;
-  }
-  GROUPlock(gloc, INN_LOCK_WRITE);
-  ge = &GROUPentries[gloc.recno];
-  ge->deleted = time(NULL);
-  HashClear(&ge->hash);
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-  return true;
-}
-
-static void GROUPLOCclear(GROUPLOC *loc) {
-  loc->recno = -1;
-}
-
-static bool GROUPLOCempty(GROUPLOC loc) {
-  return (loc.recno < 0);
-}
-
-static bool GROUPlockhash(enum inn_locktype type) {
-  return inn_lock_range(GROUPfd, type, true, 0, sizeof(GROUPHEADER));
-}
-
-static bool GROUPlock(GROUPLOC gloc, enum inn_locktype type) {
-  return inn_lock_range(GROUPfd,
-            type,
-            true,
-            sizeof(GROUPHEADER) + (sizeof(GROUPENTRY) * gloc.recno),
-            sizeof(GROUPENTRY));
-}
-
-#ifdef OV_DEBUG
-static bool ovsetcurindexblock(GROUPENTRY *ge, GROUPENTRY *georig) {
-#else
-static bool ovsetcurindexblock(GROUPENTRY *ge) {
-#endif /* OV_DEBUG */
-  OVBUFF       *ovbuff;
-  OV           ov;
-  OVINDEXHEAD  ovindexhead;
-
-  /* there is no index */
-#ifdef OV_DEBUG
-  ov = ovblocknew(georig ? georig : ge);
-#else
-  ov = ovblocknew();
-#endif /* OV_DEBUG */
-  if (ov.index == NULLINDEX) {
-    syslog(L_ERROR, "%s: ovsetcurindexblock could not get new block", LocalLogName);
-    return false;
-  }
-  if ((ovbuff = getovbuff(ov)) == NULL) {
-    syslog(L_ERROR, "%s: ovsetcurindexblock could not get ovbuff block for new, %d, %d", LocalLogName, ov.index, ov.blocknum);
-    return false;
-  }
-  ovindexhead.next = ovnull;
-  ovindexhead.low = 0;
-  ovindexhead.high = 0;
-#ifdef MMAP_MISSES_WRITES
-  if (mmapwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ov.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#else
-  if (pwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ov.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#endif /* MMAP_MISSES_WRITES */
-    syslog(L_ERROR, "%s: could not write index record index '%d', blocknum '%d': %m", LocalLogName, ge->curindex.index, ge->curindex.blocknum);
-    return true;
-  }
-  if (ge->baseindex.index == NULLINDEX) {
-    ge->baseindex = ov;
-  } else {
-    if ((ovbuff = getovbuff(ge->curindex)) == NULL)
-      return false;
-#ifdef OV_DEBUG
-    if (!ovusedblock(ovbuff, ge->curindex.blocknum, false, false)) {
-      syslog(L_FATAL, "%s: block(%d, %d) not occupied (index)", LocalLogName, ovbuff->index, ge->curindex.blocknum);
-      abort();
-    }
-#endif /* OV_DEBUG */
-    ovindexhead.next = ov;
-    ovindexhead.low = ge->curlow;
-    ovindexhead.high = ge->curhigh;
-#ifdef MMAP_MISSES_WRITES
-    if (mmapwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#else
-    if (pwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#endif /* MMAP_MISSES_WRITES */
-      syslog(L_ERROR, "%s: could not write index record index '%d', blocknum '%d': %m", LocalLogName, ge->curindex.index, ge->curindex.blocknum);
-      return false;
-    }
-  }
-  ge->curindex = ov;
-  ge->curindexoffset = 0;
-  ge->curlow = 0;
-  ge->curhigh = 0;
-  return true;
-}
-
-#ifdef OV_DEBUG
-static bool ovaddrec(GROUPENTRY *ge, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires, GROUPENTRY *georig) {
-#else
-static bool ovaddrec(GROUPENTRY *ge, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires) {
-#endif /* OV_DEBUG */
-  OV           ov;
-  OVINDEX      ie;
-  OVBUFF       *ovbuff;
-  OVINDEXHEAD  ovindexhead;
-  bool         needupdate = false;
-#ifdef OV_DEBUG
-  int          recno;
-#endif /* OV_DEBUG */
-
-  Nospace = false;
-  if (OV_BLOCKSIZE < len) {
-    syslog(L_ERROR, "%s: overview data must be under %d (%d)", LocalLogName, OV_BLOCKSIZE, len);
-    return false;
-  }
-  if (ge->curdata.index == NULLINDEX) {
-    /* no data block allocated */
-#ifdef OV_DEBUG
-    ov = ovblocknew(georig ? georig : ge);
-#else
-    ov = ovblocknew();
-#endif /* OV_DEBUG */
-    if (ov.index == NULLINDEX) {
-      syslog(L_ERROR, "%s: ovaddrec could not get new block", LocalLogName);
-      return false;
-    }
-    if ((ovbuff = getovbuff(ov)) == NULL) {
-      syslog(L_ERROR, "%s: ovaddrec could not get ovbuff block for new, %d, %d, %ld", LocalLogName, ov.index, ov.blocknum, artnum);
-      return false;
-    }
-    ge->curdata = ov;
-    ge->curoffset = 0;
-  } else if ((ovbuff = getovbuff(ge->curdata)) == NULL)
-    return false;
-  else if (OV_BLOCKSIZE - ge->curoffset < len) {
-    /* too short to store data, allocate new block */
-#ifdef OV_DEBUG
-    ov = ovblocknew(georig ? georig : ge);
-#else
-    ov = ovblocknew();
-#endif /* OV_DEBUG */
-    if (ov.index == NULLINDEX) {
-      syslog(L_ERROR, "%s: ovaddrec could not get new block", LocalLogName);
-      return false;
-    }
-    if ((ovbuff = getovbuff(ov)) == NULL) {
-      syslog(L_ERROR, "%s: ovaddrec could not get ovbuff block for new, %d, %d, %ld", LocalLogName, ov.index, ov.blocknum, artnum);
-      return false;
-    }
-    ge->curdata = ov;
-    ge->curoffset = 0;
-  }
-#ifdef OV_DEBUG
-  if (!ovusedblock(ovbuff, ge->curdata.blocknum, false, false)) {
-    syslog(L_FATAL, "%s: block(%d, %d) not occupied", LocalLogName, ovbuff->index, ge->curdata.blocknum);
-    buffindexed_close();
-    abort();
-  }
-#endif /* OV_DEBUG */
-#ifdef MMAP_MISSES_WRITES
-  if (mmapwrite(ovbuff->fd, data, len, ovbuff->base + ge->curdata.blocknum * OV_BLOCKSIZE + ge->curoffset) != len) {
-#else
-  if (pwrite(ovbuff->fd, data, len, ovbuff->base + ge->curdata.blocknum * OV_BLOCKSIZE + ge->curoffset) != len) {
-#endif /* MMAP_MISSES_WRITES */
-    syslog(L_ERROR, "%s: could not append overview record index '%d', blocknum '%d': %m", LocalLogName, ge->curdata.index, ge->curdata.blocknum);
-    return false;
-  }
-  memset(&ie, '\0', sizeof(ie));
-  ie.artnum = artnum;
-  ie.len = len;
-  ie.index = ge->curdata.index;
-  ie.blocknum = ge->curdata.blocknum;
-  ie.offset = ge->curoffset;
-  ie.token = token;
-  ie.arrived = arrived;
-  ie.expires = expires;
-
-  if (ge->baseindex.index == NULLINDEX || ge->curindexoffset == OVINDEXMAX) {
-#ifdef OV_DEBUG
-    if (!ovsetcurindexblock(ge, georig)) {
-#else
-    if (!ovsetcurindexblock(ge)) {
-#endif /* OV_DEBUG */
-      syslog(L_ERROR, "%s: could not set current index", LocalLogName);
-      return false;
-    }
-  }
-  if ((ovbuff = getovbuff(ge->curindex)) == NULL)
-    return false;
-#ifdef OV_DEBUG
-  if (!ovusedblock(ovbuff, ge->curindex.blocknum, false, false)) {
-    syslog(L_FATAL, "%s: block(%d, %d) not occupied (index)", LocalLogName, ovbuff->index, ge->curindex.blocknum);
-    buffindexed_close();
-    abort();
-  }
-#endif /* OV_DEBUG */
-#ifdef MMAP_MISSES_WRITES
-  if (mmapwrite(ovbuff->fd, &ie, sizeof(ie), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE + sizeof(OVINDEXHEAD) + sizeof(ie) * ge->curindexoffset) != sizeof(ie)) {
-#else
-  if (pwrite(ovbuff->fd, &ie, sizeof(ie), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE + sizeof(OVINDEXHEAD) + sizeof(ie) * ge->curindexoffset) != sizeof(ie)) {
-#endif /* MMAP_MISSES_WRITES */
-    syslog(L_ERROR, "%s: could not write index record index '%d', blocknum '%d': %m", LocalLogName, ge->curindex.index, ge->curindex.blocknum);
-    return true;
-  }
-  if ((ge->curlow <= 0) || (ge->curlow > artnum)) {
-    ge->curlow = artnum;
-    needupdate = true;
-  }
-  if ((ge->curhigh <= 0) || (ge->curhigh < artnum)) {
-    ge->curhigh = artnum;
-    needupdate = true;
-  }
-  if (needupdate) {
-    ovindexhead.next = ovnull;
-    ovindexhead.low = ge->curlow;
-    ovindexhead.high = ge->curhigh;
-#ifdef MMAP_MISSES_WRITES
-    if (mmapwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#else
-    if (pwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), ovbuff->base + ge->curindex.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {
-#endif /* MMAP_MISSES_WRITES */
-      syslog(L_ERROR, "%s: could not write index record index '%d', blocknum '%d': %m", LocalLogName, ge->curindex.index, ge->curindex.blocknum);
-      return true;
-    }
-  }
-  if ((ge->low <= 0) || (ge->low > artnum))
-    ge->low = artnum;
-  if ((ge->high <= 0) || (ge->high < artnum))
-    ge->high = artnum;
-  ge->curindexoffset++;
-  ge->curoffset += len;
-  ge->count++;
-  return true;
-}
-
-bool buffindexed_add(char *group, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires) {
-  GROUPLOC     gloc;
-  GROUPENTRY   *ge;
-
-  if (len > OV_BLOCKSIZE) {
-    syslog(L_ERROR, "%s: overview data is too large %d", LocalLogName, len);
-    return true;
-  }
-
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    return true;
-  }
-  GROUPlock(gloc, INN_LOCK_WRITE);
-  /* prepend block(s) if needed. */
-  ge = &GROUPentries[gloc.recno];
-  if (Cutofflow && ge->low > artnum) {
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-    return true;
-  }
-#ifdef OV_DEBUG
-  if (!ovaddrec(ge, artnum, token, data, len, arrived, expires, NULL)) {
-#else
-  if (!ovaddrec(ge, artnum, token, data, len, arrived, expires)) {
-#endif /* OV_DEBUG */
-    if (Nospace) {
-      GROUPlock(gloc, INN_LOCK_UNLOCK);
-      syslog(L_ERROR, "%s: no space left for buffer, adding '%s'", LocalLogName, group);
-      return false;
-    }
-    syslog(L_ERROR, "%s: could not add overview for '%s'", LocalLogName, group);
-  }
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-
-  return true;
-}
-
-bool buffindexed_cancel(TOKEN token UNUSED) {
-    return true;
-}
-
-#ifdef OV_DEBUG
-static void freegroupblock(GROUPENTRY *ge) {
-#else
-static void freegroupblock(void) {
-#endif /* OV_DEBUG */
-  GROUPDATABLOCK       *gdb;
-  int                  i;
-  GIBLIST              *giblist;
-
-  for (giblist = Giblist ; giblist != NULL ; giblist = giblist->next) {
-#ifdef OV_DEBUG
-    ovblockfree(giblist->ov, ge);
-#else
-    ovblockfree(giblist->ov);
-#endif /* OV_DEBUG */
-  }
-  for (i = 0 ; i < GROUPDATAHASHSIZE ; i++) {
-    for (gdb = groupdatablock[i] ; gdb != NULL ; gdb = gdb->next) {
-#ifdef OV_DEBUG
-      ovblockfree(gdb->datablk, ge);
-#else
-      ovblockfree(gdb->datablk);
-#endif /* OV_DEBUG */
-    }
-  }
-}
-
-static void ovgroupunmap(void) {
-  GROUPDATABLOCK       *gdb, *gdbnext;
-  int                  i;
-  GIBLIST              *giblist, *giblistnext;
-
-  for (i = 0 ; i < GROUPDATAHASHSIZE ; i++) {
-    for (gdb = groupdatablock[i] ; gdb != NULL ; gdb = gdbnext) {
-      gdbnext = gdb->next;
-      free(gdb);
-    }
-    groupdatablock[i] = NULL;
-  }
-  for (giblist = Giblist ; giblist != NULL ; giblist = giblistnext) {
-    giblistnext = giblist->next;
-    free(giblist);
-  }
-  Giblist = NULL;
-  if (!Cache && (Gib != NULL)) {
-    free(Gib);
-    Gib = NULL;
-    if (Cachesearch != NULL) {
-      free(Cachesearch->group);
-      free(Cachesearch);
-      Cachesearch = NULL;
-    }
-  }
-}
-
-static void insertgdb(OV *ov, GROUPDATABLOCK *gdb) {
-  gdb->next = groupdatablock[(ov->index + ov->blocknum) % GROUPDATAHASHSIZE];
-  groupdatablock[(ov->index + ov->blocknum) % GROUPDATAHASHSIZE] = gdb;
-  return;
-}
-
-static GROUPDATABLOCK *searchgdb(OV *ov) {
-  GROUPDATABLOCK       *gdb;
-
-  gdb = groupdatablock[(ov->index + ov->blocknum) % GROUPDATAHASHSIZE];
-  for (; gdb != NULL ; gdb = gdb->next) {
-    if (ov->index == gdb->datablk.index && ov->blocknum == gdb->datablk.blocknum)
-      break;
-  }
-  return gdb;
-}
-
-static int INDEXcompare(const void *p1, const void *p2) {
-  OVINDEX      *oi1;
-  OVINDEX      *oi2;
-  oi1 = (OVINDEX *)p1;
-  oi2 = (OVINDEX *)p2;  
-  return oi1->artnum - oi2->artnum;
-}
-
-static bool ovgroupmmap(GROUPENTRY *ge, int low, int high, bool needov) {
-  OV                   ov = ge->baseindex;
-  OVBUFF               *ovbuff;
-  GROUPDATABLOCK       *gdb;
-  int                  pagefudge, limit, i, count, len;
-  off_t                 offset, mmapoffset;
-  OVBLOCK              *ovblock;
-  void *               addr;
-  GIBLIST              *giblist;
-
-  if (high - low < 0) {
-    Gibcount = 0;
-    return true;
-  }
-  Gibcount = ge->count;
-  if (Gibcount == 0)
-    return true;
-  Gib = xmalloc(Gibcount * sizeof(OVINDEX));
-  count = 0;
-  while (ov.index != NULLINDEX) {
-    ovbuff = getovbuff(ov);
-    if (ovbuff == NULL) {
-      syslog(L_ERROR, "%s: ovgroupmmap ovbuff is null(ovindex is %d, ovblock is %d", LocalLogName, ov.index, ov.blocknum);
-      ovgroupunmap();
-      return false;
-    }
-    offset = ovbuff->base + (ov.blocknum * OV_BLOCKSIZE);
-    pagefudge = offset % pagesize;
-    mmapoffset = offset - pagefudge;
-    len = pagefudge + OV_BLOCKSIZE;
-    if ((addr = mmap(NULL, len, PROT_READ, MAP_SHARED, ovbuff->fd, mmapoffset)) == MAP_FAILED) {
-      syslog(L_ERROR, "%s: ovgroupmmap could not mmap index block: %m", LocalLogName);
-      ovgroupunmap();
-      return false;
-    }
-    ovblock = (OVBLOCK *)((char *)addr + pagefudge);
-    if (ov.index == ge->curindex.index && ov.blocknum == ge->curindex.blocknum) {
-      limit = ge->curindexoffset;
-    } else {
-      limit = OVINDEXMAX;
-    }
-    for (i = 0 ; i < limit ; i++) {
-      if (Gibcount == count) {
-       Gibcount += OV_FUDGE;
-        Gib = xrealloc(Gib, Gibcount * sizeof(OVINDEX));
-      }
-      Gib[count++] = ovblock->ovindex[i];
-    }
-    giblist = xmalloc(sizeof(GIBLIST));
-    giblist->ov = ov;
-    giblist->next = Giblist;
-    Giblist = giblist;
-    ov = ovblock->ovindexhead.next;
-    munmap(addr, len);
-  }
-  Gibcount = count;
-  qsort(Gib, Gibcount, sizeof(OVINDEX), INDEXcompare);
-  /* Remove duplicates. */
-  for (i = 0; i < Gibcount - 1; i++) {
-    if (Gib[i].artnum == Gib[i+1].artnum) {
-      /* lower position is removed */
-      Gib[i].artnum = 0;
-    }
-  }
-  if (!needov)
-    return true;
-  count = 0;
-  for (i = 0 ; i < Gibcount ; i++) {
-    if (Gib[i].artnum == 0 || Gib[i].artnum < low || Gib[i].artnum > high)
-      continue;
-    ov.index = Gib[i].index;
-    ov.blocknum = Gib[i].blocknum;
-    gdb = searchgdb(&ov);
-    if (gdb != NULL)
-      continue;
-    ovbuff = getovbuff(ov);
-    if (ovbuff == NULL)
-      continue;
-    gdb = xmalloc(sizeof(GROUPDATABLOCK));
-    gdb->datablk = ov;
-    gdb->next = NULL;
-    gdb->mmapped = false;
-    insertgdb(&ov, gdb);
-    count++;
-  }
-  if (count == 0)
-    return true;
-  if (count * OV_BLOCKSIZE > innconf->keepmmappedthreshold * 1024)
-    /* large retrieval, mmap is done in ovsearch() */
-    return true;
-  for (i = 0 ; i < GROUPDATAHASHSIZE ; i++) {
-    for (gdb = groupdatablock[i] ; gdb != NULL ; gdb = gdb->next) {
-      ov = gdb->datablk;
-      ovbuff = getovbuff(ov);
-      offset = ovbuff->base + (ov.blocknum * OV_BLOCKSIZE);
-      pagefudge = offset % pagesize;
-      mmapoffset = offset - pagefudge;
-      gdb->len = pagefudge + OV_BLOCKSIZE;
-      if ((gdb->addr = mmap(NULL, gdb->len, PROT_READ, MAP_SHARED, ovbuff->fd, mmapoffset)) == MAP_FAILED) {
-        syslog(L_ERROR, "%s: ovgroupmmap could not mmap data block: %m", LocalLogName);
-        free(gdb);
-        ovgroupunmap();
-        return false;
-      }
-      gdb->data = (char *)gdb->addr + pagefudge;
-      gdb->mmapped = true;
-    }
-  }
-  return true;
-}
-
-static void *ovopensearch(char *group, int low, int high, bool needov) {
-  GROUPLOC             gloc;
-  GROUPENTRY           *ge;
-  OVSEARCH             *search;
-
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc))
-    return NULL;
-
-  ge = &GROUPentries[gloc.recno];
-  if (low < ge->low)
-    low = ge->low;
-  if (high > ge->high)
-    high = ge->high;
-
-  if (!ovgroupmmap(ge, low, high, needov)) {
-    return NULL;
-  }
-
-  search = xmalloc(sizeof(OVSEARCH));
-  search->hi = high;
-  search->lo = low;
-  search->cur = 0;
-  search->group = xstrdup(group);
-  search->needov = needov;
-  search->gloc = gloc;
-  search->count = ge->count;
-  search->gdb.mmapped = false;
-  return (void *)search;
-}
-
-void *buffindexed_opensearch(char *group, int low, int high) {
-  GROUPLOC             gloc;
-  void                 *handle;
-
-  if (Gib != NULL) {
-    free(Gib);
-    Gib = NULL;
-    if (Cachesearch != NULL) {
-      free(Cachesearch->group);
-      free(Cachesearch);
-      Cachesearch = NULL;
-    }
-  }
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    return NULL;
-  }
-  GROUPlock(gloc, INN_LOCK_WRITE);
-  if ((handle = ovopensearch(group, low, high, true)) == NULL)
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-  return(handle);
-}
-
-static bool ovsearch(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived, time_t *expires) {
-  OVSEARCH             *search = (OVSEARCH *)handle;
-  OV                   srchov;
-  GROUPDATABLOCK       *gdb;
-  off_t                        offset, mmapoffset;
-  OVBUFF               *ovbuff;
-  int                  pagefudge;
-  bool                 newblock;
-
-  if (search->cur == Gibcount) {
-    return false;
-  }
-  while (Gib[search->cur].artnum == 0 || Gib[search->cur].artnum < search->lo) {
-    search->cur++;
-    if (search->cur == Gibcount)
-      return false;
-  }
-  if (Gib[search->cur].artnum > search->hi)
-      return false;
-
-  if (search->needov) {
-    if (Gib[search->cur].index == NULLINDEX) {
-      if (len)
-       *len = 0;
-      if (artnum)
-       *artnum = Gib[search->cur].artnum;
-    } else {
-      if (artnum)
-       *artnum = Gib[search->cur].artnum;
-      if (len)
-       *len = Gib[search->cur].len;
-      if (arrived)
-       *arrived = Gib[search->cur].arrived;
-      if (expires)
-       *expires = Gib[search->cur].expires;
-      if (data) {
-       srchov.index = Gib[search->cur].index;
-       srchov.blocknum = Gib[search->cur].blocknum;
-       gdb = searchgdb(&srchov);
-       if (gdb == NULL) {
-         if (len)
-           *len = 0;
-         search->cur++;
-         return true;
-       }
-       if (!gdb->mmapped) {
-         /* block needs to be mmapped */
-         if (search->gdb.mmapped) {
-           /* check previous mmapped area */
-           if (search->gdb.datablk.blocknum != srchov.blocknum || search->gdb.datablk.index != srchov.index) {
-             /* different one, release previous one */
-             munmap(search->gdb.addr, search->gdb.len);
-             newblock = true;
-           } else
-             newblock = false;
-         } else
-           newblock = true;
-         if (newblock) {
-           search->gdb.datablk.blocknum = srchov.blocknum;
-           search->gdb.datablk.index = srchov.index;
-           ovbuff = getovbuff(srchov);
-           offset = ovbuff->base + (srchov.blocknum * OV_BLOCKSIZE);
-           pagefudge = offset % pagesize;
-           mmapoffset = offset - pagefudge;
-           search->gdb.len = pagefudge + OV_BLOCKSIZE;
-           if ((search->gdb.addr = mmap(NULL, search->gdb.len, PROT_READ, MAP_SHARED, ovbuff->fd, mmapoffset)) == MAP_FAILED) {
-             syslog(L_ERROR, "%s: ovsearch could not mmap data block: %m", LocalLogName);
-             return false;
-           }
-           gdb->data = search->gdb.data = (char *)search->gdb.addr + pagefudge;
-           search->gdb.mmapped = true;
-         }
-       }
-       *data = (char *)gdb->data + Gib[search->cur].offset;
-      }
-    }
-  }
-  if (token) {
-    if (Gib[search->cur].index == NULLINDEX && !search->needov) {
-      search->cur++;
-      return false;
-    }
-    *token = Gib[search->cur].token;
-  }
-  search->cur++;
-  return true;
-}
-
-bool buffindexed_search(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived) {
-  return(ovsearch(handle, artnum, data, len, token, arrived, NULL));
-}
-
-static void ovclosesearch(void *handle, bool freeblock) {
-  OVSEARCH             *search = (OVSEARCH *)handle;
-  GROUPDATABLOCK       *gdb;
-  int                  i;
-#ifdef OV_DEBUG
-  GROUPENTRY   *ge;
-  GROUPLOC     gloc;
-#endif /* OV_DEBUG */
-
-  for (i = 0 ; i < GROUPDATAHASHSIZE ; i++) {
-    for (gdb = groupdatablock[i] ; gdb != NULL ; gdb = gdb->next) {
-      if (gdb->mmapped)
-       munmap(gdb->addr, gdb->len);
-    }
-  }
-  if (search->gdb.mmapped)
-    munmap(search->gdb.addr, search->gdb.len);
-  if (freeblock) {
-#ifdef OV_DEBUG
-    gloc = GROUPfind(search->group, false);
-    if (!GROUPLOCempty(gloc)) {
-      ge = &GROUPentries[gloc.recno];
-      freegroupblock(ge);
-    }
-#else
-    freegroupblock();
-#endif /* OV_DEBUG */
-  }
-  ovgroupunmap();
-  if (Cache) {
-    Cachesearch = search;
-  } else {
-    free(search->group);
-    free(search);
-  }
-  return;
-}
-
-void buffindexed_closesearch(void *handle) {
-  OVSEARCH     *search = (OVSEARCH *)handle;
-  GROUPLOC     gloc;
-
-  gloc = search->gloc;
-  ovclosesearch(handle, false);
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-}
-
-/* get token from sorted index */
-static bool gettoken(ARTNUM artnum, TOKEN *token) {
-  int  i, j, offset, limit;
-  offset = 0;
-  limit = Gibcount;
-  for (i = (limit - offset) / 2 ; i > 0 ; i = (limit - offset) / 2) {
-    if (Gib[offset + i].artnum == artnum) {
-      *token = Gib[offset + i].token;
-      return true;
-    } else if (Gib[offset + i].artnum == 0) {
-      /* case for duplicated index */
-      for (j = offset + i - 1; j >= offset ; j --) {
-       if (Gib[j].artnum != 0)
-         break;
-      }
-      if (j < offset) {
-       /* article not found */
-       return false;
-      }
-      if (Gib[j].artnum == artnum) {
-       *token = Gib[j].token;
-       return true;
-      } else if (Gib[j].artnum < artnum) {
-       /* limit is not changed */
-       offset += i + 1;
-      } else {
-       /* offset is not changed */
-       limit = j;
-      }
-    } else if (Gib[offset + i].artnum < artnum) {
-      /* limit is unchanged */
-      offset += i + 1;
-    } else {
-      /* offset is unchanged */
-      limit = offset + i;
-    }
-  }
-  /* i == 0 */
-  if (Gib[offset].artnum != artnum) {
-    /* article not found */
-    return false;
-  }
-  *token = Gib[offset].token;
-  return true;
-}
-
-bool buffindexed_getartinfo(char *group, ARTNUM artnum, TOKEN *token) {
-  GROUPLOC     gloc;
-  void         *handle;
-  bool         retval, grouplocked = false;
-
-  if (Gib != NULL) {
-    if (Cachesearch != NULL && strcmp(Cachesearch->group, group) != 0) {
-      free(Gib);
-      Gib = NULL;
-      free(Cachesearch->group);
-      free(Cachesearch);
-      Cachesearch = NULL;
-    } else {
-      if (gettoken(artnum, token))
-       return true;
-      else {
-       /* examine to see if overview index are increased */
-       gloc = GROUPfind(group, false);
-       if (GROUPLOCempty(gloc)) {
-         return false;
-       }
-       GROUPlock(gloc, INN_LOCK_WRITE);
-       if ((Cachesearch != NULL) && (GROUPentries[gloc.recno].count == Cachesearch->count)) {
-         /* no new overview data is stored */
-         GROUPlock(gloc, INN_LOCK_UNLOCK);
-         return false;
-       } else {
-         grouplocked = true;
-         free(Gib);
-         Gib = NULL;
-         if (Cachesearch != NULL) {
-           free(Cachesearch->group);
-           free(Cachesearch);
-           Cachesearch = NULL;
-         }
-       }
-      }
-    }
-  }
-  if (!grouplocked) {
-    gloc = GROUPfind(group, false);
-    if (GROUPLOCempty(gloc)) {
-      return false;
-    }
-    GROUPlock(gloc, INN_LOCK_WRITE);
-  }
-  if (!(handle = ovopensearch(group, artnum, artnum, false))) {
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-    return false;
-  }
-  retval = buffindexed_search(handle, NULL, NULL, NULL, token, NULL);
-  ovclosesearch(handle, false);
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-  return retval;
-}
-
-bool buffindexed_expiregroup(char *group, int *lo, struct history *h) {
-  void         *handle;
-  GROUPENTRY   newge, *ge;
-  GROUPLOC     gloc, next;
-  char         *data;
-  int          i, j, len;
-  TOKEN                token;
-  ARTNUM       artnum, low, high;
-  ARTHANDLE    *ah;
-  char         flag;
-  HASH         hash;
-  time_t       arrived, expires;
-
-  if (group == NULL) {
-    for (i = 0 ; i < GROUPheader->freelist.recno ; i++) {
-      gloc.recno = i;
-      GROUPlock(gloc, INN_LOCK_WRITE);
-      ge = &GROUPentries[gloc.recno];
-      if (ge->expired >= OVrealnow || ge->count == 0) {
-       GROUPlock(gloc, INN_LOCK_UNLOCK);
-       continue;
-      }
-      if (!ovgroupmmap(ge, ge->low, ge->high, true)) {
-       GROUPlock(gloc, INN_LOCK_UNLOCK);
-       syslog(L_ERROR, "%s: could not mmap overview for hidden groups(%d)", LocalLogName, i);
-       continue;
-      }
-      for (j = 0 ; j < Gibcount ; j++) {
-       if (Gib[j].artnum == 0)
-         continue;
-       /* this may be duplicated, but ignore it in this case */
-       OVEXPremove(Gib[j].token, true, NULL, 0);
-      }
-#ifdef OV_DEBUG
-      freegroupblock(ge);
-#else
-      freegroupblock();
-#endif
-      ovgroupunmap();
-      ge->expired = time(NULL);
-      ge->count = 0;
-      GROUPlock(gloc, INN_LOCK_UNLOCK);
-    }
-    return true;
-  }
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    return false;
-  }
-  GROUPlock(gloc, INN_LOCK_WRITE);
-  ge = &GROUPentries[gloc.recno];
-  if (ge->count == 0) {
-    if (lo)
-      *lo = ge->low;
-    ge->expired = time(NULL);
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-    return true;
-  }
-  flag = ge->flag;
-  hash = ge->hash;
-  next = ge->next;
-  low = ge->low;
-  high = ge->high;
-
-  newge.low = 0;
-  setinitialge(&newge, hash, &flag, next, 0, high);
-  if ((handle = ovopensearch(group, low, high, true)) == NULL) {
-    ge->expired = time(NULL);
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-    syslog(L_ERROR, "%s: could not open overview for '%s'", LocalLogName, group);
-    return false;
-  }
-  while (ovsearch(handle, &artnum, &data, &len, &token, &arrived, &expires)) {
-    ah = NULL;
-    if (len == 0)
-      continue; 
-    if (!SMprobe(EXPENSIVESTAT, &token, NULL) || OVstatall) {
-      if ((ah = SMretrieve(token, RETR_STAT)) == NULL)
-        continue; 
-      SMfreearticle(ah);
-    } else {
-      if (!OVhisthasmsgid(h, data))
-       continue; 
-    }
-    if (innconf->groupbaseexpiry && OVgroupbasedexpire(token, group, data, len, arrived, expires))
-      continue;
-#ifdef OV_DEBUG
-    if (!ovaddrec(&newge, artnum, token, data, len, arrived, expires, ge)) {
-#else
-    if (!ovaddrec(&newge, artnum, token, data, len, arrived, expires)) {
-#endif /* OV_DEBUG */
-      ovclosesearch(handle, true);
-      ge->expired = time(NULL);
-      GROUPlock(gloc, INN_LOCK_UNLOCK);
-      syslog(L_ERROR, "%s: could not add new overview for '%s'", LocalLogName, group);
-      return false;
-    }
-  }
-  if (newge.low == 0)
-    /* no article for the group */
-    newge.low = newge.high;
-  *ge = newge;
-  if (lo) {
-    if (ge->count == 0)
-      /* lomark should be himark + 1, if no article for the group */
-      *lo = ge->low + 1;
-    else
-      *lo = ge->low;
-  }
-  ovclosesearch(handle, true);
-  ge->expired = time(NULL);
-  GROUPlock(gloc, INN_LOCK_UNLOCK);
-  return true;
-}
-
-bool buffindexed_ctl(OVCTLTYPE type, void *val) {
-  int                  total, used, *i, j;
-  OVBUFF               *ovbuff = ovbufftab;
-  OVSORTTYPE           *sorttype;
-  bool                 *boolval;
-  GROUPDATABLOCK       *gdb;
-
-  switch (type) {
-  case OVSPACE:
-    for (total = used = 0 ; ovbuff != (OVBUFF *)NULL ; ovbuff = ovbuff->next) {
-      ovlock(ovbuff, INN_LOCK_READ);
-      ovreadhead(ovbuff);
-      total += ovbuff->totalblk;
-      used += ovbuff->usedblk;
-      ovlock(ovbuff, INN_LOCK_UNLOCK);
-    }
-    i = (int *)val;
-    *i = (used * 100) / total;
-    return true;
-  case OVSORT:
-    sorttype = (OVSORTTYPE *)val;
-    *sorttype = OVNOSORT;
-    return true;
-  case OVCUTOFFLOW:
-    Cutofflow = *(bool *)val;
-    return true;
-  case OVSTATICSEARCH:
-    i = (int *)val;
-    *i = true;
-    for (j = 0 ; j < GROUPDATAHASHSIZE ; j++) {
-      for (gdb = groupdatablock[j] ; gdb != NULL ; gdb = gdb->next) {
-        if  (gdb->mmapped) {
-         *i = false;
-         return true;
-        }
-      }
-    }
-    return true;
-  case OVCACHEKEEP:
-    Cache = *(bool *)val;
-    return true;
-  case OVCACHEFREE:
-    boolval = (bool *)val;
-    *boolval = true;
-    if (Gib != NULL) {
-      free(Gib);
-      Gib = NULL;
-      if (Cachesearch != NULL) {
-       free(Cachesearch->group);
-       free(Cachesearch);
-       Cachesearch = NULL;
-      }
-    }
-    return true;
-  default:
-    return false;
-  }
-}
-
-void buffindexed_close(void) {
-  struct stat  sb;
-  OVBUFF       *ovbuffnext, *ovbuff = ovbufftab;
-#ifdef OV_DEBUG
-  FILE         *F = NULL;
-  pid_t                pid;
-  char         *path = NULL;
-  int          i,j;
-  struct ov_trace_array *trace;
-  struct ov_name_table *ntp;
-  size_t length;
-#endif /* OV_DEBUG */
-
-#ifdef OV_DEBUG
-  for (; ovbuff != (OVBUFF *)NULL; ovbuff = ovbuff->next) {
-    for (i = 0 ; i < ovbuff->totalblk ; i++) {
-      trace = &ovbuff->trace[i];
-      if (trace->ov_trace == NULL)
-       continue;
-      for (j = 0 ; j <= trace->cur && j < trace->max ; j++) {
-       if (trace->ov_trace[j].occupied != 0 ||
-         trace->ov_trace[j].freed != 0) {
-         if (F == NULL) {
-            length = strlen(innconf->pathtmp) + 11;
-           path = xmalloc(length);
-           pid = getpid();
-           snprintf(path, length, "%s/%d", innconf->pathtmp, pid);
-           if ((F = fopen(path, "w")) == NULL) {
-             syslog(L_ERROR, "%s: could not open %s: %m", LocalLogName, path);
-             break;
-           }
-         }
-         fprintf(F, "%d: % 6d, % 2d: 0x%08x, % 10d, % 10d\n", ovbuff->index, i, j,
-         trace->ov_trace[j].gloc.recno,
-         trace->ov_trace[j].occupied,
-         trace->ov_trace[j].freed);
-       }
-      }
-    }
-  }
-  if ((ntp = name_table) != NULL) {
-    if (F == NULL) {
-      length = strlen(innconf->pathtmp) + 11;
-      path = xmalloc(length);
-      pid = getpid();
-      sprintf(path, length, "%s/%d", innconf->pathtmp, pid);
-      if ((F = fopen(path, "w")) == NULL) {
-        syslog(L_ERROR, "%s: could not open %s: %m", LocalLogName, path);
-      }
-    }
-    if (F != NULL) {
-      while(ntp) {
-        fprintf(F, "0x%08x: %s\n", ntp->recno, ntp->name);
-        ntp = ntp->next;
-      }
-    }
-  }
-  if (F != NULL)
-    fclose(F);
-  if (path != NULL)
-    free(path);
-#endif /* OV_DEBUG */
-  if (Gib != NULL) {
-    free(Gib);
-    Gib = NULL;
-    if (Cachesearch != NULL) {
-      free(Cachesearch->group);
-      free(Cachesearch);
-      Cachesearch = NULL;
-    }
-  }
-  if (fstat(GROUPfd, &sb) < 0)
-    return;
-  close(GROUPfd);
-
-  if (GROUPheader) {
-    if (munmap((void *)GROUPheader, GROUPfilesize(GROUPcount)) < 0) {
-      syslog(L_FATAL, "%s: could not munmap group.index in buffindexed_close: %m", LocalLogName);
-      return;
-    }
-  }
-  for (; ovbuff != (OVBUFF *)NULL; ovbuff = ovbuffnext) {
-    ovbuffnext = ovbuff->next;
-    free(ovbuff);
-  }
-  ovbufftab = NULL;
-}
-
-#ifdef BUFF_DEBUG
-static int countgdb(void) {
-  int                  i, count = 0;
-  GROUPDATABLOCK       *gdb;
-
-  for (i = 0 ; i < GROUPDATAHASHSIZE ; i++) {
-    for (gdb = groupdatablock[i] ; gdb != NULL ; gdb = gdb->next)
-      count++;
-  }
-  return count;
-}
-
-main(int argc, char **argv) {
-  char                 *group, flag[2], buff[OV_BLOCKSIZE];
-  int                  lo, hi, count, flags, i;
-  OVSEARCH             *search;
-  OVBLOCK              *ovblock;
-  OVINDEX              *ovindex;
-  OVBUFF               *ovbuff;
-  GROUPENTRY           *ge;
-  GROUPLOC             gloc;
-  GIBLIST              *giblist;
-
-  if (argc != 2) {
-    fprintf(stderr, "only one argument can be specified\n");
-    exit(1);
-  }
-  /* if innconf isn't already read in, do so. */
-  if (innconf == NULL) {
-    if (!innconf_read(NULL)) {
-      fprintf(stderr, "reading inn.conf failed\n");
-      exit(1);
-    }
-  }
-  if (!buffindexed_open(OV_READ)) {
-    fprintf(stderr, "buffindexed_open failed\n");
-    exit(1);
-  }
-  fprintf(stdout, "GROUPheader->freelist.recno is %d(0x%08x)\n", GROUPheader->freelist.recno, GROUPheader->freelist.recno);
-  group = argv[1];
-  if (isdigit(*group)) {
-    gloc.recno = atoi(group);
-    ge = &GROUPentries[gloc.recno];
-    fprintf(stdout, "left articles are %d for %d, last expiry is %d\n", ge->count, gloc.recno, ge->expired);
-    if (ge->count == 0) {
-      GROUPlock(gloc, INN_LOCK_UNLOCK);
-      exit(0);
-    }
-    if (!ovgroupmmap(ge, ge->low, ge->high, true)) {
-      fprintf(stderr, "ovgroupmmap failed\n");
-      GROUPlock(gloc, INN_LOCK_UNLOCK);
-    }
-    for (giblist = Giblist, i = 0 ; giblist != NULL ; giblist = giblist->next, i++);
-    fprintf(stdout, "%d index block(s)\n", i);
-    fprintf(stdout, "%d data block(s)\n", countgdb());
-    for (giblist = Giblist ; giblist != NULL ; giblist = giblist->next) {
-      fprintf(stdout, "  % 8d(% 5d)\n", giblist->ov.blocknum, giblist->ov.index);
-    }
-    for (i = 0 ; i < Gibcount ; i++) {
-      if (Gib[i].artnum == 0)
-       continue;
-      if (Gib[i].index == NULLINDEX)
-       fprintf(stdout, "    %d empty\n");
-      else {
-       fprintf(stdout, "    %d %d\n", Gib[i].offset, Gib[i].len);
-      }
-    }
-    ovgroupunmap();
-    GROUPlock(gloc, INN_LOCK_UNLOCK);
-    exit(0);
-  }
-  gloc = GROUPfind(group, false);
-  if (GROUPLOCempty(gloc)) {
-    fprintf(stderr, "gloc is null\n");
-  }
-  GROUPlock(gloc, INN_LOCK_READ);
-  ge = &GROUPentries[gloc.recno];
-  fprintf(stdout, "base %d(%d), cur %d(%d), expired at %s\n", ge->baseindex.blocknum, ge->baseindex.index, ge->curindex.blocknum, ge->curindex.index, ge->expired == 0 ? "none\n" : ctime(&ge->expired));
-  if (!buffindexed_groupstats(group, &lo, &hi, &count, &flags)) {
-    fprintf(stderr, "buffindexed_groupstats failed for group %s\n", group);
-    exit(1);
-  }
-  flag[0] = (char)flags;
-  flag[1] = '\0';
-  fprintf(stdout, "%s: low is %d, high is %d, count is %d, flag is '%s'\n", group, lo, hi, count, flag);
-  if ((search = (OVSEARCH *)ovopensearch(group, lo, hi, true)) == NULL) {
-    fprintf(stderr, "ovopensearch failed for group %s\n", group);
-    exit(1);
-  }
-  fprintf(stdout, "  gloc is %d(0x%08x)\n", search->gloc.recno, search->gloc.recno);
-  for (giblist = Giblist, i = 0 ; giblist != NULL ; giblist = giblist->next, i++);
-  fprintf(stdout, "%d index block(s)\n", i);
-  fprintf(stdout, "%d data block(s)\n", countgdb());
-  for (giblist = Giblist ; giblist != NULL ; giblist = giblist->next) {
-    fprintf(stdout, "  % 8d(% 5d)\n", giblist->ov.blocknum, giblist->ov.index);
-  }
-  for (i = 0 ; i < Gibcount ; i++) {
-    if (Gib[i].artnum == 0)
-      continue;
-    if (Gib[i].index == NULLINDEX)
-      fprintf(stdout, "    %d empty\n");
-    else {
-      fprintf(stdout, "    %d %d\n", Gib[i].offset, Gib[i].len);
-    }
-  }
-  {
-    ARTNUM artnum;
-    char *data;
-    int len;
-    TOKEN token;
-    while (buffindexed_search((void *)search, &artnum, &data, &len, &token, NULL)) {
-      if (len == 0)
-       fprintf(stdout, "%d: len is 0\n", artnum);
-      else {
-       memcpy(buff, data, len);
-       buff[len] = '\0';
-       fprintf(stdout, "%d: %s\n", artnum, buff);
-      }
-    }
-  }
-}
-#endif /* BUFF_DEBUG */
diff --git a/storage/buffindexed/buffindexed.h b/storage/buffindexed/buffindexed.h
deleted file mode 100644 (file)
index 17ab69c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _BUFFINDEXED_H_
-#define _BUFFINDEXED_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-bool buffindexed_open(int mode);
-bool buffindexed_groupstats(char *group, int *lo, int *hi, int *count, int *flag);
-bool buffindexed_groupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag);
-bool buffindexed_groupdel(char *group);
-bool buffindexed_add(char *group, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires);
-bool buffindexed_cancel(TOKEN token);
-void *buffindexed_opensearch(char *group, int low, int high);
-bool buffindexed_search(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived);
-void buffindexed_closesearch(void *handle);
-bool buffindexed_getartinfo(char *group, ARTNUM artnum, TOKEN *token);
-bool buffindexed_expiregroup(char *group, int *lo, struct history *h);
-bool buffindexed_ctl(OVCTLTYPE type, void *val);
-void buffindexed_close(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _BUFFINDEXED_H_ */
diff --git a/storage/buffindexed/ovmethod.config b/storage/buffindexed/ovmethod.config
deleted file mode 100644 (file)
index a26410c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = buffindexed
-number  = 3
-sources = buffindexed.c
diff --git a/storage/buffindexed/ovmethod.mk b/storage/buffindexed/ovmethod.mk
deleted file mode 100644 (file)
index 578c466..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# This rule requires a compiler that supports -o with -c.  Since it's normally
-# used by developers, that should be acceptable.
-buffindexed/buffindexed_d.o: buffindexed/buffindexed.c
-       $(CC) $(CFLAGS) -DBUFF_DEBUG -c -o $@ buffindexed/buffindexed.c
-
-buffindexed/debug: buffindexed/buffindexed_d.o libstorage.$(EXTLIB) $(LIBHIST)
-       $(LIBLD) $(LDFLAGS) -o $@ buffindexed/buffindexed_d.o \
-           $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
diff --git a/storage/buildconfig.in b/storage/buildconfig.in
deleted file mode 100644 (file)
index 22d2188..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-#! /usr/bin/perl
-
-##  $Id: buildconfig.in 6806 2004-05-18 01:18:57Z rra $
-##
-##  Generate linkage code and makefiles for storage and overview methods.
-##
-##  Goes through all subdirectories of the current directory and finds
-##  directories that are either storage methods or overview methods.  Builds
-##  methods.[ch] and ovmethods.[ch] as well as makefile stubs.
-
-require 5.003;
-
-use strict;
-use vars qw(@OVERVIEW @STORAGE);
-
-# Storage API functions.
-@STORAGE = qw(init store retrieve next freearticle cancel ctl flushcacheddata
-              printfiles shutdown);
-
-# Overview API functions.
-@OVERVIEW = qw(open groupstats groupadd groupdel add cancel opensearch search
-               closesearch getartinfo expiregroup ctl close);
-
-# Used to make heredocs more readable.
-sub unquote { my ($string) = @_; $string =~ s/^:( {0,7}|\t)//gm; $string }
-
-# Parse a method.config file for a storage method, putting information about
-# that storage method into the given hash ref.
-sub parse_config {
-    my ($dir, $file, $config) = @_;
-    local $_;
-    $$config{sources} ||= [];
-    $$config{extra} ||= [];
-    $$config{programs} ||= [];
-    $$config{makefiles} ||= [];
-    open (CONFIG, "$dir/$file") or die "Can't open $dir/$file: $!\n";
-    while (<CONFIG>) {
-        s/^\s+//;
-        s/\s+$//;
-        if (/^name\s*=\s*(\S+)$/) {
-            my $method = $1;
-            die "$dir/$file: $method has already been defined\n"
-                if (defined $$config{method}{$method});
-            $$config{method}{$method} = $dir;
-        } elsif (/^number\s*=\s*(\d+)$/) {
-            my $number = $1;
-            if (defined $$config{number}{$number}) {
-                die "$dir/$file: method number $number was already "
-                    . "allocated in $$config{number}{$number}\n";
-            }
-            $$config{number}{$dir} = $number;
-        } elsif (/^sources\s*=\s*(.*)/) {
-            my $sources = $1;
-            my @sources = split (' ', $sources);
-            push (@{ $$config{sources} }, map { "$dir/$_" } @sources);
-        } elsif (/^extra-sources\s*=\s*(.*)/) {
-            my $extra = $1;
-            my @extra = split (' ', $extra);
-            push (@{ $$config{extra} }, map { "$dir/$_" } @extra);
-        } elsif (/^programs\s*=\s*(.*)/) {
-            my $programs = $1;
-            my @programs = split (' ', $programs);
-            push (@{ $$config{programs} }, map { "$dir/$_" } @programs);
-        } else {
-            warn "$dir/$file: ignoring unknown line: $_\n";
-        }
-    }
-
-    # If there is a makefile fragment in the directory, note it.
-    if (-f "$dir/method.mk") {
-        push (@{ $$config{makefiles} }, "$dir/method.mk");
-    } elsif (-f "$dir/ovmethod.mk") {
-        push (@{ $$config{makefiles} }, "$dir/ovmethod.mk");
-    }
-}
-
-# Write out include directives for a list of files.
-sub write_includes {
-    my ($fh, $config) = @_;
-    my $method;
-    for $method (sort keys %{ $$config{method} }) {
-        my $path = $$config{method}{$method};
-        print $fh qq(\#include "$path/$method.h"\n);
-    }
-}
-
-# Write out the method struct.
-sub write_methods {
-    my ($fh, $config, $prefix, @funcs) = @_;
-    my ($notfirst, $method);
-    for $method (sort keys %{ $$config{method} }) {
-        print $fh "\n},\n" if $notfirst;
-        print $fh qq(\{\n    "$method");
-        print $fh ', ', $prefix, '_', uc ($method) if $prefix;
-        for (@funcs) {
-            print $fh ",\n    ${method}_$_";
-        }
-        $notfirst++;
-    }
-    print $fh "\n}\n};\n\n";
-}
-
-# Write out the constant defines for methods.
-sub write_constants {
-    my ($fh, $config, $prefix) = @_;
-    my $method;
-    for $method (sort keys %{ $$config{method} }) {
-        printf $fh "#define ${prefix}_%-30s%d\n", uc ($method),
-            $$config{number}{$$config{method}{$method}};
-    }
-}
-
-# Write out methods.c and methods.h for the interface to the storage
-# methods.
-sub write_storage {
-    my $storage = shift;
-    open (DEF, '> methods.c.new') or die "Can't create methods.c.new: $!\n";
-    print DEF unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig. */
-:
-:       #include "interface.h"
-:       #include "methods.h"
-EOE
-    my $method;
-    write_includes (\*DEF, $storage);
-    print DEF "\nSTORAGE_METHOD storage_methods[",
-        scalar (keys %{ $$storage{method} }), "] = {\n";
-    write_methods (\*DEF, $storage, 'TOKEN', @STORAGE);
-    close DEF;
-    rename ('methods.c.new', 'methods.c');
-
-    open (H, '> methods.h.new') or die "Can't open methods.h.new: $!\n";
-    print H unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig */
-:
-:       #ifndef METHODS_H
-:       #define METHODS_H 1
-:
-:       #include "interface.h"
-:
-EOE
-    print H '#define NUM_STORAGE_METHODS ',
-        scalar (keys %{ $$storage{method} }), "\n\n";
-    write_constants (\*H, $storage, 'TOKEN');
-    print H unquote (<<'EOE');
-:
-:       extern STORAGE_METHOD storage_methods[NUM_STORAGE_METHODS];
-:
-:       #endif /* METHODS_H */
-EOE
-    close H;
-    rename ('methods.h.new', 'methods.h');
-}
-
-# Write out ovmethods.c and ovmethods.h for the interface to the overview
-# methods.
-sub write_overview {
-    my $overview = shift;
-    open (DEF, '> ovmethods.c.new')
-        or die "Can't create ovmethods.c.new: $!\n";
-    print DEF unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig. */
-:
-:       #include "ovinterface.h"
-EOE
-    write_includes (\*DEF, $overview);
-    print DEF "\nOV_METHOD ov_methods[",
-        scalar (keys %{ $$overview{method} }), "] = {\n";
-    write_methods (\*DEF, $overview, undef, @OVERVIEW);
-    close DEF;
-    rename ('ovmethods.c.new', 'ovmethods.c');
-
-    open (H, '> ovmethods.h.new') or die "Can't open ovmethods.h.new: $!\n";
-    print H unquote (<<'EOE');
-:       /* This file is automatically generated by buildconfig */
-:
-:       #ifndef OVMETHODS_H
-:       #define OVMETHODS_H 1
-:
-:       #include "ovinterface.h"
-:
-EOE
-    print H '#define NUM_OV_METHODS ',
-        scalar (keys %{ $$overview{method} }), "\n";
-    print H unquote (<<'EOE');
-:
-:       extern OV_METHOD ov_methods[NUM_OV_METHODS];
-:
-:       #endif /* OVMETHODS_H */
-EOE
-    close H;
-    rename ('ovmethods.h.new', 'ovmethods.h');
-}
-
-# Return a string setting a makefile variable.  Tab over the = properly and
-# wrap to fit our coding standards.
-sub makefile_var {
-    my ($variable, @values) = @_;
-    my $output;
-    $output = sprintf ("%-15s =", $variable);
-    my $column = 17;
-    for (@values) {
-        if ($column > 17 && 77 - $column < length ($_)) {
-            $output .= " \\\n" . ' ' x 17;
-            $column = 17;
-        }
-        $output .= " $_";
-        $column += 1 + length ($_);
-    }
-    $output .= "\n";
-    return $output;
-}
-
-# Write out the makefile fragment for overview and storage methods.
-sub write_makefile {
-    my ($dirs, $sources, $extra, $programs, $makefiles) = @_;
-    open (MAKE, '> Make.methods.new')
-        or die "Can't create Make.methods.new: $!\n";
-    print MAKE "# This file is automatically generated by buildconfig\n\n";
-    print MAKE makefile_var ('METHOD_SOURCES', @$sources);
-    print MAKE makefile_var ('EXTRA_SOURCES', @$extra);
-    print MAKE makefile_var ('PROGRAMS', @$programs);
-    for (@$makefiles) {
-        print MAKE "\n\n##  Included from $_\n\n";
-        open (FRAG, $_) or die "Can't open $_: $!\n";
-        print MAKE <FRAG>;
-        close FRAG;
-    }
-    rename ('Make.methods.new', 'Make.methods');
-}
-
-my ($dir, %storage, %overview);
-if (!-d 'cnfs') {
-    if (-d 'storage/cnfs') {
-        chdir 'storage' or die "Can't chdir to storage: $!\n";
-    } else {
-        die "Can't find storage directory (looking for storage/cnfs)\n";
-    }
-}
-opendir (D, ".") or die "Can't open current directory: $!\n";
-my @dirs = sort readdir D;
-for $dir (@dirs) {
-    if (-e "$dir/method.config") {
-        parse_config ($dir, 'method.config', \%storage);
-    }
-    if (-e "$dir/ovmethod.config") {
-        parse_config ($dir, 'ovmethod.config', \%overview);
-    }
-}
-write_storage (\%storage);
-write_overview (\%overview);
-@dirs = (sort values %{ $storage{method} },
-         sort values %{ $overview{method} });
-my @sources = (sort @{ $storage{sources} }, sort @{ $overview{sources} });
-my @extra = (sort @{ $storage{extra} }, sort @{ $overview{extra} });
-my @programs = sort (@{ $storage{programs} }, @{ $overview{programs} });
-my @makefiles = sort (@{ $storage{makefiles} }, @{ $overview{makefiles} });
-write_makefile (\@dirs, \@sources, \@extra, \@programs, \@makefiles);
diff --git a/storage/cnfs/cnfs-private.h b/storage/cnfs/cnfs-private.h
deleted file mode 100644 (file)
index c899449..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*  $Id: cnfs-private.h 5975 2002-12-11 04:51:43Z rra $
-**
-**  CNFS disk/file mode header file.
-*/
-
-#ifndef        CNFS_PRIVATE_H
-#define CNFS_PRIVATE_H 1
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#define _PATH_CYCBUFFCONFIG    "cycbuff.conf"
-
-/* Page boundary on which to mmap() the CNFS article usage header.  Should be
-   a multiple of the pagesize for all the architectures you expect might need
-   access to your CNFS buffer.  If you don't expect to share your buffer
-   across several platforms, you can use 'pagesize' here. */
-#define        CNFS_HDR_PAGESIZE       16384
-
-#define        CNFS_MAGICV1    "Cycbuff"       /* CNFSMASIZ bytes */
-#define        CNFS_MAGICV2    "CBuf1"         /* CNFSMASIZ bytes */
-#define        CNFS_MAGICV3    "CBuf3"         /* CNFSMASIZ bytes */
-#define        CNFS_BLOCKSIZE  512             /* Unit block size we'll work with */
-
-/* Amount of data stored at beginning of CYCBUFF before the bitfield */
-#define        CNFS_BEFOREBITF (1 * CNFS_BLOCKSIZE)
-
-struct metacycbuff;            /* Definition comes below */
-
-#define        CNFSMAXCYCBUFFNAME      8
-#define        CNFSMASIZ       8
-#define        CNFSNASIZ       16      /* Effective size is 9, not 16 */
-#define        CNFSPASIZ       64
-#define        CNFSLASIZ       16      /* Match length of ASCII hex off_t
-                                  representation */
-
-typedef struct _CYCBUFF {
-  char         name[CNFSNASIZ];/* Symbolic name */
-  char         path[CNFSPASIZ];/* Path to file */
-  off_t         len;           /* Length of writable area, in bytes */
-  off_t         free;          /* Offset (relative to byte 0 of file) to first
-                                  freely available byte */
-  time_t       updated;        /* Time of last update to header */
-  int          fd;             /* file descriptor for this cycbuff */
-  uint32_t     cyclenum;       /* Number of current cycle, 0 = invalid */
-  int          magicver;       /* Magic version number */
-  void *       bitfield;       /* Bitfield for article in use */
-  off_t         minartoffset;  /* The minimum offset allowed for article
-                                  storage */
-  bool         needflush;      /* true if CYCBUFFEXTERN is needed to be
-                                  flushed */
-  struct _CYCBUFF      *next;
-  bool         currentbuff;    /* true if this cycbuff is currently used */
-  char         metaname[CNFSNASIZ];/* Symbolic name of meta */
-  int          order;          /* Order in meta, start from 1 not 0 */
-} CYCBUFF;
-
-/*
-** A structure suitable for thwapping onto disk in a quasi-portable way.
-** We assume that sizeof(CYCBUFFEXTERN) < CNFS_BLOCKSIZE.
-*/
-typedef struct {
-    char       magic[CNFSMASIZ];
-    char       name[CNFSNASIZ];
-    char       path[CNFSPASIZ];
-    char       lena[CNFSLASIZ];        /* ASCII version of len */
-    char       freea[CNFSLASIZ];       /* ASCII version of free */
-    char       updateda[CNFSLASIZ];    /* ASCII version of updated */
-    char       cyclenuma[CNFSLASIZ];   /* ASCII version of cyclenum */
-    char       metaname[CNFSNASIZ];
-    char       orderinmeta[CNFSLASIZ];
-    char       currentbuff[CNFSMASIZ];
-} CYCBUFFEXTERN;
-
-#define METACYCBUFF_UPDATE     25
-#define REFRESH_INTERVAL       30
-
-typedef enum {INTERLEAVE, SEQUENTIAL} METAMODE;
-
-typedef struct metacycbuff {
-  char         *name;          /* Symbolic name of the pool */
-  int          count;          /* Number of files/devs in this pool */
-  CYCBUFF      **members;      /* Member cycbuffs */
-  int          memb_next;      /* Index to next member to write onto */
-  unsigned long        write_count;    /* Number of writes since last header flush */
-  struct metacycbuff   *next;
-  METAMODE     metamode;
-} METACYCBUFF;
-
-typedef struct _CNFSEXPIRERULES {
-  STORAGECLASS         class;
-  METACYCBUFF          *dest;
-  struct _CNFSEXPIRERULES      *next;
-} CNFSEXPIRERULES;
-
-typedef struct {
-  long         size;           /* Size of the article */
-  time_t       arrived;        /* This is the time when article arrived */
-  STORAGECLASS class;          /* storage class */
-} CNFSARTHEADER;
-
-/* uncomment below for old cnfs spool */
-/* #ifdef OLD_CNFS */
-typedef struct {
-  long      zottf;      /* This should always be 0x01234*/
-  long      size;       /* Size of the article */
-  char      m_id[64];   /* We'll only store up to 63 bytes of the
-                              Message-ID, that should be good enough */
-} oldCNFSARTHEADER;
-
-#endif /* !CNFS_PRIVATE_H */
diff --git a/storage/cnfs/cnfs.c b/storage/cnfs/cnfs.c
deleted file mode 100644 (file)
index 66e00a6..0000000
+++ /dev/null
@@ -1,1771 +0,0 @@
-/*  $Id: cnfs.c 7412 2005-10-09 03:44:35Z eagle $
-**
-**  Cyclic News File System.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <netinet/in.h>
-#include <syslog.h> 
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#include "inn/innconf.h"
-#include "interface.h"
-#include "libinn.h"
-#include "methods.h"
-#include "paths.h"
-#include "inn/wire.h"
-#include "inn/mmap.h"
-
-#include "cnfs.h"
-#include "cnfs-private.h"
-
-/* Temporary until cnfs_mapcntl is handled like mapcntl.  Make MS_ASYNC
-   disappear on platforms that don't have it. */
-#ifndef MS_ASYNC
-# define MS_ASYNC 0
-#endif
-
-/* We can give a more descriptive error below about not having largefile           support if the platform has EOVERFLOW; on other platforms some other
- *    errno will be used and so we won't know when to give the descriptive
- *       error.  Oh well. */
-#ifndef EOVERFLOW
-# define EOVERFLOW 0
-#endif
-
-typedef struct {
-    /**** Stuff to be cleaned up when we're done with the article */
-    char               *base;          /* Base of mmap()ed art */
-    int                        len;            /* Length of article (and thus
-                                          mmap()ed art */
-    CYCBUFF            *cycbuff;       /* pointer to current CYCBUFF */
-    off_t               offset;                /* offset to current article */
-    bool               rollover;       /* true if the search is rollovered */
-} PRIV_CNFS;
-
-static char LocalLogName[] = "CNFS-sm";
-static CYCBUFF         *cycbufftab = (CYCBUFF *)NULL;
-static METACYCBUFF     *metacycbufftab = (METACYCBUFF *)NULL;
-static CNFSEXPIRERULES *metaexprulestab = (CNFSEXPIRERULES *)NULL;
-static long            pagesize = 0;
-static int             metabuff_update = METACYCBUFF_UPDATE;
-static int             refresh_interval = REFRESH_INTERVAL;
-
-static TOKEN CNFSMakeToken(char *cycbuffname, off_t offset,
-                      uint32_t cycnum, STORAGECLASS class) {
-    TOKEN               token;
-    int32_t            int32;
-
-    /*
-    ** XXX We'll assume that TOKENSIZE is 16 bytes and that we divvy it
-    ** up as: 8 bytes for cycbuffname, 4 bytes for offset, 4 bytes
-    ** for cycnum.  See also: CNFSBreakToken() for hard-coded constants.
-    */
-    token.type = TOKEN_CNFS;
-    token.class = class;
-    memcpy(token.token, cycbuffname, CNFSMAXCYCBUFFNAME);
-    int32 = htonl(offset / CNFS_BLOCKSIZE);
-    memcpy(&token.token[8], &int32, sizeof(int32));
-    int32 = htonl(cycnum);
-    memcpy(&token.token[12], &int32, sizeof(int32));
-    return token;
-}
-
-/*
-** NOTE: We assume that cycbuffname is 9 bytes long.
-*/
-
-static bool CNFSBreakToken(TOKEN token, char *cycbuffname,
-                          off_t *offset, uint32_t *cycnum) {
-    int32_t    int32;
-
-    if (cycbuffname == NULL || offset == NULL || cycnum == NULL) {
-       syslog(L_ERROR, "%s: BreakToken: invalid argument: %s",
-              LocalLogName, cycbuffname);
-       SMseterror(SMERR_INTERNAL, "BreakToken: invalid argument");
-       return false;
-    }
-    memcpy(cycbuffname, token.token, CNFSMAXCYCBUFFNAME);
-    *(cycbuffname + CNFSMAXCYCBUFFNAME) = '\0';        /* Just to be paranoid */
-    memcpy(&int32, &token.token[8], sizeof(int32));
-    *offset = (off_t)ntohl(int32) * (off_t)CNFS_BLOCKSIZE;
-    memcpy(&int32, &token.token[12], sizeof(int32));
-    *cycnum = ntohl(int32);
-    return true;
-}
-
-static char hextbl[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-                       'a', 'b', 'c', 'd', 'e', 'f'};
-
-/*
-** CNFSofft2hex -- Given an argument of type off_t, return
-**     a static ASCII string representing its value in hexadecimal.
-**
-**     If "leadingzeros" is true, the number returned will have leading 0's.
-*/
-
-static char * CNFSofft2hex(off_t offset, bool leadingzeros) {
-    static char        buf[24];
-    char       *p;
-
-    if (sizeof(off_t) <= 4) {
-       snprintf(buf, sizeof(buf), (leadingzeros) ? "%016lx" : "%lx", offset);
-    } else { 
-       int     i;
-
-       for (i = 0; i < CNFSLASIZ; i++)
-           buf[i] = '0';       /* Pad with zeros to start */
-       for (i = CNFSLASIZ - 1; i >= 0; i--) {
-           buf[i] = hextbl[offset & 0xf];
-           offset >>= 4;
-       }
-    }
-    if (! leadingzeros) {
-       for (p = buf; *p == '0'; p++)
-           ;
-       if (*p != '\0')
-               return p;
-       else
-               return p - 1;   /* We converted a "0" and then bypassed all
-                                  the zeros */
-    } else 
-       return buf;
-}
-
-/*
-** CNFShex2offt -- Given an ASCII string containing a hexadecimal representation
-**     of a off_t, return a off_t.
-*/
-
-static off_t CNFShex2offt(char *hex) {
-    if (sizeof(off_t) <= 4) {
-       unsigned long rpofft;
-       /* I'm lazy */
-       sscanf(hex, "%lx", &rpofft);
-       return rpofft;
-    } else {
-       char            diff;
-       off_t           n = 0;
-
-       for (; *hex != '\0'; hex++) {
-           if (*hex >= '0' && *hex <= '9')
-               diff = '0';
-           else if (*hex >= 'a' && *hex <= 'f')
-               diff = 'a' - 10;
-           else if (*hex >= 'A' && *hex <= 'F')
-               diff = 'A' - 10;
-           else {
-               /*
-               ** We used to have a syslog() message here, but the case
-               ** where we land here because of a ":" happens, er, often.
-               */
-               break;
-           }
-           n += (*hex - diff);
-           if (isalnum((int)*(hex + 1)))
-               n <<= 4;
-       }
-       return n;
-    }
-}
-
-static bool CNFSflushhead(CYCBUFF *cycbuff) {
-  CYCBUFFEXTERN                rpx;
-
-  if (!cycbuff->needflush)
-    return true;
-  if (!SMopenmode) {
-    syslog(L_ERROR, "%s: CNFSflushhead: attempted flush whilst read only",
-      LocalLogName);
-    return false;
-  }
-  memset(&rpx, 0, sizeof(CYCBUFFEXTERN));
-  if (cycbuff->magicver == 3) {
-    cycbuff->updated = time(NULL);
-    strncpy(rpx.magic, CNFS_MAGICV3, strlen(CNFS_MAGICV3));
-    strncpy(rpx.name, cycbuff->name, CNFSNASIZ);
-    strncpy(rpx.path, cycbuff->path, CNFSPASIZ);
-    /* Don't use sprintf() directly ... the terminating '\0' causes grief */
-    strncpy(rpx.lena, CNFSofft2hex(cycbuff->len, true), CNFSLASIZ);
-    strncpy(rpx.freea, CNFSofft2hex(cycbuff->free, true), CNFSLASIZ);
-    strncpy(rpx.cyclenuma, CNFSofft2hex(cycbuff->cyclenum, true), CNFSLASIZ);
-    strncpy(rpx.updateda, CNFSofft2hex(cycbuff->updated, true), CNFSLASIZ);
-    strncpy(rpx.metaname, cycbuff->metaname, CNFSNASIZ);
-    strncpy(rpx.orderinmeta, CNFSofft2hex(cycbuff->order, true), CNFSLASIZ);
-    if (cycbuff->currentbuff) {
-       strncpy(rpx.currentbuff, "TRUE", CNFSMASIZ);
-    } else {
-       strncpy(rpx.currentbuff, "FALSE", CNFSMASIZ);
-    }
-    memcpy(cycbuff->bitfield, &rpx, sizeof(CYCBUFFEXTERN));
-    msync(cycbuff->bitfield, cycbuff->minartoffset, MS_ASYNC);
-    cycbuff->needflush = false;
-  } else {
-    syslog(L_ERROR, "%s: CNFSflushhead: bogus magicver for %s: %d",
-      LocalLogName, cycbuff->name, cycbuff->magicver);
-    return false;
-  }
-  return true;
-}
-
-static void CNFSshutdowncycbuff(CYCBUFF *cycbuff) {
-    if (cycbuff == (CYCBUFF *)NULL)
-       return;
-    if (cycbuff->needflush) {
-       syslog(L_NOTICE, "%s: CNFSshutdowncycbuff: flushing %s", LocalLogName, cycbuff->name);
-       CNFSflushhead(cycbuff);
-    }
-    if (cycbuff->bitfield != NULL) {
-       munmap(cycbuff->bitfield, cycbuff->minartoffset);
-       cycbuff->bitfield = NULL;
-    }
-    if (cycbuff->fd >= 0)
-       close(cycbuff->fd);
-    cycbuff->fd = -1;
-}
-
-static void CNFScleancycbuff(void) {
-    CYCBUFF    *cycbuff, *nextcycbuff;
-
-    for (cycbuff = cycbufftab; cycbuff != (CYCBUFF *)NULL;) {
-      CNFSshutdowncycbuff(cycbuff);
-      nextcycbuff = cycbuff->next;
-      free(cycbuff);
-      cycbuff = nextcycbuff;
-    }
-    cycbufftab = (CYCBUFF *)NULL;
-}
-
-static void CNFScleanmetacycbuff(void) {
-    METACYCBUFF        *metacycbuff, *nextmetacycbuff;
-
-    for (metacycbuff = metacycbufftab; metacycbuff != (METACYCBUFF *)NULL;) {
-      nextmetacycbuff = metacycbuff->next;
-      free(metacycbuff->members);
-      free(metacycbuff->name);
-      free(metacycbuff);
-      metacycbuff = nextmetacycbuff;
-    }
-    metacycbufftab = (METACYCBUFF *)NULL;
-}
-
-static void CNFScleanexpirerule(void) {
-    CNFSEXPIRERULES    *metaexprule, *nextmetaexprule;
-
-    for (metaexprule = metaexprulestab; metaexprule != (CNFSEXPIRERULES *)NULL;) {
-      nextmetaexprule = metaexprule->next;
-      free(metaexprule);
-      metaexprule = nextmetaexprule;
-    }
-    metaexprulestab = (CNFSEXPIRERULES *)NULL;
-}
-
-static CYCBUFF *CNFSgetcycbuffbyname(char *name) {
-    CYCBUFF    *cycbuff;
-    if (name == NULL)
-       return NULL;
-    for (cycbuff = cycbufftab; cycbuff != (CYCBUFF *)NULL; cycbuff = cycbuff->next)
-       if (strcmp(name, cycbuff->name) == 0) 
-           return cycbuff;
-    return NULL;
-}
-
-static METACYCBUFF *CNFSgetmetacycbuffbyname(char *name) {
-  METACYCBUFF  *metacycbuff;
-
-  if (name == NULL)
-    return NULL;
-  for (metacycbuff = metacycbufftab; metacycbuff != (METACYCBUFF *)NULL; metacycbuff = metacycbuff->next)
-    if (strcmp(name, metacycbuff->name) == 0) 
-      return metacycbuff;
-  return NULL;
-}
-
-static void CNFSflushallheads(void) {
-  CYCBUFF      *cycbuff;
-
-  for (cycbuff = cycbufftab; cycbuff != (CYCBUFF *)NULL; cycbuff = cycbuff->next) {
-    if (cycbuff->needflush)
-       syslog(L_NOTICE, "%s: CNFSflushallheads: flushing %s", LocalLogName, cycbuff->name);
-    CNFSflushhead(cycbuff);
-  }
-}
-
-/*
-** CNFSReadFreeAndCycle() -- Read from disk the current values of CYCBUFF's
-**     free pointer and cycle number.  Return 1 on success, 0 otherwise.
-*/
-
-static void CNFSReadFreeAndCycle(CYCBUFF *cycbuff) {
-    CYCBUFFEXTERN      rpx;
-    char               buf[64];
-
-    memcpy(&rpx, cycbuff->bitfield, sizeof(CYCBUFFEXTERN));
-    /* Sanity checks are not needed since CNFSinit_disks() has already done. */
-    strncpy(buf, rpx.freea, CNFSLASIZ);
-    buf[CNFSLASIZ] = '\0';
-    cycbuff->free = CNFShex2offt(buf);
-    strncpy(buf, rpx.updateda, CNFSLASIZ);
-    buf[CNFSLASIZ] = '\0';
-    cycbuff->updated = CNFShex2offt(buf);
-    strncpy(buf, rpx.cyclenuma, CNFSLASIZ);
-    buf[CNFSLASIZ] = '\0';
-    cycbuff->cyclenum = CNFShex2offt(buf);
-    return;
-}
-
-static bool CNFSparse_part_line(char *l) {
-  char         *p;
-  struct stat  sb;
-  off_t         len, minartoffset;
-  int          tonextblock;
-  CYCBUFF      *cycbuff, *tmp;
-
-  /* Symbolic cnfs partition name */
-  if ((p = strchr(l, ':')) == NULL || p - l <= 0 || p - l > CNFSMAXCYCBUFFNAME - 1) {
-    syslog(L_ERROR, "%s: bad cycbuff name in line '%s'", LocalLogName, l);
-    return false;
-  }
-  *p = '\0';
-  if (CNFSgetcycbuffbyname(l) != NULL) {
-    *p = ':';
-    syslog(L_ERROR, "%s: duplicate cycbuff name in line '%s'", LocalLogName, l);
-    return false;
-  }
-  cycbuff = xmalloc(sizeof(CYCBUFF));
-  memset(cycbuff->name, '\0', CNFSNASIZ);
-  strlcpy(cycbuff->name, l, CNFSNASIZ);
-  l = ++p;
-
-  /* Path to cnfs partition */
-  if ((p = strchr(l, ':')) == NULL || p - l <= 0 || p - l > CNFSPASIZ - 1) {
-    syslog(L_ERROR, "%s: bad pathname in line '%s'", LocalLogName, l);
-    free(cycbuff);
-    return false;
-  }
-  *p = '\0';
-  memset(cycbuff->path, '\0', CNFSPASIZ);
-  strlcpy(cycbuff->path, l, CNFSPASIZ);
-  if (stat(cycbuff->path, &sb) < 0) {
-    if (errno == EOVERFLOW) {
-      syslog(L_ERROR, "%s: file '%s' : %s, ignoring '%s' cycbuff",
-            LocalLogName, cycbuff->path,
-            "Overflow (probably >2GB without largefile support)",
-            cycbuff->name);
-    } else {
-      syslog(L_ERROR, "%s: file '%s' : %m, ignoring '%s' cycbuff",
-            LocalLogName, cycbuff->path, cycbuff->name);
-    }
-    free(cycbuff);
-    return false;
-  }
-  l = ++p;
-
-  /* Length/size of symbolic partition */
-  len = strtoul(l, NULL, 10) * (off_t)1024;    /* This value in KB in decimal */
-  if (S_ISREG(sb.st_mode) && len != sb.st_size) {
-    if (sizeof(CYCBUFFEXTERN) > (size_t) sb.st_size) {
-      syslog(L_NOTICE, "%s: length must be at least '%lu' for '%s' cycbuff(%lu bytes)",
-       LocalLogName, (unsigned long) sizeof(CYCBUFFEXTERN), cycbuff->name,
-        (unsigned long) sb.st_size);
-      free(cycbuff);
-      return false;
-    }
-  }
-  cycbuff->len = len;
-  cycbuff->fd = -1;
-  cycbuff->next = (CYCBUFF *)NULL;
-  cycbuff->needflush = false;
-  cycbuff->bitfield = NULL;
-  /*
-  ** The minimum article offset will be the size of the bitfield itself,
-  ** len / (blocksize * 8), plus however many additional blocks the CYCBUFF
-  ** external header occupies ... then round up to the next block.
-  */
-  minartoffset =
-      cycbuff->len / (CNFS_BLOCKSIZE * 8) + CNFS_BEFOREBITF;
-  tonextblock = CNFS_HDR_PAGESIZE - (minartoffset & (CNFS_HDR_PAGESIZE - 1));
-  cycbuff->minartoffset = minartoffset + tonextblock;
-
-  if (cycbufftab == (CYCBUFF *)NULL)
-    cycbufftab = cycbuff;
-  else {
-    for (tmp = cycbufftab; tmp->next != (CYCBUFF *)NULL; tmp = tmp->next);
-    tmp->next = cycbuff;
-  }
-  /* Done! */
-  return true;
-}
-
-static bool CNFSparse_metapart_line(char *l) {
-  char         *p, *cycbuff, *q = l;
-  CYCBUFF      *rp;
-  METACYCBUFF  *metacycbuff, *tmp;
-
-  /* Symbolic metacycbuff name */
-  if ((p = strchr(l, ':')) == NULL || p - l <= 0) {
-    syslog(L_ERROR, "%s: bad partition name in line '%s'", LocalLogName, l);
-    return false;
-  }
-  *p = '\0';
-  if (CNFSgetmetacycbuffbyname(l) != NULL) {
-    *p = ':';
-    syslog(L_ERROR, "%s: duplicate metabuff name in line '%s'", LocalLogName, l);
-    return false;
-  }
-  metacycbuff = xmalloc(sizeof(METACYCBUFF));
-  metacycbuff->members = (CYCBUFF **)NULL;
-  metacycbuff->count = 0;
-  metacycbuff->name = xstrdup(l);
-  metacycbuff->next = (METACYCBUFF *)NULL;
-  metacycbuff->metamode = INTERLEAVE;
-  l = ++p;
-
-  if ((p = strchr(l, ':')) != NULL) {
-      if (p - l <= 0) {
-       syslog(L_ERROR, "%s: bad mode in line '%s'", LocalLogName, q);
-       return false;
-      }
-      if (strcmp(++p, "INTERLEAVE") == 0)
-       metacycbuff->metamode = INTERLEAVE;
-      else if (strcmp(p, "SEQUENTIAL") == 0)
-       metacycbuff->metamode = SEQUENTIAL;
-      else {
-       syslog(L_ERROR, "%s: unknown mode in line '%s'", LocalLogName, q);
-       return false;
-      }
-      *--p = '\0';
-  }
-  /* Cycbuff list */
-  while ((p = strchr(l, ',')) != NULL && p - l > 0) {
-    *p = '\0';
-    cycbuff = l;
-    l = ++p;
-    if ((rp = CNFSgetcycbuffbyname(cycbuff)) == NULL) {
-      syslog(L_ERROR, "%s: bogus cycbuff '%s' (metacycbuff '%s')",
-            LocalLogName, cycbuff, metacycbuff->name);
-      free(metacycbuff->members);
-      free(metacycbuff->name);
-      free(metacycbuff);
-      return false;
-    }
-    if (metacycbuff->count == 0)
-      metacycbuff->members = xmalloc(sizeof(CYCBUFF *));
-    else
-      metacycbuff->members = xrealloc(metacycbuff->members, (metacycbuff->count + 1) * sizeof(CYCBUFF *));
-    metacycbuff->members[metacycbuff->count++] = rp;
-  }
-  /* Gotta deal with the last cycbuff on the list */
-  cycbuff = l;
-  if ((rp = CNFSgetcycbuffbyname(cycbuff)) == NULL) {
-    syslog(L_ERROR, "%s: bogus cycbuff '%s' (metacycbuff '%s')",
-          LocalLogName, cycbuff, metacycbuff->name);
-    free(metacycbuff->members);
-    free(metacycbuff->name);
-    free(metacycbuff);
-    return false;
-  } else {
-    if (metacycbuff->count == 0)
-      metacycbuff->members = xmalloc(sizeof(CYCBUFF *));
-    else
-      metacycbuff->members = xrealloc(metacycbuff->members, (metacycbuff->count + 1) * sizeof(CYCBUFF *));
-    metacycbuff->members[metacycbuff->count++] = rp;
-  }
-  
-  if (metacycbuff->count == 0) {
-    syslog(L_ERROR, "%s: no cycbuffs assigned to cycbuff '%s'",
-          LocalLogName, metacycbuff->name);
-    free(metacycbuff->name);
-    free(metacycbuff);
-    return false;
-  }
-  if (metacycbufftab == (METACYCBUFF *)NULL)
-    metacycbufftab = metacycbuff;
-  else {
-    for (tmp = metacycbufftab; tmp->next != (METACYCBUFF *)NULL; tmp = tmp->next);
-    tmp->next = metacycbuff;
-  }
-  /* DONE! */
-  return true;
-}
-
-static bool CNFSparse_groups_line(void) {
-  METACYCBUFF  *mrp;
-  STORAGE_SUB  *sub = (STORAGE_SUB *)NULL;
-  CNFSEXPIRERULES      *metaexprule, *tmp;
-
-  sub = SMGetConfig(TOKEN_CNFS, sub);
-  for (;sub != (STORAGE_SUB *)NULL; sub = SMGetConfig(TOKEN_CNFS, sub)) {
-    if (sub->options == (char *)NULL) {
-      syslog(L_ERROR, "%s: storage.conf options field is missing",
-          LocalLogName);
-      CNFScleanexpirerule();
-      return false;
-    }
-    if ((mrp = CNFSgetmetacycbuffbyname(sub->options)) == NULL) {
-      syslog(L_ERROR, "%s: storage.conf options field '%s' undefined",
-          LocalLogName, sub->options);
-      CNFScleanexpirerule();
-      return false;
-    }
-    metaexprule = xmalloc(sizeof(CNFSEXPIRERULES));
-    metaexprule->class = sub->class;
-    metaexprule->dest = mrp;
-    metaexprule->next = (CNFSEXPIRERULES *)NULL;
-    if (metaexprulestab == (CNFSEXPIRERULES *)NULL)
-      metaexprulestab = metaexprule;
-    else {
-      for (tmp = metaexprulestab; tmp->next != (CNFSEXPIRERULES *)NULL; tmp = tmp->next);
-      tmp->next = metaexprule;
-    }
-  }
-  /* DONE! */
-  return true;
-}
-
-/*
-** CNFSinit_disks -- Finish initializing cycbufftab
-**     Called by "innd" only -- we open (and keep) a read/write
-**     file descriptor for each CYCBUFF.
-**
-** Calling this function repeatedly shouldn't cause any harm
-** speed-wise or bug-wise, as long as the caller is accessing the
-** CYCBUFFs _read-only_.  If innd calls this function repeatedly,
-** bad things will happen.
-*/
-
-static bool CNFSinit_disks(CYCBUFF *cycbuff) {
-  char         buf[64];
-  CYCBUFFEXTERN        *rpx;
-  int          fd;
-  off_t         tmpo;
-  bool         oneshot;
-
-  /*
-  ** Discover the state of our cycbuffs.  If any of them are in icky shape,
-  ** duck shamelessly & return false.
-  */
-
-  if (cycbuff != (CYCBUFF *)NULL)
-    oneshot = true;
-  else {
-    oneshot = false;
-    cycbuff = cycbufftab;
-  }
-  for (; cycbuff != (CYCBUFF *)NULL; cycbuff = cycbuff->next) {
-    if (strcmp(cycbuff->path, "/dev/null") == 0) {
-       syslog(L_ERROR, "%s: ERROR opening '%s' is not available",
-               LocalLogName, cycbuff->path);
-       return false;
-    }
-    if (cycbuff->fd < 0) {
-       if ((fd = open(cycbuff->path, SMopenmode ? O_RDWR : O_RDONLY)) < 0) {
-           syslog(L_ERROR, "%s: ERROR opening '%s' O_RDONLY : %m",
-                  LocalLogName, cycbuff->path);
-           return false;
-       } else {
-           close_on_exec(fd, true);
-           cycbuff->fd = fd;
-       }
-    }
-    errno = 0;
-    cycbuff->bitfield = mmap(NULL, cycbuff->minartoffset,
-                            SMopenmode ? (PROT_READ | PROT_WRITE) : PROT_READ,
-                            MAP_SHARED, cycbuff->fd, 0);
-    if (cycbuff->bitfield == MAP_FAILED || errno != 0) {
-       syslog(L_ERROR,
-              "%s: CNFSinitdisks: mmap for %s offset %d len %ld failed: %m",
-              LocalLogName, cycbuff->path, 0, (long) cycbuff->minartoffset);
-       cycbuff->bitfield = NULL;
-       return false;
-    }
-
-    /*
-    ** Much of this checking from previous revisions is (probably) bogus
-    ** & buggy & particularly icky & unupdated.  Use at your own risk.  :-)
-    */
-    rpx = (CYCBUFFEXTERN *)cycbuff->bitfield;
-    if (strncmp(rpx->magic, CNFS_MAGICV3, strlen(CNFS_MAGICV3)) == 0) {
-       cycbuff->magicver = 3;
-       if (strncmp(rpx->name, cycbuff->name, CNFSNASIZ) != 0) {
-           syslog(L_ERROR, "%s: Mismatch 3: read %s for cycbuff %s", LocalLogName,
-                  rpx->name, cycbuff->name);
-           return false;
-       }
-       if (strncmp(rpx->path, cycbuff->path, CNFSPASIZ) != 0) {
-           syslog(L_ERROR, "%s: Path mismatch: read %s for cycbuff %s",
-                  LocalLogName, rpx->path, cycbuff->path);
-       } 
-       strncpy(buf, rpx->lena, CNFSLASIZ);
-        buf[CNFSLASIZ] = '\0';
-       tmpo = CNFShex2offt(buf);
-       if (tmpo != cycbuff->len) {
-           syslog(L_ERROR, "%s: Mismatch: read 0x%s length for cycbuff %s",
-                  LocalLogName, CNFSofft2hex(tmpo, false), cycbuff->path);
-           return false;
-       }
-       strncpy(buf, rpx->freea, CNFSLASIZ);
-        buf[CNFSLASIZ] = '\0';
-       cycbuff->free = CNFShex2offt(buf);
-       strncpy(buf, rpx->updateda, CNFSLASIZ);
-        buf[CNFSLASIZ] = '\0';
-       cycbuff->updated = CNFShex2offt(buf);
-       strncpy(buf, rpx->cyclenuma, CNFSLASIZ);
-        buf[CNFSLASIZ] = '\0';
-       cycbuff->cyclenum = CNFShex2offt(buf);
-       strncpy(cycbuff->metaname, rpx->metaname, CNFSLASIZ);
-       strncpy(buf, rpx->orderinmeta, CNFSLASIZ);
-       cycbuff->order = CNFShex2offt(buf);
-       if (strncmp(rpx->currentbuff, "TRUE", CNFSMASIZ) == 0) {
-           cycbuff->currentbuff = true;
-       } else
-           cycbuff->currentbuff = false;
-    } else {
-       syslog(L_NOTICE,
-               "%s: No magic cookie found for cycbuff %s, initializing",
-               LocalLogName, cycbuff->name);
-       cycbuff->magicver = 3;
-       cycbuff->free = cycbuff->minartoffset;
-       cycbuff->updated = 0;
-       cycbuff->cyclenum = 1;
-       cycbuff->currentbuff = true;
-       cycbuff->order = 0;     /* to indicate this is newly added cycbuff */
-       cycbuff->needflush = true;
-       memset(cycbuff->metaname, '\0', CNFSLASIZ);
-       if (!CNFSflushhead(cycbuff))
-           return false;
-    }
-    if (oneshot)
-      break;
-  }
-  return true;
-}
-
-static bool CNFS_setcurrent(METACYCBUFF *metacycbuff) {
-  CYCBUFF      *cycbuff;
-  int          i, currentcycbuff = 0, order = -1;
-  bool         foundcurrent = false;
-  for (i = 0 ; i < metacycbuff->count ; i++) {
-    cycbuff = metacycbuff->members[i];
-    if (strncmp(cycbuff->metaname, metacycbuff->name, CNFSNASIZ) != 0) {
-      /* this cycbuff is moved from other metacycbuff , or is new */
-      cycbuff->order = i + 1;
-      cycbuff->currentbuff = false;
-      strncpy(cycbuff->metaname, metacycbuff->name, CNFSLASIZ);
-      cycbuff->needflush = true;
-      continue;
-    }
-    if (foundcurrent == false && cycbuff->currentbuff == true) {
-      currentcycbuff = i;
-      foundcurrent = true;
-    }
-    if (foundcurrent == false || order == -1 || order > cycbuff->order) {
-      /* this cycbuff is a candidate for current cycbuff */
-      currentcycbuff = i;
-      order = cycbuff->order;
-    }
-    if (cycbuff->order != i + 1) {
-      /* cycbuff order seems to be changed */
-      cycbuff->order = i + 1;
-      cycbuff->needflush = true;
-    }
-  }
-  /* If no current cycbuff found (say, all our cycbuffs are new) default to 0 */
-  if (foundcurrent == false) {
-    currentcycbuff = 0;
-  }
-  for (i = 0 ; i < metacycbuff->count ; i++) {
-    cycbuff = metacycbuff->members[i];
-    if (currentcycbuff == i && cycbuff->currentbuff == false) {
-      cycbuff->currentbuff = true;
-      cycbuff->needflush = true;
-    }
-    if (currentcycbuff != i && cycbuff->currentbuff == true) {
-      cycbuff->currentbuff = false;
-      cycbuff->needflush = true;
-    }
-    if (cycbuff->needflush == true && !CNFSflushhead(cycbuff))
-       return false;
-  }
-  metacycbuff->memb_next = currentcycbuff;
-  return true;
-}
-
-/*
-** CNFSread_config() -- Read the cnfs partition/file configuration file.
-**
-** Oh, for the want of Perl!  My parser probably shows that I don't use
-** C all that often anymore....
-*/
-
-static bool CNFSread_config(void) {
-    char       *path, *config, *from, *to, **ctab = (char **)NULL;
-    int                ctab_free = 0;  /* Index to next free slot in ctab */
-    int                ctab_i;
-    bool       metacycbufffound = false;
-    bool       cycbuffupdatefound = false;
-    bool       refreshintervalfound = false;
-    int                update, refresh;
-
-    path = concatpath(innconf->pathetc, _PATH_CYCBUFFCONFIG);
-    config = ReadInFile(path, NULL);
-    if (config == NULL) {
-       syslog(L_ERROR, "%s: cannot read %s", LocalLogName, path);
-       free(config);
-        free(path);
-       return false;
-    }
-    free(path);
-    for (from = to = config; *from; ) {
-       if (*from == '#') {     /* Comment line? */
-           while (*from && *from != '\n')
-               from++;                         /* Skip past it */
-           from++;
-           continue;                           /* Back to top of loop */
-       }
-       if (*from == '\n') {    /* End or just a blank line? */
-           from++;
-           continue;                           /* Back to top of loop */
-       }
-       if (ctab_free == 0)
-          ctab = xmalloc(sizeof(char *));
-       else
-          ctab = xrealloc(ctab, (ctab_free + 1) * sizeof(char *));
-       /* If we're here, we've got the beginning of a real entry */
-       ctab[ctab_free++] = to = from;
-       while (1) {
-           if (*from && *from == '\\' && *(from + 1) == '\n') {
-               from += 2;              /* Skip past backslash+newline */
-               while (*from && isspace((int)*from))
-                   from++;
-               continue;
-           }
-           if (*from && *from != '\n')
-               *to++ = *from++;
-           if (*from == '\n') {
-               *to++ = '\0';
-               from++;
-               break;
-           }
-           if (! *from)
-               break;
-       }
-    }
-
-    for (ctab_i = 0; ctab_i < ctab_free; ctab_i++) {
-       if (strncmp(ctab[ctab_i], "cycbuff:", 8) == 0) {
-           if (metacycbufffound) {
-               syslog(L_ERROR, "%s: all cycbuff entries shoud be before metacycbuff entries", LocalLogName);
-               free(config);
-               free(ctab);
-               return false;
-           }
-           if (!CNFSparse_part_line(ctab[ctab_i] + 8)) {
-               free(config);
-               free(ctab);
-               return false;
-           }
-       } else if (strncmp(ctab[ctab_i], "metacycbuff:", 12) == 0) {
-           metacycbufffound = true;
-           if (!CNFSparse_metapart_line(ctab[ctab_i] + 12)) {
-               free(config);
-               free(ctab);
-               return false;
-           }
-       } else if (strncmp(ctab[ctab_i], "cycbuffupdate:", 14) == 0) {
-           if (cycbuffupdatefound) {
-               syslog(L_ERROR, "%s: duplicate cycbuffupdate entries", LocalLogName);
-               free(config);
-               free(ctab);
-               return false;
-           }
-           cycbuffupdatefound = true;
-           update = atoi(ctab[ctab_i] + 14);
-           if (update < 0) {
-               syslog(L_ERROR, "%s: invalid cycbuffupdate", LocalLogName);
-               free(config);
-               free(ctab);
-               return false;
-           }
-           if (update == 0)
-               metabuff_update = METACYCBUFF_UPDATE;
-           else
-               metabuff_update = update;
-       } else if (strncmp(ctab[ctab_i], "refreshinterval:", 16) == 0) {
-           if (refreshintervalfound) {
-               syslog(L_ERROR, "%s: duplicate refreshinterval entries", LocalLogName);
-               free(config);
-               free(ctab);
-               return false;
-           }
-           refreshintervalfound = true;
-           refresh = atoi(ctab[ctab_i] + 16);
-           if (refresh < 0) {
-               syslog(L_ERROR, "%s: invalid refreshinterval", LocalLogName);
-               free(config);
-               free(ctab);
-               return false;
-           }
-           if (refresh == 0)
-               refresh_interval = REFRESH_INTERVAL;
-           else
-               refresh_interval = refresh;
-       } else {
-           syslog(L_ERROR, "%s: Bogus metacycbuff config line '%s' ignored",
-                  LocalLogName, ctab[ctab_i]);
-       }
-    }
-    free(config);
-    free(ctab);
-    if (!CNFSparse_groups_line()) {
-       return false;
-    }
-    if (cycbufftab == (CYCBUFF *)NULL) {
-       syslog(L_ERROR, "%s: zero cycbuffs defined", LocalLogName);
-       return false;
-    }
-    if (metacycbufftab == (METACYCBUFF *)NULL) {
-       syslog(L_ERROR, "%s: zero metacycbuffs defined", LocalLogName);
-       return false;
-    }
-    return true;
-}
-
-/* Figure out what page an address is in and flush those pages */
-static void
-cnfs_mapcntl(void *p, size_t length, int flags)
-{
-    char *start, *end;
-
-    start = (char *)((size_t)p & ~(size_t)(pagesize - 1));
-    end = (char *)((size_t)((char *)p + length + pagesize) &
-                  ~(size_t)(pagesize - 1));
-    if (flags == MS_INVALIDATE) {
-       msync(start, end - start, flags);
-    } else {
-       static char *sstart, *send;
-
-       /* Don't thrash the system with msync()s - keep the last value
-        * and check each time, only if the pages which we should
-        * flush change actually flush the previous ones. Calling
-        * cnfs_mapcntl(NULL, 0, MS_ASYNC) then flushes the final
-        * piece */
-       if (start != sstart || end != send) {
-           if (sstart != NULL && send != NULL) {
-               msync(sstart, send - sstart, flags);
-           }
-           sstart = start;
-           send = send;
-       }
-    }
-}
-
-/*
-**     Bit arithmetic by brute force.
-**
-**     XXXYYYXXX WARNING: the code below is not endian-neutral!
-*/
-
-typedef unsigned long  ULONG;
-
-static int CNFSUsedBlock(CYCBUFF *cycbuff, off_t offset,
-             bool set_operation, bool setbitvalue) {
-    off_t               blocknum;
-    off_t               longoffset;
-    int                        bitoffset;      /* From the 'left' side of the long */
-    static int         uninitialized = 1;
-    static int         longsize = sizeof(long);
-    int        i;
-    ULONG              bitlong, on, off, mask;
-    static ULONG       onarray[64], offarray[64];
-    ULONG              *where;
-
-    if (uninitialized) {
-       on = 1;
-       off = on;
-       off ^= ULONG_MAX;
-       for (i = (longsize * 8) - 1; i >= 0; i--) {
-           onarray[i] = on;
-           offarray[i] = off;
-           on <<= 1;
-           off = on;
-           off ^= ULONG_MAX;
-       }
-       uninitialized = 0;
-    }
-
-    /* We allow bit-setting under minartoffset, but it better be false */
-    if ((offset < cycbuff->minartoffset && setbitvalue) ||
-       offset > cycbuff->len) {
-       char    bufoff[64], bufmin[64], bufmax[64];
-       SMseterror(SMERR_INTERNAL, NULL);
-       strlcpy(bufoff, CNFSofft2hex(offset, false), sizeof(bufoff));
-       strlcpy(bufmin, CNFSofft2hex(cycbuff->minartoffset, false),
-                sizeof(bufmin));
-       strlcpy(bufmax, CNFSofft2hex(cycbuff->len, false), sizeof(bufmax));
-       syslog(L_ERROR,
-              "%s: CNFSUsedBlock: invalid offset %s, min = %s, max = %s",
-              LocalLogName, bufoff, bufmin, bufmax);
-       return 0;
-    }
-    if (offset % CNFS_BLOCKSIZE != 0) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       syslog(L_ERROR,
-              "%s: CNFSsetusedbitbyrp: offset %s not on %d-byte block boundary",
-              LocalLogName, CNFSofft2hex(offset, false), CNFS_BLOCKSIZE);
-       return 0;
-    }
-    blocknum = offset / CNFS_BLOCKSIZE;
-    longoffset = blocknum / (longsize * 8);
-    bitoffset = blocknum % (longsize * 8);
-    where = (ULONG *)cycbuff->bitfield + (CNFS_BEFOREBITF / longsize)
-       + longoffset;
-    bitlong = *where;
-    if (set_operation) {
-       if (setbitvalue) {
-           mask = onarray[bitoffset];
-           bitlong |= mask;
-       } else {
-           mask = offarray[bitoffset];
-           bitlong &= mask;
-       }
-       *where = bitlong;
-       if (innconf->nfswriter) {
-           cnfs_mapcntl(where, sizeof *where, MS_ASYNC);
-       }
-       return 2;       /* XXX Clean up return semantics */
-    }
-    /* It's a read operation */
-    mask = onarray[bitoffset];
-
-/* 
- * return bitlong & mask; doesn't work if sizeof(ulong) > sizeof(int)
- */
-    if ( bitlong & mask ) return 1; else return 0;
-
-}
-
-static int CNFSArtMayBeHere(CYCBUFF *cycbuff, off_t offset, uint32_t cycnum) {
-    static time_t       lastupdate = 0;
-    CYCBUFF            *tmp;
-
-    if (SMpreopen && !SMopenmode) {
-       if ((time(NULL) - lastupdate) > refresh_interval) {     /* XXX Changed to refresh every 30sec - cmo*/
-           for (tmp = cycbufftab; tmp != (CYCBUFF *)NULL; tmp = tmp->next) {
-               CNFSReadFreeAndCycle(tmp);
-           }
-           lastupdate = time(NULL);
-       } else if (cycnum == cycbuff->cyclenum + 1) {   /* rollover ? */
-           CNFSReadFreeAndCycle(cycbuff);
-       }
-    }
-    /*
-    ** The current cycle number may have advanced since the last time we
-    ** checked it, so use a ">=" check instead of "==".  Our intent is
-    ** avoid a false negative response, *not* a false positive response.
-    */
-    if (! (cycnum == cycbuff->cyclenum ||
-       (cycnum == cycbuff->cyclenum - 1 && offset > cycbuff->free) ||
-       (cycnum + 1 == 0 && cycbuff->cyclenum == 2 && offset > cycbuff->free))) {
-       /* We've been overwritten */
-       return 0;
-    }
-    return CNFSUsedBlock(cycbuff, offset, false, false);
-}
-
-bool cnfs_init(SMATTRIBUTE *attr) {
-    METACYCBUFF        *metacycbuff;
-    CYCBUFF    *cycbuff;
-
-    if (attr == NULL) {
-       syslog(L_ERROR, "%s: attr is NULL", LocalLogName);
-       SMseterror(SMERR_INTERNAL, "attr is NULL");
-       return false;
-    }
-    attr->selfexpire = true;
-    attr->expensivestat = false;
-    if (innconf == NULL) {
-        if (!innconf_read(NULL)) {
-           syslog(L_ERROR, "%s: innconf_read failed", LocalLogName);
-           SMseterror(SMERR_INTERNAL, "ReadInnConf() failed");
-           return false;
-       }
-    }
-    if (pagesize == 0) {
-        pagesize = getpagesize();
-        if (pagesize == -1) {
-            syslog(L_ERROR, "%s: getpagesize failed: %m", LocalLogName);
-            SMseterror(SMERR_INTERNAL, "getpagesize failed");
-            pagesize = 0;
-            return false;
-        }
-       if ((pagesize > CNFS_HDR_PAGESIZE) || (CNFS_HDR_PAGESIZE % pagesize)) {
-           syslog(L_ERROR, "%s: CNFS_HDR_PAGESIZE (%d) is not a multiple of pagesize (%ld)", LocalLogName, CNFS_HDR_PAGESIZE, pagesize);
-           SMseterror(SMERR_INTERNAL, "CNFS_HDR_PAGESIZE not multiple of pagesize");
-           return false;
-       }
-    }
-    if (STORAGE_TOKEN_LENGTH < 16) {
-       syslog(L_ERROR, "%s: token length is less than 16 bytes", LocalLogName);
-       SMseterror(SMERR_TOKENSHORT, NULL);
-       return false;
-    }
-
-    if (!CNFSread_config()) {
-       CNFScleancycbuff();
-       CNFScleanmetacycbuff();
-       CNFScleanexpirerule();
-       SMseterror(SMERR_INTERNAL, NULL);
-       return false;
-    }
-    if (!CNFSinit_disks(NULL)) {
-       CNFScleancycbuff();
-       CNFScleanmetacycbuff();
-       CNFScleanexpirerule();
-       SMseterror(SMERR_INTERNAL, NULL);
-       return false;
-    }
-    for (metacycbuff = metacycbufftab; metacycbuff != (METACYCBUFF *)NULL; metacycbuff = metacycbuff->next) {
-      metacycbuff->memb_next = 0;
-      metacycbuff->write_count = 0;            /* Let's not forget this */
-      if (metacycbuff->metamode == SEQUENTIAL)
-       /* mark current cycbuff */
-       if (CNFS_setcurrent(metacycbuff) == false) {
-         CNFScleancycbuff();
-         CNFScleanmetacycbuff();
-         CNFScleanexpirerule();
-         SMseterror(SMERR_INTERNAL, NULL);
-         return false;
-       }
-    }
-    if (!SMpreopen) {
-      for (cycbuff = cycbufftab; cycbuff != (CYCBUFF *)NULL; cycbuff = cycbuff->next) {
-       CNFSshutdowncycbuff(cycbuff);
-      }
-    }
-    return true;
-}
-
-TOKEN cnfs_store(const ARTHANDLE article, const STORAGECLASS class) {
-    TOKEN               token;
-    CYCBUFF            *cycbuff = NULL;
-    METACYCBUFF                *metacycbuff = NULL;
-    int                        i;
-    static char                buf[1024];
-    static char                alignbuf[CNFS_BLOCKSIZE];
-    char               *artcycbuffname;
-    off_t               artoffset, middle;
-    uint32_t           artcyclenum;
-    CNFSARTHEADER      cah;
-    static struct iovec        *iov;
-    static int         iovcnt;
-    int                        tonextblock;
-    CNFSEXPIRERULES    *metaexprule;
-    off_t              left;
-    size_t             totlen;
-
-    for (metaexprule = metaexprulestab; metaexprule != (CNFSEXPIRERULES *)NULL; metaexprule = metaexprule->next) {
-       if (metaexprule->class == class)
-           break;
-    }
-    if (metaexprule == (CNFSEXPIRERULES *)NULL) {
-       SMseterror(SMERR_INTERNAL, "no rules match");
-       syslog(L_ERROR, "%s: no matches for group '%s'",
-              LocalLogName, buf);
-       token.type = TOKEN_EMPTY;
-       return token;
-    }
-    metacycbuff = metaexprule->dest;
-
-    cycbuff = metacycbuff->members[metacycbuff->memb_next];  
-    if (cycbuff == NULL) {
-       SMseterror(SMERR_INTERNAL, "no cycbuff found");
-       syslog(L_ERROR, "%s: no cycbuff found for %d", LocalLogName, metacycbuff->memb_next);
-       token.type = TOKEN_EMPTY;
-       return token;
-    } else if (!SMpreopen && !CNFSinit_disks(cycbuff)) {
-       SMseterror(SMERR_INTERNAL, "cycbuff initialization fail");
-       syslog(L_ERROR, "%s: cycbuff '%s' initialization fail", LocalLogName, cycbuff->name);
-       token.type = TOKEN_EMPTY;
-       return token;
-    }
-
-    /* cycbuff->free should have already been aligned by the last write, but
-       realign it just to be sure. */
-    tonextblock = CNFS_BLOCKSIZE - (cycbuff->free & (CNFS_BLOCKSIZE - 1));
-    if (tonextblock != CNFS_BLOCKSIZE)
-       cycbuff->free += tonextblock;
-
-    /* Article too big? */
-    if (cycbuff->len - cycbuff->free < CNFS_BLOCKSIZE + 1)
-        left = 0;
-    else
-        left = cycbuff->len - cycbuff->free - CNFS_BLOCKSIZE - 1;
-    if (article.len > left) {
-       for (middle = cycbuff->free ;middle < cycbuff->len - CNFS_BLOCKSIZE - 1;
-           middle += CNFS_BLOCKSIZE) {
-           CNFSUsedBlock(cycbuff, middle, true, false);
-       }
-       if (innconf->nfswriter) {
-           cnfs_mapcntl(NULL, 0, MS_ASYNC);
-       }
-       cycbuff->free = cycbuff->minartoffset;
-       cycbuff->cyclenum++;
-       if (cycbuff->cyclenum == 0)
-         cycbuff->cyclenum += 2;               /* cnfs_next() needs this */
-       cycbuff->needflush = true;
-       if (metacycbuff->metamode == INTERLEAVE) {
-         CNFSflushhead(cycbuff);               /* Flush, just for giggles */
-         syslog(L_NOTICE, "%s: cycbuff %s rollover to cycle 0x%x... remain calm",
-              LocalLogName, cycbuff->name, cycbuff->cyclenum);
-       } else {
-         /* SEQUENTIAL */
-         cycbuff->currentbuff = false;
-         CNFSflushhead(cycbuff);               /* Flush, just for giggles */
-         if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-         metacycbuff->memb_next = (metacycbuff->memb_next + 1) % metacycbuff->count;
-         cycbuff = metacycbuff->members[metacycbuff->memb_next];  
-         if (!SMpreopen && !CNFSinit_disks(cycbuff)) {
-             SMseterror(SMERR_INTERNAL, "cycbuff initialization fail");
-             syslog(L_ERROR, "%s: cycbuff '%s' initialization fail", LocalLogName, cycbuff->name);
-             token.type = TOKEN_EMPTY;
-             return token;
-         }
-         syslog(L_NOTICE, "%s: metacycbuff %s cycbuff is moved to %s remain calm",
-              LocalLogName, metacycbuff->name, cycbuff->name);
-         cycbuff->currentbuff = true;
-         cycbuff->needflush = true;
-         CNFSflushhead(cycbuff);               /* Flush, just for giggles */
-       }
-    }
-
-    /* Ah, at least we know all three important data */
-    artcycbuffname = cycbuff->name;
-    artoffset = cycbuff->free;
-    artcyclenum = cycbuff->cyclenum;
-
-    memset(&cah, 0, sizeof(cah));
-    cah.size = htonl(article.len);
-    if (article.arrived == (time_t)0)
-       cah.arrived = htonl(time(NULL));
-    else
-       cah.arrived = htonl(article.arrived);
-    cah.class = class;
-
-    if (lseek(cycbuff->fd, artoffset, SEEK_SET) < 0) {
-       SMseterror(SMERR_INTERNAL, "lseek failed");
-       syslog(L_ERROR, "%s: lseek failed for '%s' offset 0x%s: %m",
-              LocalLogName, cycbuff->name, CNFSofft2hex(artoffset, false));
-       token.type = TOKEN_EMPTY;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return token;
-    }
-    if (iovcnt == 0) {
-       iov = xmalloc((article.iovcnt + 2) * sizeof(struct iovec));
-       iovcnt = article.iovcnt + 2;
-    } else if (iovcnt < article.iovcnt + 2) {
-        iov = xrealloc(iov, (article.iovcnt + 2) * sizeof(struct iovec));
-       iovcnt = article.iovcnt + 2;
-    }
-    iov[0].iov_base = (char *) &cah;
-    iov[0].iov_len = sizeof(cah);
-    totlen = iov[0].iov_len;
-    for (i = 1; i <= article.iovcnt; i++) {
-        iov[i].iov_base = article.iov[i-1].iov_base;
-        iov[i].iov_len = article.iov[i-1].iov_len;
-       totlen += iov[i].iov_len;
-    }
-    if ((totlen & (CNFS_BLOCKSIZE - 1)) != 0) {
-       /* Want to xwritev an exact multiple of CNFS_BLOCKSIZE */
-       iov[i].iov_base = alignbuf;
-       iov[i].iov_len = CNFS_BLOCKSIZE - (totlen & (CNFS_BLOCKSIZE - 1));
-       totlen += iov[i].iov_len;
-       i++;
-    }
-    if (xwritev(cycbuff->fd, iov, i) < 0) {
-       SMseterror(SMERR_INTERNAL, "cnfs_store() xwritev() failed");
-       syslog(L_ERROR,
-              "%s: cnfs_store xwritev failed for '%s' offset 0x%s: %m",
-              LocalLogName, artcycbuffname, CNFSofft2hex(artoffset, false));
-       token.type = TOKEN_EMPTY;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return token;
-    }
-    cycbuff->needflush = true;
-
-    /* Now that the article is written, advance the free pointer & flush */
-    cycbuff->free += totlen;
-
-    /*
-    ** If cycbuff->free > cycbuff->len, don't worry.  The next cnfs_store()
-    ** will detect the situation & wrap around correctly.
-    */
-    if (metacycbuff->metamode == INTERLEAVE)
-      metacycbuff->memb_next = (metacycbuff->memb_next + 1) % metacycbuff->count;
-    if (++metacycbuff->write_count % metabuff_update == 0) {
-       for (i = 0; i < metacycbuff->count; i++) {
-           CNFSflushhead(metacycbuff->members[i]);
-       }
-    }
-    CNFSUsedBlock(cycbuff, artoffset, true, true);
-    for (middle = artoffset + CNFS_BLOCKSIZE; middle < cycbuff->free;
-        middle += CNFS_BLOCKSIZE) {
-       CNFSUsedBlock(cycbuff, middle, true, false);
-    }
-    if (innconf->nfswriter) {
-       cnfs_mapcntl(NULL, 0, MS_ASYNC);
-    }
-    if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-    return CNFSMakeToken(artcycbuffname, artoffset, artcyclenum, class);
-}
-
-ARTHANDLE *cnfs_retrieve(const TOKEN token, const RETRTYPE amount) {
-    char               cycbuffname[9];
-    off_t               offset;
-    uint32_t           cycnum;
-    CYCBUFF            *cycbuff;
-    ARTHANDLE          *art;
-    CNFSARTHEADER      cah;
-    PRIV_CNFS          *private;
-    char               *p;
-    long               pagefudge;
-    off_t               mmapoffset;
-    static TOKEN       ret_token;
-    static bool                nomessage = false;
-    int                        plusoffset = 0;
-
-    if (token.type != TOKEN_CNFS) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return NULL;
-    }
-    if (! CNFSBreakToken(token, cycbuffname, &offset, &cycnum)) {
-       /* SMseterror() should have already been called */
-       return NULL;
-    }
-    if ((cycbuff = CNFSgetcycbuffbyname(cycbuffname)) == NULL) {
-       SMseterror(SMERR_NOENT, NULL);
-       if (!nomessage) {
-           syslog(L_ERROR, "%s: cnfs_retrieve: token %s: bogus cycbuff name: %s:0x%s:%d",
-              LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum);
-           nomessage = true;
-       }
-       return NULL;
-    }
-    if (!SMpreopen && !CNFSinit_disks(cycbuff)) {
-       SMseterror(SMERR_INTERNAL, "cycbuff initialization fail");
-       syslog(L_ERROR, "%s: cycbuff '%s' initialization fail", LocalLogName, cycbuff->name);
-       return NULL;
-    }
-    if (! CNFSArtMayBeHere(cycbuff, offset, cycnum)) {
-       SMseterror(SMERR_NOENT, NULL);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return NULL;
-    }
-
-    art = xmalloc(sizeof(ARTHANDLE));
-    art->type = TOKEN_CNFS;
-    if (amount == RETR_STAT) {
-       art->data = NULL;
-       art->len = 0;
-       art->private = NULL;
-       ret_token = token;    
-       art->token = &ret_token;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    /*
-    ** Because we don't know the length of the article (yet), we'll
-    ** just mmap() a chunk of memory which is guaranteed to be larger
-    ** than the largest article can be.
-    ** XXX Because the max article size can be changed, we could get into hot
-    ** XXX water here.  So, to be safe, we double MAX_ART_SIZE and add enough
-    ** XXX extra for the pagesize fudge factor and CNFSARTHEADER structure.
-    */
-    if (pread(cycbuff->fd, &cah, sizeof(cah), offset) != sizeof(cah)) {
-        SMseterror(SMERR_UNDEFINED, "read failed");
-        syslog(L_ERROR, "%s: could not read token %s %s:0x%s:%d: %m",
-               LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum);
-        free(art);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-        return NULL;
-    }
-#ifdef OLD_CNFS
-    if(cah.size == htonl(0x1234) && ntohl(cah.arrived) < time(NULL)-10*365*24*3600) {
-       oldCNFSARTHEADER cahh;
-       *(CNFSARTHEADER *)&cahh = cah;
-       if(pread(cycbuff->fd, ((char *)&cahh)+sizeof(CNFSARTHEADER), sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER), offset+sizeof(cah)) != sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER)) {
-            SMseterror(SMERR_UNDEFINED, "read2 failed");
-            syslog(L_ERROR, "%s: could not read2 token %s %s:0x%s:%ld: %m",
-                    LocalLogName, TokenToText(token), cycbuffname,
-                    CNFSofft2hex(offset, false), cycnum);
-            free(art);
-            if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-            return NULL;
-       }
-       cah.size = cahh.size;
-       cah.arrived = htonl(time(NULL));
-       cah.class = 0;
-       plusoffset = sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER);
-    }
-#endif /* OLD_CNFS */
-    if (offset > cycbuff->len - CNFS_BLOCKSIZE - (off_t) ntohl(cah.size) - 1) {
-        if (!SMpreopen) {
-           SMseterror(SMERR_UNDEFINED, "CNFSARTHEADER size overflow");
-           syslog(L_ERROR, "%s: could not match article size token %s %s:0x%s:%d: %d",
-               LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum, ntohl(cah.size));
-           free(art);
-           CNFSshutdowncycbuff(cycbuff);
-           return NULL;
-       }
-       CNFSReadFreeAndCycle(cycbuff);
-       if (offset > cycbuff->len - CNFS_BLOCKSIZE - (off_t) ntohl(cah.size) - 1) {
-           SMseterror(SMERR_UNDEFINED, "CNFSARTHEADER size overflow");
-           syslog(L_ERROR, "%s: could not match article size token %s %s:0x%s:%d: %d",
-               LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum, ntohl(cah.size));
-           free(art);
-           return NULL;
-       }
-    }
-    /* checking the bitmap to ensure cah.size is not broken was dropped */
-    if (innconf->cnfscheckfudgesize != 0 && innconf->maxartsize != 0 &&
-       (ntohl(cah.size) > (size_t) innconf->maxartsize + innconf->cnfscheckfudgesize)) {
-       char buf1[24];
-       strlcpy(buf1, CNFSofft2hex(cycbuff->free, false), sizeof(buf1));
-       SMseterror(SMERR_UNDEFINED, "CNFSARTHEADER fudge size overflow");
-       syslog(L_ERROR, "%s: fudge size overflows bitmaps %s %s:0x%s: %u",
-       LocalLogName, TokenToText(token), cycbuffname, buf1, ntohl(cah.size));
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       free(art);
-       return NULL;
-    }
-    private = xmalloc(sizeof(PRIV_CNFS));
-    art->private = (void *)private;
-    art->arrived = ntohl(cah.arrived);
-    offset += sizeof(cah) + plusoffset;
-    if (innconf->articlemmap) {
-       pagefudge = offset % pagesize;
-       mmapoffset = offset - pagefudge;
-       private->len = pagefudge + ntohl(cah.size);
-       if ((private->base = mmap(NULL, private->len, PROT_READ,
-               MAP_SHARED, cycbuff->fd, mmapoffset)) == MAP_FAILED) {
-           SMseterror(SMERR_UNDEFINED, "mmap failed");
-           syslog(L_ERROR, "%s: could not mmap token %s %s:0x%s:%d: %m",
-               LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum);
-           free(art->private);
-           free(art);
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return NULL;
-       }
-       mmap_invalidate(private->base, private->len);
-        if (amount == RETR_ALL)
-           madvise(private->base, private->len, MADV_WILLNEED);
-        else
-           madvise(private->base, private->len, MADV_SEQUENTIAL);
-    } else {
-       private->base = xmalloc(ntohl(cah.size));
-       pagefudge = 0;
-       if (pread(cycbuff->fd, private->base, ntohl(cah.size), offset) < 0) {
-           SMseterror(SMERR_UNDEFINED, "read failed");
-           syslog(L_ERROR, "%s: could not read token %s %s:0x%s:%d: %m",
-               LocalLogName, TokenToText(token), cycbuffname, CNFSofft2hex(offset, false), cycnum);
-           free(private->base);
-           free(art->private);
-           free(art);
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return NULL;
-       }
-    }
-    ret_token = token;    
-    art->token = &ret_token;
-    art->len = ntohl(cah.size);
-    if (amount == RETR_ALL) {
-       art->data = innconf->articlemmap ? private->base + pagefudge : private->base;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    if ((p = wire_findbody(innconf->articlemmap ? private->base + pagefudge : private->base, art->len)) == NULL) {
-        SMseterror(SMERR_NOBODY, NULL);
-       if (innconf->articlemmap)
-           munmap(private->base, private->len);
-       else
-           free(private->base);
-        free(art->private);
-        free(art);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-        return NULL;
-    }
-    if (amount == RETR_HEAD) {
-       if (innconf->articlemmap) {
-           art->data = private->base + pagefudge;
-            art->len = p - private->base - pagefudge;
-       } else {
-           art->data = private->base;
-            art->len = p - private->base;
-       }
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-        return art;
-    }
-    if (amount == RETR_BODY) {
-        art->data = p;
-       if (innconf->articlemmap)
-           art->len = art->len - (p - private->base - pagefudge);
-       else
-           art->len = art->len - (p - private->base);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-        return art;
-    }
-    SMseterror(SMERR_UNDEFINED, "Invalid retrieve request");
-    if (innconf->articlemmap)
-       munmap(private->base, private->len);
-    else
-       free(private->base);
-    free(art->private);
-    free(art);
-    if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-    return NULL;
-}
-
-void cnfs_freearticle(ARTHANDLE *article) {
-    PRIV_CNFS  *private;
-
-    if (!article)
-       return;
-    
-    if (article->private) {
-       private = (PRIV_CNFS *)article->private;
-       if (innconf->articlemmap)
-           munmap(private->base, private->len);
-       else
-           free(private->base);
-       free(private);
-    }
-    free(article);
-}
-
-bool cnfs_cancel(TOKEN token) {
-    char               cycbuffname[9];
-    off_t               offset;
-    uint32_t           cycnum;
-    CYCBUFF            *cycbuff;
-
-    if (token.type != TOKEN_CNFS) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return false;
-    }
-    if (! CNFSBreakToken(token, cycbuffname, &offset, &cycnum)) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       /* SMseterror() should have already been called */
-       return false;
-    }
-    if ((cycbuff = CNFSgetcycbuffbyname(cycbuffname)) == NULL) {
-       SMseterror(SMERR_INTERNAL, "bogus cycbuff name");
-       return false;
-    }
-    if (!SMpreopen && !CNFSinit_disks(cycbuff)) {
-       SMseterror(SMERR_INTERNAL, "cycbuff initialization fail");
-       syslog(L_ERROR, "%s: cycbuff '%s' initialization fail", LocalLogName, cycbuff->name);
-       return false;
-    }
-    if (! (cycnum == cycbuff->cyclenum ||
-       (cycnum == cycbuff->cyclenum - 1 && offset > cycbuff->free) ||
-       (cycnum + 1 == 0 && cycbuff->cyclenum == 2 && offset > cycbuff->free))) {
-       SMseterror(SMERR_NOENT, NULL);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return false;
-    }
-    if (CNFSUsedBlock(cycbuff, offset, false, false) == 0) {
-       SMseterror(SMERR_NOENT, NULL);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return false;
-    }
-    CNFSUsedBlock(cycbuff, offset, true, false);
-    if (innconf->nfswriter) {
-       cnfs_mapcntl(NULL, 0, MS_ASYNC);
-    }
-    if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-    return true;
-}
-
-ARTHANDLE *cnfs_next(const ARTHANDLE *article, const RETRTYPE amount) {
-    ARTHANDLE           *art;
-    CYCBUFF            *cycbuff;
-    PRIV_CNFS          priv, *private;
-    off_t               middle = 0, limit;
-    CNFSARTHEADER      cah;
-    off_t               offset;
-    long               pagefudge, blockfudge;
-    static TOKEN       token;
-    int                        tonextblock;
-    off_t               mmapoffset;
-    char               *p;
-    int                        plusoffset = 0;
-
-    if (article == (ARTHANDLE *)NULL) {
-       if ((cycbuff = cycbufftab) == (CYCBUFF *)NULL)
-           return (ARTHANDLE *)NULL;
-       priv.offset = 0;
-       priv.rollover = false;
-    } else {        
-       priv = *(PRIV_CNFS *)article->private;
-       free(article->private);
-       free((void *)article);
-       if (innconf->articlemmap)
-           munmap(priv.base, priv.len);
-       else {
-           /* In the case we return art->data = NULL, we
-             * must not free an already stale pointer.
-               -mibsoft@mibsoftware.com
-            */
-           if (priv.base) {
-               free(priv.base);
-               priv.base = 0;
-           }
-       }
-       cycbuff = priv.cycbuff;
-    }
-
-    for (;cycbuff != (CYCBUFF *)NULL;
-           cycbuff = cycbuff->next,
-           priv.offset = 0) {
-
-       if (!SMpreopen && !CNFSinit_disks(cycbuff)) {
-           SMseterror(SMERR_INTERNAL, "cycbuff initialization fail");
-           continue;
-       }
-       if (priv.rollover && priv.offset >= cycbuff->free) {
-           priv.offset = 0;
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           continue;
-       }
-       if (priv.offset == 0) {
-           if (cycbuff->cyclenum == 1) {
-               priv.offset = cycbuff->minartoffset;
-               priv.rollover = true;
-           } else {
-               priv.offset = cycbuff->free;
-               priv.rollover = false;
-           }
-       }
-       if (!priv.rollover) {
-           for (middle = priv.offset ;middle < cycbuff->len - CNFS_BLOCKSIZE - 1;
-               middle += CNFS_BLOCKSIZE) {
-               if (CNFSUsedBlock(cycbuff, middle, false, false) != 0)
-                   break;
-           }
-           if (middle >= cycbuff->len - CNFS_BLOCKSIZE - 1) {
-               priv.rollover = true;
-               middle = cycbuff->minartoffset;
-           }
-           break;
-       } else {
-           for (middle = priv.offset ;middle < cycbuff->free;
-               middle += CNFS_BLOCKSIZE) {
-               if (CNFSUsedBlock(cycbuff, middle, false, false) != 0)
-                   break;
-           }
-           if (middle >= cycbuff->free) {
-               middle = 0;
-               if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-               continue;
-           } else
-               break;
-       }
-    }
-    if (cycbuff == (CYCBUFF *)NULL)
-       return (ARTHANDLE *)NULL;
-
-    offset = middle;
-    if (pread(cycbuff->fd, &cah, sizeof(cah), offset) != sizeof(cah)) {
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return (ARTHANDLE *)NULL;
-    }
-#ifdef OLD_CNFS
-    if(cah.size == htonl(0x1234) && ntohl(cah.arrived) < time(NULL)-10*365*24*3600) {
-       oldCNFSARTHEADER cahh;
-       *(CNFSARTHEADER *)&cahh = cah;
-       if(pread(cycbuff->fd, ((char *)&cahh)+sizeof(CNFSARTHEADER), sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER), offset+sizeof(cah)) != sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER)) {
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return (ARTHANDLE *)NULL;
-       }
-       cah.size = cahh.size;
-       cah.arrived = htonl(time(NULL));
-       cah.class = 0;
-       plusoffset = sizeof(oldCNFSARTHEADER)-sizeof(CNFSARTHEADER);
-    }
-#endif /* OLD_CNFS */
-    art = xmalloc(sizeof(ARTHANDLE));
-    private = xmalloc(sizeof(PRIV_CNFS));
-    art->private = (void *)private;
-    art->type = TOKEN_CNFS;
-    *private = priv;
-    private->cycbuff = cycbuff;
-    private->offset = middle;
-    if (cycbuff->len - cycbuff->free < (off_t) ntohl(cah.size) + CNFS_BLOCKSIZE + 1) {
-       private->offset += CNFS_BLOCKSIZE;
-       art->data = NULL;
-       art->len = 0;
-       art->token = NULL;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    /* check the bitmap to ensure cah.size is not broken */
-    blockfudge = (sizeof(cah) + plusoffset + ntohl(cah.size)) % CNFS_BLOCKSIZE;
-    limit = private->offset + sizeof(cah) + plusoffset + ntohl(cah.size) - blockfudge + CNFS_BLOCKSIZE;
-    if (offset < cycbuff->free) {
-       for (middle = offset + CNFS_BLOCKSIZE; (middle < cycbuff->free) && (middle < limit);
-           middle += CNFS_BLOCKSIZE) {
-           if (CNFSUsedBlock(cycbuff, middle, false, false) != 0)
-               /* Bitmap set.  This article assumes to be broken */
-               break;
-       }
-       if ((middle > cycbuff->free) || (middle != limit)) {
-           private->offset = middle;
-           art->data = NULL;
-           art->len = 0;
-           art->token = NULL;
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return art;
-       }
-    } else {
-       for (middle = offset + CNFS_BLOCKSIZE; (middle < cycbuff->len) && (middle < limit);
-           middle += CNFS_BLOCKSIZE) {
-           if (CNFSUsedBlock(cycbuff, middle, false, false) != 0)
-               /* Bitmap set.  This article assumes to be broken */
-               break;
-       }
-       if ((middle >= cycbuff->len) || (middle != limit)) {
-           private->offset = middle;
-           art->data = NULL;
-           art->len = 0;
-           art->token = NULL;
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return art;
-       }
-    }
-    if (innconf->cnfscheckfudgesize != 0 && innconf->maxartsize != 0 &&
-       ((off_t) ntohl(cah.size) > innconf->maxartsize + innconf->cnfscheckfudgesize)) {
-       art->data = NULL;
-       art->len = 0;
-       art->token = NULL;
-       private->base = 0;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-
-    private->offset += (off_t) ntohl(cah.size) + sizeof(cah) + plusoffset;
-    tonextblock = CNFS_BLOCKSIZE - (private->offset & (CNFS_BLOCKSIZE - 1));
-    private->offset += (off_t) tonextblock;
-    art->arrived = ntohl(cah.arrived);
-    token = CNFSMakeToken(cycbuff->name, offset, (offset > cycbuff->free) ? cycbuff->cyclenum - 1 : cycbuff->cyclenum, cah.class);
-    art->token = &token;
-    offset += sizeof(cah) + plusoffset;
-    if (innconf->articlemmap) {
-       pagefudge = offset % pagesize;
-       mmapoffset = offset - pagefudge;
-       private->len = pagefudge + ntohl(cah.size);
-       if ((private->base = mmap(0, private->len, PROT_READ,
-           MAP_SHARED, cycbuff->fd, mmapoffset)) == MAP_FAILED) {
-           art->data = NULL;
-           art->len = 0;
-           art->token = NULL;
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           return art;
-       }
-       mmap_invalidate(private->base, private->len);
-       madvise(private->base, private->len, MADV_SEQUENTIAL);
-    } else {
-       private->base = xmalloc(ntohl(cah.size));
-       pagefudge = 0;
-       if (pread(cycbuff->fd, private->base, ntohl(cah.size), offset) < 0) {
-           art->data = NULL;
-           art->len = 0;
-           art->token = NULL;
-           if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-           free(private->base);
-           private->base = 0;
-           return art;
-       }
-    }
-    art->len = ntohl(cah.size);
-    if (amount == RETR_ALL) {
-       art->data = innconf->articlemmap ? private->base + pagefudge : private->base;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    if ((p = wire_findbody(innconf->articlemmap ? private->base + pagefudge : private->base, art->len)) == NULL) {
-       art->data = NULL;
-       art->len = 0;
-       art->token = NULL;
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    if (amount == RETR_HEAD) {
-       if (innconf->articlemmap) {
-           art->data = private->base + pagefudge;
-           art->len = p - private->base - pagefudge;
-       } else {
-           art->data = private->base;
-           art->len = p - private->base;
-       }
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    if (amount == RETR_BODY) {
-       art->data = p;
-       if (innconf->articlemmap)
-           art->len = art->len - (p - private->base - pagefudge);
-       else
-           art->len = art->len - (p - private->base);
-       if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-       return art;
-    }
-    art->data = NULL;
-    art->len = 0;
-    art->token = NULL;
-    if (!SMpreopen) CNFSshutdowncycbuff(cycbuff);
-    return art;
-}
-
-bool cnfs_ctl(PROBETYPE type, TOKEN *token UNUSED, void *value) {
-    struct artngnum *ann;
-
-    switch (type) {
-    case SMARTNGNUM:    
-       if ((ann = (struct artngnum *)value) == NULL)
-           return false;
-       /* make SMprobe() call cnfs_retrieve() */
-       ann->artnum = 0;
-       return true; 
-    default:
-       return false; 
-    }   
-}
-
-bool cnfs_flushcacheddata(FLUSHTYPE type) {
-    if (type == SM_ALL || type == SM_HEAD)
-       CNFSflushallheads();
-    return true; 
-}
-
-void
-cnfs_printfiles(FILE *file, TOKEN token, char **xref UNUSED,
-                int ngroups UNUSED)
-{
-    fprintf(file, "%s\n", TokenToText(token));
-}
-
-void cnfs_shutdown(void) {
-    CNFScleancycbuff();
-    CNFScleanmetacycbuff();
-    CNFScleanexpirerule();
-}
diff --git a/storage/cnfs/cnfs.h b/storage/cnfs/cnfs.h
deleted file mode 100644 (file)
index fc7f1c9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*  $Id: cnfs.h 4266 2001-01-04 06:01:36Z rra $
-**
-**  cyclic news file system header
-*/
-
-#ifndef __CNFS_H__
-#define __CNFS_H__
-
-bool cnfs_init(SMATTRIBUTE *attr);
-TOKEN cnfs_store(const ARTHANDLE article, const STORAGECLASS class);
-ARTHANDLE *cnfs_retrieve(const TOKEN token, const RETRTYPE amount);
-ARTHANDLE *cnfs_next(const ARTHANDLE *article, const RETRTYPE amount);
-void cnfs_freearticle(ARTHANDLE *article);
-bool cnfs_cancel(TOKEN token);
-bool cnfs_ctl(PROBETYPE type, TOKEN *token, void *value);
-bool cnfs_flushcacheddata(FLUSHTYPE type);
-void cnfs_printfiles(FILE *file, TOKEN token, char **xref, int ngroups);
-void cnfs_shutdown(void);
-
-#endif
diff --git a/storage/cnfs/method.config b/storage/cnfs/method.config
deleted file mode 100644 (file)
index 2ba88a6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = cnfs
-number  = 3
-sources = cnfs.c
diff --git a/storage/expire.c b/storage/expire.c
deleted file mode 100644 (file)
index 37f4a80..0000000
+++ /dev/null
@@ -1,906 +0,0 @@
-/*  $Id: expire.c 6775 2004-05-17 06:23:42Z rra $
-**
-**  Code for overview-driven expiration.
-**
-**  In order to expire on a per-newsgroup (instead of per-storage-class)
-**  basis, one has to use overview-driven expiration.  This contains all of
-**  the code to do that.  It provides OVgroupbasedexpire, OVhisthasmsgid, and
-**  OVgroupmatch for the use of various overview methods.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "ov.h"
-#include "ovinterface.h"
-#include "paths.h"
-#include "storage.h"
-
-enum KRP {Keep, Remove, Poison};
-
-/* Statistics */
-static long             EXPprocessed;
-static long             EXPunlinked;
-static long             EXPoverindexdrop;
-
-#define NGH_HASH(Name, p, j)    \
-        for (p = Name, j = 0; *p; ) j = (j << 5) + j + *p++
-#define NGH_SIZE        2048
-#define NGH_BUCKET(j)   &NGHtable[j & (NGH_SIZE - 1)]
-
-#define OVFMT_UNINIT    -2
-#define OVFMT_NODATE    -1
-#define OVFMT_NOXREF    -1
-
-static int              Dateindex = OVFMT_UNINIT; 
-static int              Xrefindex = OVFMT_UNINIT;
-static int              Messageidindex = OVFMT_UNINIT;
-
-typedef struct _NEWSGROUP {
-    char                *Name;
-    char                *Rest;
-    unsigned long       Last;
-    unsigned long       Lastpurged;
-        /* These fields are new. */
-    time_t              Keep;
-    time_t              Default;
-    time_t              Purge;
-    /* X flag => remove entire article when it expires in this group */
-    bool                Poison;
-} NEWSGROUP;
-
-typedef struct _NGHASH {
-    int         Size;
-    int         Used;
-    NEWSGROUP   **Groups;
-} NGHASH;
-
-#define MAGIC_TIME      49710.
-
-typedef struct _BADGROUP {
-    struct _BADGROUP    *Next;
-    char                *Name;
-} BADGROUP;
-
-/*
-**  Information about the schema of the news overview files.
-*/
-typedef struct _ARTOVERFIELD {  
-    char        *Header;
-    int         Length;
-    bool        HasHeader;
-    bool        NeedsHeader;
-} ARTOVERFIELD;
-
-static BADGROUP         *EXPbadgroups;
-static int              nGroups;
-static NEWSGROUP        *Groups;
-static NEWSGROUP        EXPdefault;
-static NGHASH           NGHtable[NGH_SIZE];
-
-static char             **arts;
-static enum KRP         *krps;
-
-static ARTOVERFIELD *   ARTfields;
-static int              ARTfieldsize;
-static bool             ReadOverviewfmt = false;
-
-
-/* FIXME: The following variables are shared between this file and ov.c.
-   This should be cleaned up with a better internal interface. */
-extern time_t   OVnow;
-extern char *   ACTIVE;
-extern FILE *   EXPunlinkfile;
-extern bool     OVignoreselfexpire;
-extern bool     OVusepost;
-extern bool     OVkeep;
-extern bool     OVearliest;
-extern bool     OVquiet;
-extern int      OVnumpatterns;
-extern char **  OVpatterns;
-
-
-/*
-**  Hash a newsgroup and see if we get it.
-*/
-static NEWSGROUP *
-NGfind(char *Name)
-{
-    char                *p;
-    int                 i;
-    unsigned int        j;
-    NEWSGROUP           **ngp;
-    char                c;
-    NGHASH              *htp;
-
-    NGH_HASH(Name, p, j);
-    htp = NGH_BUCKET(j);
-    for (c = *Name, ngp = htp->Groups, i = htp->Used; --i >= 0; ngp++)
-        if (c == ngp[0]->Name[0] && strcmp(Name, ngp[0]->Name) == 0)
-            return ngp[0];
-    return NULL;
-}
-
-/*
-**  Sorting predicate to put newsgroups in rough order of their activity.
-*/
-static int
-NGcompare(const void *p1, const void *p2)
-{
-    const NEWSGROUP * const * ng1 = p1;
-    const NEWSGROUP * const * ng2 = p2;
-
-    return ng1[0]->Last - ng2[0]->Last;
-}
-
-/*
-**  Split a line at a specified field separator into a vector and return
-**  the number of fields found, or -1 on error.
-*/
-static int
-EXPsplit(char *p, char sep, char **argv, int count)
-{
-    int i;
-
-    if (!p)
-      return 0;
-
-    while (*p == sep)
-      ++p;
-
-    if (!*p)
-      return 0;
-
-    if (!p)
-      return 0;
-
-    while (*p == sep)
-      ++p;
-
-    if (!*p)
-      return 0;
-
-    for (i = 1, *argv++ = p; *p; )
-        if (*p++ == sep) {
-            p[-1] = '\0';
-            for (; *p == sep; p++);
-            if (!*p)
-                return i;
-            if (++i == count)
-                /* Overflow. */
-                return -1;
-            *argv++ = p;
-        }
-    return i;
-}
-
-/*
-**  Build the newsgroup structures from the active file.
-*/
-static void
-BuildGroups(char *active)
-{
-    NGHASH              *htp;
-    NEWSGROUP           *ngp;
-    char                *p;
-    char                *q;
-    int                 i;
-    unsigned            j;
-    int                 lines;
-    int                 NGHbuckets;
-    char                *fields[5];
-
-    /* Count the number of groups. */
-    for (p = active, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
-        continue;
-    nGroups = i;
-    Groups = xmalloc(i * sizeof(NEWSGROUP));
-
-    /* Set up the default hash buckets. */
-    NGHbuckets = i / NGH_SIZE;
-    if (NGHbuckets == 0)
-        NGHbuckets = 1;
-    for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++) {
-        htp->Size = NGHbuckets;
-        htp->Groups = xmalloc(htp->Size * sizeof(NEWSGROUP *));
-        htp->Used = 0;
-    }
-
-    /* Fill in the array. */
-    lines = 0;
-    for (p = active, ngp = Groups, i = nGroups; --i >= 0; ngp++, p = q + 1) {
-        lines++;
-        if ((q = strchr(p, '\n')) == NULL) {
-            fprintf(stderr, "%s: line %d missing newline\n", ACTIVE, lines);
-            exit(1);
-        }
-       if (*p == '.')
-            continue;
-        *q = '\0';
-        if (EXPsplit(p, ' ', fields, ARRAY_SIZE(fields)) != 4) {
-            fprintf(stderr, "%s: line %d wrong number of fields\n", ACTIVE, lines);
-            exit(1);
-        }
-        ngp->Name = fields[0];
-        ngp->Last = atol(fields[1]);
-        ngp->Rest = fields[3];
-
-        /* Find the right bucket for the group, make sure there is room. */
-        NGH_HASH(ngp->Name, p, j);
-        htp = NGH_BUCKET(j);
-        if (htp->Used >= htp->Size) {
-            htp->Size += NGHbuckets;
-            htp->Groups = xrealloc(htp->Groups, htp->Size * sizeof(NEWSGROUP *));
-        }
-        htp->Groups[htp->Used++] = ngp;
-    }
-
-    /* Sort each hash bucket. */
-    for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++)
-    if (htp->Used > 1)
-        qsort(htp->Groups, htp->Used, sizeof htp->Groups[0], NGcompare);
-
-    /* Ok, now change our use of the Last field.  Set them all to maxint. */
-    for (i = NGH_SIZE, htp = NGHtable; --i >= 0; htp++) {
-        NEWSGROUP       **ngpa;
-        int             k;
-
-        for (ngpa = htp->Groups, k = htp->Used; --k >= 0; ngpa++) {
-            ngpa[0]->Last = ~(unsigned long) 0;
-            ngpa[0]->Lastpurged = 0;
-        }
-    }
-}
-
-/*
-**  Parse a number field converting it into a "when did this start?".
-**  This makes the "keep it" tests fast, but inverts the logic of
-**  just about everything you expect.  Print a message and return false
-**  on error.
-*/
-static bool
-EXPgetnum(int line, char *word, time_t *v, const char *name)
-{
-    char                *p;
-    bool                SawDot;
-    double              d;
-
-    if (strcasecmp(word, "never") == 0) {
-        *v = (time_t)0;
-        return true;
-    }
-
-    /* Check the number.  We don't have strtod yet. */
-    for (p = word; ISWHITE(*p); p++)
-        continue;
-    if (*p == '+' || *p == '-')
-        p++;
-    for (SawDot = false; *p; p++)
-        if (*p == '.') {
-            if (SawDot)
-                break;
-            SawDot = true;
-        }
-        else if (!CTYPE(isdigit, (int)*p))
-            break;
-    if (*p) {
-        fprintf(stderr, "Line %d, bad `%c' character in %s field\n",
-                line, *p, name);
-        return false;
-    }
-    d = atof(word);
-    if (d > MAGIC_TIME)
-        *v = (time_t)0;
-    else
-        *v = OVnow - (time_t)(d * 86400.);
-    return true;
-}
-
-/*
-**  Set the expiration fields for all groups that match this pattern.
-*/
-static void
-EXPmatch(char *p, NEWSGROUP *v, char mod)
-{
-    NEWSGROUP           *ngp;
-    int                 i;
-    bool                negate;
-
-    negate = *p == '!';
-    if (negate)
-        p++;
-    for (ngp = Groups, i = nGroups; --i >= 0; ngp++)
-        if (negate ? !uwildmat(ngp->Name, p) : uwildmat(ngp->Name, p))
-            if (mod == 'a'
-             || (mod == 'm' && ngp->Rest[0] == NF_FLAG_MODERATED)
-             || (mod == 'u' && ngp->Rest[0] != NF_FLAG_MODERATED)) {
-                ngp->Keep      = v->Keep;
-                ngp->Default   = v->Default;
-                ngp->Purge     = v->Purge;
-                ngp->Poison    = v->Poison;
-            }
-}
-
-/*
-**  Parse the expiration control file.  Return true if okay.
-*/
-static bool
-EXPreadfile(FILE *F)
-{
-    char                *p;
-    int                 i;
-    int                 j;
-    int                 k;
-    char                mod;
-    NEWSGROUP           v;
-    bool                SawDefault;
-    char                buff[BUFSIZ];
-    char                *fields[7];
-    char                **patterns;
-
-    /* Scan all lines. */
-    SawDefault = false;
-    patterns = xmalloc(nGroups * sizeof(char *));
-    
-    for (i = 1; fgets(buff, sizeof buff, F) != NULL; i++) {
-        if ((p = strchr(buff, '\n')) == NULL) {
-            fprintf(stderr, "Line %d too long\n", i);
-            free(patterns);
-            return false;
-        }
-        *p = '\0';
-        p = strchr(buff, '#');
-        if (p)
-            *p = '\0';
-        else
-            p = buff + strlen(buff);
-        while (--p >= buff) {
-            if (isspace((int)*p))
-                *p = '\0';
-            else
-                break;
-        }
-        if (buff[0] == '\0')
-            continue;
-        if ((j = EXPsplit(buff, ':', fields, ARRAY_SIZE(fields))) == -1) {
-            fprintf(stderr, "Line %d too many fields\n", i);
-            free(patterns);
-            return false;
-        }
-
-        /* Expired-article remember line? */
-        if (strcmp(fields[0], "/remember/") == 0) {
-            continue;
-        }
-
-        /* Regular expiration line -- right number of fields? */
-        if (j != 5) {
-            fprintf(stderr, "Line %d bad format\n", i);
-            free(patterns);
-            return false;
-        }
-
-        /* Parse the fields. */
-        if (strchr(fields[1], 'M') != NULL)
-            mod = 'm';
-        else if (strchr(fields[1], 'U') != NULL)
-            mod = 'u';
-        else if (strchr(fields[1], 'A') != NULL)
-            mod = 'a';
-        else {
-            fprintf(stderr, "Line %d bad modflag\n", i);
-            free(patterns);
-            return false;
-        }
-        v.Poison = (strchr(fields[1], 'X') != NULL);
-        if (!EXPgetnum(i, fields[2], &v.Keep,    "keep")
-         || !EXPgetnum(i, fields[3], &v.Default, "default")
-         || !EXPgetnum(i, fields[4], &v.Purge,   "purge")) {
-            free(patterns);
-            return false;
-        }
-        /* These were turned into offsets, so the test is the opposite
-         * of what you think it should be.  If Purge isn't forever,
-         * make sure it's greater then the other two fields. */
-        if (v.Purge) {
-            /* Some value not forever; make sure other values are in range. */
-            if (v.Keep && v.Keep < v.Purge) {
-                fprintf(stderr, "Line %d keep>purge\n", i);
-                free(patterns);
-                return false;
-            }
-            if (v.Default && v.Default < v.Purge) {
-                fprintf(stderr, "Line %d default>purge\n", i);
-                free(patterns);
-                return false;
-            }
-        }
-
-        /* Is this the default line? */
-        if (fields[0][0] == '*' && fields[0][1] == '\0' && mod == 'a') {
-            if (SawDefault) {
-                fprintf(stderr, "Line %d duplicate default\n", i);
-                free(patterns);
-                return false;
-            }
-            EXPdefault.Keep    = v.Keep;
-            EXPdefault.Default = v.Default;
-            EXPdefault.Purge   = v.Purge;
-            EXPdefault.Poison  = v.Poison;
-            SawDefault = true;
-        }
-
-        /* Assign to all groups that match the pattern and flags. */
-        if ((j = EXPsplit(fields[0], ',', patterns, nGroups)) == -1) {
-            fprintf(stderr, "Line %d too many patterns\n", i);
-            free(patterns);
-            return false;
-        }
-        for (k = 0; k < j; k++)
-            EXPmatch(patterns[k], &v, mod);
-    }
-    free(patterns);
-
-    return true;
-}
-
-/*
-**  Handle a newsgroup that isn't in the active file.
-*/
-static NEWSGROUP *
-EXPnotfound(char *Entry)
-{
-    static NEWSGROUP    Removeit;
-    BADGROUP            *bg;
-
-    /* See if we already know about this group. */
-    for (bg = EXPbadgroups; bg; bg = bg->Next)
-        if (strcmp(Entry, bg->Name) == 0)
-            break;
-    if (bg == NULL) {
-        bg = xmalloc(sizeof(BADGROUP));
-        bg->Name = xstrdup(Entry);
-        bg->Next = EXPbadgroups;
-        EXPbadgroups = bg;
-    }
-    /* remove it all now. */
-    if (Removeit.Keep == 0) {
-        Removeit.Keep = OVnow;
-        Removeit.Default = OVnow;
-        Removeit.Purge = OVnow;
-    }
-    return &Removeit;
-}
-
-/*
-**  Should we keep the specified article?
-*/
-static enum KRP
-EXPkeepit(char *Entry, time_t when, time_t expires)
-{
-    NEWSGROUP           *ngp;
-    enum KRP            retval = Remove;
-
-    if ((ngp = NGfind(Entry)) == NULL)
-        ngp = EXPnotfound(Entry);
-
-    /* Bad posting date? */
-    if (when > OVrealnow + 86400) {
-        /* Yes -- force the article to go right now. */
-        when = expires ? ngp->Purge : ngp->Default;
-    }
-
-    /* If no expiration, make sure it wasn't posted before the default. */
-    if (expires == 0) {
-        if (when >= ngp->Default)
-            retval = Keep;
-
-    /* Make sure it's not posted before the purge cut-off and
-     * that it's not due to expire. */
-    } else {
-        if (when >= ngp->Purge && (expires >= OVnow || when >= ngp->Keep))
-            retval = Keep;
-    }
-    if (retval == Keep) {
-        return Keep;
-    } else {
-        return ngp->Poison ? Poison : Remove;
-    }
-}
-
-/*
-**  An article can be removed.  Either print a note, or actually remove it.
-**  Takes in the Xref information so that it can pass this to the storage
-**  API callback used to generate the list of files to remove.
-*/
-void
-OVEXPremove(TOKEN token, bool deletedgroups, char **xref, int ngroups)
-{
-    EXPunlinked++;
-    if (deletedgroups) {
-        EXPprocessed++;
-        EXPoverindexdrop++;
-    }
-    if (EXPunlinkfile && xref != NULL) {
-        SMprintfiles(EXPunlinkfile, token, xref, ngroups);
-        if (!ferror(EXPunlinkfile))
-            return;
-        fprintf(stderr, "Can't write to -z file, %s\n", strerror(errno));
-        fprintf(stderr, "(Will ignore it for rest of run.)\n");
-        fclose(EXPunlinkfile);
-        EXPunlinkfile = NULL;
-    }
-    if (!SMcancel(token) && SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT)
-        fprintf(stderr, "Can't unlink %s: %s\n", TokenToText(token),
-                SMerrorstr);
-}
-
-/*
-**  Read the overview schema.
-*/
-static void
-ARTreadschema(void)
-{
-    FILE                        *F;
-    char                        *p;
-    char                        *path;
-    ARTOVERFIELD                *fp;
-    int                         i;
-    char                        buff[SMBUF];
-    bool                        foundxref = false;
-    bool                        foundxreffull = false;
-
-    /* Open file, count lines. */
-    path = concatpath(innconf->pathetc, _PATH_SCHEMA);
-    F = fopen(path, "r");
-    if (F == NULL)
-        return;
-    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 (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->NeedsHeader = (strcmp(p, "full") == 0);
-        }
-        else
-            fp->NeedsHeader = false;
-        fp->HasHeader = false;
-        fp->Header = xstrdup(buff);
-        fp->Length = strlen(buff);
-        if (strcasecmp(buff, "Xref") == 0) {
-            foundxref = true;
-            foundxreffull = fp->NeedsHeader;
-        }
-        fp++;
-    }
-    ARTfieldsize = fp - ARTfields;
-    fclose(F);
-    if (!foundxref || !foundxreffull) {
-        fprintf(stderr, "'Xref:full' must be included in %s", path);
-        exit(1);
-    }
-    free(path);
-}
-
-/*
-**  Return a field from the overview line or NULL on error.  Return a copy
-**  since we might be re-using the line later.
-*/
-static char *
-OVERGetHeader(const char *p, int field)
-{
-    static char         *buff;
-    static int          buffsize;
-    int                 i;
-    ARTOVERFIELD        *fp;
-    char                *next;
-
-    fp = &ARTfields[field];
-
-    /* Skip leading headers. */
-    for (; field-- >= 0 && *p; p++)
-        if ((p = strchr(p, '\t')) == NULL)
-            return NULL;
-    if (*p == '\0')
-        return NULL;
-
-    if (fp->HasHeader)
-        p += fp->Length + 2;
-
-    if (fp->NeedsHeader) {              /* find an exact match */
-         while (strncmp(fp->Header, p, fp->Length) != 0) {
-              if ((p = strchr(p, '\t')) == NULL) 
-                return NULL;
-              p++;
-         }
-         p += fp->Length + 2;
-    }
-
-    /* Figure out length; get space. */
-    if ((next = strpbrk(p, "\n\r\t")) != NULL) {
-        i = next - p;
-    } else {
-        i = strlen(p);
-    }
-    if (buffsize == 0) {
-        buffsize = i;
-        buff = xmalloc(buffsize + 1);
-    }
-    else if (buffsize < i) {
-        buffsize = i;
-        buff = xrealloc(buff, buffsize + 1);
-    }
-
-    strncpy(buff, p, i);
-    buff[i] = '\0';
-    return buff;
-}
-
-/*
-**  Read overview.fmt and find index for headers
-*/
-static void
-OVfindheaderindex(void)
-{
-    FILE        *F;
-    char        *active;
-    char        *path;
-    int         i;
-
-    if (ReadOverviewfmt)
-        return;
-    if (innconf->groupbaseexpiry) {
-        ACTIVE = concatpath(innconf->pathdb, _PATH_ACTIVE);
-        if ((active = ReadInFile(ACTIVE, (struct stat *)NULL)) == NULL) {
-            fprintf(stderr, "Can't read %s, %s\n",
-            ACTIVE, strerror(errno));
-            exit(1);
-        }
-        BuildGroups(active);
-        arts = xmalloc(nGroups * sizeof(char *));
-        krps = xmalloc(nGroups * sizeof(enum KRP));
-        path = concatpath(innconf->pathetc, _PATH_EXPIRECTL);
-        F = fopen(path, "r");
-        free(path);
-        if (!EXPreadfile(F)) {
-            fclose(F);
-            fprintf(stderr, "Format error in expire.ctl\n");
-            exit(1);
-        }
-        fclose(F);
-    }
-    ARTreadschema();
-    if (Dateindex == OVFMT_UNINIT) {
-        for (Dateindex = OVFMT_NODATE, i = 0; i < ARTfieldsize; i++) {
-            if (strcasecmp(ARTfields[i].Header, "Date") == 0) {
-                Dateindex = i;
-            } else if (strcasecmp(ARTfields[i].Header, "Xref") == 0) {
-                Xrefindex = i;
-            } else if (strcasecmp(ARTfields[i].Header, "Message-ID") == 0) {
-                Messageidindex = i;
-            }
-        }
-    }
-    ReadOverviewfmt = true;
-    return;
-}
-
-/*
-**  Do the work of expiring one line.  Assumes article still exists in the
-**  spool.  Returns true if article should be purged, or return false.
-*/
-bool
-OVgroupbasedexpire(TOKEN token, const char *group, const char *data,
-                   int len UNUSED, time_t arrived, time_t expires)
-{
-    static char         *Group = NULL;
-    char                *p;
-    int                 i;
-    int                 count;
-    time_t              when;
-    bool                poisoned;
-    bool                keeper;
-    bool                delete;
-    bool                purge;
-    char                *Xref;
-
-    if (SMprobe(SELFEXPIRE, &token, NULL)) {
-        if (!OVignoreselfexpire)
-            /* this article should be kept */
-            return false;
-    }
-    if (!ReadOverviewfmt) {
-        OVfindheaderindex();
-    }
-
-    if (OVusepost) {
-        if ((p = OVERGetHeader(data, Dateindex)) == NULL) {
-            EXPoverindexdrop++;
-            return true;
-        }
-        if ((when = parsedate(p, NULL)) == -1) {
-            EXPoverindexdrop++;
-            return true;
-        }
-    } else {
-        when = arrived;
-    }
-    if ((Xref = OVERGetHeader(data, Xrefindex)) == NULL) {
-        if (Group != NULL) {
-            free(Group);
-        }
-        Group = concat(group, ":", (char *) 0);
-        Xref = Group;
-    } else {
-        if ((Xref = strchr(Xref, ' ')) == NULL) {
-            EXPoverindexdrop++;
-            return true;
-        }
-        for (Xref++; *Xref == ' '; Xref++)
-            ;
-    }
-    if ((count = EXPsplit(Xref, ' ', arts, nGroups)) == -1) {
-        EXPoverindexdrop++;
-        return true;
-    }
-
-    /* arts is now an array of strings, each of which is a group name, a
-       colon, and an article number.  EXPkeepit wants just pure group names,
-       so replace the colons with nuls (deleting the overview entry if it
-       isn't in the expected form). */
-    for (i = 0; i < count; i++) {
-        p = strchr(arts[i], ':');
-        if (p == NULL) {
-            fflush(stdout);
-            fprintf(stderr, "Bad entry, \"%s\"\n", arts[i]);
-            EXPoverindexdrop++;
-            return true;
-        }
-        *p = '\0';
-    }
-
-    /* First check all postings */
-    poisoned = false;
-    keeper = false;
-    delete = false;
-    purge = true;
-    for (i = 0; i < count; ++i) {
-        if ((krps[i] = EXPkeepit(arts[i], when, expires)) == Poison)
-            poisoned = true;
-        if (OVkeep && (krps[i] == Keep))
-            keeper = true;
-        if ((krps[i] == Remove) && strcmp(group, arts[i]) == 0)
-            delete = true;
-        if ((krps[i] == Keep))
-            purge = false;
-    }
-    EXPprocessed++;
-
-    if (OVearliest) {
-        if (delete || poisoned || token.type == TOKEN_EMPTY) {
-            /* delete article if this is first entry */
-            if (strcmp(group, arts[0]) == 0) {
-                for (i = 0; i < count; i++)
-                    arts[i][strlen(arts[i])] = ':';
-                OVEXPremove(token, false, arts, count);
-            }
-            EXPoverindexdrop++;
-            return true;
-        }
-    } else { /* not earliest mode */
-        if ((!keeper && delete) || token.type == TOKEN_EMPTY) {
-            /* delete article if purge is set, indicating that it has
-               expired out of every group to which it was posted */
-            if (purge) {
-                for (i = 0; i < count; i++)
-                    arts[i][strlen(arts[i])] = ':';
-                OVEXPremove(token, false, arts, count);
-            }
-            EXPoverindexdrop++;
-            return true;
-        }
-    }
-
-    /* this article should be kept */
-    return false;
-}
-
-bool
-OVhisthasmsgid(struct history *h, const char *data)
-{
-    char *p;
-
-    if (!ReadOverviewfmt) {
-        OVfindheaderindex();
-    }
-    if ((p = OVERGetHeader(data, Messageidindex)) == NULL)
-        return false;
-    return HISlookup(h, p, NULL, NULL, NULL, NULL);
-}
-
-bool
-OVgroupmatch(const char *group)
-{
-    int i;
-    bool wanted = false;
-
-    if (OVnumpatterns == 0 || group == NULL)
-        return true;
-    for (i = 0; i < OVnumpatterns; i++) {
-        switch (OVpatterns[i][0]) {
-        case '!':
-            if (!wanted && uwildmat(group, &OVpatterns[i][1]))
-                break;
-        case '@':
-            if (uwildmat(group, &OVpatterns[i][1])) {
-                return false;
-            }
-            break;
-        default:
-            if (uwildmat(group, OVpatterns[i]))
-                wanted = true;
-        }
-    }
-    return wanted;
-}
-
-void
-OVEXPcleanup(void)
-{
-    int i;
-    BADGROUP *bg, *bgnext;
-    ARTOVERFIELD *fp;
-    NGHASH *htp;
-
-    if (EXPprocessed != 0) {
-        if (!OVquiet) {
-            printf("    Article lines processed %8ld\n", EXPprocessed);
-            printf("    Articles dropped        %8ld\n", EXPunlinked);
-            printf("    Overview index dropped  %8ld\n", EXPoverindexdrop);
-        }
-        EXPprocessed = EXPunlinked = EXPoverindexdrop = 0;
-    }
-    if (innconf->ovgrouppat != NULL) {
-        for (i = 0 ; i < OVnumpatterns ; i++)
-            free(OVpatterns[i]);
-        free(OVpatterns);
-    }
-    for (bg = EXPbadgroups; bg; bg = bgnext) {
-        bgnext = bg->Next;
-        free(bg->Name);
-        free(bg);
-    }
-    for (fp = ARTfields, i = 0; i < ARTfieldsize ; i++, fp++) {
-        free(fp->Header);
-    }
-    free(ARTfields);
-    if (ACTIVE != NULL) {
-        free(ACTIVE);
-        ACTIVE = NULL;
-    }
-    if (Groups != NULL) {
-        free(Groups);
-        Groups = NULL;
-    }
-    for (i = 0, htp = NGHtable ; i < NGH_SIZE ; i++, htp++) {
-        if (htp->Groups != NULL) {
-            free(htp->Groups);
-            htp->Groups = NULL;
-        }
-    }
-}
diff --git a/storage/interface.c b/storage/interface.c
deleted file mode 100644 (file)
index dde700d..0000000
+++ /dev/null
@@ -1,962 +0,0 @@
-/*  $Id: interface.c 7277 2005-06-07 04:40:16Z eagle $
-**
-**  Storage Manager interface
-*/
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <syslog.h>
-#include <time.h>
-
-#include "conffile.h"
-#include "inn/innconf.h"
-#include "inn/wire.h"
-#include "interface.h"
-#include "libinn.h"
-#include "methods.h"
-#include "paths.h"
-
-typedef enum {INIT_NO, INIT_DONE, INIT_FAIL} INITTYPE;
-typedef struct {
-    INITTYPE           initialized;
-    bool               configured;
-    bool               selfexpire;
-    bool               expensivestat;
-} METHOD_DATA;
-
-METHOD_DATA method_data[NUM_STORAGE_METHODS];
-
-static STORAGE_SUB      *subscriptions = NULL;
-static unsigned int     typetoindex[256];
-int                     SMerrno;
-char                    *SMerrorstr = NULL;
-static bool             ErrorAlloc = false;
-static bool             Initialized = false;
-bool                   SMopenmode = false;
-bool                   SMpreopen = false;
-
-/*
-** Checks to see if the token is valid
-*/
-bool IsToken(const char *text) {
-    const char          *p;
-    
-    if (!text)
-       return false;
-    
-    if (strlen(text) != (sizeof(TOKEN) * 2) + 2)
-       return false;
-    
-    if (text[0] != '@')
-       return false;
-
-    if (text[(sizeof(TOKEN) * 2) + 1] != '@')
-       return false;
-
-    for (p = text + 1; *p != '@'; p++)
-       if (!isxdigit((int)*p))
-           return false;
-    
-    return true;
-}
-
-/*
-** Converts a token to a textual representation for error messages
-** and the like.
-*/
-char *
-TokenToText(const TOKEN token)
-{
-    static const char   hex[] = "0123456789ABCDEF";
-    static char         result[(sizeof(TOKEN) * 2) + 3];
-    const char          *p;
-    char                *q;
-    size_t              i;
-
-    
-    result[0] = '@';
-    for (q = result + 1, p = (const char *) &token, i = 0; i < sizeof(TOKEN);
-         i++, p++) {
-       *q++ = hex[(*p & 0xF0) >> 4];
-       *q++ = hex[*p & 0x0F];
-    }
-    *q++ = '@';
-    *q++ = '\0';
-    return result;
-    
-}
-
-/*
-** Converts a hex digit and converts it to a int
-*/
-static int hextodec(const int c) {
-    return isdigit(c) ? (c - '0') : ((c - 'A') + 10);
-}
-
-/*
-** Converts a textual representation of a token back to a native
-** representation
-*/
-TOKEN TextToToken(const char *text) {
-    const char          *p;
-    char                *q;
-    int                 i;
-    TOKEN               token;
-
-    if (text[0] == '@')
-       p = &text[1];
-    else
-       p = text;
-
-    for (q = (char *)&token, i = 0; i != sizeof(TOKEN); i++) {
-       q[i] = (hextodec(*p) << 4) + hextodec(*(p + 1));
-       p += 2;
-    }
-    return token;
-}
-
-/*
-** Given an article and length in non-wire format, return a malloced region
-** containing the article in wire format.  Set *newlen to the length of the
-** new article.
-*/ 
-char *
-ToWireFmt(const char *article, size_t len, size_t *newlen)
-{
-    size_t bytes;
-    char *newart;
-    const char *p;
-    char  *dest;
-    bool atstartofline=true;
-
-    /* First go thru article and count number of bytes we need. */
-    for (bytes = 0, p=article ; p < &article[len] ; ++p) {
-       if (*p == '.' && atstartofline) ++bytes; /* 1 byte for escaping . */
-       ++bytes;
-       if (*p == '\n') {
-           ++bytes; /* need another byte for CR */
-           atstartofline = true; /* next char starts new line */
-       } else {
-           atstartofline = false;
-       }
-    }
-    bytes += 3; /* for .\r\n */
-    newart = xmalloc(bytes + 1);
-    *newlen = bytes;
-
-    /* now copy the article, making changes */
-    atstartofline = true;
-    for (p=article, dest=newart ; p < &article[len] ; ++p) {
-       if (*p == '\n') {
-           *dest++ = '\r';
-           *dest++ = '\n';
-           atstartofline = true;
-       } else {
-           if (atstartofline && *p == '.') *dest++ = '.'; /* add extra . */
-           *dest++ = *p;
-           atstartofline = false;
-       }
-    }
-    *dest++ = '.';
-    *dest++ = '\r';
-    *dest++ = '\n';
-    *dest = '\0';
-    return newart;
-}
-
-char *
-FromWireFmt(const char *article, size_t len, size_t *newlen)
-{
-    size_t bytes;
-    char *newart;
-    const char *p;
-    char *dest;
-    bool atstartofline = true;
-
-    /* First go thru article and count number of bytes we need */
-    for (bytes = 0, p=article ; p < &article[len] ; ) {
-       /* check for terminating .\r\n and if so break */
-       if (p == &article[len-3] && *p == '.' && p[1] == '\r' && p[2] == '\n')
-           break;
-       /* check for .. at start-of-line */
-       if (atstartofline && p < &article[len-1] && *p == '.' && p[1] == '.') {
-           bytes++; /* only output 1 byte */
-           p+=2; 
-           atstartofline = false;
-       } else if (p < &article[len-1] && *p == '\r' && p[1] == '\n') { 
-           bytes++; /* \r\n counts as only one byte in output */
-           p += 2;
-           atstartofline = true;
-       } else {
-           bytes++;
-           p++;
-           atstartofline = false;
-       }
-    }
-    newart = xmalloc(bytes + 1);
-    *newlen = bytes;
-    for (p = article, dest = newart ; p < &article[len]; ) {
-       /* check for terminating .\r\n and if so break */
-       if (p == &article[len-3] && *p == '.' && p[1] == '\r' && p[2] == '\n')
-           break;
-       if (atstartofline && p < &article[len-1] && *p == '.' && p[1] == '.') {
-           *dest++ = '.';
-           p += 2;
-           atstartofline = false;
-       } else if (p < &article[len-1] && *p == '\r' && p[1] == '\n') {
-           *dest++ = '\n';
-           p += 2;
-           atstartofline = true;
-       } else {
-           *dest++ = *p++;
-           atstartofline = false;
-       }
-    }
-    *dest = '\0';
-    return newart;
-}
-
-/*
-**  get Xref header without pathhost
-*/
-static char *
-GetXref(ARTHANDLE *art)
-{
-  const char *p, *p1;
-  const char *q;
-  char *buff;
-  bool Nocr = false;
-
-  p = wire_findheader(art->data, art->len, "xref");
-  if (p == NULL)
-    return NULL;
-  q = p;
-  for (p1 = NULL; p < art->data + art->len; p++) {
-    if (p1 != (char *)NULL && *p1 == '\r' && *p == '\n') {
-      Nocr = false;
-      break;
-    }
-    if (*p == '\n') {
-      Nocr = true;
-      break;
-    }
-    p1 = p;
-  }
-  if (p >= art->data + art->len)
-    return NULL;
-  if (!Nocr)
-    p = p1;
-  /* skip pathhost */
-  for (; (*q == ' ') && (q < p); q++);
-  if (q == p)
-    return NULL;
-  if ((q = memchr(q, ' ', p - q)) == NULL)
-    return NULL;
-  for (q++; (*q == ' ') && (q < p); q++);
-  if (q == p)
-    return NULL;
-  buff = xmalloc(p - q + 1);
-  memcpy(buff, q, p - q);
-  buff[p - q] = '\0';
-  return buff;
-}
-
-/*
-**  Split newsgroup and returns artnum
-**  or 0 if there are no newsgroup.
-*/
-static ARTNUM GetGroups(char *Xref) {
-  char *p;
-
-  if ((p = strchr(Xref, ':')) == NULL)
-    return 0;
-  *p++ = '\0';
-  return ((ARTNUM)atoi(p));
-}
-
-STORAGE_SUB *SMGetConfig(STORAGETYPE type, STORAGE_SUB *sub) {
-    if (sub == (STORAGE_SUB *)NULL)
-       sub = subscriptions;
-    else
-       sub = sub->next;
-    for (;sub != NULL; sub = sub->next) {
-       if (sub->type == type) {
-           return sub;
-       }
-    }
-    return (STORAGE_SUB *)NULL;
-}
-
-static time_t ParseTime(char *tmbuf)
-{
-    char *startnum;
-    time_t ret;
-    int tmp;
-
-    ret = 0;
-    startnum = tmbuf;
-    while (*tmbuf) {
-       if (!isdigit((int)*tmbuf)) {
-           tmp = atol(startnum);
-           switch (*tmbuf) {
-             case 'M':
-               ret += tmp*60*60*24*31;
-               break;
-             case 'd':
-               ret += tmp*60*60*24;
-               break;
-             case 'h':
-               ret += tmp*60*60;
-               break;
-             case 'm':
-               ret += tmp*60;
-               break;
-             case 's':
-               ret += tmp;
-               break;
-             default:
-               return(0);
-           }
-           startnum = tmbuf+1;
-       }
-       tmbuf++;
-    }
-    return(ret);
-}
-
-#define SMlbrace  1
-#define SMrbrace  2
-#define SMmethod  10
-#define SMgroups  11
-#define SMsize    12
-#define SMclass   13
-#define SMexpire  14
-#define SMoptions 15
-#define SMexactmatch 16
-
-static CONFTOKEN smtoks[] = {
-  { SMlbrace,  "{" },
-  { SMrbrace,  "}" },
-  { SMmethod,  "method" },
-  { SMgroups,  "newsgroups:" },
-  { SMsize,    "size:" },
-  { SMclass,   "class:" },
-  { SMexpire,  "expires:" },
-  { SMoptions, "options:" },
-  { SMexactmatch,      "exactmatch:" },
-  { 0, 0 }
-};
-
-/* Open the config file and parse it, generating the policy data */
-static bool
-SMreadconfig(void)
-{
-    CONFFILE            *f;
-    CONFTOKEN           *tok;
-    int                        type;
-    int                 i;
-    char                *p;
-    char                *q;
-    char                *path;
-    char                *method = NULL;
-    char                *pattern = NULL;
-    size_t              minsize = 0;
-    size_t              maxsize = 0;
-    time_t             minexpire = 0;
-    time_t             maxexpire = 0;
-    int                 class = 0;
-    STORAGE_SUB         *sub = NULL;
-    STORAGE_SUB         *prev = NULL;
-    char               *options = 0;
-    int                        inbrace;
-    bool               exactmatch = false;
-
-    /* if innconf isn't already read in, do so. */
-    if (innconf == NULL) {
-        if (!innconf_read(NULL)) {
-           SMseterror(SMERR_INTERNAL, "ReadInnConf() failed");
-           return false;
-       }
-    }
-
-    for (i = 0; i < NUM_STORAGE_METHODS; i++) {
-       method_data[i].initialized = INIT_NO;
-       method_data[i].configured = false;
-    }
-    path = concatpath(innconf->pathetc, _PATH_STORAGECTL);
-    f = CONFfopen(path);
-    if (f == NULL) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "SM Could not open %s: %m", path);
-        free(path);
-       return false;
-    }
-    free(path);
-    
-    inbrace = 0;
-    while ((tok = CONFgettoken(smtoks, f)) != NULL) {
-       if (!inbrace) {
-           if (tok->type != SMmethod) {
-               SMseterror(SMERR_CONFIG, "Expected 'method' keyword");
-               syslog(L_ERROR, "SM expected 'method' keyword, line %d", f->lineno);
-               return false;
-           }
-           if ((tok = CONFgettoken(0, f)) == NULL) {
-               SMseterror(SMERR_CONFIG, "Expected method name");
-               syslog(L_ERROR, "SM expected method name, line %d", f->lineno);
-               return false;
-           }
-           method = xstrdup(tok->name);
-           if ((tok = CONFgettoken(smtoks, f)) == NULL || tok->type != SMlbrace) {
-               SMseterror(SMERR_CONFIG, "Expected '{'");
-               syslog(L_ERROR, "SM Expected '{', line %d", f->lineno);
-               return false;
-           }
-           inbrace = 1;
-           /* initialize various params to defaults. */
-           minsize = 0;
-           maxsize = 0; /* zero means no limit */
-           class = 0;
-            pattern = NULL;
-           options = NULL;
-           minexpire = 0;
-           maxexpire = 0;
-           exactmatch = false;
-
-       } else {
-           type = tok->type;
-           if (type == SMrbrace)
-               inbrace = 0;
-           else {
-               if ((tok = CONFgettoken(0, f)) == NULL) {
-                   SMseterror(SMERR_CONFIG, "Keyword with no value");
-                   syslog(L_ERROR, "SM keyword with no value, line %d", f->lineno);
-                   return false;
-               }
-               p = tok->name;
-               switch(type) {
-                 case SMgroups:
-                   if (pattern)
-                       free(pattern);
-                   pattern = xstrdup(tok->name);
-                   break;
-                 case SMsize:
-                   minsize = strtoul(p, NULL, 10);
-                   if ((p = strchr(p, ',')) != NULL) {
-                       p++;
-                       maxsize = strtoul(p, NULL, 10);
-                   }
-                   break;
-                 case SMclass:
-                   class = atoi(p);
-                    if (class > NUM_STORAGE_CLASSES) {
-                        SMseterror(SMERR_CONFIG, "Storage class too large");
-                        warn("SM: storage class larger than %d, line %d",
-                             NUM_STORAGE_CLASSES, f->lineno);
-                        return false;
-                    }
-                   break;
-                 case SMexpire:
-                   q = strchr(p, ',');
-                   if (q)
-                       *q++ = 0;
-                   minexpire = ParseTime(p);
-                   if (q)
-                       maxexpire = ParseTime(q);
-                   break;
-                 case SMoptions:
-                   if (options)
-                       free(options);
-                   options = xstrdup(p);
-                   break;
-                 case SMexactmatch:
-                   if (strcasecmp(p, "true") == 0
-                        || strcasecmp(p, "yes") == 0
-                        || strcasecmp(p, "on") == 0)
-                       exactmatch = true;
-                   break;
-                 default:
-                   SMseterror(SMERR_CONFIG, "Unknown keyword in method declaration");
-                   syslog(L_ERROR, "SM Unknown keyword in method declaration, line %d: %s", f->lineno, tok->name);
-                   free(method);
-                   return false;
-                   break;
-               }
-           }
-       }
-       if (!inbrace) {
-           /* just finished a declaration */
-           sub = xmalloc(sizeof(STORAGE_SUB));
-           sub->type = TOKEN_EMPTY;
-           for (i = 0; i < NUM_STORAGE_METHODS; i++) {
-               if (!strcasecmp(method, storage_methods[i].name)) {
-                   sub->type = storage_methods[i].type;
-                   method_data[i].configured = true;
-                   break;
-               }
-           }
-           if (sub->type == TOKEN_EMPTY) {
-               SMseterror(SMERR_CONFIG, "Invalid storage method name");
-               syslog(L_ERROR, "SM no configured storage methods are named '%s'", method);
-               free(options);
-               free(sub);
-               return false;
-           }
-           if (!pattern) {
-               SMseterror(SMERR_CONFIG, "pattern not defined");
-               syslog(L_ERROR, "SM no pattern defined");
-               free(options);
-               free(sub);
-               return false;
-           }
-            sub->pattern = pattern;
-           sub->minsize = minsize;
-           sub->maxsize = maxsize;
-           sub->class = class;
-           sub->options = options;
-           sub->minexpire = minexpire;
-           sub->maxexpire = maxexpire;
-           sub->exactmatch = exactmatch;
-
-           free(method);
-           method = 0;
-
-           if (!prev)
-               subscriptions = sub;
-           if (prev)
-               prev->next = sub;
-           prev = sub;
-           sub->next = NULL;
-       }
-    }
-    
-    CONFfclose(f);
-
-    return true;
-}
-
-/*
-** setup storage api environment (open mode etc.)
-*/
-bool SMsetup(SMSETUP type, void *value) {
-    if (Initialized)    
-       return false;
-    switch (type) {
-    case SM_RDWR:
-       SMopenmode = *(bool *)value;
-       break;
-    case SM_PREOPEN:
-       SMpreopen = *(bool *)value;
-       break;
-    default:
-       return false;
-    }
-    return true;
-}
-
-/*
-** Calls the setup function for all of the configured methods and returns
-** true if they all initialize ok, false if they don't
-*/
-bool SMinit(void) {
-    int                 i;
-    bool               allok = true;
-    static             bool once = false;
-    SMATTRIBUTE                smattr;
-
-    if (Initialized)
-       return true;
-    
-    Initialized = true;
-    
-    if (!SMreadconfig()) {
-       SMshutdown();
-       Initialized = false;
-       return false;
-    }
-
-    for (i = 0; i < NUM_STORAGE_METHODS; i++) {
-       if (method_data[i].configured) {
-           if (method_data[i].configured && storage_methods[i].init(&smattr)) {
-               method_data[i].initialized = INIT_DONE;
-               method_data[i].selfexpire = smattr.selfexpire;
-               method_data[i].expensivestat = smattr.expensivestat;
-           } else {
-               method_data[i].initialized = INIT_FAIL;
-               method_data[i].selfexpire = false;
-               method_data[i].expensivestat = true;
-               syslog(L_ERROR, "SM storage method '%s' failed initialization", storage_methods[i].name);
-               allok = false;
-           }
-       }
-       typetoindex[storage_methods[i].type] = i;
-    }
-    if (!allok) {
-       SMshutdown();
-       Initialized = false;
-       SMseterror(SMERR_UNDEFINED, "one or more storage methods failed initialization");
-       syslog(L_ERROR, "SM one or more storage methods failed initialization");
-       return false;
-    }
-    if (!once && atexit(SMshutdown) < 0) {
-       SMshutdown();
-       Initialized = false;
-       SMseterror(SMERR_UNDEFINED, NULL);
-       return false;
-    }
-    once = true;
-    return true;
-}
-
-static bool InitMethod(STORAGETYPE method) {
-    SMATTRIBUTE                smattr;
-
-    if (!Initialized)
-       if (!SMreadconfig()) {
-           Initialized = false;
-           return false;
-       }
-    Initialized = true;
-    
-    if (method_data[method].initialized == INIT_DONE)
-       return true;
-
-    if (method_data[method].initialized == INIT_FAIL)
-       return false;
-
-    if (!method_data[method].configured) {
-       method_data[method].initialized = INIT_FAIL;
-       SMseterror(SMERR_UNDEFINED, "storage method is not configured.");
-       return false;
-    }
-    if (!storage_methods[method].init(&smattr)) {
-       method_data[method].initialized = INIT_FAIL;
-       method_data[method].selfexpire = false;
-       method_data[method].expensivestat = true;
-       SMseterror(SMERR_UNDEFINED, "Could not initialize storage method late.");
-       return false;
-    }
-    method_data[method].initialized = INIT_DONE;
-    method_data[method].selfexpire = smattr.selfexpire;
-    method_data[method].expensivestat = smattr.expensivestat;
-    return true;
-}
-
-static bool
-MatchGroups(const char *g, int len, const char *pattern, bool exactmatch)
-{
-    char *group, *groups, *q;
-    int i, lastwhite;
-    enum uwildmat matched;
-    bool wanted = false;
-
-    q = groups = xmalloc(len + 1);
-    for (lastwhite = -1,  i = 0 ; i < len ; i++) {
-       /* trim white chars */
-       if (g[i] == '\r' || g[i] == '\n' || g[i] == ' ' || g[i] == '\t') {
-           if (lastwhite + 1 != i)
-               *q++ = ' ';
-           lastwhite = i;
-       } else
-           *q++ = g[i];
-    }
-    *q = '\0';
-
-    group = strtok(groups, " ,");
-    while (group != NULL) {
-        q = strchr(group, ':');
-        if (q != NULL)
-            *q = '\0';
-        matched = uwildmat_poison(group, pattern);
-        if (matched == UWILDMAT_POISON || (exactmatch && !matched)) {
-           free(groups);
-           return false;
-       }
-        if (matched == UWILDMAT_MATCH)
-            wanted = true;
-        group = strtok(NULL, " ,");
-    }
-
-    free(groups);
-    return wanted;
-}
-
-STORAGE_SUB *SMgetsub(const ARTHANDLE article) {
-    STORAGE_SUB         *sub;
-
-    if (article.len == 0) {
-       SMseterror(SMERR_BADHANDLE, NULL);
-       return NULL;
-    }
-
-    if (article.groups == NULL)
-       return NULL;
-
-    for (sub = subscriptions; sub != NULL; sub = sub->next) {
-       if (!(method_data[typetoindex[sub->type]].initialized == INIT_FAIL) &&
-           (article.len >= sub->minsize) &&
-           (!sub->maxsize || (article.len <= sub->maxsize)) &&
-           (!sub->minexpire || article.expires >= sub->minexpire) &&
-           (!sub->maxexpire || (article.expires <= sub->maxexpire)) &&
-           MatchGroups(article.groups, article.groupslen, sub->pattern,
-                        sub->exactmatch)) {
-           if (InitMethod(typetoindex[sub->type]))
-               return sub;
-       }
-    }
-    errno = 0;
-    SMseterror(SMERR_NOMATCH, "no matching entry in storage.conf");
-    return NULL;
-}
-
-TOKEN SMstore(const ARTHANDLE article) {
-    STORAGE_SUB         *sub;
-    TOKEN               result;
-
-    if (!SMopenmode) {
-       result.type = TOKEN_EMPTY;
-       SMseterror(SMERR_INTERNAL, "read only storage api");
-       return result;
-    }
-    result.type = TOKEN_EMPTY;
-    if ((sub = SMgetsub(article)) == NULL) {
-       return result;
-    }
-    return storage_methods[typetoindex[sub->type]].store(article, sub->class);
-}
-
-ARTHANDLE *SMretrieve(const TOKEN token, const RETRTYPE amount) {
-    ARTHANDLE           *art;
-
-    if (method_data[typetoindex[token.type]].initialized == INIT_FAIL) {
-       SMseterror(SMERR_UNINIT, NULL);
-       return NULL;
-    }
-    if (method_data[typetoindex[token.type]].initialized == INIT_NO && !InitMethod(typetoindex[token.type])) {
-       syslog(L_ERROR, "SM could not find token type or method was not initialized (%d)",
-              token.type);
-       SMseterror(SMERR_UNINIT, NULL);
-       return NULL;
-    }
-    art = storage_methods[typetoindex[token.type]].retrieve(token, amount);
-    if (art)
-       art->nextmethod = 0;
-    return art;
-
-}
-
-ARTHANDLE *SMnext(const ARTHANDLE *article, const RETRTYPE amount) {
-    unsigned char       i;
-    int                 start;
-    ARTHANDLE           *newart;
-
-    if (article == NULL)
-       start = 0;
-    else
-       start= article->nextmethod;
-
-    if (method_data[start].initialized == INIT_FAIL) {
-       SMseterror(SMERR_UNINIT, NULL);
-       return NULL;
-    }
-    if (method_data[start].initialized == INIT_NO && method_data[start].configured
-      && !InitMethod(start)) {
-       SMseterror(SMERR_UNINIT, NULL);
-       return NULL;
-    }
-
-    for (i = start, newart = NULL; i < NUM_STORAGE_METHODS; i++) {
-       if (method_data[i].configured && (newart = storage_methods[i].next(article, amount)) != (ARTHANDLE *)NULL) {
-           newart->nextmethod = i;
-           break;
-       } else
-           article = NULL;
-    }
-
-    return newart;
-}
-
-void SMfreearticle(ARTHANDLE *article) {
-    if (method_data[typetoindex[article->type]].initialized == INIT_FAIL) {
-       return;
-    }
-    if (method_data[typetoindex[article->type]].initialized == INIT_NO && !InitMethod(typetoindex[article->type])) {
-       syslog(L_ERROR, "SM can't free article with uninitialized method");
-       return;
-    }
-    storage_methods[typetoindex[article->type]].freearticle(article);
-}
-
-bool SMcancel(TOKEN token) {
-    if (!SMopenmode) {
-       SMseterror(SMERR_INTERNAL, "read only storage api");
-       return false;
-    }
-    if (method_data[typetoindex[token.type]].initialized == INIT_FAIL) {
-       SMseterror(SMERR_UNINIT, NULL);
-       return false;
-    }
-    if (method_data[typetoindex[token.type]].initialized == INIT_NO && !InitMethod(typetoindex[token.type])) {
-       SMseterror(SMERR_UNINIT, NULL);
-       syslog(L_ERROR, "SM can't cancel article with uninitialized method");
-       return false;
-    }
-    return storage_methods[typetoindex[token.type]].cancel(token);
-}
-
-bool SMprobe(PROBETYPE type, TOKEN *token, void *value) {
-    struct artngnum    *ann;
-    ARTHANDLE          *art;
-
-    switch (type) {
-    case SELFEXPIRE:
-       return (method_data[typetoindex[token->type]].selfexpire);
-    case SMARTNGNUM:
-       if (method_data[typetoindex[token->type]].initialized == INIT_FAIL) {
-           SMseterror(SMERR_UNINIT, NULL);
-           return false;
-       }
-       if (method_data[typetoindex[token->type]].initialized == INIT_NO && !InitMethod(typetoindex[token->type])) {
-           SMseterror(SMERR_UNINIT, NULL);
-           syslog(L_ERROR, "SM can't cancel article with uninitialized method");
-           return false;
-       }
-       if ((ann = (struct artngnum *)value) == NULL)
-           return false;
-       ann->groupname = NULL;
-       if (storage_methods[typetoindex[token->type]].ctl(type, token, value)) {
-           if (ann->artnum != 0) {
-               /* set by storage method */
-               return true;
-           } else {
-               art = storage_methods[typetoindex[token->type]].retrieve(*token, RETR_HEAD);
-               if (art == NULL) {
-                   if (ann->groupname != NULL)
-                       free(ann->groupname);
-                   storage_methods[typetoindex[token->type]].freearticle(art);
-                   return false;
-               }
-               if ((ann->groupname = GetXref(art)) == NULL) {
-                   if (ann->groupname != NULL)
-                       free(ann->groupname);
-                   storage_methods[typetoindex[token->type]].freearticle(art);
-                   return false;
-               }
-               storage_methods[typetoindex[token->type]].freearticle(art);
-               if ((ann->artnum = GetGroups(ann->groupname)) == 0) {
-                   if (ann->groupname != NULL)
-                       free(ann->groupname);
-                   return false;
-               }
-               return true;
-           }
-       } else {
-           return false;
-       }
-    case EXPENSIVESTAT:
-       return (method_data[typetoindex[token->type]].expensivestat);
-    default:
-       return false;
-    }
-}
-
-bool SMflushcacheddata(FLUSHTYPE type) {
-    int                i;
-
-    for (i = 0; i < NUM_STORAGE_METHODS; i++) {
-       if (method_data[i].initialized == INIT_DONE &&
-           !storage_methods[i].flushcacheddata(type))
-           syslog(L_ERROR, "SM can't flush cached data method '%s'", storage_methods[i].name);
-    }
-    return true;
-}
-
-void SMprintfiles(FILE *file, TOKEN token, char **xref, int ngroups) {
-    if (method_data[typetoindex[token.type]].initialized == INIT_FAIL)
-       return;
-    if (method_data[typetoindex[token.type]].initialized == INIT_NO
-        && !InitMethod(typetoindex[token.type])) {
-       SMseterror(SMERR_UNINIT, NULL);
-       syslog(L_ERROR, "SM can't print files for article with uninitialized method");
-       return;
-    }
-    storage_methods[typetoindex[token.type]].printfiles(file, token, xref, ngroups);
-}
-
-void SMshutdown(void) {
-    int                 i;
-    STORAGE_SUB         *old;
-
-    if (!Initialized)
-       return;
-
-    for (i = 0; i < NUM_STORAGE_METHODS; i++)
-       if (method_data[i].initialized == INIT_DONE) {
-           storage_methods[i].shutdown();
-           method_data[i].initialized = INIT_NO;
-           method_data[i].configured = false;
-       }
-    while (subscriptions) {
-       old = subscriptions;
-       subscriptions = subscriptions->next;
-       free(old->pattern);
-       free(old->options);
-       free(old);
-    }
-    Initialized = false;
-}
-
-void SMseterror(int errornum, char *error) {
-    if (ErrorAlloc)
-       free(SMerrorstr);
-
-    ErrorAlloc = false;
-    
-    if ((errornum == SMERR_UNDEFINED) && (errno == ENOENT))
-       errornum = SMERR_NOENT;
-           
-    SMerrno = errornum;
-
-    if (error == NULL) {
-       switch (SMerrno) {
-       case SMERR_UNDEFINED:
-           SMerrorstr = xstrdup(strerror(errno));
-           ErrorAlloc = true;
-           break;
-       case SMERR_INTERNAL:
-           SMerrorstr = "Internal error";
-           break;
-       case SMERR_NOENT:
-           SMerrorstr = "Token not found";
-           break;
-       case SMERR_TOKENSHORT:
-           SMerrorstr = "Configured token size too small";
-           break;
-       case SMERR_NOBODY:
-           SMerrorstr = "No article body found";
-           break;
-       case SMERR_UNINIT:
-           SMerrorstr = "Storage manager is not initialized";
-           break;
-       case SMERR_CONFIG:
-           SMerrorstr = "Error reading config file";
-           break;
-       case SMERR_BADHANDLE:
-           SMerrorstr = "Bad article handle";
-           break;
-       case SMERR_BADTOKEN:
-           SMerrorstr = "Bad token";
-           break;
-       case SMERR_NOMATCH:
-           SMerrorstr = "No matching entry in storage.conf";
-           break;
-       default:
-           SMerrorstr = "Undefined error";
-       }
-    } else {
-       SMerrorstr = xstrdup(error);
-       ErrorAlloc = true;
-    }
-}
-
diff --git a/storage/interface.h b/storage/interface.h
deleted file mode 100644 (file)
index b59a783..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*  $Id: interface.h 5933 2002-12-07 09:47:17Z rra $
-**
-**  Storage Manager interface header
-*/
-
-#ifndef __INTERFACE_H__
-#define __INTERFACE_H__
-
-#include "config.h"
-#include "storage.h"
-#include <stdio.h>
-
-typedef struct {
-    bool       selfexpire;
-    bool       expensivestat;
-} SMATTRIBUTE;
-
-typedef struct {
-    const char          *name;
-    unsigned char       type;
-    bool                (*init)(SMATTRIBUTE *attr);
-    TOKEN               (*store)(const ARTHANDLE article, const STORAGECLASS storageclass);
-    ARTHANDLE           *(*retrieve)(const TOKEN token, const RETRTYPE amount);
-    ARTHANDLE           *(*next)(const ARTHANDLE *article, const RETRTYPE amount);
-    void                (*freearticle)(ARTHANDLE *article);
-    bool                (*cancel)(TOKEN token);
-    bool                (*ctl)(PROBETYPE type, TOKEN *token, void *value);
-    bool                (*flushcacheddata)(FLUSHTYPE type);
-    void                (*printfiles)(FILE *, TOKEN, char **xref, int ngroups);
-    void                (*shutdown)(void);
-} STORAGE_METHOD;
-
-typedef struct __S_SUB__ {
-    int                 type;        /* Index into storage_methods of the one to use */
-    size_t              minsize;     /* Minimum size to send to this method */
-    size_t              maxsize;     /* Maximum size to send to this method */
-    time_t             minexpire;   /* Minimum expire offset to send method */
-    time_t             maxexpire;   /* Maximum expire offset to send method */
-    int                 numpatterns; /* Number of patterns in patterns */
-    int                 class;       /* Number of the storage class for this subscription */
-    char                *pattern;    /* Wildmat pattern to check against the
-                                       groups to determine if the article
-                                       should go to this method */
-    char               *options;    /* additional options specific to the
-                                       method */
-    bool               exactmatch;  /* all newsgroups to which article belongs
-                                       should match the patterns */
-    struct __S_SUB__   *next;
-} STORAGE_SUB;
-
-extern bool SMopenmode;
-extern bool SMpreopen;
-char *SMFindBody(char *article, int len);
-STORAGE_SUB *SMGetConfig(STORAGETYPE type, STORAGE_SUB *sub);
-STORAGE_SUB *SMgetsub(const ARTHANDLE article);
-void SMseterror(int errorno, char *error);
-
-#endif /* __INTERFACE_H__ */
diff --git a/storage/ov.c b/storage/ov.c
deleted file mode 100644 (file)
index 37288aa..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*  $Id: ov.c 6135 2003-01-19 01:15:40Z rra $
-**
-**  The implementation of the overview API.
-**
-**  This code handles calls to the overview API by passing them along to the
-**  appropriate underlying overview method, as well as implementing those
-**  portions of the overview subsystem that are independent of storage
-**  method.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#include "inn/innconf.h"
-#include "libinn.h"
-#include "ov.h"
-#include "ovinterface.h"
-#include "ovmethods.h"
-
-/* FIXME: The following variables are shared between this file and expire.c.
-   This should be cleaned up with a better internal interface. */
-static bool    OVdelayrm;
-static OV_METHOD       ov;
-
-bool
-OVopen(int mode)
-{
-    int        i;
-    bool val;
-    char *p;
-
-    if (ov.open)
-       /* already opened */
-       return true;
-
-    /* if innconf isn't already read in, do so. */
-    if (innconf == NULL)
-        if (!innconf_read(NULL))
-            return false;
-    if (!innconf->enableoverview) {
-       syslog(L_FATAL, "enableoverview is not true");
-       fprintf(stderr, "enableoverview is not true\n");
-       return false;
-    }
-    if (innconf->ovmethod == NULL) {
-       syslog(L_FATAL, "ovmethod is not defined");
-       fprintf(stderr, "ovmethod is not defined\n");
-       return false;
-    }
-    for (i=0;i<NUM_OV_METHODS;i++) {
-       if (!strcmp(innconf->ovmethod, ov_methods[i].name))
-           break;
-    }
-    if (i == NUM_OV_METHODS) {
-       syslog(L_FATAL, "%s is not found for ovmethod", innconf->ovmethod);
-       fprintf(stderr, "%s is not found for ovmethod\n", innconf->ovmethod);
-       return false;
-    }
-    ov = ov_methods[i];
-    val = (*ov.open)(mode);
-    if (atexit(OVclose) < 0) {
-       OVclose();
-       return false;
-    }
-    if (innconf->ovgrouppat != NULL) {
-       for (i = 1, p = innconf->ovgrouppat; *p && (p = strchr(p+1, ',')); i++);
-       OVnumpatterns = i;
-       OVpatterns = xmalloc(OVnumpatterns * sizeof(char *));
-       for (i = 0, p = strtok(innconf->ovgrouppat, ","); p != NULL && i <= OVnumpatterns ; i++, p = strtok(NULL, ","))
-           OVpatterns[i] = xstrdup(p);
-       if (i != OVnumpatterns) {
-           syslog(L_FATAL, "extra ',' in pattern");
-           fprintf(stderr, "extra ',' in pattern");
-           return false;
-       }
-    }
-    return val;
-}
-
-bool
-OVgroupstats(char *group, int *lo, int *hi, int *count, int *flag)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.groupstats)(group, lo, hi, count, flag));
-}
-
-bool
-OVgroupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag)
-{
-    /* lomark should never be changed in each ovmethod if lo is 0 */
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.groupadd)(group, lo, hi, flag));
-}
-
-bool
-OVgroupdel(char *group)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.groupdel)(group));
-}
-
-OVADDRESULT
-OVadd(TOKEN token, char *data, int len, time_t arrived, time_t expires)
-{
-    char               *next, *nextcheck;
-    static char                *xrefdata, *patcheck, *overdata;
-    char                *xrefstart = NULL;
-    char               *xrefend;
-    static int         xrefdatalen = 0, overdatalen = 0;
-    bool               found = false;
-    int                        xreflen;
-    int                        i;
-    char               *group;
-    ARTNUM             artnum;
-
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return OVADDFAILED;
-    }
-
-    /*
-     * find last Xref: in the overview line.  Note we need to find the *last*
-     * Xref:, since there have been corrupted articles on Usenet with Xref:
-     * fragments stuck in other header lines.  The last Xref: is guaranteed
-     * to be from our server.
-     */
-
-    for (next = data; ((len - (next - data)) > 6 ) && ((next = memchr(next, 'X', len - (next - data))) != NULL); ) {
-        if (memcmp(next, "Xref: ", 6) == 0) {
-            found =  true;
-            xrefstart = next;
-        }
-        next++;
-    }
-
-    if (!found)
-        return OVADDFAILED;
-
-    next = xrefstart;
-    for (i = 0; (i < 2) && (next < (data + len)); i++) {
-        if ((next = memchr(next, ' ', len - (next - data))) == NULL)
-            return OVADDFAILED;
-        next++;
-    }
-    xreflen = len - (next - data);
-
-    /*
-     * If there are other fields beyond Xref in overview, then
-     * we must find Xref's end, or data following is misinterpreted.
-     */
-    if ((xrefend = memchr(next, '\t', xreflen)) != NULL)
-       xreflen = xrefend - next;
-
-    if (xrefdatalen == 0) {
-        xrefdatalen = BIG_BUFFER;
-        xrefdata = xmalloc(xrefdatalen);
-        if (innconf->ovgrouppat != NULL)
-            patcheck = xmalloc(xrefdatalen);
-    }
-    if (xreflen > xrefdatalen) {
-        xrefdatalen = xreflen;
-        xrefdata = xrealloc(xrefdata, xrefdatalen + 1);
-        if (innconf->ovgrouppat != NULL)
-            patcheck = xrealloc(patcheck, xrefdatalen + 1);
-    }
-    if (overdatalen == 0) {
-       overdatalen = BIG_BUFFER;
-       overdata = xmalloc(overdatalen);
-    }
-    if (len + 16 > overdatalen) {
-       overdatalen = len + 16;
-        overdata = xrealloc(overdata, overdatalen);
-    }
-
-    if (innconf->ovgrouppat != NULL) {
-        memcpy(patcheck, next, xreflen);
-        patcheck[xreflen] = '\0';
-        for (group = patcheck; group && *group; group = memchr(nextcheck, ' ', xreflen - (nextcheck - patcheck))) {
-            while (isspace((int)*group))
-                group++;
-            if ((nextcheck = memchr(group, ':', xreflen - (patcheck - group))) == NULL)
-                return OVADDFAILED;
-            *nextcheck++ = '\0';
-            if (!OVgroupmatch(group)) {
-                if (!SMprobe(SELFEXPIRE, &token, NULL) && innconf->groupbaseexpiry)
-                    /* this article will never be expired, since it does not
-                       have self expiry function in stored method and
-                       groupbaseexpiry is true */
-                    return OVADDFAILED;
-                return OVADDGROUPNOMATCH;
-            }
-        }
-    }
-    memcpy(xrefdata, next, xreflen);
-    xrefdata[xreflen] = '\0';
-    for (group = xrefdata; group && *group; group = memchr(next, ' ', xreflen - (next - xrefdata))) {
-        /* Parse the xref part into group name and article number */
-        while (isspace((int)*group))
-            group++;
-        if ((next = memchr(group, ':', xreflen - (group - xrefdata))) == NULL)
-            return OVADDFAILED;
-        *next++ = '\0';
-        artnum = atoi(next);
-        if (artnum <= 0)
-            continue;
-
-        sprintf(overdata, "%ld\t", artnum);
-        i = strlen(overdata);
-        memcpy(overdata + i, data, len);
-        i += len;
-        memcpy(overdata + i, "\r\n", 2);
-        i += 2;
-
-       if(! (*ov.add)(group, artnum, token, overdata, i, arrived, expires))
-           return OVADDFAILED;
-    }
-
-    return OVADDCOMPLETED;
-}
-
-bool
-OVcancel(TOKEN token)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.cancel)(token));
-}
-
-void *
-OVopensearch(char *group, int low, int high)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.opensearch)(group, low, high));
-}
-
-bool
-OVsearch(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token,
-         time_t *arrived)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.search)(handle, artnum, data, len, token, arrived));
-}
-
-void
-OVclosesearch(void *handle)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return;
-    }
-    (*ov.closesearch)(handle);
-    return;
-}
-
-bool
-OVgetartinfo(char *group, ARTNUM artnum, TOKEN *token)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.getartinfo)(group, artnum, token));
-}
-
-bool
-OVexpiregroup(char *group, int *lo, struct history *h)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    return ((*ov.expiregroup)(group, lo, h));
-}
-
-bool
-OVctl(OVCTLTYPE type, void *val)
-{
-    if (!ov.open) {
-       /* must be opened */
-       syslog(L_ERROR, "ovopen must be called first");
-       fprintf(stderr, "ovopen must be called first");
-       return false;
-    }
-    switch (type) {
-    case OVGROUPBASEDEXPIRE:
-       if (!innconf->groupbaseexpiry) {
-           syslog(L_ERROR, "OVGROUPBASEDEXPIRE is not allowed if groupbaseexpiry if false");
-           fprintf(stderr, "OVGROUPBASEDEXPIRE is not allowed if groupbaseexpiry if false");
-           return false;
-       }
-       if (((OVGE *)val)->delayrm) {
-           if ((((OVGE *)val)->filename == NULL) || (strlen(((OVGE *)val)->filename) == 0)) {
-               syslog(L_ERROR, "file name must be specified");
-               fprintf(stderr, "file name must be specified");
-               return false;
-           }
-           if ((EXPunlinkfile = fopen(((OVGE *)val)->filename, "w")) == NULL) {
-               syslog(L_ERROR, "fopen: %s failed: %m", ((OVGE *)val)->filename);
-               fprintf(stderr, "fopen: %s failed: %s", ((OVGE *)val)->filename, 
-                             strerror(errno));
-               return false;
-           }
-       }
-       OVdelayrm = ((OVGE *)val)->delayrm;
-       OVusepost = ((OVGE *)val)->usepost;
-       OVrealnow = ((OVGE *)val)->now;
-       OVnow = ((OVGE *)val)->now + (time_t)((OVGE *)val)->timewarp;
-       OVquiet = ((OVGE *)val)->quiet;
-       OVkeep = ((OVGE *)val)->keep;
-       OVearliest = ((OVGE *)val)->earliest;
-       OVignoreselfexpire = ((OVGE *)val)->ignoreselfexpire;
-       return true;
-    case OVSTATALL:
-       OVstatall = *(bool *)val;
-       return true;
-    default:
-       return ((*ov.ctl)(type, val));
-    }
-}
-
-void
-OVclose(void)
-{
-    if (!ov.open)
-       return;
-    (*ov.close)();
-    memset(&ov, '\0', sizeof(ov));
-    OVEXPcleanup();
-}
diff --git a/storage/ovdb/ovdb-private.h b/storage/ovdb/ovdb-private.h
deleted file mode 100644 (file)
index 54be538..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-#ifdef USE_BERKELEY_DB
-
-#include <db.h>
-
-#if DB_VERSION_MAJOR == 2
-#if DB_VERSION_MINOR < 6
-#error "Need BerkeleyDB 2.6.x, 2.7.x, 3.x or 4.x"
-#endif
-#else
-#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR > 4
-#error "Need BerkeleyDB 2.6.x, 2.7.x, 3.x or 4.x"
-#endif
-#endif
-
-/*
- * How data is stored:
- *
- * Each group is assigned an integer ID.  The mapping between a group name
- * and its ID is stored in the groupinfo DB.  Overview data itself
- * is stored in one or more btree DBs.  The specific DB file that is used
- * to store data for a certain group is chosen by taking the hash of the
- * group name, copying the first bytes of the hash into an int, and then
- * modding the int value to the number of DBs.
- *
- * Each group has one groupinfo structure in the groupinfo DB, whose key
- * is the newsgroup name.  The overview records for the group have a
- * 'struct datakey' as their keys, which consists of the group ID (in
- * native byteorder) followed by the article number in network byteorder.
- * The reason for storing the article number in net byte order (big-endian)
- * is that the keys will sort correctly using BerkeleyDB's default sort
- * function (basically, a memcmp).
- *
- * The overview records consist of a 'struct ovdata' followed by the actual
- * overview data.  The struct ovdata contains the token and arrival time.
- */ 
-
-struct ovdb_conf {
-    char *home;                /* path to directory where db files are stored */
-    int  txn_nosync;   /* whether to pass DB_TXN_NOSYNC to db_appinit */
-    int  numdbfiles;
-    size_t cachesize;
-    size_t pagesize;
-    int minkey;
-    int maxlocks;
-    int nocompact;
-    int readserver;
-    int numrsprocs;
-    int maxrsconn;
-    int useshm;
-    int shmkey;
-};
-
-typedef u_int32_t group_id_t;
-
-struct groupinfo {
-    ARTNUM     low;
-    ARTNUM     high;
-    int        count;
-    int        flag;
-    time_t     expired;                /* when this group was last touched by expiregroup */
-    group_id_t current_gid;    /* group ID */
-    group_id_t new_gid;                /* pending ID (expireover) */
-    int        current_db;     /* which DB file the records are in */
-    int        new_db;         /* pending DB file */
-    pid_t      expiregrouppid; /* PID of expireover process */
-    int        status;
-};
-#define GROUPINFO_DELETED    1
-#define GROUPINFO_EXPIRING   (1<<1)
-#define GROUPINFO_MOVING     (1<<2)
-#define GROUPINFO_MOVE_REQUESTED (1<<3) /*NYI*/
-
-struct datakey {
-    group_id_t groupnum;       /* must be the first member of this struct */
-    u_int32_t artnum;
-};
-
-struct ovdata {
-    TOKEN token;
-    time_t arrived;
-    time_t expires;
-};
-
-
-#define DATA_VERSION 2
-
-extern struct ovdb_conf ovdb_conf;
-extern DB_ENV *OVDBenv;
-
-#define OVDB_ERR_NONE   0
-#define OVDB_ERR_SYSLOG 1      /* default */
-#define OVDB_ERR_STDERR 2
-extern int ovdb_errmode;
-
-void read_ovdb_conf(void);
-int ovdb_open_berkeleydb(int mode, int flags);
-void ovdb_close_berkeleydb(void);
-int ovdb_getgroupinfo(char *group, struct groupinfo *gi, int ignoredeleted, DB_TXN *tid, int getflags);
-
-#define OVDB_RECOVER    1
-#define OVDB_UPGRADE    2
-
-#define OVDB_LOCK_NORMAL 0
-#define OVDB_LOCK_ADMIN 1
-#define OVDB_LOCK_EXCLUSIVE 2
-
-bool ovdb_getlock(int mode);
-bool ovdb_releaselock(void);
-bool ovdb_check_pidfile(char *file);
-bool ovdb_check_user(void);
-
-#define OVDB_LOCKFN "ovdb.sem"
-#define OVDB_MONITOR_PIDFILE "ovdb_monitor.pid"
-#define OVDB_SERVER_PIDFILE "ovdb_server.pid"
-#define SPACES "                "
-
-/* read server stuff */
-#define CMD_QUIT       0x01
-#define CMD_GROUPSTATS 0x02
-#define CMD_OPENSRCH   0x03
-#define CMD_SRCH       0x04
-#define CMD_CLOSESRCH  0x05
-#define CMD_ARTINFO    0x06
-#define CMD_MASK       0x0F
-#define RPLY_OK                0x00
-#define RPLY_ERROR     0x10
-#define OVDB_SERVER    (1<<4)
-#define OVDB_SERVER_BANNER "ovdb read protocol 1"
-#define OVDB_SERVER_PORT 32323 /* only used if don't have unix domain sockets */
-#define OVDB_SERVER_SOCKET "ovdb.server"
-
-struct rs_cmd {
-    uint32_t   what;
-    uint32_t   grouplen;
-    uint32_t   artlo;
-    uint32_t   arthi;
-    void *     handle;
-};
-
-struct rs_groupstats {
-    uint32_t   status;
-    int                lo;
-    int                hi;
-    int                count;
-    int                flag;
-    uint32_t   aliaslen;
-    /* char alias */
-};
-
-struct rs_opensrch {
-    uint32_t   status;
-    void *     handle;
-};
-
-struct rs_srch {
-    uint32_t   status;
-    ARTNUM     artnum;
-    TOKEN      token;
-    time_t     arrived;
-    int                len;
-    /* char data */
-};
-
-struct rs_artinfo {
-    uint32_t   status;
-    TOKEN      token;
-};
-
-
-#if DB_VERSION_MAJOR == 2
-char *db_strerror(int err);
-
-#define TXN_START(label, tid) \
-label: { \
-  int txn_ret; \
-  txn_ret = txn_begin(OVDBenv->tx_info, NULL, &tid); \
-  if (txn_ret != 0) { \
-    syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
-    tid = NULL; \
-  } \
-}
-
-#define TXN_RETRY(label, tid) \
-{ txn_abort(tid); goto label; }
-
-#define TXN_ABORT(label, tid) txn_abort(tid)
-#define TXN_COMMIT(label, tid) txn_commit(tid)
-
-#define TRYAGAIN EAGAIN
-
-#elif DB_VERSION_MAJOR == 3
-
-#define TXN_START(label, tid) \
-label: { \
-  int txn_ret; \
-  txn_ret = txn_begin(OVDBenv, NULL, &tid, 0); \
-  if (txn_ret != 0) { \
-    syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
-    tid = NULL; \
-  } \
-}
-
-#define TXN_RETRY(label, tid) \
-{ txn_abort(tid); goto label; }
-
-#define TXN_ABORT(label, tid) txn_abort(tid)
-#define TXN_COMMIT(label, tid) txn_commit(tid, 0)
-
-#define TRYAGAIN DB_LOCK_DEADLOCK
-
-#else /* DB_VERSION_MAJOR == 4 */
-
-#define TXN_START(label, tid) \
-label: { \
-  int txn_ret; \
-  txn_ret = OVDBenv->txn_begin(OVDBenv, NULL, &tid, 0); \
-  if (txn_ret != 0) { \
-    syslog(L_ERROR, "OVDB: " #label " txn_begin: %s", db_strerror(ret)); \
-    tid = NULL; \
-  } \
-}
-
-#define TXN_RETRY(label, tid) \
-{ (tid)->abort(tid); goto label; }
-
-#define TXN_ABORT(label, tid) (tid)->abort(tid)
-#define TXN_COMMIT(label, tid) (tid)->commit(tid, 0)
-
-#define TRYAGAIN DB_LOCK_DEADLOCK
-
-#endif /* DB_VERSION_MAJOR == 4 */
-
-#endif /* USE_BERKELEY_DB */
diff --git a/storage/ovdb/ovdb.c b/storage/ovdb/ovdb.c
deleted file mode 100644 (file)
index bd03481..0000000
+++ /dev/null
@@ -1,3004 +0,0 @@
-/*
- * ovdb.c
- * ovdb 2.00
- * Overview storage using BerkeleyDB 2.x/3.x/4.x
- *
- * 2004-02-17 : Need to track search cursors, since it's possible that
- *              ovdb_closesearch does not get called.  We now close
- *              any cursors still open in ovdb_close, or they'd be in
- *              the database indefinitely causing deadlocks.
- * 2002-08-13 : Change BOOL to bool, remove portability to < 2.4.
- * 2002-08-11 : Cleaned up use of sprintf and fixed a bunch of warnings.
- * 2002-02-28 : Update getartinfo for the overview API change in 2.4.  This
- *              breaks compatibility with INN 2.3.x....
- * 2000-12-12 : Add support for BerkeleyDB DB_SYSTEM_MEM option, controlled
- *            : by ovdb.conf 'useshm' and 'shmkey'
- * 2000-11-27 : Update for DB 3.2.x compatibility
- * 2000-11-13 : New 'readserver' feature
- * 2000-10-10 : ovdb_search now closes the cursor right after the last
- *              record is read.
- * 2000-10-05 : artnum member of struct datakey changed from ARTNUM to u_int32_t.
- *              OS's where sizeof(long)==8 will have to rebuild their databases
- *              after this update.
- * 2000-10-05 : from Dan Riley: struct datakey needs to be zero'd, for
- *              64-bit OSs where the struct has internal padding bytes.
- * 2000-09-29 : ovdb_expiregroup can now fix incorrect counts; use new
- *              inn/version.h so can have same ovdb.c for 2.3.0, 2.3.1, and 2.4
- * 2000-09-28 : low mark in ovdb_expiregroup still wasn't right
- * 2000-09-27 : Further improvements to ovdb_expiregroup: restructured the
- *              loop; now updates groupinfo as it goes along rather than
- *              counting records at the end, which prevents a possible
- *              deadlock.
- * 2000-09-19 : *lo wasn't being set in ovdb_expiregroup
- * 2000-09-15 : added ovdb_check_user(); tweaked some error msgs; fixed an
- *              improper use of RENEW
- * 2000-08-28:  New major release: version 2.00 (beta)
- *    + "groupsbyname" and "groupstats" databases replaced with "groupinfo".
- *    + ovdb_recover, ovdb_upgrade, and dbprocs are now deprecated; their
- *         functionality is now in ovdb_init and ovdb_monitor.
- *    + ovdb_init can upgrade a database from the old version of ovdb to
- *         work with this version.
- *    + Rewrote ovdb_expiregroup(); it can now re-write OV data rather
- *         than simply deleting old keys (which can leave 'holes' that result
- *         in inefficient disk-space use).
- *    + Add "nocompact" to ovdb.conf, which controls whether ovdb_expiregroup()
- *         rewrites OV data.
- *    + No longer needs the BerkeleyDB tools db_archive, db_checkpoint, and
- *         db_deadlock.  That functionality is now in ovdb_monitor.
- *    + ovdb_open() won't succeed if ovdb_monitor is not running.  This will
- *         prevent the problems that happen if the database is not regularly
- *         checkpointed and deadlock-tested.
- *    + Internal group IDs (32-bit ints) are now reused.
- *    + Add "maxlocks" to ovdb.conf, which will set the DB lk_max parameter.
- *    + Pull "test" code out into ovdb_stat.  ovdb_stat will also provide
- *         functionality similar to the BerkeleyDB "db_stat" command.
- *    + Update docs: write man pages for the new ovdb_* commands; update
- *         ovdb.pod
- *         
- * 2000-07-11 : fix possible alignment problem; add test code
- * 2000-07-07 : bugfix: timestamp handling
- * 2000-06-10 : Modified groupnum() interface; fix ovdb_add() to return false
- *              for certain groupnum() errors
- * 2000-06-08 : Added BerkeleyDB 3.1.x compatibility
- * 2000-04-09 : Tweak some default parameters; store aliased group info
- * 2000-03-29 : Add DB_RMW flag to the 'get' of get-modify-put sequences
- * 2000-02-17 : Update expire behavior to be consistent with current
- *              ov3 and buffindexed
- * 2000-01-13 : Fix to make compatible with unmodified nnrpd/article.c
- * 2000-01-04 : Added data versioning
- * 1999-12-20 : Added BerkeleyDB 3.x compatibility
- * 1999-12-06 : First Release -- H. Kehoe <hakehoe@avalon.net>
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/socket.h"
-#include "portable/time.h"
-#include <errno.h>
-#include <fcntl.h>
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <pwd.h>
-#include <signal.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#include <syslog.h>
-
-#include "conffile.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-
-#include "ov.h"
-#include "ovinterface.h"
-#include "ovdb.h"
-#include "ovdb-private.h"
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-#ifndef USE_BERKELEY_DB
-
-/* Provide stub functions if we don't have db */
-
-bool ovdb_open(int mode UNUSED)
-{
-    syslog(L_FATAL, "OVDB: ovdb support not enabled");
-    return false;
-}
-
-bool ovdb_groupstats(char *group UNUSED, int *lo UNUSED, int *hi UNUSED, int *count UNUSED, int *flag UNUSED)
-{ return false; }
-
-bool ovdb_groupadd(char *group UNUSED, ARTNUM lo UNUSED, ARTNUM hi UNUSED, char *flag UNUSED)
-{ return false; }
-
-bool ovdb_groupdel(char *group UNUSED)
-{ return false; }
-
-bool ovdb_add(char *group UNUSED, ARTNUM artnum UNUSED, TOKEN token UNUSED, char *data UNUSED, int len UNUSED, time_t arrived UNUSED, time_t expires UNUSED)
-{ return false; }
-
-bool ovdb_cancel(TOKEN token UNUSED)
-{ return false; }
-
-void *ovdb_opensearch(char *group UNUSED, int low UNUSED, int high UNUSED)
-{ return NULL; }
-
-bool ovdb_search(void *handle UNUSED, ARTNUM *artnum UNUSED, char **data UNUSED, int *len UNUSED, TOKEN *token UNUSED, time_t *arrived UNUSED)
-{ return false; }
-
-void ovdb_closesearch(void *handle UNUSED) { }
-
-bool ovdb_getartinfo(char *group UNUSED, ARTNUM artnum UNUSED, TOKEN *token UNUSED)
-{ return false; }
-
-bool ovdb_expiregroup(char *group UNUSED, int *lo UNUSED, struct history *h UNUSED)
-{ return false; }
-
-bool ovdb_ctl(OVCTLTYPE type UNUSED, void *val UNUSED)
-{ return false; }
-
-void ovdb_close(void) { }
-
-#else /* USE_BERKELEY_DB */
-
-#define EXPIREGROUP_TXN_SIZE 100
-#define DELETE_TXN_SIZE 500
-
-struct ovdb_conf ovdb_conf;
-DB_ENV *OVDBenv = NULL;
-int ovdb_errmode = OVDB_ERR_SYSLOG;
-
-static int OVDBmode;
-static bool Cutofflow;
-static DB **dbs = NULL;
-static int oneatatime = 0;
-static int current_db = -1;
-static time_t eo_start = 0;
-static int clientmode = 0;
-
-static DB *groupinfo = NULL;
-static DB *groupaliases = NULL;
-
-#define OVDBtxn_nosync 1
-#define OVDBnumdbfiles 2
-#define OVDBpagesize   3
-#define OVDBcachesize  4
-#define OVDBminkey     5
-#define OVDBmaxlocks   6
-#define OVDBnocompact  7
-#define OVDBreadserver 8
-#define OVDBnumrsprocs 9
-#define OVDBmaxrsconn  10
-#define OVDBuseshm     11
-#define OVDBshmkey     12
-
-static CONFTOKEN toks[] = {
-  { OVDBtxn_nosync, "txn_nosync" },
-  { OVDBnumdbfiles, "numdbfiles" },
-  { OVDBpagesize, "pagesize" },
-  { OVDBcachesize, "cachesize" },
-  { OVDBminkey, "minkey" },
-  { OVDBmaxlocks, "maxlocks" },
-  { OVDBnocompact, "nocompact" },
-  { OVDBreadserver, "readserver" },
-  { OVDBnumrsprocs, "numrsprocs" },
-  { OVDBmaxrsconn, "maxrsconn" },
-  { OVDBuseshm, "useshm" },
-  { OVDBshmkey, "shmkey" },
-  { 0, NULL },
-};
-
-#define _PATH_OVDBCONF "ovdb.conf"
-
-/*********** readserver functions ***********/
-
-static int clientfd = -1;
-
-/* read client send and recieve functions. */
-
-static int
-csend(void *data, int n)
-{
-    ssize_t status;
-
-    if (n == 0)
-       return 0;
-    status = xwrite(clientfd, data, n);
-    if (status < 0)
-        syswarn("OVDB: rc: cant write");
-    return status;
-}
-
-static int crecv(void *data, int n)
-{
-    int r, p = 0;
-
-    if(n == 0)
-       return 0;
-
-    while(p < n) {
-       r = read(clientfd, (char *)data + p, n - p);
-       if(r <= 0) {
-           if(r < 0 && errno == EINTR)
-               continue;
-           syslog(LOG_ERR, "OVDB: rc: cant read: %m");
-           clientfd = -1;
-           exit(1);
-       }
-       p+= r;
-    }
-    return p;
-}
-
-/* Attempt to connect to the readserver.  If anything fails, we
-   return -1 so that ovdb_open can open the database directly. */
-
-static int client_connect()
-{
-    ssize_t r;
-    size_t p = 0;
-    char *path;
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    struct sockaddr_un sa;
-#else
-    struct sockaddr_in sa;
-#endif
-    char banner[sizeof(OVDB_SERVER_BANNER)];
-    fd_set fds;
-    struct timeval timeout;
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    clientfd = socket(AF_UNIX, SOCK_STREAM, 0);
-#else
-    clientfd = socket(AF_INET, SOCK_STREAM, 0);
-#endif
-    if(clientfd < 0) {
-       syslog(LOG_ERR, "OVDB: rc: socket: %m");
-       return -1;
-    }
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    sa.sun_family = AF_UNIX;
-    path = concatpath(innconf->pathrun, OVDB_SERVER_SOCKET);
-    strlcpy(sa.sun_path, path, sizeof(sa.sun_path));
-    free(path);
-#else
-    sa.sin_family = AF_INET;
-    sa.sin_port = 0;
-    sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-    bind(clientfd, (struct sockaddr *) &sa, sizeof sa);
-    sa.sin_port = htons(OVDB_SERVER_PORT);
-#endif
-    if((r = connect(clientfd, (struct sockaddr *) &sa, sizeof sa)) != 0) {
-       syslog(LOG_ERR, "OVDB: rc: cant connect to server: %m");
-       close(clientfd);
-       clientfd = -1;
-       return -1;
-    }
-
-    while(p < sizeof(OVDB_SERVER_BANNER)) {
-       FD_ZERO(&fds);
-       FD_SET(clientfd, &fds);
-       timeout.tv_sec = 30;
-       timeout.tv_usec = 0;
-
-       r = select(clientfd+1, &fds, NULL, NULL, &timeout);
-
-       if(r < 0) {
-           if(errno == EINTR)
-               continue;
-           syslog(LOG_ERR, "OVDB: rc: select: %m");
-           close(clientfd);
-           clientfd = -1;
-           return -1;
-       }
-       if(r == 0) {
-           syslog(LOG_ERR, "OVDB: rc: timeout waiting for server");
-           close(clientfd);
-           clientfd = -1;
-           return -1;
-       }
-
-       r = read(clientfd, banner + p, sizeof(OVDB_SERVER_BANNER) - p);
-       if(r <= 0) {
-           if(r < 0 && errno == EINTR)
-               continue;
-           syslog(LOG_ERR, "OVDB: rc: cant read: %m");
-           close(clientfd);
-           clientfd = -1;
-           return -1;
-       }
-       p+= r;
-    }
-
-    if(memcmp(banner, OVDB_SERVER_BANNER, sizeof(OVDB_SERVER_BANNER))) {
-       syslog(LOG_ERR, "OVDB: rc: unknown reply from server");
-       close(clientfd);
-       clientfd = -1;
-       return -1;
-    }
-    return 0;
-}
-
-static void
-client_disconnect(void)
-{
-    struct rs_cmd rs;
-
-    if (clientfd != -1) {
-       rs.what = CMD_QUIT;
-       csend(&rs, sizeof(rs));
-    }
-    clientfd = -1;
-}
-
-
-/*********** internal functions ***********/
-
-#if DB_VERSION_MAJOR == 2
-char *db_strerror(int err)
-{
-    switch(err) {
-    case DB_RUNRECOVERY:
-       return "Recovery Needed";
-    default:
-       return strerror(err);
-    }
-}
-#endif /* DB_VERSION_MAJOR == 2 */
-
-
-static bool conf_bool_val(char *str, bool *value)
-{
-    if(strcasecmp(str, "on") == 0
-       || strcasecmp(str, "true") == 0
-       || strcasecmp(str, "yes") == 0) {
-       *value = true;
-       return true;
-    }
-    if(strcasecmp(str, "off") == 0
-       || strcasecmp(str, "false") == 0
-       || strcasecmp(str, "no") == 0) {
-       *value = false;
-       return true;
-    }
-    return false;
-}
-
-static bool conf_long_val(char *str, long *value)
-{
-    long v;
-
-    errno = 0;
-    v = strtol(str, NULL, 10);
-    if(v == 0 && errno != 0) {
-       return false;
-    }
-    *value = v;
-    return true;
-}
-
-void read_ovdb_conf(void)
-{
-    static int confread = 0;
-    int done = 0;
-    char *path;
-    CONFFILE *f;
-    CONFTOKEN *tok;
-    bool b;
-    long l;
-
-    if(confread)
-       return;
-
-    /* defaults */
-    ovdb_conf.home = innconf->pathoverview;
-    ovdb_conf.txn_nosync = 1;
-    ovdb_conf.numdbfiles = 32;
-    ovdb_conf.pagesize = 8192;
-    ovdb_conf.cachesize = 8000 * 1024;
-    ovdb_conf.minkey = 0;
-    ovdb_conf.maxlocks = 4000;
-    ovdb_conf.nocompact = 1;
-    ovdb_conf.readserver = 0;
-    ovdb_conf.numrsprocs = 5;
-    ovdb_conf.maxrsconn = 0;
-    ovdb_conf.useshm = 0;
-    ovdb_conf.shmkey = 6400;
-
-    path = concatpath(innconf->pathetc, _PATH_OVDBCONF);
-    f = CONFfopen(path);
-    free(path);
-
-    if(f) {
-       while(!done && (tok = CONFgettoken(toks, f))) {
-           switch(tok->type) {
-           case OVDBtxn_nosync:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_bool_val(tok->name, &b)) {
-                   ovdb_conf.txn_nosync = b;
-               }
-               break;
-           case OVDBnumdbfiles:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 0) {
-                   ovdb_conf.numdbfiles = l;
-               }
-               break;
-           case OVDBpagesize:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 0) {
-                   ovdb_conf.pagesize = l;
-               }
-               break;
-           case OVDBcachesize:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 0) {
-                   ovdb_conf.cachesize = l * 1024;
-               }
-               break;
-           case OVDBminkey:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 1) {
-                   ovdb_conf.minkey = l;
-               }
-               break;
-           case OVDBmaxlocks:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 0) {
-                   ovdb_conf.maxlocks = l;
-               }
-               break;
-           case OVDBnocompact:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l >= 0) {
-                   ovdb_conf.nocompact = l;
-               }
-               break;
-           case OVDBreadserver:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_bool_val(tok->name, &b)) {
-                   ovdb_conf.readserver = b;
-               }
-               break;
-           case OVDBnumrsprocs:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l > 0) {
-                   ovdb_conf.numrsprocs = l;
-               }
-               break;
-           case OVDBmaxrsconn:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l >= 0) {
-                   ovdb_conf.maxrsconn = l;
-               }
-               break;
-           case OVDBuseshm:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_bool_val(tok->name, &b)) {
-                   ovdb_conf.useshm = b;
-               }
-               break;
-           case OVDBshmkey:
-               tok = CONFgettoken(0, f);
-               if(!tok) {
-                   done = 1;
-                   continue;
-               }
-               if(conf_long_val(tok->name, &l) && l >= 0) {
-                   ovdb_conf.shmkey = l;
-               }
-               break;
-           }
-       }
-       CONFfclose(f);
-    }
-
-    /* If user did not specify minkey, choose one based on pagesize */
-    if(ovdb_conf.minkey == 0) {
-       ovdb_conf.minkey = ovdb_conf.pagesize / 2048 - 1;
-       if(ovdb_conf.minkey < 2)
-           ovdb_conf.minkey = 2;
-    }
-
-    confread = 1;
-}
-
-
-/* Function that db will use to report errors */
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
-static void OVDBerror(const DB_ENV *dbenv UNUSED, const char *db_errpfx UNUSED, const char *buffer)
-#else
-static void OVDBerror(const char *db_errpfx UNUSED, char *buffer)
-#endif
-{
-    switch(ovdb_errmode) {
-    case OVDB_ERR_SYSLOG:
-       syslog(L_ERROR, "OVDB: %s", buffer);
-       break;
-    case OVDB_ERR_STDERR:
-       fprintf(stderr, "OVDB: %s\n", buffer);
-       break;
-    }
-}
-
-static u_int32_t _db_flags = 0;
-#if DB_VERSION_MAJOR == 2
-static DB_INFO   _dbinfo;
-#endif
-
-static int open_db_file(int which)
-{
-    int ret;
-    char name[10];
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    DB_TXN *tid;
-#endif
-
-    if(dbs[which] != NULL)
-       return 0;
-
-    snprintf(name, sizeof(name), "ov%05d", which);
-
-#if DB_VERSION_MAJOR == 2
-    ret = db_open(name, DB_BTREE, _db_flags, 0666, OVDBenv, &_dbinfo,
-                  &(dbs[which]));
-    if (ret != 0) {
-       dbs[which] = NULL;
-       return ret;
-    }
-#else
-    ret = db_create(&(dbs[which]), OVDBenv, 0);
-    if (ret != 0)
-       return ret;
-
-    if(ovdb_conf.minkey > 0)
-       (dbs[which])->set_bt_minkey(dbs[which], ovdb_conf.minkey);
-    if(ovdb_conf.pagesize > 0)
-       (dbs[which])->set_pagesize(dbs[which], ovdb_conf.pagesize);
-
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    TXN_START(t_open_db_file, tid);
-    ret = (dbs[which])->open(dbs[which], tid, name, NULL, DB_BTREE, _db_flags,
-                             0666);
-    if (ret == 0)
-       TXN_COMMIT(t_open_db_file, tid);
-#else
-    ret = (dbs[which])->open(dbs[which], name, NULL, DB_BTREE, _db_flags,
-                             0666);
-#endif
-    if (ret != 0) {
-       (dbs[which])->close(dbs[which], 0);
-       dbs[which] = NULL;
-       return ret;
-    }
-#endif
-    return 0;
-}
-
-static void close_db_file(int which)
-{
-    if(which == -1 || dbs[which] == NULL)
-       return;
-    
-    dbs[which]->close(dbs[which], 0);
-    dbs[which] = NULL;
-}
-
-static int which_db(char *group)
-{
-    HASH grouphash;
-    unsigned int i;
-
-    grouphash = Hash(group, strlen(group));
-    memcpy(&i, &grouphash, sizeof(i));
-    return i % ovdb_conf.numdbfiles;
-}
-
-static DB *get_db_bynum(int which)
-{
-    int ret;
-    if(which >= ovdb_conf.numdbfiles)
-       return NULL;
-    if(oneatatime) {
-       if(which != current_db && current_db != -1)
-           close_db_file(current_db);
-
-        ret = open_db_file(which);
-       if (ret != 0)
-           syslog(L_ERROR, "OVDB: open_db_file failed: %s", db_strerror(ret));
-
-       current_db = which;
-    }
-    return(dbs[which]);
-}
-
-
-int ovdb_getgroupinfo(char *group, struct groupinfo *gi, int ignoredeleted, DB_TXN *tid, int getflags)
-{
-    int ret;
-    DBT key, val;
-
-    if(group == NULL)  /* just in case */
-       return DB_NOTFOUND;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    key.data = group;
-    key.size = strlen(group);
-    val.data = gi;
-    val.ulen = sizeof(struct groupinfo);
-    val.flags = DB_DBT_USERMEM;
-
-    ret = groupinfo->get(groupinfo, tid, &key, &val, getflags);
-    if (ret != 0)
-       return ret;
-
-    if(val.size != sizeof(struct groupinfo)) {
-       syslog(L_ERROR, "OVDB: wrong size for %s groupinfo (%u)",
-           group, val.size);
-       return DB_NOTFOUND;
-    }
-
-    if(ignoredeleted && (gi->status & GROUPINFO_DELETED))
-       return DB_NOTFOUND;
-
-    return 0;
-}
-
-#define GROUPID_MAX_FREELIST 10240
-#define GROUPID_MIN_FREELIST 100
-
-/* allocate a new group ID and return in gno */
-/* must be used in a transaction */
-static int groupid_new(group_id_t *gno, DB_TXN *tid)
-{
-    DBT key, val;
-    int ret, n;
-    group_id_t newgno, *freelist, one;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    key.data = (char *) "!groupid_freelist";
-    key.size = sizeof("!groupid_freelist");
-
-    ret = groupinfo->get(groupinfo, tid, &key, &val, DB_RMW);
-    if (ret != 0) {
-       if(ret == DB_NOTFOUND) {
-           val.size = sizeof(group_id_t);
-           val.data = &one;
-           one = 1;
-       } else {
-           return ret;
-       }
-    }
-
-    if(val.size % sizeof(group_id_t)) {
-       syslog(L_ERROR, "OVDB: invalid size (%d) for !groupid_freelist",
-               val.size);
-       return EINVAL;
-    }
-
-    n = val.size / sizeof(group_id_t);
-    freelist = xmalloc(n * sizeof(group_id_t));
-    memcpy(freelist, val.data, val.size);
-    if(n <= GROUPID_MIN_FREELIST ) {
-       newgno = freelist[n-1];
-       (freelist[n-1])++;
-       val.data = freelist;
-    } else {
-       newgno = freelist[0];
-       val.data = &(freelist[1]);
-       val.size -= sizeof(group_id_t);
-    }
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-    if (ret != 0) {
-       free(freelist);
-       return ret;
-    }
-
-    free(freelist);
-    *gno = newgno;
-    return 0;
-}
-
-/* mark given group ID as "unused" */
-/* must be used in a transaction */
-static int groupid_free(group_id_t gno, DB_TXN *tid)
-{
-    DBT key, val;
-    int ret, n, i;
-    group_id_t *freelist;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    key.data = (char *) "!groupid_freelist";
-    key.size = sizeof("!groupid_freelist");
-
-    ret = groupinfo->get(groupinfo, tid, &key, &val, DB_RMW);
-    if (ret != 0) {
-       return ret;
-    }
-
-    if(val.size % sizeof(group_id_t)) {
-       syslog(L_ERROR, "OVDB: invalid size (%d) for !groupid_freelist",
-               val.size);
-       return EINVAL;
-    }
-
-    n = val.size / sizeof(group_id_t);
-    if(n > GROUPID_MAX_FREELIST)
-       return 0;
-    freelist = xmalloc((n + 1) * sizeof(group_id_t));
-    memcpy(freelist, val.data, val.size);
-
-    if(gno >= freelist[n-1]) { /* shouldn't happen */
-       free(freelist);
-       return 0;
-    }
-    for(i = 0; i < n-1; i++) {
-       if(gno == freelist[i]) {        /* already on freelist */
-           free(freelist);
-           return 0;
-       }
-    }
-       
-    freelist[n] = freelist[n-1];
-    freelist[n-1] = gno;
-    val.data = freelist;
-    val.size += sizeof(group_id_t);
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-
-    free(freelist);
-    return ret;
-}
-
-/* Must be called outside of a transaction because it makes its own
-   transactions */
-static int delete_all_records(int whichdb, group_id_t gno)
-{
-    DB *db;
-    DBC *dbcursor;
-    DBT key, val;
-    struct datakey dk;
-    int count;
-    int ret;
-    DB_TXN *tid;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    memset(&dk, 0, sizeof dk);
-
-    db = get_db_bynum(whichdb);
-    if(db == NULL)
-       return DB_NOTFOUND;
-
-    dk.groupnum = gno;
-    dk.artnum = 0;
-
-    while(1) {
-       TXN_START(t_del, tid);
-
-       /* get a cursor to traverse the ov records and delete them */
-       ret = db->cursor(db, tid, &dbcursor, 0);
-       switch(ret)
-       {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_del, tid);
-       default:
-           TXN_ABORT(t_del, tid);
-           syslog(L_ERROR, "OVDB: delete_all_records: db->cursor: %s", db_strerror(ret));
-           return ret;
-       }
-
-       key.data = &dk;
-       key.size = sizeof dk;
-       val.flags = DB_DBT_PARTIAL;
-
-       for(count = 0; count < DELETE_TXN_SIZE; count++) {
-           ret = dbcursor->c_get(dbcursor, &key, &val,
-                           count ? DB_NEXT : DB_SET_RANGE);
-           switch (ret)
-           {
-           case 0:
-               break;
-           case DB_NOTFOUND:
-               dbcursor->c_close(dbcursor);
-               TXN_COMMIT(t_del, tid);
-               return 0;
-           case TRYAGAIN:
-               dbcursor->c_close(dbcursor);
-               TXN_RETRY(t_del, tid);
-           default:
-               warn("OVDB: delete_all_records: DBcursor->c_get: %s",
-                    db_strerror(ret));
-               dbcursor->c_close(dbcursor);
-               TXN_ABORT(t_del, tid);
-               return ret;
-           }
-
-           if(key.size == sizeof dk
-                   && memcmp(key.data, &gno, sizeof gno)) {
-               break;
-           }
-
-           ret = dbcursor->c_del(dbcursor, 0);
-           switch (ret) {
-           case 0:
-           case DB_KEYEMPTY:
-               break;
-           case TRYAGAIN:
-               dbcursor->c_close(dbcursor);
-               TXN_RETRY(t_del, tid);
-           default:
-               warn("OVDB: delete_all_records: DBcursor->c_del: %s",
-                    db_strerror(ret));
-               dbcursor->c_close(dbcursor);
-               TXN_ABORT(t_del, tid);
-               return ret;
-           }
-       }
-       dbcursor->c_close(dbcursor);
-       TXN_COMMIT(t_del, tid);
-       if(count < DELETE_TXN_SIZE) {
-           break;
-       }
-    }
-    return 0;
-}
-
-/* Make a temporary groupinfo key using the given db number and group ID.
-   Must be called in a transaction */
-static int
-mk_temp_groupinfo(int whichdb, group_id_t gno, DB_TXN *tid)
-{
-    char keystr[1 + sizeof gno];
-    DBT key, val;
-    struct groupinfo gi;
-    int ret;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    memset(&gi, 0, sizeof gi);
-
-    keystr[0] = 0;
-    memcpy(keystr + 1, &gno, sizeof gno);
-
-    gi.current_db = whichdb;
-    gi.current_gid = gno;
-    gi.status = GROUPINFO_DELETED;
-
-    key.data = keystr;
-    key.size = sizeof keystr;
-    val.data = &gi;
-    val.size = sizeof gi;
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-    switch (ret) {
-    case 0:
-       break;
-    default:
-       syslog(L_ERROR, "OVDB: mk_temp_groupinfo: groupinfo->put: %s", db_strerror(ret));
-    case TRYAGAIN:
-       return ret;
-    }
-
-    return 0;
-}
-
-/* Delete a temporary groupinfo key created by mk_temp_groupid, then
-   frees the group id.
-   Must NOT be called within a transaction. */
-static int
-rm_temp_groupinfo(group_id_t gno)
-{
-    char keystr[1 + sizeof gno];
-    DB_TXN *tid;
-    DBT key;
-    int ret;
-
-    memset(&key, 0, sizeof key);
-
-    keystr[0] = 0;
-    memcpy(keystr + 1, &gno, sizeof gno);
-
-    key.data = keystr;
-    key.size = sizeof keystr;
-
-    TXN_START(t_tmp, tid);
-
-    ret = groupinfo->del(groupinfo, tid, &key, 0);
-    switch(ret) {
-    case 0:
-    case DB_NOTFOUND:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_tmp, tid);
-    default:
-       TXN_ABORT(t_tmp, tid);
-       syslog(L_ERROR, "OVDB: rm_temp_groupinfo: groupinfo->del: %s", db_strerror(ret));
-       return ret;
-    }
-
-    switch(groupid_free(gno, tid)) {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_tmp, tid);
-    default:
-       TXN_ABORT(t_tmp, tid);
-       syslog(L_ERROR, "OVDB: rm_temp_groupinfo: groupid_free: %s", db_strerror(ret));
-       return ret;
-    }
-
-    TXN_COMMIT(t_tmp, tid);
-    return 0;
-}
-
-/* This function deletes overview records for deleted or forgotton groups */
-/* argument: 0 = process deleted groups   1 = process forgotton groups */
-static bool delete_old_stuff(int forgotton)
-{
-    DBT key, val;
-    DBC *cursor;
-    DB_TXN *tid;
-    struct groupinfo gi;
-    char **dellist = NULL;
-    size_t *dellistsz = NULL;
-    int listlen, listcount;
-    int i, ret;
-
-    TXN_START(t_dellist, tid);
-    if (dellist != NULL) {
-        for (i = 0; i < listcount; ++i)
-            free(dellist[i]);
-        free(dellist);
-    }
-    if (dellistsz != NULL)
-       free(dellistsz);
-    listlen = 20;
-    listcount = 0;
-    dellist = xmalloc(listlen * sizeof(char *));
-    dellistsz = xmalloc(listlen * sizeof(size_t));
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    val.data = &gi;
-    val.ulen = val.dlen = sizeof gi;
-    val.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-    /* get a cursor to traverse all of the groupinfo records */
-    ret = groupinfo->cursor(groupinfo, tid, &cursor, 0);
-    if (ret != 0) {
-       syslog(L_ERROR, "OVDB: delete_old_stuff: groupinfo->cursor: %s", db_strerror(ret));
-       free(dellist);
-       free(dellistsz);
-       return false;
-    }
-
-    while((ret = cursor->c_get(cursor, &key, &val, DB_NEXT)) == 0) {
-       if(key.size == sizeof("!groupid_freelist") &&
-               !strcmp("!groupid_freelist", key.data))
-           continue;
-       if(val.size != sizeof(struct groupinfo)) {
-           syslog(L_ERROR, "OVDB: delete_old_stuff: wrong size for groupinfo record");
-           continue;
-       }
-       if((!forgotton && (gi.status & GROUPINFO_DELETED))
-               || (forgotton && (gi.expired < eo_start))) {
-           dellist[listcount] = xmalloc(key.size);
-           memcpy(dellist[listcount], key.data, key.size);
-           dellistsz[listcount] = key.size;
-           listcount++;
-           if(listcount >= listlen) {
-               listlen += 20;
-                dellist = xrealloc(dellist, listlen * sizeof(char *));
-                dellistsz = xrealloc(dellistsz, listlen * sizeof(size_t));
-           }
-       }
-    }
-    cursor->c_close(cursor);
-    switch (ret) {
-    case 0:
-    case DB_NOTFOUND:
-        TXN_COMMIT(t_dellist, tid);
-        break;
-    case TRYAGAIN:
-        TXN_RETRY(t_dellist, tid);
-    default:
-        TXN_ABORT(t_dellist, tid);
-       syslog(L_ERROR, "OVDB: delete_old_stuff: cursor->c_get: %s", db_strerror(ret));
-        for (i = 0; i < listcount; ++i)
-            free(dellist[i]);
-        free(dellist);
-        free(dellistsz);
-        return false;
-    }
-
-    for(i = 0; i < listcount; i++) {
-       TXN_START(t_dos, tid);
-
-       /* Can't use ovdb_getgroupinfo here */
-       key.data = dellist[i];
-       key.size = dellistsz[i];
-       val.data = &gi;
-       val.ulen = sizeof(struct groupinfo);
-       val.flags = DB_DBT_USERMEM;
-
-       ret = groupinfo->get(groupinfo, tid, &key, &val, 0);
-
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_dos, tid);
-       case DB_NOTFOUND:
-           TXN_ABORT(t_dos, tid);
-           continue;
-       default:
-           syslog(L_ERROR, "OVDB: delete_old_stuff: groupinfo->get: %s\n", db_strerror(ret));
-           TXN_ABORT(t_dos, tid);
-           continue;
-       }
-       if(val.size != sizeof(struct groupinfo)) {
-           TXN_ABORT(t_dos, tid);
-           continue;
-       }
-
-       /* This if() is true if this ISN'T a key created by mk_temp_groupinfo */
-       if(*((char *)key.data) != 0 || key.size != 1 + sizeof(group_id_t)) {
-
-           switch(mk_temp_groupinfo(gi.current_db, gi.current_gid, tid)) {
-           case 0:
-               break;
-           case TRYAGAIN:
-               TXN_RETRY(t_dos, tid);
-           default:
-               TXN_ABORT(t_dos, tid);
-               continue;
-           }
-           if(gi.status & GROUPINFO_MOVING) {
-               switch(mk_temp_groupinfo(gi.new_db, gi.new_gid, tid)) {
-               case 0:
-                   break;
-               case TRYAGAIN:
-                   TXN_RETRY(t_dos, tid);
-               default:
-                   TXN_ABORT(t_dos, tid);
-                   continue;
-               }
-           }
-
-           /* delete the corresponding groupaliases record (if exists) */
-           switch(groupaliases->del(groupaliases, tid, &key, 0)) {
-           case 0:
-           case DB_NOTFOUND:
-               break;
-           case TRYAGAIN:
-               TXN_RETRY(t_dos, tid);
-           default:
-               TXN_ABORT(t_dos, tid);
-               continue;
-           }
-
-           switch(groupinfo->del(groupinfo, tid, &key, 0)) {
-           case 0:
-           case DB_NOTFOUND:
-               break;
-           case TRYAGAIN:
-               TXN_RETRY(t_dos, tid);
-           default:
-               TXN_ABORT(t_dos, tid);
-               continue;
-           }
-       }
-
-       TXN_COMMIT(t_dos, tid);
-
-       if(delete_all_records(gi.current_db, gi.current_gid) == 0) {
-           rm_temp_groupinfo(gi.current_gid);
-       }
-       if(gi.status & GROUPINFO_MOVING) {
-           if(delete_all_records(gi.new_db, gi.new_gid) == 0) {
-               rm_temp_groupinfo(gi.new_gid);
-           }
-       }
-    }
-out:
-    for(i = 0; i < listcount; i++)
-       free(dellist[i]);
-    free(dellist);
-    free(dellistsz);
-    return true;
-}
-
-static int count_records(struct groupinfo *gi)
-{
-    int ret;
-    DB *db;
-    DBC *cursor;
-    DBT key, val;
-    struct datakey dk;
-    u_int32_t artnum, newlow = 0;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    memset(&dk, 0, sizeof dk);
-
-    db = get_db_bynum(gi->current_db);
-    if(db == NULL)
-       return DB_NOTFOUND;
-
-    dk.groupnum = gi->current_gid;
-    dk.artnum = 0;
-    key.data = &dk;
-    key.size = key.ulen = sizeof dk;
-    key.flags = DB_DBT_USERMEM;
-    val.flags = DB_DBT_PARTIAL;
-
-    gi->count = 0;
-
-    ret = db->cursor(db, NULL, &cursor, 0);
-    if (ret)
-       return ret;
-
-    ret = cursor->c_get(cursor, &key, &val, DB_SET_RANGE);
-    switch (ret)
-    {
-    case 0:
-    case DB_NOTFOUND:
-       break;
-    default:
-       cursor->c_close(cursor);
-       return ret;
-    }
-    while(ret == 0 && key.size == sizeof(dk) && dk.groupnum == gi->current_gid) {
-       artnum = ntohl(dk.artnum);
-       if(newlow == 0 || newlow > artnum)
-           newlow = artnum;
-       if(artnum > gi->high)
-           gi->high = artnum;
-       gi->count++;
-
-       ret = cursor->c_get(cursor, &key, &val, DB_NEXT);
-    }
-    cursor->c_close(cursor);
-    if(gi->count == 0)
-       gi->low = gi->high + 1;
-    else
-       gi->low = newlow;
-
-    if(ret == DB_NOTFOUND)
-       return 0;
-    return ret;
-}
-
-
-/*
- * Locking:  OVopen() calls ovdb_getlock(OVDB_LOCK_NORMAL).  This
- * aquires a read (shared) lock on the lockfile.  Multiple processes
- * can have this file locked at the same time.  That way, if there
- * are any processes that are using the database, the lock file will
- * have one or more shared locks on it.
- *
- * ovdb_init, when starting, calls ovdb_getlock(OVDB_LOCK_EXCLUSIVE).
- * This tries to get a write (exclusive) lock, which will fail if
- * anyone has a shared lock.  This way, ovdb_init can tell if there
- * are any processes using the database.  If not, and the excl. lock
- * succeeds, ovdb_init is free to do DB_RUNRECOVER.
- *
- * ovdb_getlock() in the "normal" lock mode calls ovdb_check_monitor,
- * which looks for the OVDB_MONITOR_PIDFILE.  If said file does not
- * exist, or the PID in it does not exist, it will fail.  This will
- * prevent OVopen() from opening the database if ovdb_monitor is not running.
- *
- * The OVDB_LOCK_ADMIN mode is used by ovdb_monitor to get a shared lock
- * without testing the pidfile.
- */
-static int lockfd = -1;
-bool ovdb_getlock(int mode)
-{
-    if(lockfd == -1) {
-       char *lockfn = concatpath(innconf->pathrun, OVDB_LOCKFN);
-       lockfd = open(lockfn,
-               mode == OVDB_LOCK_NORMAL ? O_RDWR : O_CREAT|O_RDWR, 0660);
-       if(lockfd == -1) {
-           free(lockfn);
-           if(errno == ENOENT)
-               syslog(L_FATAL, "OVDB: can not open database unless ovdb_monitor is running.");
-           return false;
-       }
-       close_on_exec(lockfd, true);
-       free(lockfn);
-    } else
-       return true;
-
-    if(mode == OVDB_LOCK_NORMAL) {
-       if(!ovdb_check_pidfile(OVDB_MONITOR_PIDFILE)) {
-           syslog(L_FATAL, "OVDB: can not open database unless ovdb_monitor is running.");
-           return false;
-       }
-    }
-    if(mode == OVDB_LOCK_EXCLUSIVE) {
-       if(!inn_lock_file(lockfd, INN_LOCK_WRITE, false)) {
-           close(lockfd);
-           lockfd = -1;
-           return false;
-       }
-       return true;
-    } else {
-       if(!inn_lock_file(lockfd, INN_LOCK_READ, false)) {
-           close(lockfd);
-           lockfd = -1;
-           return false;
-       }
-       return true;
-    }
-}
-
-bool ovdb_releaselock(void)
-{
-    bool r;
-    if(lockfd == -1)
-       return true;
-    r = inn_lock_file(lockfd, INN_LOCK_UNLOCK, false);
-    close(lockfd);
-    lockfd = -1;
-    return r;
-}
-
-bool ovdb_check_pidfile(char *file)
-{
-    int f, pid;
-    char buf[SMBUF];
-    char *pidfn = concatpath(innconf->pathrun, file);
-
-    f = open(pidfn, O_RDONLY);
-    if(f == -1) {
-       if(errno != ENOENT)
-           syslog(L_FATAL, "OVDB: can't open %s: %m", pidfn);
-       free(pidfn);
-       return false;
-    }
-    memset(buf, 0, SMBUF);
-    if(read(f, buf, SMBUF-1) < 0) {
-       syslog(L_FATAL, "OVDB: can't read from %s: %m", pidfn);
-       free(pidfn);
-       close(f);
-       return false;
-    }
-    close(f);
-    free(pidfn);
-    pid = atoi(buf);
-    if(pid <= 1) {
-       return false;
-    }
-    if(kill(pid, 0) < 0 && errno == ESRCH) {
-       return false;
-    }
-    return true;
-}
-
-/* make sure the effective uid is that of NEWSUSER */
-bool ovdb_check_user(void)
-{
-    struct passwd *p;
-    static int result = -1;
-
-    if(result == -1) {
-       p = getpwnam(NEWSUSER);
-       if(!p) {
-           syslog(L_FATAL, "OVDB: getpwnam(" NEWSUSER ") failed: %m");
-           return false;
-       }
-       result = (p->pw_uid == geteuid());
-    }
-    return result;
-}
-
-static int check_version(void)
-{
-    int ret;
-    DB *vdb;
-    DBT key, val;
-    u_int32_t dv;
-
-#if DB_VERSION_MAJOR == 2
-    DB_INFO dbinfo;
-    memset(&dbinfo, 0, sizeof dbinfo);
-
-    ret = db_open("version", DB_BTREE, _db_flags, 0666, OVDBenv, &dbinfo,
-                  &vdb);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: db_open failed: %s", db_strerror(ret));
-       return ret;
-    }
-#else
-    /* open version db */
-    ret = db_create(&vdb, OVDBenv, 0);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: open: db_create: %s", db_strerror(ret));
-       return ret;
-    }
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    ret = vdb->open(vdb, NULL, "version", NULL, DB_BTREE, _db_flags, 0666);
-#else
-    ret = vdb->open(vdb, "version", NULL, DB_BTREE, _db_flags, 0666);
-#endif
-    if (ret != 0) {
-       vdb->close(vdb, 0);
-       syslog(L_FATAL, "OVDB: open: version->open: %s", db_strerror(ret));
-       return ret;
-    }
-#endif
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    key.data = (char *) "dataversion";
-    key.size = sizeof("dataversion");
-    ret = vdb->get(vdb, NULL, &key, &val, 0);
-    if (ret != 0) {
-       if(ret != DB_NOTFOUND) {
-           syslog(L_FATAL, "OVDB: open: can't retrieve version: %s", db_strerror(ret));
-           vdb->close(vdb, 0);
-           return ret;
-       }
-    }
-    if(ret == DB_NOTFOUND || val.size != sizeof dv) {
-       dv = DATA_VERSION;
-       if(!(OVDBmode & OV_WRITE)) {
-           vdb->close(vdb, 0);
-           return EACCES;
-       }
-       val.data = &dv;
-       val.size = sizeof dv;
-        ret = vdb->put(vdb, NULL, &key, &val, 0);
-       if (ret != 0) {
-           syslog(L_FATAL, "OVDB: open: can't store version: %s", db_strerror(ret));
-           vdb->close(vdb, 0);
-           return ret;
-       }
-    } else
-       memcpy(&dv, val.data, sizeof dv);
-
-    if(dv > DATA_VERSION) {
-       syslog(L_FATAL, "OVDB: can't open database: unknown version %d", dv);
-       vdb->close(vdb, 0);
-       return EINVAL;
-    }
-    if(dv < DATA_VERSION) {
-       syslog(L_FATAL, "OVDB: database is an old version, please run ovdb_init");
-       vdb->close(vdb, 0);
-       return EINVAL;
-    }
-
-    /* The version db also stores some config values, which will override the
-       corresponding ovdb.conf setting. */
-
-    key.data = (char *) "numdbfiles";
-    key.size = sizeof("numdbfiles");
-    ret = vdb->get(vdb, NULL, &key, &val, 0);
-    if (ret != 0) {
-       if(ret != DB_NOTFOUND) {
-           syslog(L_FATAL, "OVDB: open: can't retrieve numdbfiles: %s", db_strerror(ret));
-           vdb->close(vdb, 0);
-           return ret;
-       }
-    }
-    if(ret == DB_NOTFOUND || val.size != sizeof(ovdb_conf.numdbfiles)) {
-       if(!(OVDBmode & OV_WRITE)) {
-           vdb->close(vdb, 0);
-           return EACCES;
-       }
-       val.data = &(ovdb_conf.numdbfiles);
-       val.size = sizeof(ovdb_conf.numdbfiles);
-        ret = vdb->put(vdb, NULL, &key, &val, 0);
-       if (ret != 0) {
-           syslog(L_FATAL, "OVDB: open: can't store numdbfiles: %s", db_strerror(ret));
-           vdb->close(vdb, 0);
-           return ret;
-       }
-    } else {
-       memcpy(&(ovdb_conf.numdbfiles), val.data, sizeof(ovdb_conf.numdbfiles));
-    }
-
-    vdb->close(vdb, 0);
-    return 0;
-}
-
-
-int ovdb_open_berkeleydb(int mode, int flags)
-{
-    int ret;
-    u_int32_t ai_flags = DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN;
-
-    OVDBmode = mode;
-    read_ovdb_conf();
-
-    if(OVDBenv != NULL)
-       return 0;       /* already opened */
-
-    if(OVDBmode & OV_WRITE) {
-       _db_flags |= DB_CREATE;
-       ai_flags |= DB_CREATE;
-    } else {
-       _db_flags |= DB_RDONLY;
-    }
-    if(flags & OVDB_RECOVER)
-       ai_flags |= DB_RECOVER;
-
-#if DB_VERSION_MAJOR == 2 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 2)
-    if(ovdb_conf.txn_nosync)
-       ai_flags |= DB_TXN_NOSYNC;
-#endif
-
-#if DB_VERSION_MAJOR == 2
-
-    OVDBenv = xcalloc(1, sizeof(DB_ENV));
-
-    OVDBenv->db_errcall = OVDBerror;
-    OVDBenv->mp_size = ovdb_conf.cachesize;
-    OVDBenv->lk_max = ovdb_conf.maxlocks;
-
-    /* initialize environment */
-    ret = db_appinit(ovdb_conf.home, NULL, OVDBenv, ai_flags);
-    if (ret != 0) {
-       free(OVDBenv);
-       OVDBenv = NULL;
-       syslog(L_FATAL, "OVDB: db_appinit failed: %s", db_strerror(ret));
-       return ret;
-    }
-#else
-    ret = db_env_create(&OVDBenv, 0);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: db_env_create: %s", db_strerror(ret));
-       return ret;
-    }
-
-    if((flags & (OVDB_UPGRADE | OVDB_RECOVER)) == (OVDB_UPGRADE | OVDB_RECOVER))
-       ai_flags |= DB_PRIVATE;
-    if(!(ai_flags & DB_PRIVATE)) {
-       if(ovdb_conf.useshm)
-           ai_flags |= DB_SYSTEM_MEM;
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 0)
-       OVDBenv->set_shm_key(OVDBenv, ovdb_conf.shmkey);
-#endif
-    }
-
-    OVDBenv->set_errcall(OVDBenv, OVDBerror);
-    OVDBenv->set_cachesize(OVDBenv, 0, ovdb_conf.cachesize, 1);
-#if DB_VERSION_MAJOR >= 4
-    OVDBenv->set_lk_max_locks(OVDBenv, ovdb_conf.maxlocks);
-    OVDBenv->set_lk_max_lockers(OVDBenv, ovdb_conf.maxlocks);
-    OVDBenv->set_lk_max_objects(OVDBenv, ovdb_conf.maxlocks);
-#else
-    OVDBenv->set_lk_max(OVDBenv, ovdb_conf.maxlocks);
-#endif
-
-#if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
-    if(ovdb_conf.txn_nosync)
-       OVDBenv->set_flags(OVDBenv, DB_TXN_NOSYNC, 1);
-#endif
-
-    if((flags & (OVDB_UPGRADE | OVDB_RECOVER)) != OVDB_UPGRADE) {
-#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
-       ret = OVDBenv->open(OVDBenv, ovdb_conf.home, NULL, ai_flags, 0666);
-#else
-       ret = OVDBenv->open(OVDBenv, ovdb_conf.home, ai_flags, 0666);
-#endif
-       if (ret != 0) {
-           OVDBenv->close(OVDBenv, 0);
-           OVDBenv = NULL;
-           syslog(L_FATAL, "OVDB: OVDBenv->open: %s", db_strerror(ret));
-           return ret;
-       }
-    }
-#endif /* DB_VERSION_MAJOR == 2 */
-
-    return 0;
-}
-
-bool ovdb_open(int mode)
-{
-    int i, ret;
-#if DB_VERSION_MAJOR == 2
-    DB_INFO dbinfo;
-#else
-    DB_TXN *tid;
-#endif
-
-    if(OVDBenv != NULL || clientmode) {
-       syslog(L_ERROR, "OVDB: ovdb_open called more than once");
-       return false;
-    }
-
-    read_ovdb_conf();
-    if(ovdb_conf.readserver && mode == OV_READ)
-       clientmode = 1;
-
-    if(mode & OVDB_SERVER)
-       clientmode = 0;
-
-    if(clientmode) {
-       if(client_connect() == 0)
-           return true;
-       clientmode = 0;
-    }
-    if(!ovdb_check_user()) {
-       syslog(L_FATAL, "OVDB: must be running as " NEWSUSER " to access overview.");
-       return false;
-    }
-    if(!ovdb_getlock(OVDB_LOCK_NORMAL)) {
-       syslog(L_FATAL, "OVDB: ovdb_getlock failed: %m");
-       return false;
-    }
-
-    if(ovdb_open_berkeleydb(mode, 0) != 0)
-       return false;
-
-    if(check_version() != 0)
-       return false;
-
-    if(mode & OV_WRITE || mode & OVDB_SERVER) {
-       oneatatime = 0;
-    } else {
-       oneatatime = 1;
-    }
-
-#if DB_VERSION_MAJOR == 2
-    memset(&_dbinfo, 0, sizeof _dbinfo);
-    _dbinfo.db_pagesize = ovdb_conf.pagesize;
-    _dbinfo.bt_minkey = ovdb_conf.minkey;
-#endif
-
-    dbs = xcalloc(ovdb_conf.numdbfiles, sizeof(DB *));
-    
-    if(!oneatatime) {
-       for(i = 0; i < ovdb_conf.numdbfiles; i++) {
-            ret = open_db_file(i);
-           if (ret != 0) {
-               syslog(L_FATAL, "OVDB: open_db_file failed: %s", db_strerror(ret));
-               return false;
-           }
-       }
-    }
-
-#if DB_VERSION_MAJOR == 2
-    memset(&dbinfo, 0, sizeof dbinfo);
-
-    ret = db_open("groupinfo", DB_BTREE, _db_flags, 0666, OVDBenv,
-                  &dbinfo, &groupinfo);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: db_open failed: %s", db_strerror(ret));
-       return false;
-    }
-
-    ret = db_open("groupaliases", DB_HASH, _db_flags, 0666, OVDBenv,
-                  &dbinfo, &groupaliases);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: db_open failed: %s", db_strerror(ret));
-       return false;
-    }
-#else
-    ret = db_create(&groupinfo, OVDBenv, 0);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: open: db_create: %s", db_strerror(ret));
-       return false;
-    }
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    TXN_START(t_open_groupinfo, tid);
-    ret = groupinfo->open(groupinfo, tid, "groupinfo", NULL, DB_BTREE,
-                          _db_flags, 0666);
-    if (ret == 0)
-       TXN_COMMIT(t_open_groupinfo, tid);
-#else
-    ret = groupinfo->open(groupinfo, "groupinfo", NULL, DB_BTREE,
-                          _db_flags, 0666);
-#endif
-    if (ret != 0) {
-       groupinfo->close(groupinfo, 0);
-       syslog(L_FATAL, "OVDB: open: groupinfo->open: %s", db_strerror(ret));
-       return false;
-    }
-    ret = db_create(&groupaliases, OVDBenv, 0);
-    if (ret != 0) {
-       syslog(L_FATAL, "OVDB: open: db_create: %s", db_strerror(ret));
-       return false;
-    }
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    TXN_START(t_open_groupaliases, tid);
-    ret = groupaliases->open(groupaliases, tid, "groupaliases", NULL, DB_HASH,
-                             _db_flags, 0666);
-    if (ret == 0)
-       TXN_COMMIT(t_open_groupaliases, tid);
-#else
-    ret = groupaliases->open(groupaliases, "groupaliases", NULL, DB_HASH,
-                             _db_flags, 0666);
-#endif
-    if (ret != 0) {
-       groupaliases->close(groupaliases, 0);
-       syslog(L_FATAL, "OVDB: open: groupaliases->open: %s", db_strerror(ret));
-       return false;
-    }
-#endif
-
-    Cutofflow = false;
-    return true;
-}
-
-
-bool
-ovdb_groupstats(char *group, int *lo, int *hi, int *count, int *flag)
-{
-    int ret;
-    struct groupinfo gi;
-
-    if (clientmode) {
-       struct rs_cmd rs;
-       struct rs_groupstats repl;
-
-       rs.what = CMD_GROUPSTATS;
-       rs.grouplen = strlen(group)+1;
-
-       if (csend(&rs, sizeof(rs)) < 0)
-            return false;
-       if (csend(group, rs.grouplen) < 0)
-            return false;
-       crecv(&repl, sizeof(repl));
-
-       if(repl.status != CMD_GROUPSTATS)
-           return false;
-
-       /* we don't use the alias yet, but the OV API will be extended
-          at some point so that the alias is returned also */
-       if(repl.aliaslen != 0) {
-           char *buf = xmalloc(repl.aliaslen);
-           crecv(buf, repl.aliaslen);
-           free(buf);
-       }
-
-       if(lo)
-           *lo = repl.lo;
-       if(hi)
-           *hi = repl.hi;
-       if(count)
-           *count = repl.count;
-       if(flag)
-           *flag = repl.flag;
-       return true;
-    }
-
-    ret = ovdb_getgroupinfo(group, &gi, true, NULL, 0);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case DB_NOTFOUND:
-       return false;
-    default:
-       syslog(L_ERROR, "OVDB: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-       return false;
-    }
-
-    if(lo != NULL)
-       *lo = gi.low;
-    if(hi != NULL)
-       *hi = gi.high;
-    if(count != NULL)
-       *count = gi.count;
-    if(flag != NULL)
-       *flag = gi.flag;
-    return true;
-}
-
-bool ovdb_groupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag)
-{
-    DBT key, val;
-    struct groupinfo gi;
-    DB_TXN *tid;
-    int ret = 0;
-    int new;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    TXN_START(t_groupadd, tid);
-
-    if(tid==NULL)
-       return false;
-
-    new = 0;
-    ret = ovdb_getgroupinfo(group, &gi, false, tid, DB_RMW);
-    switch (ret)
-    {
-    case DB_NOTFOUND:
-       new = 1;
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_groupadd, tid);
-    default:
-       TXN_ABORT(t_groupadd, tid);
-       syslog(L_ERROR, "OVDB: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-       return false;
-    }
-
-    if(!new && (gi.status & GROUPINFO_DELETED)
-               && !(gi.status & GROUPINFO_EXPIRING)
-               && !(gi.status & GROUPINFO_MOVING)) {
-       int s, c = 0;
-       char g[MAXHEADERSIZE];
-
-       strlcpy(g, group, sizeof(g));
-       s = strlen(g) + 1;
-       key.data = g;
-       key.size = s + sizeof(int);
-       do {
-           c++;
-           memcpy(g+s, &c, sizeof(int));
-           ret = groupinfo->get(groupinfo, tid, &key, &val, 0);
-       } while(ret == 0);
-       if(ret == TRYAGAIN) {
-           TXN_RETRY(t_groupadd, tid);
-       }
-       val.data = &gi;
-       val.size = sizeof(gi);
-        ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_groupadd, tid);
-       default:
-           TXN_ABORT(t_groupadd, tid);
-           syslog(L_ERROR, "OVDB: groupinfo->put: %s", db_strerror(ret));
-           return false;
-       }
-       key.data = group;
-       key.size = strlen(group);
-        ret = groupinfo->del(groupinfo, tid, &key, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_groupadd, tid);
-       default:
-           TXN_ABORT(t_groupadd, tid);
-           syslog(L_ERROR, "OVDB: groupinfo->del: %s", db_strerror(ret));
-           return false;
-       }
-       new = 1;
-    }
-
-    if(new) {
-        ret = groupid_new(&gi.current_gid, tid);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_groupadd, tid);
-       default:
-           TXN_ABORT(t_groupadd, tid);
-           syslog(L_ERROR, "OVDB: groupid_new: %s", db_strerror(ret));
-           return false;
-       }
-       gi.low = lo ? lo : 1;
-       gi.high = hi;
-       gi.count = 0;
-       gi.flag = *flag;
-       gi.expired = time(NULL);
-       gi.expiregrouppid = 0;
-       gi.current_db = gi.new_db = which_db(group);
-       gi.new_gid = gi.current_gid;
-       gi.status = 0;
-    } else {
-       gi.flag = *flag;
-    }
-
-    key.data = group;
-    key.size = strlen(group);
-    val.data = &gi;
-    val.size = sizeof gi;
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-    switch (ret) {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_groupadd, tid);
-    default:
-       TXN_ABORT(t_groupadd, tid);
-       syslog(L_ERROR, "OVDB: groupadd: groupinfo->put: %s", db_strerror(ret));
-       return false;
-    }
-
-    if(*flag == '=') {
-       key.data = group;
-       key.size = strlen(group);
-       val.data = flag + 1;
-       val.size = strcspn(flag, "\n") - 1;
-
-       switch(ret = groupaliases->put(groupaliases, tid, &key, &val, 0)) {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_groupadd, tid);
-       default:
-           TXN_ABORT(t_groupadd, tid);
-           syslog(L_ERROR, "OVDB: groupadd: groupaliases->put: %s", db_strerror(ret));
-           return false;
-       }
-    }
-
-    TXN_COMMIT(t_groupadd, tid);
-    return true;
-}
-
-bool ovdb_groupdel(char *group)
-{
-    DBT key, val;
-    struct groupinfo gi;
-    DB_TXN *tid;
-    int ret = 0;
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    /* We only need to set the deleted flag in groupinfo to prevent readers
-       from seeing this group.  The actual overview records aren't deleted
-       now, since that could take a significant amount of time (and innd
-       is who normally calls this function).  The expireover run will
-       clean up the deleted groups. */
-
-    TXN_START(t_groupdel, tid);
-
-    if(tid==NULL)
-       return false;
-
-    ret = ovdb_getgroupinfo(group, &gi, true, tid, DB_RMW);
-    switch (ret)
-    {
-    case DB_NOTFOUND:
-       return true;
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_groupdel, tid);
-    default:
-       syslog(L_ERROR, "OVDB: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-       TXN_ABORT(t_groupdel, tid);
-       return false;
-    }
-
-    gi.status |= GROUPINFO_DELETED;
-
-    key.data = group;
-    key.size = strlen(group);
-    val.data = &gi;
-    val.size = sizeof gi;
-
-    switch(ret = groupinfo->put(groupinfo, tid, &key, &val, 0)) {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_groupdel, tid);
-    default:
-       TXN_ABORT(t_groupdel, tid);
-       syslog(L_ERROR, "OVDB: groupadd: groupinfo->put: %s", db_strerror(ret));
-       return false;
-    }
-
-    switch(ret = groupaliases->del(groupaliases, tid, &key, 0)) {
-    case 0:
-    case DB_NOTFOUND:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_groupdel, tid);
-    default:
-       syslog(L_ERROR, "OVDB: groupdel: groupaliases->del: %s", db_strerror(ret));
-       TXN_ABORT(t_groupdel, tid);
-       return false;
-    }
-
-    TXN_COMMIT(t_groupdel, tid);
-    return true;
-}
-
-bool ovdb_add(char *group, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires)
-{
-    static size_t databuflen = 0;
-    static char *databuf;
-    DB         *db;
-    DBT                key, val;
-    DB_TXN     *tid;
-    struct groupinfo gi;
-    struct datakey dk;
-    int ret = 0;
-
-    memset(&dk, 0, sizeof dk);
-
-    if(databuflen == 0) {
-       databuflen = BIG_BUFFER;
-       databuf = xmalloc(databuflen);
-    }
-    if(databuflen < len + sizeof(struct ovdata)) {
-       databuflen = len + sizeof(struct ovdata);
-        databuf = xrealloc(databuf, databuflen);
-    }
-
-    /* hmm... BerkeleyDB needs something like a 'struct iovec' so that we don't
-       have to make a new buffer and copy everything in to it */
-
-    ((struct ovdata *)databuf)->token = token;
-    ((struct ovdata *)databuf)->arrived = arrived;
-    ((struct ovdata *)databuf)->expires = expires;
-    memcpy(databuf + sizeof(struct ovdata), data, len);
-    len += sizeof(struct ovdata);
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-
-    /* start the transaction */
-    TXN_START(t_add, tid);
-
-    if(tid==NULL)
-       return false;
-
-    /* first, retrieve groupinfo */
-    ret = ovdb_getgroupinfo(group, &gi, true, tid, DB_RMW);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case DB_NOTFOUND:
-       TXN_ABORT(t_add, tid);
-       return true;
-    case TRYAGAIN:
-       TXN_RETRY(t_add, tid);
-    default:
-       TXN_ABORT(t_add, tid);
-       syslog(L_ERROR, "OVDB: add: ovdb_getgroupinfo: %s", db_strerror(ret));
-       return false;
-    }
-
-    /* adjust groupinfo */
-    if(Cutofflow && gi.low > artnum) {
-       TXN_ABORT(t_add, tid);
-       return true;
-    }
-    if(gi.low == 0 || gi.low > artnum)
-       gi.low = artnum;
-    if(gi.high < artnum)
-       gi.high = artnum;
-    gi.count++;
-
-    /* store groupinfo */
-    key.data = group;
-    key.size = strlen(group);
-    val.data = &gi;
-    val.size = sizeof gi;
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_add, tid);
-    default:
-       TXN_ABORT(t_add, tid);
-       syslog(L_ERROR, "OVDB: add: groupinfo->put: %s", db_strerror(ret));
-       return false;
-    }
-
-    /* store overview */
-    db = get_db_bynum(gi.current_db);
-    if(db == NULL) {
-       TXN_ABORT(t_add, tid);
-       return false;
-    }
-    dk.groupnum = gi.current_gid;
-    dk.artnum = htonl((u_int32_t)artnum);
-
-    key.data = &dk;
-    key.size = sizeof dk;
-    val.data = databuf;
-    val.size = len;
-
-    ret = db->put(db, tid, &key, &val, 0);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_add, tid);
-    default:
-       TXN_ABORT(t_add, tid);
-       syslog(L_ERROR, "OVDB: add: db->put: %s", db_strerror(ret));
-       return false;
-    }
-
-    if(artnum < gi.high && gi.status & GROUPINFO_MOVING) {
-       /* If the GROUPINFO_MOVING flag is set, then expireover
-          is writing overview records under a new groupid.
-          If this overview record is not at the highmark,
-          we need to also store it under the new groupid */
-       db = get_db_bynum(gi.new_db);
-       if(db == NULL) {
-           TXN_ABORT(t_add, tid);
-           return false;
-       }
-       dk.groupnum = gi.new_gid;
-
-        ret = db->put(db, tid, &key, &val, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_add, tid);
-       default:
-           TXN_ABORT(t_add, tid);
-           syslog(L_ERROR, "OVDB: add: db->put: %s", db_strerror(ret));
-           return false;
-       }
-    }
-
-    TXN_COMMIT(t_add, tid);
-    return true;
-}
-
-bool ovdb_cancel(TOKEN token UNUSED)
-{
-    return true;
-}
-
-struct ovdbsearch {
-    DBC *cursor;
-    group_id_t gid;
-    u_int32_t firstart;
-    u_int32_t lastart;
-    int state;
-};
-
-/* Even though nnrpd only does one search at a time, a read server process could
-   do many concurrent searches; hence we must keep track of an arbitrary number of
-   open searches */
-static struct ovdbsearch **searches = NULL;
-static int nsearches = 0;
-static int maxsearches = 0;
-
-void *
-ovdb_opensearch(char *group, int low, int high)
-{
-    DB *db;
-    struct ovdbsearch *s;
-    struct groupinfo gi;
-    int ret;
-
-    if(clientmode) {
-       struct rs_cmd rs;
-       struct rs_opensrch repl;
-
-       rs.what = CMD_OPENSRCH;
-       rs.grouplen = strlen(group)+1;
-       rs.artlo = low;
-       rs.arthi = high;
-
-       if (csend(&rs, sizeof(rs)) < 0)
-            return NULL;
-       if (csend(group, rs.grouplen) < 0)
-            return NULL;
-       crecv(&repl, sizeof(repl));
-
-       if(repl.status != CMD_OPENSRCH)
-           return NULL;
-
-       return repl.handle;
-    }
-
-    ret = ovdb_getgroupinfo(group, &gi, true, NULL, 0);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case DB_NOTFOUND:
-       return NULL;
-    default:
-       syslog(L_ERROR, "OVDB: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-       return NULL;
-    }
-
-    s = xmalloc(sizeof(struct ovdbsearch));
-    db = get_db_bynum(gi.current_db);
-    if(db == NULL) {
-       free(s);
-       return NULL;
-    }
-
-    ret = db->cursor(db, NULL, &(s->cursor), 0);
-    if (ret != 0) {
-       syslog(L_ERROR, "OVDB: opensearch: s->db->cursor: %s", db_strerror(ret));
-       free(s);
-       return NULL;
-    }
-
-    s->gid = gi.current_gid;
-    s->firstart = low;
-    s->lastart = high;
-    s->state = 0;
-
-    if(searches == NULL) {
-       nsearches = 0;
-       maxsearches = 50;
-       searches = xmalloc(sizeof(struct ovdbsearch *) * maxsearches);
-    }
-    if(nsearches == maxsearches) {
-       maxsearches += 50;
-       searches = xrealloc(searches, sizeof(struct ovdbsearch *) * maxsearches);
-    }
-    searches[nsearches] = s;
-    nsearches++;
-
-    return (void *)s;
-}
-
-bool
-ovdb_search(void *handle, ARTNUM *artnum, char **data, int *len,
-            TOKEN *token, time_t *arrived)
-{
-    struct ovdbsearch *s = (struct ovdbsearch *)handle;
-    DBT key, val;
-    u_int32_t flags;
-    struct ovdata ovd;
-    struct datakey dk;
-    int ret;
-
-    if (clientmode) {
-       struct rs_cmd rs;
-       struct rs_srch repl;
-       static char *databuf;
-       static int buflen = 0;
-
-       rs.what = CMD_SRCH;
-       rs.handle = handle;
-
-       if (csend(&rs, sizeof(rs)) < 0)
-            return false;
-       if (crecv(&repl, sizeof(repl)) < 0)
-            return false;
-
-       if(repl.status != CMD_SRCH)
-           return false;
-       if(repl.len > buflen) {
-           if(buflen == 0) {
-               buflen = repl.len + 512;
-               databuf = xmalloc(buflen);
-           } else {
-               buflen = repl.len + 512;
-                databuf = xrealloc(databuf, buflen);
-           }
-       }
-       crecv(databuf, repl.len);
-
-       if(artnum)
-           *artnum = repl.artnum;
-       if(token)
-           *token = repl.token;
-       if(arrived)
-           *arrived = repl.arrived;
-       if(len)
-           *len = repl.len;
-       if(data)
-           *data = databuf;
-       return true;
-    }
-
-    switch(s->state) {
-    case 0:
-       flags = DB_SET_RANGE;
-       memset(&dk, 0, sizeof dk);
-       dk.groupnum = s->gid;
-       dk.artnum = htonl(s->firstart);
-       s->state = 1;
-       break;
-    case 1:
-       flags = DB_NEXT;
-       break;
-    case 2:
-       s->state = 3;
-       return false;
-    default:
-       syslog(L_ERROR, "OVDB: OVsearch called again after false return");
-       return false;
-    }
-
-    memset(&key, 0, sizeof key);
-    memset(&val, 0, sizeof val);
-    key.data = &dk;
-    key.size = key.ulen = sizeof(struct datakey);
-    key.flags = DB_DBT_USERMEM;
-
-    if(!data && !len) {
-       /* caller doesn't need data, so we don't have to retrieve it all */
-       val.flags |= DB_DBT_PARTIAL;
-
-       if(token || arrived)
-           val.dlen = sizeof(struct ovdata);
-    }
-
-    switch(ret = s->cursor->c_get(s->cursor, &key, &val, flags)) {
-    case 0:
-       break;
-    case DB_NOTFOUND:
-       s->state = 3;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-       return false;
-    default:
-       syslog(L_ERROR, "OVDB: search: c_get: %s", db_strerror(ret));
-       s->state = 3;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-       return false;
-    }
-
-    if(key.size != sizeof(struct datakey)) {
-       s->state = 3;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-       return false;
-    }
-
-    if(dk.groupnum != s->gid || ntohl(dk.artnum) > s->lastart) {
-       s->state = 3;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-       return false;
-    }
-
-    if( ((len || data) && val.size <= sizeof(struct ovdata))
-       || ((token || arrived) && val.size < sizeof(struct ovdata)) ) {
-       syslog(L_ERROR, "OVDB: search: bad value length");
-       s->state = 3;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-       return false;
-    }
-
-    if(ntohl(dk.artnum) == s->lastart) {
-       s->state = 2;
-       s->cursor->c_close(s->cursor);
-       s->cursor = NULL;
-    }
-
-    if(artnum)
-       *artnum = ntohl(dk.artnum);
-
-    if(token || arrived)
-       memcpy(&ovd, val.data, sizeof(struct ovdata));
-    if(token)
-       *token = ovd.token;
-    if(arrived)
-       *arrived = ovd.arrived;
-
-    if(len)
-       *len = val.size - sizeof(struct ovdata);
-    if(data)
-       *data = (char *)val.data + sizeof(struct ovdata);
-
-    return true;
-}
-
-void ovdb_closesearch(void *handle)
-{
-    int i;
-    if(clientmode) {
-       struct rs_cmd rs;
-
-       rs.what = CMD_CLOSESRCH;
-       rs.handle = handle;
-       csend(&rs, sizeof(rs));
-       /* no reply is sent for a CMD_CLOSESRCH */
-    } else {
-       struct ovdbsearch *s = (struct ovdbsearch *)handle;
-
-       if(s->cursor)
-           s->cursor->c_close(s->cursor);
-
-       for(i = 0; i < nsearches; i++) {
-           if(s == searches[i]) {
-               break;
-           }
-       }
-       nsearches--;
-       for( ; i < nsearches; i++) {
-           searches[i] = searches[i+1];
-       }
-
-       free(handle);
-    }
-}
-
-bool ovdb_getartinfo(char *group, ARTNUM artnum, TOKEN *token)
-{
-    int ret, cdb = 0;
-    group_id_t cgid = 0;
-    DB *db;
-    DBT key, val;
-    struct ovdata ovd;
-    struct datakey dk;
-    struct groupinfo gi;
-    int pass = 0;
-
-    if(clientmode) {
-       struct rs_cmd rs;
-       struct rs_artinfo repl;
-
-       rs.what = CMD_ARTINFO;
-       rs.grouplen = strlen(group)+1;
-       rs.artlo = artnum;
-
-       if (csend(&rs, sizeof(rs)) < 0)
-            return false;
-       if (csend(group, rs.grouplen) < 0)
-            return false;
-       crecv(&repl, sizeof(repl));
-
-       if(repl.status != CMD_ARTINFO)
-           return false;
-
-       if(token)
-           *token = repl.token;
-
-       return true;
-    }
-
-    while(1) {
-        ret = ovdb_getgroupinfo(group, &gi, true, NULL, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case DB_NOTFOUND:
-           return false;
-       default:
-           syslog(L_ERROR, "OVDB: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-           return false;
-       }
-
-       if(pass) {
-           /* This was our second groupinfo retrieval; because the article
-              retrieval came up empty.  If the group ID hasn't changed
-              since the first groupinfo retrieval, we can assume the article
-              is definitely not there.  Otherwise, we'll try to retrieve
-              it the article again. */
-           if(cdb == gi.current_db && cgid == gi.current_gid)
-               return false;
-       }
-
-       db = get_db_bynum(gi.current_db);
-       if(db == NULL)
-           return false;
-
-       memset(&dk, 0, sizeof dk);
-       dk.groupnum = gi.current_gid;
-       dk.artnum = htonl((u_int32_t)artnum);
-
-       memset(&key, 0, sizeof key);
-       memset(&val, 0, sizeof val);
-
-       key.data = &dk;
-       key.size = sizeof dk;
-
-        /* caller doesn't need data, so we don't have to retrieve it all */
-        val.flags = DB_DBT_PARTIAL;
-
-        if(token)
-            val.dlen = sizeof(struct ovdata);
-
-       switch(ret = db->get(db, NULL, &key, &val, 0)) {
-       case 0:
-       case DB_NOTFOUND:
-           break;
-       default:
-           syslog(L_ERROR, "OVDB: getartinfo: db->get: %s", db_strerror(ret));
-           return false;
-       }
-
-       if(ret == DB_NOTFOUND) {
-           /* If the group is being moved (i.e., its group ID is going
-              to change), there's a chance the article is now under the
-              new ID.  So we'll grab the groupinfo again to check for
-              that. */
-           if(!pass && (gi.status & GROUPINFO_MOVING)) {
-               cdb = gi.current_db;
-               cgid = gi.current_gid;
-               pass++;
-               continue;
-           }
-           return false;
-       }
-       break;
-    }
-
-    if(token && val.size < sizeof(struct ovdata)) {
-       syslog(L_ERROR, "OVDB: getartinfo: data too short");
-       return false;
-    }
-
-    if(token) {
-       memcpy(&ovd, val.data, sizeof(struct ovdata));
-       *token = ovd.token;
-    }
-    return true;
-}
-
-bool ovdb_expiregroup(char *group, int *lo, struct history *h)
-{
-    DB *db, *ndb = NULL;
-    DBT key, val, nkey, gkey, gval;
-    DB_TXN *tid;
-    DBC *cursor = NULL;
-    int ret = 0, delete, old_db = 0, cleanup;
-    struct groupinfo gi;
-    struct ovdata ovd;
-    struct datakey dk, ndk;
-    group_id_t old_gid = 0;
-    ARTHANDLE *ah;
-    u_int32_t artnum = 0, currentart, lowest;
-    int i, compact, done, currentcount, newcount;
-
-    if(eo_start == 0) {
-       eo_start = time(NULL);
-       delete_old_stuff(0);    /* remove deleted groups first */
-    }
-
-    /* Special case:  when called with NULL group, we're to clean out
-     * records for forgotton groups (groups removed from the active file
-     * but not from overview).
-     * This happens at the end of the expireover run, and only if all
-     * of the groups in the active file have been processed.
-     * delete_old_stuff(1) will remove groups that are in ovdb but
-     * have not been processed during this run.
-     */
-
-    if(group == NULL)
-       return delete_old_stuff(1);
-
-    memset(&key, 0, sizeof key);
-    memset(&nkey, 0, sizeof nkey);
-    memset(&val, 0, sizeof val);
-    memset(&dk, 0, sizeof dk);
-    memset(&ndk, 0, sizeof ndk);
-
-    TXN_START(t_expgroup_1, tid);
-
-    if(tid==NULL)
-       return false;
-
-    cleanup = 0;
-
-    ret = ovdb_getgroupinfo(group, &gi, true, tid, DB_RMW);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_expgroup_1, tid);
-    default:
-       syslog(L_ERROR, "OVDB: expiregroup: ovdb_getgroupinfo failed: %s", db_strerror(ret));
-    case DB_NOTFOUND:
-       TXN_ABORT(t_expgroup_1, tid);
-       return false;
-    }
-
-    if(gi.status & GROUPINFO_EXPIRING) {
-       /* is there another expireover working on this group? */
-        ret = kill(gi.expiregrouppid, 0);
-       switch(ret)
-        {
-       case 0:
-       case EPERM:
-           TXN_ABORT(t_expgroup_1, tid);
-           return false;
-       }
-
-       /* a previous expireover run must've died.  We'll clean
-          up after it */
-       if(gi.status & GROUPINFO_MOVING) {
-           cleanup = 1;
-           old_db = gi.new_db;
-           old_gid = gi.new_gid;
-
-           ret = mk_temp_groupinfo(old_db, old_gid, tid);
-           switch(ret) {
-           case 0:
-               break;
-           case TRYAGAIN:
-               TXN_RETRY(t_expgroup_1, tid);
-           default:
-               TXN_ABORT(t_expgroup_1, tid);
-               return false;
-           }
-           gi.status &= ~GROUPINFO_MOVING;
-       }
-    }
-
-    if(gi.count < ovdb_conf.nocompact || ovdb_conf.nocompact == 0)
-       compact = 1;
-    else
-       compact = 0;
-
-    if(gi.count == 0)
-       compact = 0;
-
-    db = get_db_bynum(gi.current_db);
-    if(db == NULL) {
-       TXN_ABORT(t_expgroup_1, tid);
-       return false;
-    }
-
-    gi.status |= GROUPINFO_EXPIRING;
-    gi.expiregrouppid = getpid();
-    if(compact) {
-       gi.status |= GROUPINFO_MOVING;
-       gi.new_db = gi.current_db;
-       ndb = db;
-        ret = groupid_new(&gi.new_gid, tid);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_1, tid);
-       default:
-           TXN_ABORT(t_expgroup_1, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: groupid_new: %s", db_strerror(ret));
-           return false;
-       }
-    }
-
-    key.data = group;
-    key.size = strlen(group);
-    val.data = &gi;
-    val.size = sizeof gi;
-
-    ret = groupinfo->put(groupinfo, tid, &key, &val, 0);
-    switch (ret)
-    {
-    case 0:
-       break;
-    case TRYAGAIN:
-       TXN_RETRY(t_expgroup_1, tid);
-    default:
-       TXN_ABORT(t_expgroup_1, tid);
-       syslog(L_ERROR, "OVDB: expiregroup: groupinfo->put: %s", db_strerror(ret));
-       return false;
-    }
-    TXN_COMMIT(t_expgroup_1, tid);
-
-    if(cleanup) {
-       if(delete_all_records(old_db, old_gid) == 0) {
-           rm_temp_groupinfo(old_gid);
-       }
-    }
-
-    /*
-     * The following loop iterates over the OV records for the group in
-     * "batches", to limit transaction sizes.
-     *
-     * loop {
-     *    start transaction
-     *    get groupinfo
-     *    process EXPIREGROUP_TXN_SIZE records
-     *    write updated groupinfo
-     *    commit transaction
-     * }
-     */
-    currentart = 0;
-    lowest = currentcount = 0;
-
-    memset(&gkey, 0, sizeof gkey);
-    memset(&gval, 0, sizeof gval);
-    gkey.data = group;
-    gkey.size = strlen(group);
-    gval.data = &gi;
-    gval.size = sizeof gi;
-
-    while(1) {
-       TXN_START(t_expgroup_loop, tid);
-       if(tid==NULL)
-           return false;
-        done = 0;
-       newcount = 0;
-
-        ret = ovdb_getgroupinfo(group, &gi, false, tid, DB_RMW);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_loop, tid);
-       default:
-           TXN_ABORT(t_expgroup_loop, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: ovdb_getgroupinfo: %s", db_strerror(ret));
-           return false;
-       }
-
-        ret = db->cursor(db, tid, &cursor, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_loop, tid);
-       default:
-           TXN_ABORT(t_expgroup_loop, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: db->cursor: %s", db_strerror(ret));
-           return false;
-       }
-
-       dk.groupnum = gi.current_gid;
-       dk.artnum = htonl(currentart);
-       key.data = &dk;
-       key.size = key.ulen = sizeof dk;
-       key.flags = DB_DBT_USERMEM;
-
-       for(i=0; i < EXPIREGROUP_TXN_SIZE; i++) {
-            ret = cursor->c_get(cursor, &key, &val,
-                                i == 0 ? DB_SET_RANGE : DB_NEXT);
-           switch (ret)
-            {
-           case 0:
-           case DB_NOTFOUND:
-               break;
-           case TRYAGAIN:
-               cursor->c_close(cursor);
-               TXN_RETRY(t_expgroup_loop, tid);
-           default:
-               cursor->c_close(cursor);
-               TXN_ABORT(t_expgroup_loop, tid);
-               syslog(L_ERROR, "OVDB: expiregroup: c_get: %s", db_strerror(ret));
-               return false;
-           }
-
-           /* stop if: there are no more keys, an unknown key is reached,
-              or reach a different group */
-
-           if(ret == DB_NOTFOUND
-                   || key.size != sizeof dk
-                   || dk.groupnum != gi.current_gid) {
-               done++;
-               break;
-           }
-
-           artnum = ntohl(dk.artnum);
-
-           delete = 0;
-           if(val.size < sizeof ovd) {
-               delete = 1;     /* must be corrupt, just delete it */
-           } else {
-               memcpy(&ovd, val.data, sizeof ovd);
-
-               ah = NULL;
-               if (!SMprobe(EXPENSIVESTAT, &ovd.token, NULL) || OVstatall) {
-                   if((ah = SMretrieve(ovd.token, RETR_STAT)) == NULL) {
-                       delete = 1;
-                   } else
-                       SMfreearticle(ah);
-               } else {
-                   if (!OVhisthasmsgid(h, (char *)val.data + sizeof(ovd))) {
-                       delete = 1;
-                   }
-               }
-               if (!delete && innconf->groupbaseexpiry &&
-                           OVgroupbasedexpire(ovd.token, group,
-                                   (char *)val.data + sizeof(ovd),
-                                   val.size - sizeof(ovd),
-                                   ovd.arrived, ovd.expires)) {
-                   delete = 1;
-               }
-           }
-
-           if(delete) {
-               if(!compact) {
-                   switch(ret = cursor->c_del(cursor, 0)) {
-                   case 0:
-                   case DB_NOTFOUND:
-                   case DB_KEYEMPTY:
-                       break;
-                   case TRYAGAIN:
-                       cursor->c_close(cursor);
-                       TXN_RETRY(t_expgroup_loop, tid);
-                   default:
-                       cursor->c_close(cursor);
-                       TXN_ABORT(t_expgroup_loop, tid);
-                       syslog(L_ERROR, "OVDB: expiregroup: c_del: %s", db_strerror(ret));
-                       return false;
-                   }
-               }
-               if(gi.count > 0)
-                   gi.count--;
-           } else {
-               if(compact) {
-                   ndk.groupnum = gi.new_gid;
-                   ndk.artnum = dk.artnum;
-                   nkey.data = &ndk;
-                   nkey.size = sizeof ndk;
-
-                   switch(ret = ndb->put(ndb, tid, &nkey, &val, 0)) {
-                   case 0:
-                       break;
-                   case TRYAGAIN:
-                       cursor->c_close(cursor);
-                       TXN_RETRY(t_expgroup_loop, tid);
-                   default:
-                       cursor->c_close(cursor);
-                       TXN_ABORT(t_expgroup_loop, tid);
-                       syslog(L_ERROR, "OVDB: expiregroup: ndb->put: %s", db_strerror(ret));
-                       return false;
-                   }
-               }
-               newcount++;
-               if(lowest != -1 && (lowest == 0 || artnum < lowest))
-                   lowest = artnum;
-           }
-       }
-       /* end of for loop */
-
-       if(cursor->c_close(cursor) == TRYAGAIN) {
-           TXN_RETRY(t_expgroup_loop, tid);
-       }
-
-       if(lowest != 0 && lowest != -1)
-           gi.low = lowest;
-
-       if(done) {
-           if(compact) {
-               old_db = gi.current_db;
-               gi.current_db = gi.new_db;
-               old_gid = gi.current_gid;
-               gi.current_gid = gi.new_gid;
-               gi.status &= ~GROUPINFO_MOVING;
-
-               ret = mk_temp_groupinfo(old_db, old_gid, tid);
-               switch(ret) {
-               case 0:
-                   break;
-               case TRYAGAIN:
-                   TXN_RETRY(t_expgroup_loop, tid);
-               default:
-                   TXN_ABORT(t_expgroup_loop, tid);
-                   return false;
-               }
-           }
-
-           gi.status &= ~GROUPINFO_EXPIRING;
-           gi.expired = time(NULL);
-           if(gi.count == 0 && lowest == 0)
-               gi.low = gi.high+1;
-       }
-
-        ret = groupinfo->put(groupinfo, tid, &gkey, &gval, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_loop, tid);
-       default:
-           TXN_ABORT(t_expgroup_loop, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: groupinfo->put: %s", db_strerror(ret));
-           return false;
-       }
-        TXN_COMMIT(t_expgroup_loop, tid);
-
-       currentcount += newcount;
-       if(lowest != 0)
-           lowest = -1;
-
-       if(done)
-           break;
-
-       currentart = artnum+1;
-    }
-
-    if(compact) {
-        if(delete_all_records(old_db, old_gid) == 0) {
-           rm_temp_groupinfo(old_gid);
-       }
-    }
-
-    if(currentcount != gi.count) {
-       syslog(L_NOTICE, "OVDB: expiregroup: recounting %s", group);
-
-       TXN_START(t_expgroup_recount, tid);
-       if(tid == NULL)
-           return false;
-
-       switch(ret = ovdb_getgroupinfo(group, &gi, false, tid, DB_RMW)) {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_recount, tid);
-       default:
-           TXN_ABORT(t_expgroup_recount, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: ovdb_getgroupinfo: %s", db_strerror(ret));
-           return false;
-       }
-
-       if(count_records(&gi) != 0) {
-           TXN_ABORT(t_expgroup_recount, tid);
-           return false;
-       }
-
-        ret = groupinfo->put(groupinfo, tid, &gkey, &gval, 0);
-       switch (ret)
-        {
-       case 0:
-           break;
-       case TRYAGAIN:
-           TXN_RETRY(t_expgroup_recount, tid);
-       default:
-           TXN_ABORT(t_expgroup_recount, tid);
-           syslog(L_ERROR, "OVDB: expiregroup: groupinfo->put: %s", db_strerror(ret));
-           return false;
-       }
-        TXN_COMMIT(t_expgroup_recount, tid);
-    }
-
-    if(lo)
-       *lo = gi.low;
-    return true;
-}
-
-bool ovdb_ctl(OVCTLTYPE type, void *val)
-{
-    int *i;
-    OVSORTTYPE *sorttype;
-    bool *boolval;
-
-    switch (type) {
-    case OVSPACE:
-        i = (int *)val;
-        *i = -1;
-        return true;
-    case OVSORT:
-        sorttype = (OVSORTTYPE *)val;
-        *sorttype = OVNEWSGROUP;
-        return true;
-    case OVCUTOFFLOW:
-        Cutofflow = *(bool *)val;
-        return true;
-    case OVSTATICSEARCH:
-       i = (int *)val;
-       *i = true;
-       return true;
-    case OVCACHEKEEP:
-    case OVCACHEFREE:
-        boolval = (bool *)val;
-        *boolval = false;
-        return true;
-    default:
-        return false;
-    }
-}
-
-void ovdb_close_berkeleydb(void)
-{
-    if(OVDBenv) {
-       /* close db environment */
-#if DB_VERSION_MAJOR == 2
-       db_appexit(OVDBenv);
-       free(OVDBenv);
-#else
-       OVDBenv->close(OVDBenv, 0);
-#endif
-       OVDBenv = NULL;
-    }
-}
-
-void ovdb_close(void)
-{
-    int i;
-
-    if(clientmode) {
-       client_disconnect();
-       return;
-    }
-
-    while(searches != NULL && nsearches) {
-       ovdb_closesearch(searches[0]);
-    }
-    if(searches != NULL) {
-       free(searches);
-       searches = NULL;
-    }
-
-    if(dbs) {
-       /* close databases */
-       for(i = 0; i < ovdb_conf.numdbfiles; i++)
-           close_db_file(i);
-
-       free(dbs);
-       dbs = NULL;
-    }
-    if(groupinfo) {
-       groupinfo->close(groupinfo, 0);
-       groupinfo = NULL;
-    }
-    if(groupaliases) {
-       groupaliases->close(groupaliases, 0);
-       groupaliases = NULL;
-    }
-
-    ovdb_close_berkeleydb();
-    ovdb_releaselock();
-}
-
-
-#endif /* USE_BERKELEY_DB */
-
diff --git a/storage/ovdb/ovdb.h b/storage/ovdb/ovdb.h
deleted file mode 100644 (file)
index 6b1d1eb..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _OVDB_H_
-#define _OVDB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-bool ovdb_open(int mode);
-bool ovdb_groupstats(char *group, int *lo, int *hi, int *count, int *flag);
-bool ovdb_groupadd(char *group, ARTNUM lo, ARTNUM hi, char *flag);
-bool ovdb_groupdel(char *group);
-bool ovdb_add(char *group, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires);
-bool ovdb_cancel(TOKEN token);
-void *ovdb_opensearch(char *group, int low, int high);
-bool ovdb_search(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived);
-void ovdb_closesearch(void *handle);
-bool ovdb_getartinfo(char *group, ARTNUM artnum, TOKEN *token);
-bool ovdb_expiregroup(char *group, int *lo, struct history *h);
-bool ovdb_ctl(OVCTLTYPE type, void *val);
-void ovdb_close(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _OVDB_H_ */
diff --git a/storage/ovdb/ovmethod.config b/storage/ovdb/ovmethod.config
deleted file mode 100644 (file)
index 076ee9b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = ovdb
-number  = 4
-sources = ovdb.c
diff --git a/storage/overdata.c b/storage/overdata.c
deleted file mode 100644 (file)
index b2de7c8..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*  $Id: overdata.c 7477 2005-12-24 21:34:38Z eagle $
-**
-**  Overview data processing.
-**
-**  Here be routines for creating and checking the overview data, the
-**  tab-separated list of overview fields.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-
-#include "inn/buffer.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "inn/wire.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "ovinterface.h"
-#include "paths.h"
-
-
-/* The standard overview fields. */
-static const char * const fields[] = {
-    "Subject", "From", "Date", "Message-ID", "References", "Bytes", "Lines"
-};
-
-
-/*
-**  Return a vector of the standard overview fields. Note there is no
-**  way to free up the resulting data structure.
-*/
-const struct cvector *
-overview_fields(void)
-{
-    static struct cvector *list = NULL;
-
-    if (list == NULL) {
-       unsigned int field;
-
-       list = cvector_new();
-       cvector_resize(list, ARRAY_SIZE(fields));
-
-       for (field = 0; field < ARRAY_SIZE(fields); ++field) {
-           cvector_add(list, fields[field]);
-       }
-    }
-    return list;
-}
-
-/*
-**  Parse the overview schema and return a vector of the additional fields
-**  over the standard ones.  Caller is responsible for freeing the vector.
-*/
-struct vector *
-overview_extra_fields(void)
-{
-    struct vector *list = NULL;
-    struct vector *result = NULL;
-    char *schema = NULL;
-    char *line, *p;
-    QIOSTATE *qp = NULL;
-    unsigned int field;
-    bool full = false;
-
-    schema = concatpath(innconf->pathetc, _PATH_SCHEMA);
-    qp = QIOopen(schema);
-    if (qp == NULL) {
-        syswarn("cannot open %s", schema);
-        goto done;
-    }
-    list = vector_new();
-    for (field = 0, line = QIOread(qp); line != NULL; line = QIOread(qp)) {
-        while (ISWHITE(*line))
-            line++;
-        p = strchr(line, '#');
-        if (p != NULL)
-            *p = '\0';
-        p = strchr(line, '\n');
-        if (p != NULL)
-            *p = '\0';
-        if (*line == '\0')
-            continue;
-        p = strchr(line, ':');
-        if (p != NULL) {
-            *p++ = '\0';
-            full = (strcmp(p, "full") == 0);
-        }
-        if (field >= ARRAY_SIZE(fields)) {
-            if (!full)
-                warn("additional field %s not marked with :full", line);
-            vector_add(list, line);
-        } else {
-            if (strcasecmp(line, fields[field]) != 0)
-                warn("field %d is %s, should be %s", field, line,
-                     fields[field]);
-        }
-        field++;
-    }
-    if (QIOerror(qp)) {
-        if (QIOtoolong(qp)) {
-            warn("line too long in %s", schema);
-        } else {
-            syswarn("error while reading %s", schema);
-        }
-    }
-    result = list;
-
-done:
-    if (schema != NULL)
-        free(schema);
-    if (qp != NULL)
-        QIOclose(qp);
-    if (result == NULL && list != NULL)
-        vector_free(list);
-    return result;
-}
-
-
-/*
-**  Given an article, its length, the name of a header, and a buffer to append
-**  the data to, append header data for that header to the overview data
-**  that's being constructed.  Doesn't append any data if the header isn't
-**  found.
-*/
-static void
-build_header(const char *article, size_t length, const char *header,
-             struct buffer *overview)
-{
-    ptrdiff_t size;
-    size_t offset;
-    const char *data, *end, *p;
-
-    data = wire_findheader(article, length, header);
-    if (data == NULL)
-        return;
-    end = wire_endheader(data, article + length - 1);
-    if (end == NULL)
-        return;
-
-    /* Someone managed to break their server so that they were appending
-       multiple Xref headers, and INN had a bug where it wouldn't notice this
-       and reject the article.  Just in case, see if there are multiple Xref
-       headers and use the last one. */
-    if (strcasecmp(header, "xref") == 0) {
-        const char *next = end + 1;
-
-        while (next != NULL) {
-            next = wire_findheader(next, length - (next - article), header);
-            if (next != NULL) {
-                data = next;
-                end = wire_endheader(data, article + length - 1);
-                if (end == NULL)
-                    return;
-            }
-        }
-    }
-
-    size = end - data + 1;
-    offset = overview->used + overview->left;
-    buffer_resize(overview, offset + size);
-
-    for (p = data; p <= end; p++) {
-        if (*p == '\r' && p[1] == '\n') {
-            p++;
-            continue;
-        }
-        if (*p == '\0' || *p == '\t' || *p == '\n' || *p == '\r')
-            overview->data[offset++] = ' ';
-        else
-            overview->data[offset++] = *p;
-        overview->left++;
-    }
-}
-
-
-/*
-**  Given an article number, an article, and a vector of additional headers,
-**  generate overview data into the provided buffer.  If the buffer parameter
-**  is NULL, a new buffer is allocated.  The article should be in wire format.
-**  Returns the buffer containing the overview data.
-*/
-struct buffer *
-overview_build(ARTNUM number, const char *article, size_t length,
-               const struct vector *extra, struct buffer *overview)
-{
-    unsigned int field;
-    char buffer[32];
-
-    snprintf(buffer, sizeof(buffer), "%lu", number);
-    if (overview == NULL)
-        overview = buffer_new();
-    buffer_set(overview, buffer, strlen(buffer));
-    for (field = 0; field < ARRAY_SIZE(fields); field++) {
-        buffer_append(overview, "\t", 1);
-        if (field == 5) {
-            snprintf(buffer, sizeof(buffer), "%lu", (unsigned long) length);
-            buffer_append(overview, buffer, strlen(buffer));
-        } else
-            build_header(article, length, fields[field], overview);
-    }
-    for (field = 0; field < extra->count; field++) {
-        buffer_append(overview, "\t", 1);
-        buffer_append(overview, extra->strings[field],
-                      strlen(extra->strings[field]));
-        buffer_append(overview, ": ", 2);
-        build_header(article, length, extra->strings[field], overview);
-    }
-    buffer_append(overview, "\r\n", 2);
-    return overview;
-}
-
-
-/*
-**  Check whether a given string is a valid number.
-*/
-static bool
-valid_number(const char *string)
-{
-    const char *p;
-
-    for (p = string; *p != '\0'; p++)
-        if (!CTYPE(isdigit, *p))
-            return false;
-    return true;
-}
-
-
-/*
-**  Check whether a given string is a valid overview string (doesn't contain
-**  CR or LF, and if the second argument is true must be preceeded by a header
-**  name, colon, and space).  Allow CRLF at the end of the data, but don't
-**  require it.
-*/
-static bool
-valid_overview_string(const char *string, bool full)
-{
-    const unsigned char *p;
-
-    /* RFC 2822 says that header fields must consist of printable ASCII
-       characters (characters between 33 and 126, inclusive) excluding colon.
-       We also allow high-bit characters, just in case, but not DEL. */
-    p = (const unsigned char *) string;
-    if (full) {
-        for (; *p != '\0' && *p != ':'; p++)
-            if (*p < 33 || *p == 127)
-                return false;
-        if (*p != ':')
-            return false;
-        p++;
-        if (*p != ' ')
-            return false;
-    }
-    for (p++; *p != '\0'; p++) {
-        if (*p == '\015' && p[1] == '\012' && p[2] == '\0')
-            break;
-        if (*p == '\015' || *p == '\012')
-            return false;
-    }
-    return true;
-}
-
-
-/*
-**  Check the given overview data and make sure it's well-formed.  Extension
-**  headers are not checked against overview.fmt (having a different set of
-**  extension headers doesn't make the data invalid), but the presence of the
-**  standard fields is checked.  Also checked is whether the article number in
-**  the data matches the passed article number.  Returns true if the data is
-**  okay, false otherwise.
-*/
-bool
-overview_check(const char *data, size_t length, ARTNUM article)
-{
-    char *copy;
-    struct cvector *overview;
-    ARTNUM overnum;
-    size_t i;
-
-    copy = xstrndup(data, length);
-    overview = cvector_split(copy, '\t', NULL);
-
-    /* The actual checks.  We don't verify all of the data, since that data
-       may be malformed in the article, but we do check to be sure that the
-       fields that should be numbers are numbers.  That should catch most
-       positional errors.  We can't check Lines yet since right now INN is
-       still accepting the value from the post verbatim. */
-    if (overview->count < 8)
-        goto fail;
-    if (!valid_number(overview->strings[0]))
-        goto fail;
-    overnum = strtoul(overview->strings[0], NULL, 10);
-    if (overnum != article)
-        goto fail;
-    if (!valid_number(overview->strings[6]))
-        goto fail;
-    for (i = 1; i < 6; i++)
-        if (!valid_overview_string(overview->strings[i], false))
-            goto fail;
-    for (i = 8; i < overview->count; i++)
-        if (!valid_overview_string(overview->strings[i], true))
-            goto fail;
-    cvector_free(overview);
-    free(copy);
-    return true;
-
- fail:
-    cvector_free(overview);
-    free(copy);
-    return false;
-}
-
-
-/*
-**  Given an overview header, return the offset of the field within
-**  the overview data, or -1 if the field is not present in the
-**  overview schema for this installation.
-*/
-int
-overview_index(const char *field, const struct vector *extra)
-{
-    int i;
-
-    for (i = 0; i < (sizeof fields / sizeof fields[0]); ++i) {
-       if (strcasecmp(field, fields[i]) == 0)
-           return i;
-    }
-    for (i = 0; i < extra->count; i++) {
-       if (strcasecmp(field, extra->strings[i]) == 0)
-           return i + (sizeof fields / sizeof fields[0]);
-    }
-    return -1;
-}
-
-
-/*
-**  Given an overview header line, split out a vector pointing at each
-**  of the components (within line), returning a pointer to the
-**  vector. If the vector initially passed in is NULL a new vector is
-**  created, else the existing one is filled in.
-**
-**  A member `n' of the vector is of length (vector->strings[n+1] -
-**  vector->strings[n] - 1). Note that the last member of the vector
-**  will always point beyond (line + length).
-*/
-struct cvector *
-overview_split(const char *line, size_t length, ARTNUM *number,
-              struct cvector *vector)
-{
-    const char *p = NULL;
-
-    if (vector == NULL) {
-       vector = cvector_new();
-    } else {
-       cvector_clear(vector);
-    }
-    while (line != NULL) {
-       /* the first field is the article number */
-       if (p == NULL) {
-           if (number != NULL) {
-               *number = atoi(line);
-           }
-       } else {
-           cvector_add(vector, line);
-       }
-       p = memchr(line, '\t', length);
-       if (p != NULL) {
-           /* skip over the tab */
-           ++p;
-           /* and calculate the remaining length */
-           length -= (p - line);
-       } else {
-           /* add in a pointer to beyond the end of the final
-            * component, so you can always calculate the length.
-            * overview lines are always terminated with \r\n, so the
-            * -1 ends up chopping those off */
-           cvector_add(vector, line + length - 1);
-       }
-       line = p;
-    }
-    return vector;
-}
-
-/*
-**  Given an overview vector (from overview_split), return a copy of
-**  the member which the caller is interested in (and must free).
-*/
-char *
-overview_getheader(const struct cvector *vector, int element,
-                  const struct vector *extra)
-{
-    char *field = NULL;
-    size_t len;
-    const char *p;
-
-    if ((element + 1) >= vector->count ||
-       (element >= ARRAY_SIZE(fields) &&
-        (element - ARRAY_SIZE(fields)) >= extra->count)) {
-       warn("request for invalid overview field %d", element);
-       return NULL;
-    }
-    /* Note... this routine does not synthesise Newsgroups: on behalf
-     * of the caller... */
-    if (element >= ARRAY_SIZE(fields)) {
-       /* +2 for `: ' */
-       p = vector->strings[element] +
-           strlen(extra->strings[element - ARRAY_SIZE(fields)]) + 2;
-       len = vector->strings[element + 1] - p - 1;
-    } else {
-       p = vector->strings[element];
-       len = vector->strings[element + 1] - vector->strings[element] - 1;
-    }
-    field = xstrndup(p, len);
-    return field;
-}
diff --git a/storage/ovinterface.h b/storage/ovinterface.h
deleted file mode 100644 (file)
index 896ea7b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*  $Id: ovinterface.h 6113 2003-01-04 16:29:56Z kondou $
-**
-**  Overview interface header
-*/
-
-#ifndef __OVINTERFACE_H__
-#define __OVINTERFACE_H__
-
-#include "config.h"
-#include "ov.h"
-#include "storage.h"
-#include "inn/history.h"
-
-struct buffer;
-struct vector;
-
-typedef struct {
-    const char *name;
-    bool       (*open)(int mode);
-    bool       (*groupstats)(char *group, int *lo, int *hi, int *count, int *flag);
-    bool       (*groupadd)(char *group, ARTNUM lo, ARTNUM hi, char *flag);
-    bool       (*groupdel)(char *group);
-    bool       (*add)(char *group, ARTNUM artnum, TOKEN token, char *data, int len, time_t arrived, time_t expires);
-    bool       (*cancel)(TOKEN token);
-    void       *(*opensearch)(char *group, int low, int high);
-    bool       (*search)(void *handle, ARTNUM *artnum, char **data, int *len, TOKEN *token, time_t *arrived);
-    void       (*closesearch)(void *handle);
-    bool       (*getartinfo)(char *group, ARTNUM artnum, TOKEN *token);
-    bool       (*expiregroup)(char *group, int *lo, struct history *h);
-    bool       (*ctl)(OVCTLTYPE type, void *val);
-    void       (*close)(void);
-} OV_METHOD;
-
-extern time_t  OVrealnow;
-bool OVgroupbasedexpire(TOKEN token, const char *group, const char *data,
-                        int len, time_t arrived, time_t expires);
-bool OVgroupmatch(const char *group);
-bool OVhisthasmsgid(struct history *, const char *data);
-void OVEXPremove(TOKEN token, bool deletedgroups, char **xref, int ngroups);
-void OVEXPcleanup(void);
-bool OVstatall;
-time_t OVnow;
-char *ACTIVE;
-FILE *EXPunlinkfile;
-bool OVignoreselfexpire;
-bool OVusepost;
-bool OVkeep;
-bool OVearliest;
-bool OVquiet;
-int  OVnumpatterns;
-char **OVpatterns;
-time_t OVrealnow;
-
-#define DEFAULT_MAX_XREF_LEN 8192
-
-#endif /* __OVINTERFACE_H__ */
diff --git a/storage/timecaf/README.CAF b/storage/timecaf/README.CAF
deleted file mode 100644 (file)
index 8ac0b64..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-The timecaf storage manager is like the timehash storage manager, except that
-it stores multiple articles in one file.  The file format is called CAF
-(for "crunched article file", putting multiple articles together into one big
-file), and uses a library 'caf.c' dating back from the pre-storage manager 
-days when I made a locally-hacked version of INN1.5 that used this
-code in order to boost performance on my system.  Originally I had planned to
-do one big file per newsgroup, but it turns out that a time-based file layout
-rather than newsgroup-name-based is a. more efficient and b. much easier to
-fit into the current storage manager interface paradigm.  Anyway, the 
-pathnames for the files are of the form
-       <patharticles>/timecaf-nn/bb/aacc.CF
-where 'nn' is the numeric storage class (same as in 'timehash') and the
-file contains all articles written during the interval from 
-(time_t) 0xaabbcc00 to 0xaabbccFF.  
-
-  The way expiration works on the 'timecaf' storage manager is a bit
-complicated.  When articles are expired or cancelled (via SMcancel())
-they are at first just marked as expired in the .CF file -- no actual
-disk space is freed at first.  But if fastrm/SMcancel() notices that a
-certain amount of space has been marked as free, then it will do a
-sort of garbage collection pass on the file, writing out a new file
-containing only the articles from the old file that have not yet
-expired and removing the old file.  If fastrm notices that *all* the
-articles in a file have been expired, it just deletes the file and
-doesn't create a new one.  This means that if your setup has
-newsgroups with differing expiration lengths put in the same timecaf
-storage class, everything will work ok but your expire runs will spend
-some extra time copying files about.  In my experience this hasn't been too
-much of a problem.  If you find that it is a problem, you may wish to 
-consider dividing up your spool layout so each storage class gets newsgroups
-that expire at more-or-less the same time, or putting *.binaries in their own
-storage class.
-
-Some advantages and disadvantages compared to the 'timehash' and
-'CNFS' storage methods:
-
-  timecaf is somewhat faster than timehash in writing articles (the tests
-I did on the old news.ecn.uoknor.edu showed a roughly 4x improvement in
-artwrite speed).  This is presumably due to improved locality of reference and
-not having to open/close article files all the time but only every 4 minutes or
-so.  Artcancel speed, on the other hand, is not much different, because
-cancel requests have terrible locality of reference.   Expire times seem
-to be generally somewhat faster than timehash as well, even given the 
-extra copying overhead mentioned above.
-
-  Timecaf is probably slower than CNFS, but I haven't had a chance
-to do any comparison tests.  Timecaf does share the feature with timehash
-that you can get much more fine-tuned control of your expire times (on a 
-group-by-group basis, if needed) than you can with CNFS.  
-
-Down below is an old README telling more about the implementation details
-of the CAF file format.  Most people won't care about this, but if you're
-curious, read on; it also tells some of the historical developments that
-went on in this code.  I've been running some version of this code off and
-on for the past two years, and have been running it as a storage manager
-module for the past few months, so I'm pretty sure of it's stability.
-
-                       Richard Todd
-       (rmtodd@mailhost.ecn.ou.edu/rmtodd@servalan.servalan.com)
-
-\f
-Implementation details (format of a CAF file) and some design rationale:
-
- Look at include/caf.h for the details, but basically, the layout is
-something like this.  Each CAF file has a blocksize associated with it
-(usually 512 bytes, but it can vary).  The layout of a CAF file is as
-follows:
-  1.   Header (~52 bytes) containing information like low and high
-article numbers, amount of free space, blocksize.  
-  2.   Free space bitmap (size given by the FreeZoneTabSize field of the
-header).
-  3.   CAFTOCENTs (CAF Table of Contents Entries), 1/article storable
-in the file.  Each CAFTOCENT gives the article's size, creation time,
-and offset in the CAF file.  Usually space is alloted in the CAF file
-for 64K CAFTOCENTs, even if the # of articles in the CAF file is
-nowhere near that amount.  The unused CAFTOCENTs are all zeros, and
-this means CAF files are almost always sparse.
-  4.   Articles, always stored starting at blocksize boundaries. 
-
-When fastrm is told to remove an article, the article is not actually
-removed as such, it is merely marked as non-existent (the CAFTOCENT is
-zeroed), and the blocks taken up by the article are marked as 'free'
-in the free space bitmap.  When innd writes an article to a CAF file,
-it first looks to see if the CAF file has any free blocks in a
-contiguous chunk large enough to handle the article, and if so writes
-the article into those blocks and marks those blocks as being in use.
-If there is no suitable free space chunk in the CAF file, then innd
-merely appends the article to the end of the CAF file and records the
-article's position in the TOC. [Given the way the CAF code is currently
-used by the timecaf storage manager, it's almost always the case that we're
-appending to the end of the file.] 
-
-   A note on the free bitmap portion of the CAF file: it's not just a simple
-bitmap (each bit of the bitmap tells whether a data block is in use or free.)
-First there is an 'index' bitmap which tells which blocks of the 'main' bitmap
-have free blocks listed in them, and then a 'main' bitmap which tells whether
-the data blocks are in use or free.  This setup means that we can have 
-bitmaps for CAF files as large as 8GB, while still being able to find free
-space by only reading the 'index' bitmap and one block of the 'main' bitmap.
-(Previous versions of the CAF code had just a 'main' bitmap and scaled the 
-blocksize up when CAF files got large; this became rather, um, non-optimal
-when control.cancel started to hit hundreds of thousands of articles and 8K
-blocksizes.)  In practice, CAF files over 2GB or 4GB may be a problem because
-of unsigned/signed long problems, and ones over 4G are probably impossible 
-on anything besides an Alpha unless you track down all the places in innd
-where they assume off_t is a long and fix it to work with long longs.  
-
-  At some point I'd also like to try some other, more efficient
-directory layout for the CAF files, as opposed to the old 
-/var/spool/news/newsgroup/name/component/ scheme.  At the time I
-started implementing this, it seemed like it'd be too much of a hassle
-to change this in INN as it stands.  I'm hoping that changing this
-assumption (that newsgroup a.b.c is always in directory a/b/c) will be
-easier once INN acquires a nice interface for specifying alternate
-storage managers.  [It is and it isn't; as I said, we've currently abandoned
-all relationship between newsgroup names and CAF file names, which
-provided a sizable jump in performance.  Before that, I had changed the code
-so that the CAF file for, e.g.,
-alt.tv.babylon-5 will now be /var/spool/news/alt/tv/babylon-5.CF -- note the
-final . instead of a /.  This pretty much bypasses the need for the 'terminal'
-layer of directories to be read, and means that these directory blocks will not
-be fighting with other blocks for the limited space available in the buffer 
-cache.   This provides more of an improvement than you might think; thruput on 
-news.ecn.uoknor.edu went from 160,000 articles/day to >200,000 articles/day
-with this patch, and this is on an aging 32M 486/66.]
diff --git a/storage/timecaf/caf.c b/storage/timecaf/caf.c
deleted file mode 100644 (file)
index 450b561..0000000
+++ /dev/null
@@ -1,1823 +0,0 @@
-/*  $Id: caf.c 6723 2004-05-16 21:12:53Z rra $
-**
-**  Library routines needed for handling CAF (Crunched Article Files)
-**  Written by Richard Todd (rmtodd@mailhost.ecn.uoknor.edu) 3/24/96,
-**  modified extensively since then.  Altered to work with storage manager
-**  in INN1.8 by rmtodd 3/27/98.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "libinn.h"
-
-#define CAF_INNARDS
-#include "caf.h"
-
-/* following code lifted from inndf.c */
-
-#ifdef HAVE_STATVFS
-#include <sys/statvfs.h>               /* specific includes */
-/* XXX is there a 'fstatvfs'? I don't have such a system to check--rmtodd*/
-#define STATFUNCT      fstatvfs                /* function call */
-#define STATSTRUC      statvfs         /* structure name */
-#define STATAVAIL      f_bavail        /* blocks available */
-#define STATMULTI      f_frsize        /* fragment size/block size */
-#define STATINODE      f_favail        /* inodes available */
-#define STATTYPES      u_long          /* type of f_bavail etc */
-#define STATFORMT      "%lu"           /* format string to match */
-#define STATFORMTPAD   "%*lu"          /* format string to match */
-#endif /* HAVE_STATVFS */
-
-#ifdef HAVE_STATFS
-#ifdef HAVE_SYS_VFS_H
-#include <sys/vfs.h>
-#endif /* HAVE_SYS_VFS_H */
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif /* HAVE_SYS_PARAM_H */
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif /* HAVE_SYS_MOUNT_H */
-#define STATFUNCT      fstatfs
-#define STATSTRUC      statfs
-#define STATAVAIL      f_bavail
-#define STATMULTI      f_bsize
-#define STATINODE      f_ffree;
-#define STATTYPES      long
-#define STATFORMT      "%ld"
-#define STATFORMTPAD   "%*ld"
-#endif /* HAVE_STATFS */
-
-int CAFClean(char *path, int verbose, double PercentFreeThreshold);
-
-int caf_error = 0;
-int caf_errno = 0;
-
-/* check assertions in code (lifted from lib/malloc.c) */
-#define        ASSERT(p)   do { if (!(p)) botch(__FILE__, __LINE__, #p); } while (0)
-
-static void
-botch(const char *f, int l, const char *s)
-{
-
-       fprintf(stderr, "assertion botched: %s:%d:%s\n", f,l,s);
-       fflush(stderr); /* if stderr writing to file--needed? */
-       abort();
-}
-
-
-/* set error code appropriately. */
-static void
-CAFError(int code)
-{
-    caf_error = code;
-    if (caf_error == CAF_ERR_IO) {
-       caf_errno = errno;
-    }
-}
-
-/*
-** Wrapper around read that calls CAFError if needed. 0 for success, -1 for  failure.
-*/
-
-static int
-OurRead(int fd, void *buf, size_t n)
-{
-    ssize_t rval;
-
-    rval = read(fd, buf, n);
-    if (rval < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    if ((size_t) rval < n) {
-       /* not enough data! */
-       CAFError(CAF_ERR_BADFILE);
-       return -1;
-    }
-    return 0;
-}
-
-/* Same as OurRead except for writes. */
-static int
-OurWrite(int fd, const void *buf, size_t n)
-{
-    ssize_t rval;
-
-    rval = write(fd, buf, n);
-    if (rval < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    if ((size_t) rval < n) {
-       /* not enough data written */
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    return 0;
-}
-
-/*
-** Given an fd, read in a CAF_HEADER from a file. Ret. 0 on success.
-*/
-
-int
-CAFReadHeader(int fd, CAFHEADER *h)
-{
-    /* probably already at start anyway, but paranoia is good. */
-    if (lseek(fd, 0L, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    if (OurRead(fd, h, sizeof(CAFHEADER)) < 0) return -1;
-
-    if (strncmp(h->Magic, CAF_MAGIC, CAF_MAGIC_LEN) != 0) {
-       CAFError(CAF_ERR_BADFILE);
-       return -1;
-    }
-    return 0;
-}
-
-/* 
-** Seek to the TOC entry for a given article.  As usual, -1 for error, 0 succ.
-*/
-
-static int
-CAFSeekTOCEnt(int fd, CAFHEADER *head, ARTNUM art)
-{
-    off_t offset;
-
-    offset = sizeof(CAFHEADER) + head->FreeZoneTabSize;
-    offset += (art - head->Low) * sizeof(CAFTOCENT);
-    if (lseek(fd, offset, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    return 0;
-}
-
-/*
-** Fetch the TOC entry for a  given article.  As usual -1 for error, 0 success */
-
-static int
-CAFGetTOCEnt(int fd, CAFHEADER *head, ARTNUM art, CAFTOCENT *tocp)
-{
-    if (CAFSeekTOCEnt(fd, head, art) < 0) {
-       return -1;
-    }
-
-    if (OurRead(fd, tocp, sizeof(CAFTOCENT)) < 0) return -1;
-
-    return 0;
-}
-
-/*
-** Round an offset up to the next highest block boundary. Needs the CAFHEADER
-** to find out what the blocksize is.
-*/
-off_t
-CAFRoundOffsetUp(off_t off, unsigned int blocksize)
-{
-    off_t off2;
-
-    /* Zero means default blocksize, though we shouldn't need this for long,
-       as all new CAF files will have BlockSize set. */
-    if (blocksize == 0) {
-       blocksize = CAF_DEFAULT_BLOCKSIZE;
-    }
-
-    off2 = ((off + blocksize - 1) / blocksize) * blocksize;
-    return off2;
-}
-
-/*
-** Dispose of an already-allocated CAFBITMAP.
-*/
-void
-CAFDisposeBitmap(CAFBITMAP *bm)
-{
-    unsigned int i;
-    CAFBMB *bmb;
-
-    for (i = 0 ; i < bm->NumBMB ; ++i) {
-       if (bm->Blocks[i]) {
-           bmb = bm->Blocks[i];
-           if (bmb->BMBBits) free(bmb->BMBBits);
-           free(bmb);
-       }
-    }
-    free(bm->Blocks);
-    free(bm->Bits);
-    free(bm);
-}
-
-/*
-** Read the index bitmap from a CAF file, return a CAFBITMAP structure.
-*/
-
-/* define this instead of littering all our formulas with semi-mysterious 8s. */
-#define BYTEWIDTH 8
-
-CAFBITMAP *
-CAFReadFreeBM(int fd, CAFHEADER *h)
-{
-    size_t i;
-    struct stat statbuf;
-    CAFBITMAP *bm;
-
-    if (lseek(fd, sizeof(CAFHEADER), SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return NULL;
-    }
-    bm = xmalloc(sizeof(CAFBITMAP));
-
-    bm->FreeZoneTabSize = h->FreeZoneTabSize;
-    bm->FreeZoneIndexSize = h->FreeZoneIndexSize;
-    bm->NumBMB = BYTEWIDTH * bm->FreeZoneIndexSize;
-    bm->BytesPerBMB = (h->BlockSize) * (h->BlockSize * BYTEWIDTH);
-    bm->BlockSize = h->BlockSize;
-    
-    bm->Blocks = xmalloc(bm->NumBMB * sizeof(CAFBMB *));
-    bm->Bits = xmalloc(bm->FreeZoneIndexSize);
-    for (i = 0 ; i < bm->NumBMB ; ++i) {
-       bm->Blocks[i] = NULL;
-    }
-       
-    if (OurRead(fd, bm->Bits, bm->FreeZoneIndexSize) < 0) {
-       CAFDisposeBitmap(bm);
-       return NULL;
-    }
-
-    bm->StartDataBlock = h->StartDataBlock;
-
-    if (fstat(fd, &statbuf) < 0) {
-       /* it'd odd for this to fail, but paranoia is good for the soul. */
-       CAFError(CAF_ERR_IO);
-       CAFDisposeBitmap(bm);
-       return NULL;
-    }
-    /* round st_size down to a mult. of BlockSize */
-    bm->MaxDataBlock = (statbuf.st_size / bm->BlockSize) * bm->BlockSize + bm->BlockSize;
-    /* (note: MaxDataBlock points to the block *after* the last block of the file. */
-    return bm;
-}
-
-/*
-** Fetch a given bitmap block into memory, and make the CAFBITMAP point to
-** the new BMB appropriately.  Return NULL on failure, and the BMB * on success.
-*/
-static CAFBMB *
-CAFFetchBMB(unsigned int blkno, int fd, CAFBITMAP *bm)
-{
-    CAFBMB *newbmb;
-
-    ASSERT(blkno < bm->NumBMB);
-    /* if already in memory, don't need to do anything. */
-    if (bm->Blocks[blkno]) return bm->Blocks[blkno];
-
-    newbmb = xmalloc(sizeof(CAFBMB));
-
-    newbmb->Dirty = 0;
-    newbmb->StartDataBlock = bm->StartDataBlock + blkno*(bm->BytesPerBMB);
-
-    newbmb->MaxDataBlock = newbmb->StartDataBlock + bm->BytesPerBMB;
-    if (newbmb->MaxDataBlock > bm->MaxDataBlock) {
-       /* limit the per-BMB MaxDataBlock to that for the bitmap as a whole */
-       newbmb->MaxDataBlock = bm->MaxDataBlock;
-    }
-
-    newbmb->BMBBits = xmalloc(bm->BlockSize);
-
-    if (lseek(fd, (blkno + 1) * bm->BlockSize, SEEK_SET) < 0) {
-       free(newbmb->BMBBits);
-       free(newbmb);
-       CAFError(CAF_ERR_IO);
-       return NULL;
-    }
-
-    if (OurRead(fd, newbmb->BMBBits, bm->BlockSize) < 0) {
-       free(newbmb->BMBBits);
-        free(newbmb);
-       return NULL;
-    }
-
-    bm->Blocks[blkno] = newbmb;
-    return newbmb;
-}
-
-/*
-** Flush out (if needed) a BMB to disk.  Return 0 on success, -1 on failure.
-*/
-
-static int
-CAFFlushBMB(unsigned int blkno, int fd, CAFBITMAP *bm)
-{
-    CAFBMB *bmb;
-
-    ASSERT(blkno < bm->NumBMB);
-
-    if (bm->Blocks[blkno] == NULL) return 0; /* nothing to do. */
-
-    bmb = bm->Blocks[blkno];
-    if (!bmb->Dirty) return 0;
-
-    if (lseek(fd, (blkno + 1) * bm->BlockSize, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    if (OurWrite(fd, bmb->BMBBits, bm->BlockSize) < 0) return -1;
-
-    bmb->Dirty = 0; 
-    return 0;
-}
-
-
-/*
-** Write the free bit map to the CAF file.  Return 0 on success, -1 on failure.
-*/
-static int
-CAFWriteFreeBM(int fd, CAFBITMAP *bm)
-{
-    size_t blkno;
-    
-    for (blkno = 0 ; blkno < bm->NumBMB ; ++blkno) {
-       if (CAFFlushBMB(blkno, fd, bm) < 0) {
-           return -1;
-       }
-    }
-
-    if (lseek(fd, sizeof(CAFHEADER), SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    if(OurWrite(fd, bm->Bits, bm->FreeZoneIndexSize) < 0) return -1;
-
-    return 0;
-}
-
-/* 
-** Determine if a block at a given offset is free.  Return 1 if it is, 0 
-** otherwise.
-*/
-
-int
-CAFIsBlockFree(CAFBITMAP *bm, int fd, off_t block)
-{
-    unsigned int ind;
-    char mask;
-    int blkno;
-    CAFBMB *bmb;
-
-    /* round block down to BlockSize boundary. */
-    block = block - (block % bm->BlockSize);
-
-    /* if < Start, always return 0 (should never happen in real usage) */
-    if (block < bm->StartDataBlock) return 0;
-    
-    /* if off the end, also return 0. */
-    if (block >= bm->MaxDataBlock) return 0;
-
-    /* find blk # of appropriate BMB */
-    blkno = (block - bm->StartDataBlock) / bm->BytesPerBMB;
-
-    bmb = CAFFetchBMB(blkno, fd, bm);
-    /* ick. not a lot we can do here if this fails. */ 
-    if (bmb == NULL) return 0;
-
-    /* Sanity checking that we have the right BMB. */
-    ASSERT(block >= bmb->StartDataBlock);
-    ASSERT(block < bmb->MaxDataBlock);
-
-    ind = ((block - bmb->StartDataBlock) / bm->BlockSize) / BYTEWIDTH;
-    mask =  1 << (((block - bmb->StartDataBlock) / bm->BlockSize) % BYTEWIDTH);
-
-    ASSERT(ind < bm->BlockSize);
-    
-    return ((bmb->BMBBits[ind]) & mask) != 0;
-}
-
-/*
-** Check if a bitmap chunk is all zeros or not.
-*/
-static int
-IsMapAllZero(char *data, int len)
-{
-    int i;
-    for (i = 0 ; i < len ; ++i) {
-       if (data[i] != 0) return 0;
-    }
-    return 1;
-}
-
-/* Set the free bitmap entry for a given block to be a given value (1 or 0). */
-static void
-CAFSetBlockFree(CAFBITMAP *bm, int fd, off_t block, int isfree)
-{
-    unsigned int ind;
-    char mask;
-    int blkno;
-    CAFBMB *bmb;
-    int allzeros;
-
-    /* round block down to BlockSize boundary. */
-    block = block - (block % bm->BlockSize);
-
-    /* if < Start, always return (should never happen in real usage) */
-    if (block < bm->StartDataBlock) return;
-    
-    /* if off the end, also return. */
-    if (block >= bm->MaxDataBlock) return;
-    /* find blk # of appropriate BMB */
-    blkno = (block - bm->StartDataBlock) / bm->BytesPerBMB;
-
-    bmb = CAFFetchBMB(blkno, fd, bm);
-    /* ick. not a lot we can do here if this fails. */ 
-    if (bmb == NULL) return;
-
-    /* Sanity checking that we have the right BMB. */
-    ASSERT(block >= bmb->StartDataBlock);
-    ASSERT(block < bmb->MaxDataBlock);
-
-    ind = ((block - bmb->StartDataBlock) / bm->BlockSize) / BYTEWIDTH;
-    mask =  1 << (((block - bmb->StartDataBlock) / bm->BlockSize) % BYTEWIDTH);
-
-    ASSERT(ind < bm->BlockSize);
-
-    if (isfree) {
-       bmb->BMBBits[ind] |= mask; /* set bit */
-    } else {
-       bmb->BMBBits[ind] &= ~mask; /* clear bit. */
-    }
-
-    bmb->Dirty = 1;
-
-    /* now have to set top level (index) bitmap appropriately */
-    allzeros = IsMapAllZero(bmb->BMBBits, bm->BlockSize);
-
-    ind = blkno/BYTEWIDTH;
-    mask = 1 << (blkno % BYTEWIDTH);
-
-    if (allzeros) {
-       bm->Bits[ind] &= ~mask; /* clear bit */
-    } else {
-       bm->Bits[ind] |= mask;
-    }
-
-    return;
-}
-
-/* 
-** Search a freebitmap to find n contiguous free blocks.  Returns 0 for
-** failure, offset of starting block if successful.
-** XXX does not attempt to find chunks that span BMB boundaries.  This is 
-** messy to fix.
-** (Actually I think this case  works, as does the case when it tries to find
-** a block bigger than BytesPerBMB.  Testing reveals that it does seem to work, 
-** though not optimally (some BMBs will get scanned several times).  
-*/
-static off_t
-CAFFindFreeBlocks(CAFBITMAP *bm, int fd, unsigned int n)
-{
-    off_t startblk, curblk;
-    unsigned int i, ind, blkno, j;
-    unsigned int bmblkno, k, l;
-    CAFBMB *bmb;
-
-    /* Iterate over all bytes and all bits in the toplevel bitmap. */
-    for (k = 0 ; k < bm->FreeZoneIndexSize ; ++k) {
-       if (bm->Bits[k] == 0) continue;
-       for (l = 0; l < BYTEWIDTH ; ++l) {
-           if ((bm->Bits[k] & (1 << l)) != 0) {
-               /* found a bit set! fetch the BMB. */
-               bmblkno = k*BYTEWIDTH + l;
-               bmb = CAFFetchBMB(bmblkno, fd, bm);
-               if (bmb == NULL) return 0;
-
-               curblk = bmb->StartDataBlock;
-               while (curblk < bmb->MaxDataBlock) {
-                   blkno = (curblk - bmb->StartDataBlock)/(bm->BlockSize);
-                   ind = blkno/BYTEWIDTH;
-                   if (bmb->BMBBits[ind] == 0) { 
-                       /* nothing set in this byte, skip this byte and move on. */
-                       blkno = (ind+1)*BYTEWIDTH;
-                       curblk = blkno*bm->BlockSize + bmb->StartDataBlock;
-                       continue;
-                   }
-
-                   /* scan rest of current byte for 1 bits */
-                   for (j = blkno % BYTEWIDTH ; j < BYTEWIDTH ; j++, curblk += bm->BlockSize) {
-                       if ((bmb->BMBBits[ind] & (1 << j)) != 0) break; 
-                   }
-                   if (j == BYTEWIDTH) continue;
-
-                   /* found a 1 bit, set startblk to be locn of corresponding free blk. */
-                   startblk = curblk;
-                   curblk += bm->BlockSize;
-
-                   /* scan for n blocks in a row. */
-                   for (i = 1 ; i < n ; ++i, curblk += bm->BlockSize) {
-                       if (!CAFIsBlockFree(bm, fd, curblk)) break; 
-                   }
-
-                   if (i == n) return startblk;
-
-                   /* otherwise curblk points to a non-free blk, continue searching from there. */
-                   continue;
-               }
-           }
-       }
-    }
-    return 0;
-}
-
-/*
-** Open a CAF file for reading and seek to the start of a given article.
-** Take as args the CAF file pathname, article #, and a pointer to where
-** the art. length can be returned.
-*/
-
-int
-CAFOpenArtRead(const char *path, ARTNUM art, size_t *len)
-{
-    CAFHEADER head;
-    int fd;
-    CAFTOCENT tocent;
-    struct stat st;
-
-    if ( (fd = open(path, O_RDONLY)) < 0) {
-       /* 
-       ** if ENOENT (not there), just call this "article not found",
-       ** otherwise it's a more serious error and stash the errno.
-       */
-       if (errno == ENOENT) {
-           CAFError(CAF_ERR_ARTNOTHERE);
-       } else {
-           CAFError(CAF_ERR_IO);
-       }
-       return -1;
-    }
-
-    /* Fetch the header */
-    if (CAFReadHeader(fd, &head) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    /* Is the requested article even in the file? */
-    if (art < head.Low || art > head.High) {
-       CAFError(CAF_ERR_ARTNOTHERE);
-       close(fd);
-       return -1;
-    }
-
-    if (CAFGetTOCEnt(fd, &head, art, &tocent) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    if (tocent.Size == 0) {
-       /* empty/otherwise not present article */
-       CAFError(CAF_ERR_ARTNOTHERE);
-       close(fd);
-       return -1;
-    }
-
-    if (lseek(fd, tocent.Offset, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       close(fd);
-       return -1;
-    }
-
-    /* I'm not sure if this fstat is worth the speed hit, but unless we check
-       here, we may simply segfault when we try to access mmap'd space beyond
-       the end of the file.  I think robustness wins. */
-    if (fstat(fd, &st) == 0)
-        if (tocent.Size > st.st_size - tocent.Offset) {
-            CAFError(CAF_ERR_IO);
-            close(fd);
-            return -1;
-        }
-
-    *len = tocent.Size;
-    return fd;
-}
-
-/*
-** variables for keeping track of currently pending write.
-** FIXME: assumes only one article open for writing at a time.  
-*/
-
-static int CAF_fd_write;
-static ARTNUM CAF_artnum_write;
-static off_t CAF_startoffset_write;
-static CAFHEADER CAF_header_write;
-static CAFBITMAP *CAF_free_bitmap_write;
-static unsigned int CAF_numblks_write;
-
-/* 
-** Given estimated size of CAF file (i.e., the size of the old CAF file found
-** by cafclean), find an "optimal" blocksize (one big enough so that the 
-** default FreeZoneTabSize can cover the entire
-** file so that we don't "lose" free space and not be able to reuse it.
-** (Currently only returns CAF_DEFAULT_BLOCKSIZE, as with the new 2-level
-** bitmaps, the FreeZoneTabSize that results from a 512-byte blocksize can 
-** handle any newsgroup with <7.3G of data.  Yow!)
-*/
-
-static unsigned int
-CAFFindOptimalBlocksize(ARTNUM tocsize UNUSED, size_t cfsize)
-{
-
-    if (cfsize == 0) return CAF_DEFAULT_BLOCKSIZE; /* no size given, use default. */
-
-    return CAF_DEFAULT_BLOCKSIZE;
-}
-
-/* 
-** Create an empty CAF file.  Used by CAFOpenArtWrite.
-** Must be careful here and create the new CAF file under a temp name and then
-** link it into place, to avoid possible race conditions.
-** Note: CAFCreateCAFFile returns fd locked, also to avoid race conds.
-** New args added for benefit of the cleaner program: "nolink", a flag that
-** tells it not to bother with the link business, and "temppath", a pointer
-** to a buffer that (if non-null) gets the pathname of the temp file copied
-** to it. "estcfsize", if nonzero, is an estimate of what the CF filesize will
-** be, used to automatically select a good blocksize.
-*/
-int
-CAFCreateCAFFile(char *cfpath, ARTNUM artnum, ARTNUM tocsize,
-                 size_t estcfsize, int nolink, char *temppath)
-{
-    CAFHEADER head;
-    int fd;
-    char path[SPOOLNAMEBUFF];
-    char finalpath[SPOOLNAMEBUFF];
-    off_t offset;
-    char nulls[1];
-
-    strlcpy(finalpath, cfpath, sizeof(finalpath));
-    snprintf(path, sizeof(path), "%s.%d", cfpath, getpid());/* create path with PID attached */
-    /* 
-    ** Shouldn't be anyone else with our pid trying to write to the temp.
-    ** file, but there might be an old one lying around.  Nuke it.
-    ** (yeah, I'm probably being overly paranoid.)
-    */
-    if (unlink(path) < 0 && errno != ENOENT) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    if ((fd = open(path, O_CREAT|O_EXCL|O_RDWR, 0666)) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    /* Initialize the header. */
-    strncpy(head.Magic, CAF_MAGIC, CAF_MAGIC_LEN);
-    head.Low = artnum;
-    head.High = artnum;
-    head.NumSlots = tocsize;
-    head.Free = 0;
-    head.BlockSize = CAFFindOptimalBlocksize(tocsize, estcfsize);
-    head.FreeZoneIndexSize = head.BlockSize - sizeof(CAFHEADER);
-    head.FreeZoneTabSize = head.FreeZoneIndexSize 
-       + head.BlockSize*head.FreeZoneIndexSize*BYTEWIDTH;
-    head.StartDataBlock = CAFRoundOffsetUp(sizeof(CAFHEADER)
-                                          + head.FreeZoneTabSize + tocsize*sizeof(CAFTOCENT), head.BlockSize);
-
-    head.spare[0] = head.spare[1] = head.spare[2] = 0;
-    
-    if (OurWrite(fd, &head, sizeof(head)) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    offset = sizeof(CAFHEADER) + head.FreeZoneTabSize +
-       sizeof(CAFTOCENT) * tocsize;
-
-    if (lseek(fd, offset, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    /* 
-    ** put a null after the TOC as a 'placeholder', so that we'll have a sparse
-    ** file and that EOF will be at where the articles should start going.
-    */
-    nulls[0] = 0;
-    if (OurWrite(fd, nulls, 1) < 0) {
-       close(fd);
-       return -1;
-    }
-    /* shouldn't be anyone else locking our file, since temp file has unique
-       PID-based name ... */
-    if (!inn_lock_file(fd, INN_LOCK_WRITE, false)) {
-       CAFError(CAF_ERR_IO);
-       close(fd);
-       return -1;
-    }  
-
-    if (nolink) {
-       if (temppath != NULL) {
-           strcpy(temppath, path);
-       }
-       return fd;
-    }
-
-    /*
-    ** Try to link to the real one. NOTE: we may get EEXIST here, which we
-    ** will handle specially in OpenArtWrite.
-    */
-    if (link(path, finalpath) < 0) {
-       CAFError(CAF_ERR_IO);
-       /* bounced on the link attempt, go ahead and unlink the temp file and return. */
-       unlink(path);
-       close(fd);
-       return -1;
-    }
-    /*
-    ** Unlink the temp. link. Do we really care if this fails? XXX
-    ** Not sure what we can do anyway.
-    */
-    unlink(path);
-    return fd;
-}
-
-/*
-** Try to open a CAF file for writing a given article.  Return an fd to 
-** write to (already positioned to the right place to write at) if successful,
-** else -1 on error.  if LockFlag is true, we wait for a lock on the file,
-** otherwise we fail if we can't lock it.  If size is != 0, we try to allocate
-** a chunk from free space in the CAF instead of writing at the end of the
-** file.  Artp is a pointer to the article number to use; if the article number
-** is zero, the next free article # ("High"+1) will be used, and *artp will
-** be set accordingly.   Once the CAF file is open/created, CAFStartWriteFd()
-** does the remaining dirty work.
-*/
-
-int
-CAFOpenArtWrite(char *path, ARTNUM *artp, int waitlock, size_t size)
-{
-    int fd;
-
-    while (true) {
-       /* try to open the file and lock it. */
-       if ((fd = open(path, O_RDWR)) < 0) {
-           /* if ENOENT, try creating CAF file, otherwise punt. */
-           if (errno != ENOENT) {
-               CAFError(CAF_ERR_IO);
-               return -1;
-           } else {
-               /* 
-               ** the *artp? business is so that if *artp==0, we set initial
-               ** article # to 1.
-               */
-               fd = CAFCreateCAFFile(path, (*artp ? *artp : 1),
-                                      CAF_DEFAULT_TOC_SIZE, 0, 0, NULL);
-               /*
-               ** XXX possible race condition here, so we check to see if
-               ** create failed because of EEXIST.  If so, we go back to top
-               ** of loop, because someone else was trying to create at the
-               ** same time. 
-               ** Is this the best way to solve this? 
-               ** (Hmm.  this condition should be quite rare, occuring only
-               ** when two different programs are simultaneously doing 
-               ** CAFOpenArtWrite()s, and no CF file exists previously.)
-               */
-               if (fd < 0) {
-                   if (caf_errno == EEXIST) {
-                       /* ignore the error and try again */
-                       continue; 
-                   }
-                   return -1; /* other error, assume caf_errno set properly. */
-               }
-               /* 
-               ** break here, because CreateCAFFile does 
-               ** lock fd, so we don't need to flock it ourselves.  
-               */
-               break;
-           }
-       }
-
-       /* try a nonblocking lock attempt first. */
-       if (inn_lock_file(fd, INN_LOCK_WRITE, false)) break;
-
-       if (!waitlock) {
-           CAFError(CAF_ERR_FILEBUSY);
-           close(fd); /* keep from leaking fds. */
-           return -1;
-       }
-       /* wait around to try and get a lock. */
-       inn_lock_file(fd, INN_LOCK_WRITE, true);
-       /*
-        ** and then close and reopen the file, in case someone changed the
-       ** file out from under us.
-       */ 
-       close(fd);
-    }
-    return CAFStartWriteFd(fd, artp, size);
-}
-
-/*
-** Like CAFOpenArtWrite(), except we assume the CAF file is already 
-** open/locked, and we have an open fd to it.
-*/
-int
-CAFStartWriteFd(int fd, ARTNUM *artp, size_t size)
-{
-    CAFHEADER head;
-    CAFTOCENT tocent;
-    off_t offset, startoffset;
-    unsigned int numblks = 0;
-    CAFBITMAP *freebm;
-    ARTNUM art;
-
-    /* fd is open to the CAF file, open for write and locked. */
-    /* Fetch the header */
-    if (CAFReadHeader(fd, &head) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    /* check for zero article number and  handle accordingly. */
-    art = *artp;
-    if (art == 0) {
-       /* assign next highest article number. */
-       art = head.High + 1;
-       /* and pass to caller. */
-       *artp = art;
-    }
-
-    /* Is the requested article even in the file? */
-    if (art < head.Low || art >= head.Low + head.NumSlots) {
-       CAFError(CAF_ERR_ARTWONTFIT);
-       close(fd);
-       return -1;
-    }
-
-    /*
-    ** Get the CAFTOCENT for that article, but only if article# is in the range
-    ** Low <= art# <= High.  If art# > High, use a zero CAFTOCENT.  This means
-    ** that in cases where the CAF file is inconsistent due to a crash ---
-    ** the CAFTOCENT shows an article as being existent, but the header 
-    ** doesn't show that article as being in the currently valid range ---
-    ** the header value "wins" and we assume the article does not exist.
-    ** This avoids problems with "half-existent" articles that showed up
-    ** in the CAF TOC, but were never picked up by ctlinnd renumber '' . 
-    */
-    /* (Note: We already checked above that art >= head.Low.) */
-
-    if (art > head.High) {
-       /* clear the tocent */
-       memset(&tocent, 0, sizeof(tocent));
-    } else {
-       if (CAFGetTOCEnt(fd, &head, art, &tocent) < 0) {
-           close(fd);
-           return -1;
-       }
-    }
-
-    if (tocent.Size != 0) {
-       /* article is already here */
-       CAFError(CAF_ERR_ARTALREADYHERE);
-       close(fd);
-       return -1;
-    }
-
-    startoffset = 0;
-    freebm = NULL;
-
-    if (size != 0 && (freebm = CAFReadFreeBM(fd, &head)) != NULL) {
-       numblks = (size + head.BlockSize - 1) / head.BlockSize;
-       startoffset = CAFFindFreeBlocks(freebm, fd, numblks);
-       if (startoffset == 0) {
-           CAFDisposeBitmap(freebm);
-           freebm = NULL;
-       }
-    }
-
-    if (startoffset == 0) {
-       /*
-       ** No size given or free space not available, so
-       ** seek to EOF to prepare to start writing article.
-       */
-
-       if ((offset = lseek(fd, 0, SEEK_END)) < 0) {
-           CAFError(CAF_ERR_IO);
-           close(fd);
-           return -1;
-       }
-       /* and round up offset to a block boundary. */
-       startoffset = CAFRoundOffsetUp(offset, head.BlockSize);
-    }
-
-    /* Seek to starting offset for the new artiicle. */
-    if (lseek(fd, startoffset, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       close(fd);
-       return -1;
-    }
-    
-    /* stash data for FinishArtWrite's use. */
-    CAF_fd_write = fd;
-    CAF_artnum_write = art;
-    CAF_startoffset_write = startoffset;
-    CAF_header_write = head;
-    CAF_free_bitmap_write = freebm;
-    CAF_numblks_write = numblks;
-
-    return fd;
-}
-
-/* 
-** write out TOC entries for the previous article.  Note that we do *not*
-** (as was previously done) close the fd; this allows reuse of the fd to write
-** another article to this CAF file w/o an (soemwhat expensive) open().
-*/
-
-int
-CAFFinishArtWrite(int fd)
-{
-    off_t curpos;
-    CAFTOCENT tocentry;
-    off_t curblk;
-    CAFHEADER *headp;
-    unsigned int i;
-
-    /* blah, really should handle multiple pending OpenArtWrites. */
-    if (fd != CAF_fd_write) {
-       fprintf(stderr, "CAF: fd mismatch in CloseArtWrite.\n");
-       abort();
-    }
-
-    headp = &CAF_header_write;
-
-    /* Find out where we left off writing in the file. */
-    if ((curpos = lseek(fd, 0, SEEK_CUR)) < 0) {
-       CAFError(CAF_ERR_IO);
-       CAF_fd_write = 0;
-       return -1;
-    }
-
-    /* Write the new TOC entry. */
-    if (CAFSeekTOCEnt(fd, headp, CAF_artnum_write) < 0) {
-       CAF_fd_write = 0;
-       return -1;
-    }
-    tocentry.Offset = CAF_startoffset_write;
-    tocentry.Size = curpos - CAF_startoffset_write;
-    tocentry.ModTime = time((time_t *)NULL);
-    if (OurWrite(fd, &tocentry, sizeof(CAFTOCENT)) < 0) {
-       CAF_fd_write = 0;
-       return -1;
-    }
-
-    /* if needed, update free bitmap. */
-    if (CAF_free_bitmap_write != NULL) {
-       /* Paranoia: check to make sure we didn't write more than we said we would. */
-       if (tocentry.Size > CAF_numblks_write * headp->BlockSize) {
-           /*
-           ** for now core dump (might as well, if we've done this the CAF
-           ** file is probably thoroughly hosed anyway.) 
-           */
-           fprintf(stderr, "CAF: article written overran declared size.\n");
-           abort();
-       }
-
-       curblk = CAF_startoffset_write;
-
-       for (i = 0 ; i < CAF_numblks_write ; ++i, curblk += headp->BlockSize) {
-           CAFSetBlockFree(CAF_free_bitmap_write, fd,  curblk, 0);
-       }
-       if (CAFWriteFreeBM(fd, CAF_free_bitmap_write) < 0){
-           CAFError(CAF_ERR_IO);
-           CAF_fd_write = 0;
-           return -1;
-       }
-       CAFDisposeBitmap(CAF_free_bitmap_write);
-       /* and update the Free value in the header. */
-       headp->Free -= CAF_numblks_write * headp->BlockSize;
-    }      
-
-    if (CAF_artnum_write > headp->High || CAF_free_bitmap_write) {
-       /* need to update header. */
-       if (CAF_artnum_write > headp->High) {
-           headp->High = CAF_artnum_write;
-       }
-       if (lseek(fd, 0, SEEK_SET) < 0) {
-           CAFError(CAF_ERR_IO);
-           CAF_fd_write = 0;
-           return -1;
-       }
-       if (OurWrite(fd, headp, sizeof(CAFHEADER)) < 0) {
-           CAF_fd_write = 0;
-           return -1;
-       }
-    }
-#if 0
-    if (close(fd) < 0) {
-       CAFError(CAF_ERR_IO);
-       CAF_fd_write =0;
-       return -1;
-    }
-#endif
-    CAF_fd_write = 0;
-    return 0;
-}
-
-/*
-** return a string containing a description of the error.
-** Warning: uses a static buffer, or possibly a static string.
-*/
-
-static char errbuf[512];
-
-const char *
-CAFErrorStr(void)
-{
-    if (caf_error == CAF_ERR_IO || caf_error == CAF_ERR_CANTCREATECAF) {
-       snprintf(errbuf, sizeof(errbuf), "%s errno=%s\n",
-               (caf_error == CAF_ERR_IO) ? "CAF_ERR_IO" : "CAF_ERR_CANTCREATECAF",
-               strerror(errno));
-       return errbuf;
-    } else {
-       switch(caf_error) {
-         case CAF_ERR_BADFILE:
-           return "CAF_ERR_BADFILE";
-         case CAF_ERR_ARTNOTHERE:
-           return "CAF_ERR_ARTNOTHERE";
-         case CAF_ERR_FILEBUSY:
-           return "CAF_ERR_FILEBUSY";
-         case CAF_ERR_ARTWONTFIT:
-           return "CAF_ERR_ARTWONTFIT";
-         case CAF_ERR_ARTALREADYHERE:
-           return "CAF_ERR_ARTALREADYHERE";
-         case CAF_ERR_BOGUSPATH:
-           return "CAF_ERR_BOGUSPATH";
-         default:
-           snprintf(errbuf, sizeof(errbuf), "CAF error %d", caf_error);
-           return errbuf;
-       }
-    }
-}
-
-/*
-** Open a CAF file, snarf the TOC entries for all the articles inside,
-** and close the file.  NOTE: returns the header for the CAF file in
-** the storage pointed to by *ch.  Dynamically allocates storage for
-** the TOC entries, which should be freed by the caller when the
-** caller's done with it.  Return NULL on failure.
-**
-** This function calls CAFOpenReadTOC(dir, ch, &tocp), which does most 
-** (practically all) of the dirty work.  CAFOpenReadTOC leaves the fd open
-** (and returns it); this is needed by cafls.   CAFReadTOC() closes the fd 
-** after CAFOpenReadTOC() is done with it.
-*/
-
-CAFTOCENT *
-CAFReadTOC(char *path, CAFHEADER *ch)
-{
-    CAFTOCENT *tocp;
-    int fd;
-
-    if ((fd = CAFOpenReadTOC(path, ch, &tocp)) < 0) {
-       return NULL; /* some sort of error happened */
-    }
-
-    close(fd);
-    return tocp;
-}
-
-int
-CAFOpenReadTOC(char *path, CAFHEADER *ch, CAFTOCENT **tocpp)
-{
-    int fd;
-    int nb;
-    CAFTOCENT *tocp;
-    off_t offset;
-
-    if ( (fd = open(path, O_RDONLY)) < 0) {
-       /* 
-       ** if ENOENT (not there), just call this "article not found",
-       ** otherwise it's a more serious error and stash the errno.
-       */
-       if (errno == ENOENT) {
-           CAFError(CAF_ERR_ARTNOTHERE);
-       } else {
-           CAFError(CAF_ERR_IO);
-       }
-       return -1;
-    }
-
-    /* Fetch the header */
-    if (CAFReadHeader(fd, ch) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    /* Allocate memory for TOC. */
-    tocp = xmalloc((ch->High - ch->Low + 1) * sizeof(CAFTOCENT));
-    nb = (sizeof(CAFTOCENT))*(ch->High - ch->Low + 1); /* # bytes to read for toc. */
-
-    /* seek to beginning of TOC */
-    offset = sizeof(CAFHEADER) + ch->FreeZoneTabSize;
-
-    if (lseek(fd, offset, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    if (OurRead(fd, tocp, nb) < 0) {
-       return -1;
-    }
-
-    /* read TOC successfully, return fd and stash tocp where we were told to */
-    *tocpp = tocp;
-    return fd;
-}
-
-
-/*
-** Cancel/expire articles from a CAF file.  This involves zeroing the Size
-** field of the TOC entry, and updating the Free field of the CAF header.
-** note that no disk space is actually freed by this process; space will only
-** be returned to the OS when the cleaner daemon runs on the CAF file.
-*/
-
-int
-CAFRemoveMultArts(char *path, unsigned int narts, ARTNUM *artnums)
-{
-    int fd;
-    CAFHEADER head;
-    CAFTOCENT tocent;
-    CAFBITMAP *freebitmap;
-    ARTNUM art;
-    unsigned int numblksfreed, i, j;
-    off_t curblk;
-    int errorfound = false;
-
-    while (true) {
-       /* try to open the file and lock it */
-       if ((fd = open(path, O_RDWR)) < 0) {
-           /* if ENOENT, CAF file isn't there, so return ARTNOTHERE, otherwise it's an I/O error. */
-           if (errno != ENOENT) {
-               CAFError(CAF_ERR_IO);
-               return -1;
-           } else {
-               CAFError(CAF_ERR_ARTNOTHERE);
-               return -1;
-           }
-       }
-       /* try a nonblocking lock attempt first. */
-       if (inn_lock_file(fd, INN_LOCK_WRITE, false)) break;
-
-       /* wait around to try and get a lock. */
-       inn_lock_file(fd, INN_LOCK_WRITE, true);
-       /*
-        ** and then close and reopen the file, in case someone changed the
-       ** file out from under us.
-       */ 
-       close(fd);
-    }
-    /* got the file, open for write and locked. */
-    /* Fetch the header */
-    if (CAFReadHeader(fd, &head) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    if ((freebitmap = CAFReadFreeBM(fd, &head)) == NULL) {
-       close(fd);
-       return -1;
-    }
-
-    for (j = 0 ; j < narts ; ++j) {
-       art = artnums[j];
-
-       /* Is the requested article even in the file? */
-       if (art < head.Low || art > head.High) {
-           CAFError(CAF_ERR_ARTNOTHERE);
-           errorfound = true; 
-           continue; /* don't abandon the whole remove if just one art is missing */
-       }
-
-       if (CAFGetTOCEnt(fd, &head, art, &tocent) < 0) {
-           close(fd);
-           CAFDisposeBitmap(freebitmap);
-           return -1;
-       }
-
-       if (tocent.Size == 0) {
-           CAFError(CAF_ERR_ARTNOTHERE);
-           errorfound = true; 
-           continue; /* don't abandon the whole remove if just one art is missing */
-       }
-
-       numblksfreed = (tocent.Size + head.BlockSize - 1) / head.BlockSize;
-
-       /* Mark all the blocks as free. */
-       for (curblk = tocent.Offset, i = 0 ; i < numblksfreed; ++i, curblk += head.BlockSize) {
-           CAFSetBlockFree(freebitmap, fd, curblk, 1);
-       }
-       /* Note the amount of free space added. */
-       head.Free += numblksfreed * head.BlockSize;
-       /* and mark the tocent as a deleted entry. */
-       tocent.Size = 0;
-
-       if (CAFSeekTOCEnt(fd, &head, art) < 0) {
-           close(fd);
-           CAFDisposeBitmap(freebitmap);
-           return -1;
-       }
-
-       if (OurWrite(fd, &tocent, sizeof(CAFTOCENT)) < 0) {
-           close(fd);
-           CAFDisposeBitmap(freebitmap);
-           return -1;
-       }
-    }
-
-    if (CAFWriteFreeBM(fd, freebitmap) < 0) {
-       close(fd);
-       CAFDisposeBitmap(freebitmap);
-       return -1;
-    }
-    /* dispose of bitmap storage. */
-    CAFDisposeBitmap(freebitmap);
-
-    /* need to update header. */
-    if (lseek(fd, 0, SEEK_SET) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-    if (OurWrite(fd, &head, sizeof(CAFHEADER)) < 0) {
-       return -1;
-    }
-
-    if (close(fd) < 0) {
-       CAFError(CAF_ERR_IO);
-       return -1;
-    }
-
-    if (CAFClean(path, 0, 10.0) < 0) errorfound=true;
-
-    return errorfound ? -1 : 0;
-}
-
-/* 
-** Do a fake stat() of a CAF-stored article.  Both 'inpaths' and 'innfeed'
-** find this functionality useful, so we've added a function to do this.
-** Caveats: not all of the stat structure is filled in, only these items:
-**  st_mode, st_size, st_atime, st_ctime, st_mtime.  (Note: 
-**  atime==ctime==mtime always, as we don't track times of CAF reads.)
-*/
-
-int
-CAFStatArticle(char *path, ARTNUM art, struct stat *stbuf)
-{
-    CAFHEADER head;
-    int fd;
-    CAFTOCENT tocent;
-
-    if ( (fd = open(path, O_RDONLY)) < 0) {
-       /* 
-       ** if ENOENT (not there), just call this "article not found",
-       ** otherwise it's a more serious error and stash the errno.
-       */
-       if (errno == ENOENT) {
-           CAFError(CAF_ERR_ARTNOTHERE);
-       } else {
-           CAFError(CAF_ERR_IO);
-       }
-       return -1;
-    }
-
-    /* Fetch the header */
-    if (CAFReadHeader(fd, &head) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    /* Is the requested article even in the file? */
-    if (art < head.Low || art > head.High) {
-       CAFError(CAF_ERR_ARTNOTHERE);
-       close(fd);
-       return -1;
-    }
-
-    if (CAFGetTOCEnt(fd, &head, art, &tocent) < 0) {
-       close(fd);
-       return -1;
-    }
-
-    if (tocent.Size == 0) {
-       /* empty/otherwise not present article */
-       CAFError(CAF_ERR_ARTNOTHERE);
-       close(fd);
-       return -1;
-    }
-
-    /* done with file, can close it. */
-    close(fd);
-
-    memset(stbuf, 0, sizeof(struct stat));
-    stbuf->st_mode = S_IFREG | 0444;
-    stbuf->st_size = tocent.Size;
-    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = tocent.ModTime;
-    return 0;
-}
-
-/* 
-** Taken from the old 'cafclean' program.
-** Function to clean a single CAF file. 
-** Possibly the ugliest function I've ever written in my life. 
-*/
-/*
-** We try to keep the total TOC size this many times larger than the actual 
-** amount of TOC data in use so as not to have to reclean or compact the TOC
-** so often.
-*/
-#define TOC_CLEAN_RATIO 10
-/*
-** ditto, but for compacting, we want to force a compacting if the High art#
-** wanders into the top nth of the TOC slots.
-*/
-#define TOC_COMPACT_RATIO 5
-
-int
-CAFClean(char *path, int verbose, double PercentFreeThreshold)
-{
-    char *newpath;
-    CAFHEADER head, newhead;
-    int fdin, fdout;
-    ARTNUM newlow;
-    ARTNUM i;
-    CAFTOCENT *tocarray, *tocp;
-    CAFTOCENT *newtocarray, *newtocp;
-    size_t newtocsize;
-    FILE *infile, *outfile;
-    off_t startoffset, newstartoffset;
-    char  buf[BUFSIZ];
-    int   nbytes, ncur;
-    int   n;
-    unsigned int blocksize;
-    char *zerobuff;
-    struct stat statbuf;
-    size_t datasize;
-    double percentfree;
-    int toc_needs_expansion;
-    int toc_needs_compacting;
-
-#ifdef STATFUNCT
-    struct STATSTRUC fsinfo;
-    long num_diskblocks_needed;
-#endif
-
-    /* allocate buffer for newpath */
-    newpath = xmalloc(strlen(path) + 10);
-    while (true) {
-       /* try to open the file and lock it. */
-       if ((fdin = open(path, O_RDWR)) < 0) {
-           /*
-           ** if ENOENT, obviously no CAF file is here, so just return,
-           ** otherwise report an error.
-           */
-           if (errno != ENOENT) {
-               CAFError(CAF_ERR_IO);
-               return -1;
-           } else {
-               return 0;
-           }
-       }
-
-       /* try a nonblocking lock attempt first. */
-       if (inn_lock_file(fdin, INN_LOCK_WRITE, false)) break;
-
-       /* wait around to try and get a lock. */
-       inn_lock_file(fdin, INN_LOCK_WRITE, true);
-       /*
-        ** and then close and reopen the file, in case someone changed the
-       ** file out from under us.
-       */ 
-       close(fdin);
-    }
-
-    /* got the file, open for write and locked. */
-    /* Fetch the header */
-    if (CAFReadHeader(fdin, &head) < 0) {
-       close(fdin);
-       return -1;
-    }
-
-    /* Stat the file to see how big it is */
-    if (fstat(fdin, &statbuf) < 0) {
-       close(fdin);
-       CAFError(CAF_ERR_IO);
-       perror(path);
-       return -1;
-    }
-    
-    /* compute amount of  actual data in file. */
-    datasize = statbuf.st_size - head.StartDataBlock;
-    if (datasize <= 0) {
-       /* nothing in the file, set percentfree==0 so won't bother cleaning */
-       percentfree = 0;
-    } else {
-       percentfree = (100.0 * head.Free) / datasize;
-    }
-
-    /*
-    ** Grumble, we need to read the TOC now even before we clean, just so 
-    ** we can decide if a clean or a compaction is needed.
-    */
-
-    lseek(fdin, 0L, SEEK_SET);
-       
-    /* make input file stdio-buffered. */
-    if ((infile = fdopen(fdin, "r+")) == NULL) {
-       CAFError(CAF_ERR_IO);
-       close(fdin);
-       return -1;
-    }
-
-    /* Allocate memory for TOC. */
-    tocarray = xmalloc((head.High - head.Low + 1) * sizeof(CAFTOCENT));
-
-    fseeko(infile, (off_t) (sizeof(CAFHEADER) + head.FreeZoneTabSize),
-           SEEK_SET);
-
-    n = fread(tocarray, sizeof(CAFTOCENT), (head.High - head.Low + 1), infile);
-    if (n < 0) {
-       CAFError(CAF_ERR_IO);
-       fclose(infile);
-       free(tocarray);
-       free(newpath);
-       return -1;
-    }
-
-    if ((unsigned long) n < (head.High - head.Low +1)) {
-       CAFError(CAF_ERR_BADFILE);
-       fclose(infile);
-       free(tocarray);
-       free(newpath);
-       return -1;
-    }
-    
-    /* Scan to see what the new lower bound for CAF file should be. */
-    newlow = head.High + 1;
-
-    for (tocp = tocarray, i = head.Low; i <= head.High; ++tocp, ++i) {
-       if (tocp->Size != 0) {
-           newlow = i;
-           break;
-       }
-    }
-
-    /* 
-    ** if newlow is head.High+1, the TOC is completely empty and we can
-    ** just remove the entire file. 
-    */
-    if (newlow == head.High + 1) {
-        unlink(path);
-       fclose(infile);
-       free(tocarray);
-       free(newpath);
-       return 0;
-    }
-
-    /*
-    ** Ah. NOW we get to decide if we need a clean!
-    ** Clean if either 
-    **   1) the absolute freespace threshold is crossed
-    **   2) the percent free threshold is crossed.
-    **   3) The CAF TOC is over 10% full (assume it needs to be expanded,
-    **      so we force a clean)
-    ** Note that even if we do not need a clean, we may need a compaction 
-    ** if the high article number is in the top nth of the TOC.
-    */
-
-    toc_needs_expansion = 0;
-    if ( (head.High - newlow) >= head.NumSlots/TOC_CLEAN_RATIO) {
-       toc_needs_expansion = 1;
-    }
-
-    toc_needs_compacting = 0;
-    if ( (head.Low + head.NumSlots - head.NumSlots/TOC_COMPACT_RATIO) <= head.High) {
-       toc_needs_compacting = 1;
-    }
-
-    if ( (percentfree < PercentFreeThreshold)
-       && (!toc_needs_expansion) ) {
-       /* no cleaning, but do we need a TOC compaction ? */
-       if (toc_needs_compacting) {
-           int delta;
-           CAFTOCENT *tocp2;
-
-           if (verbose) {
-               printf("Compacting   %s: Free=%lu (%f%%)\n", path,
-                       (unsigned long) head.Free, percentfree);
-           }
-
-           delta = newlow - head.Low;
-
-           /* slide TOC array down delta units. */
-           for (i = newlow, tocp = tocarray, tocp2 = tocarray+delta;
-                i <= head.High ;  ++i) {
-               *tocp++ = *tocp2++;
-           }
-
-           head.Low = newlow;
-           /* note we don't set LastCleaned, this doesn't count a a clean. */
-           /* (XXX: do we need a LastCompacted as well? might be nice.) */
-
-           /*  write new header  on top of old */
-           fseeko(infile, 0, SEEK_SET);
-           if (fwrite(&head, sizeof(CAFHEADER), 1, infile) < 1) {
-               CAFError(CAF_ERR_IO);
-               free(tocarray);
-               free(newpath);
-               fclose(infile);
-               return -1;
-           }
-           /*
-           ** this next fseeko might actually fail, because we have buffered
-           ** stuff that might fail on write.
-           */
-           if (fseeko(infile, sizeof(CAFHEADER) + head.FreeZoneTabSize,
-                      SEEK_SET) < 0) {
-               perror(path);
-               free(tocarray);
-               free(newpath);
-               fclose(infile);
-               unlink(newpath);
-               return -1;
-           }
-           if (fwrite(tocarray, sizeof(CAFTOCENT), head.High - newlow + 1, infile) < head.High - newlow + 1
-               || fflush(infile) < 0) {
-               CAFError(CAF_ERR_IO);
-               free(tocarray);
-               free(newpath);
-               fclose(infile);
-               return -1;
-           }
-           /* all done, return. */
-           fclose(infile);
-           free(tocarray);
-           free(newpath);
-           return 0;
-       } else {
-           /* need neither full cleaning nor compaction, so return. */
-           if (verbose) {
-               printf("Not cleaning %s: Free=%lu (%f%%)\n", path,
-                       (unsigned long) head.Free, percentfree);
-           }
-           fclose(infile);
-           free(tocarray);
-           free(newpath);
-           return 0;
-       }
-    }
-
-    /*
-    ** If OS supports it, try to check for free space and skip this file if
-    ** not enough free space on this filesystem.
-    */
-#ifdef STATFUNCT
-    if (STATFUNCT(fdin, &fsinfo) >= 0) {
-       /* compare avail # blocks to # blocks needed for current file. 
-       ** # blocks needed is approximately 
-       ** datasize/blocksize + (size of the TOC)/blocksize 
-       ** + Head.BlockSize/blocksize, but we need to take rounding 
-       ** into account. 
-       */
-#define RoundIt(n) (CAFRoundOffsetUp((n), fsinfo.STATMULTI) / fsinfo.STATMULTI)
-
-       num_diskblocks_needed = RoundIt((head.High - head.Low + 1)*sizeof(CAFTOCENT)) 
-           + RoundIt(datasize - head.Free) + RoundIt(head.BlockSize);
-       if (num_diskblocks_needed > fsinfo.STATAVAIL) {
-           if (verbose) {
-               printf("CANNOT clean %s: needs %ld blocks, only %ld avail.\n",
-                      path, num_diskblocks_needed,
-                       (unsigned long) fsinfo.f_bavail);
-           }
-           fclose(infile);
-           free(tocarray);
-           free(newpath);
-           return 0;
-       }
-    }
-#endif    
-
-    if (verbose) {
-       printf("Am  cleaning %s: Free=%d (%f%%) %s\n", path, head.Free,
-              percentfree, toc_needs_expansion ? "(Expanding TOC)" : "");
-    }
-
-    /* decide on proper size for new TOC */
-    newtocsize = CAF_DEFAULT_TOC_SIZE;
-    if (head.High - newlow > newtocsize/TOC_CLEAN_RATIO) {
-       newtocsize = TOC_CLEAN_RATIO*(head.High - newlow);
-    }
-
-    /* try to create new CAF file with some temp. pathname */
-    /* note: new CAF file is created in flocked state. */
-    if ((fdout = CAFCreateCAFFile(path, newlow, newtocsize,
-                                  statbuf.st_size, 1, newpath)) < 0) {
-       fclose(infile);
-       free(tocarray);
-       free(newpath);
-       return -1;
-    }
-
-    if ((outfile = fdopen(fdout, "w+")) == NULL) {
-       CAFError(CAF_ERR_IO);
-       fclose(infile);
-       free(tocarray);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    newtocarray = xcalloc((head.High - newlow + 1), sizeof(CAFTOCENT));
-
-    if (fseeko(outfile, 0, SEEK_SET) < 0) {
-       perror(newpath);
-       free(tocarray);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    /* read in the CAFheader from the new file. */
-    if (fread(&newhead, sizeof(CAFHEADER), 1, outfile) < 1) {
-       perror(newpath);
-       free(tocarray);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    /* initialize blocksize, zeroes buffer. */
-    blocksize = newhead.BlockSize;
-    if (blocksize == 0) blocksize=CAF_DEFAULT_BLOCKSIZE;
-
-    zerobuff = xcalloc(blocksize, 1);
-
-    /* seek to end of output file/place to start writing new articles */
-    fseeko(outfile, 0, SEEK_END);
-    startoffset = ftello(outfile);
-    startoffset = CAFRoundOffsetUp(startoffset, blocksize);
-    fseeko(outfile, (off_t) startoffset, SEEK_SET);
-
-    /*
-    ** Note: startoffset will always give the start offset of the next
-    ** art to be written to the outfile.
-    */
-
-    /*
-    ** Loop over all arts in old TOC, copy arts that are still here to new
-    ** file and new TOC. 
-    */
-
-    for (tocp = tocarray, i = head.Low; i <= head.High; ++tocp, ++i) {
-       if (tocp->Size != 0) {
-           newtocp = &newtocarray[i - newlow];
-           newtocp->Offset = startoffset;
-           newtocp->Size = tocp->Size;
-           newtocp->ModTime = tocp->ModTime;
-
-           /* seek to right place in input. */
-           fseeko(infile, (off_t) tocp->Offset, SEEK_SET); 
-
-           nbytes = tocp->Size;
-           while (nbytes > 0) {
-               ncur = (nbytes > BUFSIZ) ? BUFSIZ : nbytes;
-               if (fread(buf, sizeof(char), ncur, infile) < ncur 
-                   || fwrite(buf, sizeof(char), ncur, outfile) < ncur) {
-                   if (feof(infile)) {
-                       CAFError(CAF_ERR_BADFILE);
-                   } else {
-                       CAFError(CAF_ERR_IO);
-                   }
-
-                   errorexit:
-                   fclose(infile);
-                   fclose(outfile);
-                   free(tocarray);
-                   free(newtocarray);
-                   free(zerobuff);
-                   unlink(newpath);
-                   free(newpath);
-                   return -1;
-               }
-               nbytes -= ncur;
-           }
-           /* startoffset = ftello(outfile); */
-           startoffset += tocp->Size;
-           newstartoffset = CAFRoundOffsetUp(startoffset, blocksize);
-           /* fseeko(outfile, (off_t) startoffset, SEEK_SET); */
-           /* but we don't want to call fseeko, since that seems to always 
-              force a write(2) syscall, even when the new location would
-              still be inside stdio's buffer. */
-           if (newstartoffset - startoffset > 0) {
-               ncur = newstartoffset - startoffset;
-               if (fwrite(zerobuff, sizeof(char), ncur, outfile) < ncur) {
-                   /* write failed, must be disk error of some sort. */
-                   perror(newpath);
-                   goto errorexit; /* yeah, it's a goto.  eurggh. */
-               }
-           }
-           startoffset = newstartoffset;
-       }
-    }
-
-    free(tocarray); /* don't need this guy anymore. */
-    free(zerobuff);
-
-    /* 
-    ** set up new file header, TOC.
-    ** this next fseeko might actually fail, because we have buffered stuff
-    ** that might fail on write.
-    */
-    if (fseeko(outfile, 0, SEEK_SET) < 0) {
-       perror(newpath);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    /* Change what we need in new file's header. */
-    newhead.Low = newlow;
-    newhead.High = head.High;
-    newhead.LastCleaned = time((time_t *) NULL);
-/*    newhead.NumSlots = newtocsize; */
-/*    newhead.Free = 0; */
-
-    if (fwrite(&newhead, sizeof(CAFHEADER), 1, outfile) < 1) {
-       CAFError(CAF_ERR_IO);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    /*
-    ** this next fseeko might actually fail, because we have buffered stuff
-    ** that might fail on write.
-    */
-    if (fseeko(outfile, sizeof(CAFHEADER) + newhead.FreeZoneTabSize,
-              SEEK_SET) < 0) {
-       perror(newpath);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-
-    if (fwrite(newtocarray, sizeof(CAFTOCENT), head.High - newlow + 1, outfile) < head.High - newlow + 1
-       || fflush(outfile) < 0) {
-       CAFError(CAF_ERR_IO);
-       free(newtocarray);
-       fclose(infile);
-       fclose(outfile);
-       unlink(newpath);
-       free(newpath);
-       return -1;
-    }
-    
-    if (rename(newpath, path) < 0) {
-       CAFError(CAF_ERR_IO);
-       free(newtocarray);
-       free(newpath);
-       fclose(infile);
-       fclose(outfile);
-       /* if can't rename, probably no point in trying to unlink newpath, is there? */
-       return -1;
-    }
-    /* written and flushed newtocarray, can safely fclose and get out of
-       here! */
-    free(newtocarray);
-    free(newpath);
-    fclose(outfile);
-    fclose(infile);
-    return 0;
-}
diff --git a/storage/timecaf/caf.h b/storage/timecaf/caf.h
deleted file mode 100644 (file)
index babd4bd..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $Revision: 5558 $
-** Declarations needed for handling CAF (Crunched Article Files)
-** Written by Richard Todd (rmtodd@mailhost.ecn.uoknor.edu) 3/24/96
-*/
-
-
-/*
-** Format of a crunched article file:
-** Header:
-*/
-
-typedef struct _CAFHEADER {
-    char        Magic[4]; /* Magic Number "CRMT" */
-    ARTNUM      Low; /* lowest article in the file */
-    ARTNUM      NumSlots; /* number of articles there are room for in the TOC */
-    ARTNUM      High; /* last article actually present in the file */
-    size_t     Free; /* amount of space currently unused (freed by cancels/expires) */
-    off_t       StartDataBlock; /* offset of first article data block. */
-    unsigned int BlockSize; /* unit of allocation for CAF files. */
-    size_t      FreeZoneTabSize; /* amount of space taken up by the free zone table. */
-    size_t      FreeZoneIndexSize; /* size taken up by the "index" part of the free zone table. */
-    time_t      LastCleaned; /* note time of last cleaning. */
-    int         spare[3];
-} CAFHEADER;
-
-#define CAF_MAGIC "CRMT"
-#define CAF_MAGIC_LEN 4
-#define CAF_DEFAULT_BLOCKSIZE 512
-
-/*
-** then the table of free blocks.  The table is FreeZoneTabSize bytes
-** long.  First comes a "first-level" or "index" bitmap, taking up the
-** space from the end of the CAFHEADER to the end of the first
-** block, i.e. FreeZoneIndexBytes. The rest of the table is a big  bitmap
-** listing free blocks in the 'data' portion of the CAF file.
-**
-** In the "index" bitmap: LSB of bitmap byte 0 is 1 if there are any 1s 
-** (free blocks) listed in the first block of the big bitmap, and 0 if there
-** are no 1s in that block.  The remaining bits of the index bitmap 
-** correspond to the remaining blocks of the big bitmap accordingly.
-** The idea is that from the index bitmap one can tell which part of the 
-** main bitmap is likely to have free blocks w/o having to read the entire 
-** main bitmap.
-**
-** As for the main bitmap, each bit is 1 if the corresponding data
-** block (BlockSize bytes) is free.  LSB of bitmap byte 0 corresponds
-** to the block @ offset StartDataBlock, and all the rest follow on
-** accordingly.  
-**
-** Note that the main part of the bitmap is *always* FreeZoneIndexByte*8
-** blocks long, no matter how big the CAF file is.  The table of free blocks
-** is almost always sparse.  Also note that blocks past EOF in the CAF file
-** are *not* considered free.  If the CAF article write routines fail to 
-** find free space in the fre block bitmaps, they will always attempt to 
-** extend the CAF file instead. 
-*/
-
-#define CAF_DEFAULT_FZSIZE (512-sizeof(CAFHEADER))
-
-/*
-** (Note: the CAFBITMAP structure isn't what's actually stored on disk
-** in the free bitmap region, this is just a convenient structure to
-** keep the bitmap size and StartBlockOffset together with the bitmap
-** w/o having keep passing the original CAFHEADER to every routine
-** that wants it.  The bitmap structure contains the first (index) bitmap,
-** as well as pointers to structures for each block of the main bitmap that
-** has been read into memory.
-*/
-
-typedef struct _CAFBITMAP {
-    off_t StartDataBlock;
-    off_t MaxDataBlock; /* can only handle offsets < this with this bitmap. */
-    size_t FreeZoneTabSize;
-    size_t FreeZoneIndexSize;
-    size_t BytesPerBMB; /* size of chunk, in bytes, that any given BMBLK can map. */
-    unsigned int BlockSize;
-    unsigned int NumBMB; /* size of Blocks array. */
-    struct _CAFBMB **Blocks;
-    char *Bits;
-} CAFBITMAP;
-
-typedef struct _CAFBMB {
-    off_t StartDataBlock;
-    off_t MaxDataBlock;
-    int Dirty; /* 1 if this BMB has had any bits changed. */
-    char *BMBBits;
-} CAFBMB;
-
-/* 
-** Next in the file are the TOC (Table of Contents) entries.  Each TOC
-** entry describes an article. 
-*/
-
-typedef struct _CAFTOCENT {
-    off_t  Offset;
-    size_t Size;
-    time_t ModTime;
-} CAFTOCENT;
-
-/*
-** and then after the NumSlots TOC Entries, the actual articles, one after
-** another, always starting at offsets == 0 mod BlockSize
-*/
-
-/*
-** Number of slots to put in TOC by default.  Can be raised if we ever get 
-** more than 256K articles in a newsgroup (frightening thought).
-*/
-
-#define CAF_DEFAULT_TOC_SIZE (256 * 1024)
-
-/*
-** Default name for CAF file in the news spool dir for a given newsgroup.
-*/
-#define CAF_NAME "CF"
-
-extern int CAFOpenArtRead(const char *cfpath, ARTNUM art, size_t *len);
-extern int CAFOpenArtWrite(char *cfpath, ARTNUM *art, int WaitLock, size_t size);
-extern int CAFStartWriteFd(int fd, ARTNUM *art, size_t size);
-extern int CAFFinishWriteFd(int fd);
-extern int CAFFinishArtWrite(int fd);
-extern int CAFCreateCAFFile(char *cfpath, ARTNUM lowart, ARTNUM tocsize, size_t cfsize, int nolink, char *temppath);
-extern const char *CAFErrorStr(void);
-extern CAFTOCENT *CAFReadTOC(char *cfpath, CAFHEADER *ch);
-extern int CAFRemoveMultArts(char *cfpath, unsigned int narts, ARTNUM *arts);
-extern int CAFStatArticle(char *path, ARTNUM art, struct stat *st);
-
-#ifdef CAF_INNARDS
-/* functions used internally by caf.c, and by the cleaner program, and cafls
-   but probably aren't useful/desirable to be used by others. */
-extern int CAFOpenReadTOC(char *cfpath, CAFHEADER *ch, CAFTOCENT **tocpp);
-extern int CAFReadHeader(int fd, CAFHEADER *h);
-extern off_t CAFRoundOffsetUp(off_t offt, unsigned int bsize);
-extern CAFBITMAP * CAFReadFreeBM(int fd, CAFHEADER *h);
-extern void CAFDisposeBitmap(CAFBITMAP *cbm);
-/*
-** note! CAFIsBlockFree needs the fd, since blocks of the free bitmap may 
-** need to be fetched from disk.
-*/
-extern int CAFIsBlockFree(CAFBITMAP *bm, int fd, off_t block);
-#endif
-
-extern int caf_error; /* last error encountered by library. */
-extern int caf_errno; /* saved value of errno here if I/O error hit by lib. */
-
-#define CAF_ERR_IO 1           /* generic I/O error, check caf_errno for details */
-#define CAF_ERR_BADFILE 2      /* corrupt file */
-#define CAF_ERR_ARTNOTHERE 3   /* article not in the database */
-#define        CAF_ERR_CANTCREATECAF 4 /* can't create the CAF file, see errno. */
-#define CAF_ERR_FILEBUSY 5      /* file locked by someone else. */
-#define CAF_ERR_ARTWONTFIT 6   /* outside the range in the TOC */
-#define CAF_ERR_ARTALREADYHERE 7 /* tried to create an article that was already here. */
-#define CAF_ERR_BOGUSPATH 8    /* pathname not parseable. */
diff --git a/storage/timecaf/method.config b/storage/timecaf/method.config
deleted file mode 100644 (file)
index e42a08d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = timecaf
-number  = 4
-sources = caf.c timecaf.c
diff --git a/storage/timecaf/timecaf.c b/storage/timecaf/timecaf.c
deleted file mode 100644 (file)
index e053a02..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-/*  $Id: timecaf.c 7412 2005-10-09 03:44:35Z eagle $
-**
-**  Like the timehash storage method (and heavily inspired by it), but uses
-**  the CAF library to store multiple articles in a single file.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "caf.h"
-#include "inn/innconf.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "methods.h"
-#include "timecaf.h"
-#include "paths.h"
-
-/* Needed for htonl() and friends on AIX 4.1. */
-#include <netinet/in.h>
-
-typedef struct {
-    char               *artdata; /* start of the article data -- may be mmaped */
-    char               *mmapbase; /* actual start of mmaped region (on pagesize bndry, not necessarily == artdaya */
-    unsigned int       artlen; /* art length. */
-    size_t             mmaplen; /* length of mmap region. */
-    DIR                        *top; /* open handle on top level dir. */
-    DIR                        *sec; /* open handle on the 2nd level directory */
-    DIR                *ter; /* open handle on 3rd level dir. */
-    struct dirent      *topde; /* last entry we got from top */
-    struct dirent      *secde; /* last entry we got from sec */ 
-    struct dirent      *terde; /* last entry we got from sec */ 
-    CAFTOCENT          *curtoc; 
-    ARTNUM             curartnum;
-    CAFHEADER          curheader;
-} PRIV_TIMECAF;
-
-/* current path/fd for an open CAF file */
-typedef struct {
-    char       *path; /* path to file. */
-    int                fd; /* open fd -- -1 if no file currently open. */
-} CAFOPENFILE;
-
-static CAFOPENFILE ReadingFile, WritingFile;
-static char *DeletePath;
-static ARTNUM *DeleteArtnums;
-static unsigned int NumDeleteArtnums, MaxDeleteArtnums;
-
-typedef enum {FIND_DIR, FIND_CAF, FIND_TOPDIR} FINDTYPE;
-
-/*
-** Structures for the cache for stat information (to make expireover etc. 
-** faster. 
-**
-** The first structure contains the TOC info for a single CAF file.  The 2nd
-** one has pointers to the info for up to 256 CAF files, indexed
-** by the 2nd least significant byte of the arrival time.
-*/
-
-struct caftoccacheent {
-    CAFTOCENT *toc;
-    CAFHEADER header;
-};
-typedef struct caftoccacheent CAFTOCCACHEENT;
-
-struct caftocl1cache {
-    CAFTOCCACHEENT *entries[256];
-};
-typedef struct caftocl1cache CAFTOCL1CACHE;
-
-/*
-** and similar structures indexed by the 3rd and 4th bytes of the arrival time.
-** pointing to the lower level structures.  Note that the top level structure
-** (the one indexed by the MSByte of the timestamp) is likely to have only
-** one active pointer, unless your spool keeps more than 194 days of articles,
-** but it doesn't cost much to keep that one structure around and keep the
-** code general.
-*/
-
-struct caftocl2cache {
-    CAFTOCL1CACHE *l1ptr[256];
-};
-typedef struct caftocl2cache CAFTOCL2CACHE;
-
-struct caftocl3cache {
-    CAFTOCL2CACHE *l2ptr[256];
-};
-typedef struct caftocl3cache CAFTOCL3CACHE;
-
-static CAFTOCL3CACHE *TOCCache[256]; /* indexed by storage class! */
-static int TOCCacheHits, TOCCacheMisses;
-
-    
-static TOKEN MakeToken(time_t now, int seqnum, STORAGECLASS class, TOKEN *oldtoken) {
-    TOKEN               token;
-    unsigned int        i;
-    unsigned short      s;
-
-    if (oldtoken == (TOKEN *)NULL)
-       memset(&token, '\0', sizeof(token));
-    else 
-       memcpy(&token, oldtoken, sizeof(token));
-    token.type = TOKEN_TIMECAF;
-    token.class = class;
-    i = htonl(now);
-    memcpy(token.token, &i, sizeof(i));
-    if (sizeof(i) > 4)
-       memmove(token.token, &token.token[sizeof(i) - 4], 4);
-    s = htons(seqnum);
-    memcpy(&token.token[4], &s + (sizeof(s) - 2), 2);
-    return token;
-}
-
-
-static void BreakToken(TOKEN token, int *now, int *seqnum) {
-    unsigned int        i;
-    unsigned short      s = 0;
-
-    memcpy(&i, token.token, sizeof(i));
-    memcpy(&s, &token.token[4], sizeof(s));
-    *now = ntohl(i);
-    *seqnum = (int)ntohs(s);
-}
-
-/* 
-** Note: the time here is really "time>>8", i.e. a timestamp that's been
-** shifted right by 8 bits.
-*/
-static char *MakePath(int now, const STORAGECLASS class) {
-    char *path;
-    size_t length;
-    
-    /* innconf->patharticles + '/timecaf-zz/xx/xxxx.CF' */
-    length = strlen(innconf->patharticles) + 32;
-    path = xmalloc(length);
-    snprintf(path, length, "%s/timecaf-%02x/%02x/%02x%02x.CF",
-             innconf->patharticles, class,
-             (now >> 8) & 0xff, (now >> 16) & 0xff, now & 0xff);
-
-    return path;
-}
-
-static TOKEN *PathNumToToken(char *path, ARTNUM artnum) {
-    int                        n;
-    unsigned int       t1, t2, class;
-    unsigned int       timestamp;
-    static TOKEN       token;
-
-    n = sscanf(path, "timecaf-%02x/%02x/%04x.CF", &class, &t1, &t2);
-    if (n != 3)
-       return (TOKEN *)NULL;
-    timestamp = ((t1 << 8) & 0xff00) | ((t2 << 8) & 0xff0000) | ((t2 << 0) & 0xff);
-    token = MakeToken(timestamp, artnum, class, (TOKEN *)NULL);
-    return &token;
-}
-
-
-bool timecaf_init(SMATTRIBUTE *attr) {
-    if (attr == NULL) {
-       syslog(L_ERROR, "timecaf: attr is NULL");
-       SMseterror(SMERR_INTERNAL, "attr is NULL");
-       return false;
-    }
-    attr->selfexpire = false;
-    attr->expensivestat = false;
-    if (STORAGE_TOKEN_LENGTH < 6) {
-       syslog(L_FATAL, "timecaf: token length is less than 6 bytes");
-       SMseterror(SMERR_TOKENSHORT, NULL);
-       return false;
-    }
-    ReadingFile.fd = WritingFile.fd = -1;
-    ReadingFile.path = WritingFile.path = (char *)NULL;
-    return true;
-}
-
-/*
-** Routines for managing the 'TOC cache' (cache of TOCs of various CAF files)
-**
-** Attempt to look up a given TOC entry in the cache.  Takes the timestamp
-** as arguments. 
-*/
-
-static CAFTOCCACHEENT *
-CheckTOCCache(int timestamp, int tokenclass)
-{
-    CAFTOCL2CACHE *l2;
-    CAFTOCL1CACHE *l1;
-    CAFTOCCACHEENT *cent;
-    unsigned char tmp;
-
-    if (TOCCache[tokenclass] == NULL) return NULL; /* cache is empty */
-
-    tmp = (timestamp>>16) & 0xff;
-    l2 = TOCCache[tokenclass]->l2ptr[tmp];
-    if (l2 == NULL) return NULL;
-
-    tmp = (timestamp>>8) & 0xff;
-    l1 = l2->l1ptr[tmp];
-    if (l1 == NULL) return NULL;
-
-    tmp = (timestamp) & 0xff;
-    cent = l1->entries[tmp];
-
-    ++TOCCacheHits;
-    return cent;
-}
-
-/*
-** Add given TOC and header to the cache.  Assume entry is not already in
-** cache.
-*/
-static CAFTOCCACHEENT *
-AddTOCCache(int timestamp, CAFTOCENT *toc, CAFHEADER head, int tokenclass)
-{
-    CAFTOCL2CACHE *l2;
-    CAFTOCL1CACHE *l1;
-    CAFTOCCACHEENT *cent;
-    unsigned char tmp;
-    int i;
-
-    if (TOCCache[tokenclass] == NULL) {
-       TOCCache[tokenclass] = xmalloc(sizeof(CAFTOCL3CACHE));
-       for (i = 0 ; i < 256 ; ++i) TOCCache[tokenclass]->l2ptr[i] = NULL;
-    }
-
-    tmp = (timestamp>>16) & 0xff;
-    l2 = TOCCache[tokenclass]->l2ptr[tmp];
-    if (l2 == NULL) {
-       TOCCache[tokenclass]->l2ptr[tmp] = l2 = xmalloc(sizeof(CAFTOCL2CACHE));
-       for (i = 0 ; i < 256 ; ++i) l2->l1ptr[i] = NULL;
-    }
-
-    tmp = (timestamp>>8) & 0xff;
-    l1 = l2->l1ptr[tmp];
-    if (l1 == NULL) {
-       l2->l1ptr[tmp] = l1 = xmalloc(sizeof(CAFTOCL1CACHE));
-       for (i = 0 ; i < 256 ; ++i) l1->entries[i] = NULL;
-    }
-
-    tmp = (timestamp) & 0xff;
-    cent = xmalloc(sizeof(CAFTOCCACHEENT));
-    l1->entries[tmp] = cent;
-
-    cent->header = head;
-    cent->toc = toc;
-    ++TOCCacheMisses;
-    return cent;
-}
-
-/*
-** Do stating of an article, going thru the TOC cache if possible. 
-*/
-
-static ARTHANDLE *
-StatArticle(int timestamp, ARTNUM artnum, int tokenclass)
-{
-    CAFTOCCACHEENT *cent;
-    CAFTOCENT *toc;
-    CAFHEADER head;
-    char *path;
-    CAFTOCENT *tocentry;
-    ARTHANDLE *art;
-
-    cent = CheckTOCCache(timestamp,tokenclass);
-    if (cent == NULL) {
-       path = MakePath(timestamp, tokenclass);
-       toc = CAFReadTOC(path, &head);
-       if (toc == NULL) {
-           if (caf_error == CAF_ERR_ARTNOTHERE) {
-               SMseterror(SMERR_NOENT, NULL);
-           } else {
-               SMseterror(SMERR_UNDEFINED, NULL);
-           }
-           free(path);
-           return NULL;
-       }
-       cent = AddTOCCache(timestamp, toc, head, tokenclass);
-       free(path);
-    }
-    
-    /* check current TOC for the given artnum. */
-    if (artnum < cent->header.Low || artnum > cent->header.High) {
-       SMseterror(SMERR_NOENT, NULL);
-       return NULL;
-    }
-    
-    tocentry = &(cent->toc[artnum - cent->header.Low]);
-    if (tocentry->Size == 0) {
-       /* no article with that article number present */
-       SMseterror(SMERR_NOENT, NULL);
-       return NULL;
-    }
-
-    /* stat is a success, so build a null art struct to represent that. */
-    art = xmalloc(sizeof(ARTHANDLE));
-    art->type = TOKEN_TIMECAF;
-    art->data = NULL;
-    art->len = 0;
-    art->private = NULL;
-    return art;
-}
-       
-
-static void
-CloseOpenFile(CAFOPENFILE *foo) {
-    if (foo->fd >= 0) {
-       close(foo->fd);
-       foo->fd = -1;
-       free(foo->path);
-       foo->path = NULL;
-    }
-}
-
-TOKEN timecaf_store(const ARTHANDLE article, const STORAGECLASS class) {
-    char                *path;
-    char                *p;
-    time_t              now;
-    int                        timestamp;
-    TOKEN               token;
-    int                 fd;
-    ssize_t             result;
-    ARTNUM             art;
-
-    if (article.arrived == (time_t)0)
-       now = time(NULL);
-    else
-       now = article.arrived;
-
-    timestamp = now>>8;
-    art = 0;  /* magic: 0=="next available article number. */
-
-    path = MakePath(timestamp, class);
-    /* check to see if we have this CAF file already open. */
-    if (WritingFile.fd < 0 || strcmp(WritingFile.path, path) != 0) {
-       /* we're writing to a different file, close old one and start new one. */
-       CloseOpenFile(&WritingFile);
-       fd = CAFOpenArtWrite(path, &art, true, article.len);
-       if (fd < 0) {
-           if (caf_error == CAF_ERR_IO && caf_errno == ENOENT) {
-               /* directories in the path don't exist, try creating them. */
-               p = strrchr(path, '/');
-               *p = '\0';
-               if (!MakeDirectory(path, true)) {
-                   syslog(L_ERROR, "timecaf: could not make directory %s %m", path);
-                   token.type = TOKEN_EMPTY;
-                   free(path);
-                   SMseterror(SMERR_UNDEFINED, NULL);
-                   return token;
-               } else {
-                   *p = '/';
-                   fd = CAFOpenArtWrite(path, &art, true, article.len);
-                   if (fd < 0) {
-                       syslog(L_ERROR, "timecaf: could not OpenArtWrite %s/%ld, %s", path, art, CAFErrorStr());
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       free(path);
-                       token.type = TOKEN_EMPTY;
-                       return token;
-                   }
-               } 
-           } else {
-               syslog(L_ERROR, "timecaf: could not OpenArtWrite %s/%ld, %s", path, art, CAFErrorStr());
-               SMseterror(SMERR_UNDEFINED, NULL);
-               free(path);
-               token.type = TOKEN_EMPTY;
-               return token;
-           }
-       }
-    } else {
-       /* can reuse existing fd, assuming all goes well. */
-       fd = WritingFile.fd;
-
-       /* nuke extraneous copy of path to avoid mem leaks. */
-       free(path);
-       path = WritingFile.path;
-
-       if (CAFStartWriteFd(fd, &art, article.len) < 0) {
-           syslog(L_ERROR, "timecaf: could not OpenArtWrite %s/%ld, %s", path, art, CAFErrorStr());
-           SMseterror(SMERR_UNDEFINED, NULL);
-           free(path);
-           token.type = TOKEN_EMPTY;
-           return token;
-       }
-    }
-    WritingFile.fd = fd;
-    WritingFile.path = path;
-    close_on_exec(fd, true);
-    result = xwritev(fd, article.iov, article.iovcnt);
-    if (result != (ssize_t) article.len) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "timecaf error writing %s %m", path);
-       token.type = TOKEN_EMPTY;
-       CloseOpenFile(&WritingFile);
-       return token;
-    }
-    if (CAFFinishArtWrite(fd) < 0) { 
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "timecaf error writing %s %s", path, CAFErrorStr());
-       token.type = TOKEN_EMPTY;
-       CloseOpenFile(&WritingFile);
-       return token;
-    }
-    
-    return MakeToken(timestamp, art, class, article.token);
-}
-
-/* Get a handle to article artnum in CAF-file path. */
-static ARTHANDLE *OpenArticle(const char *path, ARTNUM artnum, const RETRTYPE amount) {
-    int                 fd;
-    PRIV_TIMECAF        *private;
-    char                *p;
-    size_t             len;
-    ARTHANDLE           *art;
-    static long                pagesize = 0;
-
-    if (pagesize == 0) {
-        pagesize = getpagesize();
-        if (pagesize < 0) {
-           syslog(L_ERROR, "timecaf getpagesize failed: %m");
-            pagesize = 0;
-           return NULL;
-        }
-    }
-
-/* XXX need to figure some way to cache open fds or something? */
-    if ((fd = CAFOpenArtRead((char *)path, artnum, &len)) < 0) {
-        if (caf_error == CAF_ERR_ARTNOTHERE) {
-           SMseterror(SMERR_NOENT, NULL);
-       } else {
-           SMseterror(SMERR_UNDEFINED, NULL);
-       }
-       return NULL;
-    }
-
-    art = xmalloc(sizeof(ARTHANDLE));
-    art->type = TOKEN_TIMECAF;
-
-    if (amount == RETR_STAT) {
-       art->data = NULL;
-       art->len = 0;
-       art->private = NULL;
-       close(fd);
-       return art;
-    }
-
-    private = xmalloc(sizeof(PRIV_TIMECAF));
-    art->private = (void *)private;
-    private->artlen = len;
-    if (innconf->articlemmap) {
-       off_t curoff, tmpoff;
-       size_t delta;
-
-       curoff = lseek(fd, (off_t) 0, SEEK_CUR);
-       delta = curoff % pagesize;
-       tmpoff = curoff - delta;
-       private->mmaplen = len + delta;
-       if ((private->mmapbase = mmap(NULL, private->mmaplen, PROT_READ, MAP_SHARED, fd, tmpoff)) == MAP_FAILED) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "timecaf: could not mmap article: %m");
-           free(art->private);
-           free(art);
-           return NULL;
-       }
-       mmap_invalidate(private->mmapbase, private->mmaplen);
-        if (amount == RETR_ALL)
-            madvise(private->mmapbase, private->mmaplen, MADV_WILLNEED);
-        else
-            madvise(private->mmapbase, private->mmaplen, MADV_SEQUENTIAL);
-       private->artdata = private->mmapbase + delta;
-    } else {
-        private->artdata = xmalloc(private->artlen);
-       if (read(fd, private->artdata, private->artlen) < 0) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "timecaf: could not read article: %m");
-           free(private->artdata);
-           free(art->private);
-           free(art);
-           return NULL;
-       }
-    }
-    close(fd);
-
-    private->top = NULL;
-    private->sec = NULL;
-    private->ter = NULL;
-    private->curtoc = NULL;
-    private->curartnum = 0;
-    private->topde = NULL;
-    private->secde = NULL;
-    private->terde = NULL;
-    
-    if (amount == RETR_ALL) {
-       art->data = private->artdata;
-       art->len = private->artlen;
-       return art;
-    }
-    
-    if ((p = wire_findbody(private->artdata, private->artlen)) == NULL) {
-       SMseterror(SMERR_NOBODY, NULL);
-       if (innconf->articlemmap)
-           munmap(private->mmapbase, private->mmaplen);
-       else
-           free(private->artdata);
-       free(art->private);
-       free(art);
-       return NULL;
-    }
-
-    if (amount == RETR_HEAD) {
-       art->data = private->artdata;
-       art->len = p - private->artdata;
-       return art;
-    }
-
-    if (amount == RETR_BODY) {
-       art->data = p + 4;
-       art->len = art->len - (private->artdata - p - 4);
-       return art;
-    }
-    SMseterror(SMERR_UNDEFINED, "Invalid retrieve request");
-    if (innconf->articlemmap)
-       munmap(private->mmapbase, private->mmaplen);
-    else
-       free(private->artdata);
-    free(art->private);
-    free(art);
-    return NULL;
-}
-
-ARTHANDLE *timecaf_retrieve(const TOKEN token, const RETRTYPE amount) {
-    int                 timestamp;
-    int                        artnum;
-    char                *path;
-    ARTHANDLE           *art;
-    static TOKEN       ret_token;
-    time_t             now;
-    
-    if (token.type != TOKEN_TIMECAF) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return NULL;
-    }
-
-    BreakToken(token, &timestamp, &artnum);
-
-    /*
-    ** Do a possible shortcut on RETR_STAT requests, going thru the "TOC cache"
-    ** we mentioned above.  We only try to go thru the TOC Cache under these
-    ** conditions:
-    **   1) SMpreopen is true (so we're "preopening" the TOCs.)
-    **   2) the timestamp is older than the timestamp corresponding to current
-    ** time. Any timestamp that matches current time (to within 256 secondsf
-    ** would be in a CAF file that innd is actively 
-    ** writing, in which case we would not want to cache the TOC for that
-    ** CAF file. 
-    */
-
-    if (SMpreopen && amount == RETR_STAT) {
-       now = time(NULL);
-       if (timestamp < ((now >> 8) & 0xffffff)) {
-           return StatArticle(timestamp, artnum, token.class);
-       }
-    }
-
-    path = MakePath(timestamp, token.class);
-    if ((art = OpenArticle(path, artnum, amount)) != (ARTHANDLE *)NULL) {
-       art->arrived = timestamp<<8; /* XXX not quite accurate arrival time,
-                                    ** but getting a more accurate one would 
-                                    ** require more fiddling with CAF innards.
-                                    */
-       ret_token = token;
-       art->token = &ret_token;
-    }
-    free(path);
-    return art;
-}
-
-void timecaf_freearticle(ARTHANDLE *article) {
-    PRIV_TIMECAF       *private;
-
-    if (!article)
-       return;
-    
-    if (article->private) {
-       private = (PRIV_TIMECAF *)article->private;
-       if (innconf->articlemmap)
-           munmap(private->mmapbase, private->mmaplen);
-       else
-           free(private->artdata);
-       if (private->top)
-           closedir(private->top);
-       if (private->sec)
-           closedir(private->sec);
-       if (private->ter)
-           closedir(private->ter);
-       if (private->curtoc) 
-           free(private->curtoc);
-       free(private);
-    }
-    free(article);
-}
-
-/* Do cancels of all the article ids collected for a given pathname. */
-
-static void
-DoCancels(void) {
-    if (DeletePath != NULL) {
-       if (NumDeleteArtnums != 0) {
-           /* 
-           ** Murgle. If we are trying to cancel something out of the
-           ** currently open-for-writing file, we need to close it before
-           ** doing CAFRemove...
-           */
-           if (WritingFile.path != NULL && strcmp(WritingFile.path, DeletePath) == 0) {
-               CloseOpenFile(&WritingFile);
-           }
-           /* XXX should really check err. code here, but not much we can really do. */
-           CAFRemoveMultArts(DeletePath, NumDeleteArtnums, DeleteArtnums);
-           free(DeleteArtnums);
-           DeleteArtnums = NULL;
-           NumDeleteArtnums = MaxDeleteArtnums = 0;
-       }
-       free(DeletePath);
-       DeletePath = NULL;
-    }
-}
-           
-bool timecaf_cancel(TOKEN token) {
-    int                 now;
-    int                 seqnum;
-    char                *path;
-
-    BreakToken(token, &now, &seqnum);
-    path = MakePath(now, token.class);
-    if (DeletePath == NULL) {
-       DeletePath = path;
-    } else if (strcmp(DeletePath, path) != 0) {
-       /* different path, so flush all pending cancels. */
-       DoCancels();
-       DeletePath = path;
-    } else {
-       free(path); /* free redundant copy of path */
-    }
-    if (NumDeleteArtnums >= MaxDeleteArtnums) {
-       /* allocate/expand storage for artnums. */
-       if (MaxDeleteArtnums == 0) {
-           MaxDeleteArtnums = 100;
-       } else {
-           MaxDeleteArtnums *= 2;
-       }
-        DeleteArtnums = xrealloc(DeleteArtnums, MaxDeleteArtnums * sizeof(ARTNUM));
-    }
-    DeleteArtnums[NumDeleteArtnums++] = seqnum;        
-
-    return true;
-}
-
-static struct dirent *FindDir(DIR *dir, FINDTYPE type) {
-    struct dirent       *de;
-    
-    while ((de = readdir(dir)) != NULL) {
-        if (type == FIND_TOPDIR)
-           if ((strlen(de->d_name) == 10) &&
-               (strncmp(de->d_name, "timecaf-", 8) == 0) &&
-               CTYPE(isxdigit, de->d_name[8]) &&
-               CTYPE(isxdigit, de->d_name[9]))
-               return de;
-
-       if (type == FIND_DIR)
-           if ((strlen(de->d_name) == 2)
-                && CTYPE(isxdigit, de->d_name[0])
-                && CTYPE(isxdigit, de->d_name[1]))
-               return de;
-
-       if (type == FIND_CAF)
-           if ((strlen(de->d_name) == 7) &&
-               CTYPE(isxdigit, de->d_name[0]) &&
-               CTYPE(isxdigit, de->d_name[1]) &&
-               CTYPE(isxdigit, de->d_name[2]) &&
-               CTYPE(isxdigit, de->d_name[3]) &&
-               (de->d_name[4] == '.') &&
-               (de->d_name[5] == 'C') &&
-               (de->d_name[6] == 'F'))
-               return de;
-       }
-
-    return NULL;
-}
-
-/* Grovel thru a CAF table-of-contents finding the next still-existing article */
-static int
-FindNextArt(const CAFHEADER *head, CAFTOCENT *toc, ARTNUM *artp)
-{
-    ARTNUM art;
-    CAFTOCENT *tocp;
-    art = *artp;
-    if (art == 0) {
-       art = head->Low - 1; /* we never use art # 0, so 0 is a flag to start
-                              searching at the beginning */
-    }
-    while (true) {
-       art++;
-       if (art > head->High) return false; /* ran off the end of the TOC */
-       tocp = &toc[art - head->Low];
-       if (tocp->Size != 0) {
-           /* got a valid article */
-           *artp = art;
-           return true;
-       }
-    }
-}
-
-
-
-ARTHANDLE *timecaf_next(const ARTHANDLE *article, const RETRTYPE amount) {
-    PRIV_TIMECAF       priv, *newpriv;
-    char                *path;
-    ARTHANDLE           *art;
-    size_t              length;
-
-    length = strlen(innconf->patharticles) + 32;
-    path = xmalloc(length);
-    if (article == NULL) {
-       priv.top = NULL;
-       priv.sec = NULL;
-       priv.ter = NULL;
-       priv.curtoc = NULL;
-       priv.topde = NULL;
-       priv.secde = NULL;
-       priv.terde = NULL;
-    } else {
-       priv = *(PRIV_TIMECAF *)article->private;
-       free(article->private);
-       free((void *)article);
-       if (innconf->articlemmap)
-           munmap(priv.mmapbase, priv.mmaplen);
-       else
-           free(priv.artdata);
-    }
-
-    while (priv.curtoc == NULL || !FindNextArt(&priv.curheader, priv.curtoc, &priv.curartnum)) {
-       if (priv.curtoc) {
-           free(priv.curtoc);
-           priv.curtoc = NULL;
-       }
-       while (!priv.ter || ((priv.terde = FindDir(priv.ter, FIND_CAF)) == NULL)) {
-           if (priv.ter) {
-               closedir(priv.ter);
-               priv.ter = NULL;
-           }
-           while (!priv.sec || ((priv.secde = FindDir(priv.sec, FIND_DIR)) == NULL)) {
-               if (priv.sec) {
-                   closedir(priv.sec);
-                   priv.sec = NULL;
-               }
-               if (!priv.top || ((priv.topde = FindDir(priv.top, FIND_TOPDIR)) == NULL)) {
-                   if (priv.top) {
-                       /* end of search */
-                       closedir(priv.top);
-                       priv.top = NULL;
-                       free(path);
-                       return NULL;
-                   }
-                   snprintf(path, length, "%s", innconf->patharticles);
-                   if ((priv.top = opendir(path)) == NULL) {
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       free(path);
-                       return NULL;
-                   }
-                   if ((priv.topde = FindDir(priv.top, FIND_TOPDIR)) == NULL) {
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       closedir(priv.top);
-                       free(path);
-                       return NULL;
-                   }
-               }
-               snprintf(path, length, "%s/%s", innconf->patharticles, priv.topde->d_name);
-               if ((priv.sec = opendir(path)) == NULL)
-                   continue;
-           }
-           snprintf(path, length, "%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name);
-           if ((priv.ter = opendir(path)) == NULL)
-               continue;
-       }
-       snprintf(path, length, "%s/%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name, priv.terde->d_name);
-       if ((priv.curtoc = CAFReadTOC(path, &priv.curheader)) == NULL)
-           continue;
-       priv.curartnum = 0;
-    }
-    snprintf(path, length, "%s/%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name, priv.terde->d_name);
-    art = OpenArticle(path, priv.curartnum, amount);
-    if (art == (ARTHANDLE *)NULL) {
-       art = xmalloc(sizeof(ARTHANDLE));
-       art->type = TOKEN_TIMECAF;
-       art->data = NULL;
-       art->len = 0;
-       art->private = xmalloc(sizeof(PRIV_TIMECAF));
-    }
-    newpriv = (PRIV_TIMECAF *)art->private;
-    newpriv->top = priv.top;
-    newpriv->sec = priv.sec;
-    newpriv->ter = priv.ter;
-    newpriv->topde = priv.topde;
-    newpriv->secde = priv.secde;
-    newpriv->terde = priv.terde;
-    newpriv->curheader = priv.curheader;
-    newpriv->curtoc = priv.curtoc;
-    newpriv->curartnum = priv.curartnum;
-    
-    snprintf(path, length, "%s/%s/%s", priv.topde->d_name, priv.secde->d_name, priv.terde->d_name);
-    art->token = PathNumToToken(path, priv.curartnum);
-    art->arrived = priv.curtoc[priv.curartnum - priv.curheader.Low].ModTime;
-    free(path);
-    return art;
-}
-
-bool timecaf_ctl(PROBETYPE type, TOKEN *token UNUSED, void *value) {
-    struct artngnum *ann;
-
-    switch (type) {
-    case SMARTNGNUM:
-       if ((ann = (struct artngnum *)value) == NULL)
-           return false;
-       /* make SMprobe() call timecaf_retrieve() */
-       ann->artnum = 0;
-       return true;
-    default:
-       return false;
-    }
-}
-
-bool timecaf_flushcacheddata(FLUSHTYPE type) {
-    if (type == SM_ALL || type == SM_CANCELEDART)
-       DoCancels();
-    return true;
-}
-
-void
-timecaf_printfiles(FILE *file, TOKEN token, char **xref UNUSED,
-                   int ngroups UNUSED)
-{
-    fprintf(file, "%s\n", TokenToText(token));
-}
-
-void timecaf_shutdown(void) {
-    CloseOpenFile(&WritingFile);
-    DoCancels();
-}
diff --git a/storage/timecaf/timecaf.h b/storage/timecaf/timecaf.h
deleted file mode 100644 (file)
index fd2dd34..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*  $Id: timecaf.h 4266 2001-01-04 06:01:36Z rra $
-**
-**  timecaf -- like the timehash storage method (and heavily inspired
-**  by it), but uses the CAF library to store multiple articles in a
-**  single file. 
-*/
-
-#ifndef __TIMECAF_H__
-#define __TIMECAF_H__
-
-#include "config.h"
-#include "interface.h"
-
-bool timecaf_init(SMATTRIBUTE *attr);
-TOKEN timecaf_store(const ARTHANDLE article, const STORAGECLASS class);
-ARTHANDLE *timecaf_retrieve(const TOKEN token, const RETRTYPE amount);
-ARTHANDLE *timecaf_next(const ARTHANDLE *article, const RETRTYPE amount);
-void timecaf_freearticle(ARTHANDLE *article);
-bool timecaf_cancel(TOKEN token);
-bool timecaf_ctl(PROBETYPE type, TOKEN *token, void *value);
-bool timecaf_flushcacheddata(FLUSHTYPE type);
-void timecaf_printfiles(FILE *file, TOKEN token, char **xref, int ngroups);
-void timecaf_shutdown(void);
-
-#endif
diff --git a/storage/timehash/method.config b/storage/timehash/method.config
deleted file mode 100644 (file)
index c4654bd..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = timehash
-number  = 2
-sources = timehash.c
diff --git a/storage/timehash/timehash.c b/storage/timehash/timehash.c
deleted file mode 100644 (file)
index 82c5942..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/*  $Id: timehash.c 7412 2005-10-09 03:44:35Z eagle $
-**
-**  Timehash based storage method.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "inn/innconf.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "methods.h"
-#include "paths.h"
-#include "timehash.h"
-
-typedef struct {
-    char                *base;    /* Base of the mmaped file */
-    int                 len;      /* Length of the file */
-    DIR                 *top;     /* Open handle on the top level directory */
-    DIR                 *sec;     /* Open handle on the 2nd level directory */
-    DIR                        *ter;     /* Open handle on the third level directory */
-    DIR                 *artdir;  /* Open handle on the article directory */
-    struct dirent       *topde;   /* dirent entry for the last entry retrieved in top */
-    struct dirent       *secde;   /* dirent entry for the last entry retrieved in sec */
-    struct dirent       *terde;   /* dirent entry for the last entry retrieved in ter */
-} PRIV_TIMEHASH;
-
-typedef enum {FIND_DIR, FIND_ART, FIND_TOPDIR} FINDTYPE;
-
-static int SeqNum = 0;
-
-static TOKEN MakeToken(time_t now, int seqnum, STORAGECLASS class, TOKEN *oldtoken) {
-    TOKEN               token;
-    unsigned int        i;
-    unsigned short      s;
-
-    if (oldtoken == (TOKEN *)NULL)
-       memset(&token, '\0', sizeof(token));
-    else 
-       memcpy(&token, oldtoken, sizeof(token));
-    token.type = TOKEN_TIMEHASH;
-    token.class = class;
-    i = htonl(now);
-    memcpy(token.token, &i, sizeof(i));
-    if (sizeof(i) > 4)
-       memmove(token.token, &token.token[sizeof(i) - 4], 4);
-    s = htons(seqnum);
-    memcpy(&token.token[4], &s + (sizeof(s) - 2), 2);
-    return token;
-}
-
-static void BreakToken(TOKEN token, int *now, int *seqnum) {
-    unsigned int        i;
-    unsigned short      s = 0;
-
-    memcpy(&i, token.token, sizeof(i));
-    memcpy(&s, &token.token[4], sizeof(s));
-    *now = ntohl(i);
-    *seqnum = (int)ntohs(s);
-}
-
-static char *MakePath(int now, int seqnum, const STORAGECLASS class) {
-    char *path;
-    size_t length;
-    
-    /* innconf->patharticles + '/time-zz/xx/xx/yyyy-xxxx' */
-    length = strlen(innconf->patharticles) + 32;
-    path = xmalloc(length);
-    snprintf(path, length, "%s/time-%02x/%02x/%02x/%04x-%04x",
-             innconf->patharticles, class,
-             (now >> 16) & 0xff, (now >> 8) & 0xff, seqnum,
-             (now & 0xff) | ((now >> 16 & 0xff00)));
-    return path;
-}
-
-static TOKEN *PathToToken(char *path) {
-    int                        n;
-    unsigned int       t1, t2, t3, seqnum, class;
-    time_t             now;
-    static TOKEN       token;
-
-    n = sscanf(path, "time-%02x/%02x/%02x/%04x-%04x", &class, &t1, &t2, &seqnum, &t3);
-    if (n != 5)
-       return (TOKEN *)NULL;
-    now = ((t1 << 16) & 0xff0000) | ((t2 << 8) & 0xff00) | ((t3 << 16) & 0xff000000) | (t3 & 0xff);
-    token = MakeToken(now, seqnum, class, (TOKEN *)NULL);
-    return &token;
-}
-
-bool timehash_init(SMATTRIBUTE *attr) {
-    if (attr == NULL) {
-       syslog(L_ERROR, "timehash: attr is NULL");
-       SMseterror(SMERR_INTERNAL, "attr is NULL");
-       return false;
-    }
-    attr->selfexpire = false;
-    attr->expensivestat = true;
-    if (STORAGE_TOKEN_LENGTH < 6) {
-       syslog(L_FATAL, "timehash: token length is less than 6 bytes");
-       SMseterror(SMERR_TOKENSHORT, NULL);
-       return false;
-    }
-    return true;
-}
-
-TOKEN timehash_store(const ARTHANDLE article, const STORAGECLASS class) {
-    char                *path;
-    char                *p;
-    time_t              now;
-    TOKEN               token;
-    int                 fd;
-    ssize_t             result;
-    int                 seq;
-    int                 i;
-
-    if (article.arrived == (time_t)0)
-       now = time(NULL);
-    else
-       now = article.arrived;
-
-    for (i = 0; i < 0x10000; i++) {
-       seq = SeqNum;
-       SeqNum = (SeqNum + 1) & 0xffff;
-       path = MakePath(now, seq, class);
-
-        if ((fd = open(path, O_CREAT|O_EXCL|O_WRONLY, ARTFILE_MODE)) < 0) {
-           if (errno == EEXIST)
-               continue;
-           p = strrchr(path, '/');
-           *p = '\0';
-           if (!MakeDirectory(path, true)) {
-               syslog(L_ERROR, "timehash: could not make directory %s %m", path);
-               token.type = TOKEN_EMPTY;
-               free(path);
-               SMseterror(SMERR_UNDEFINED, NULL);
-               return token;
-           } else {
-               *p = '/';
-               if ((fd = open(path, O_CREAT|O_EXCL|O_WRONLY, ARTFILE_MODE)) < 0) {
-                   SMseterror(SMERR_UNDEFINED, NULL);
-                   syslog(L_ERROR, "timehash: could not open %s %m", path);
-                   token.type = TOKEN_EMPTY;
-                   free(path);
-                   return token;
-               }
-           }
-        }
-       break;
-    }
-    if (i == 0x10000) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "timehash: all sequence numbers for the time and class are reserved %lu %d", (unsigned long)now, class);
-       token.type = TOKEN_EMPTY;
-       free(path);
-       return token;
-    }
-
-    result = xwritev(fd, article.iov, article.iovcnt);
-    if (result != (ssize_t) article.len) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "timehash error writing %s %m", path);
-       close(fd);
-       token.type = TOKEN_EMPTY;
-       unlink(path);
-       free(path);
-       return token;
-    }
-    close(fd);
-    free(path);
-    return MakeToken(now, seq, class, article.token);
-}
-
-static ARTHANDLE *OpenArticle(const char *path, RETRTYPE amount) {
-    int                 fd;
-    PRIV_TIMEHASH       *private;
-    char                *p;
-    struct stat         sb;
-    ARTHANDLE           *art;
-
-    if (amount == RETR_STAT) {
-        if (access(path, R_OK) < 0) {
-            SMseterror(SMERR_UNDEFINED, NULL);
-            return NULL;
-        }
-        art = xmalloc(sizeof(ARTHANDLE));
-        art->type = TOKEN_TIMEHASH;
-       art->data = NULL;
-       art->len = 0;
-       art->private = NULL;
-       return art;
-    }
-
-    if ((fd = open(path, O_RDONLY)) < 0) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       return NULL;
-    }
-
-    art = xmalloc(sizeof(ARTHANDLE));
-    art->type = TOKEN_TIMEHASH;
-
-    if (fstat(fd, &sb) < 0) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "timehash: could not fstat article: %m");
-       free(art);
-       return NULL;
-    }
-    
-    private = xmalloc(sizeof(PRIV_TIMEHASH));
-    art->private = (void *)private;
-    private->len = sb.st_size;
-    if (innconf->articlemmap) {
-       if ((private->base = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "timehash: could not mmap article: %m");
-           free(art->private);
-           free(art);
-           return NULL;
-       }
-        if (amount == RETR_ALL)
-            madvise(private->base, sb.st_size, MADV_WILLNEED);
-        else
-            madvise(private->base, sb.st_size, MADV_SEQUENTIAL);
-    } else {
-       private->base = xmalloc(private->len);
-       if (read(fd, private->base, private->len) < 0) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "timehash: could not read article: %m");
-           free(private->base);
-           free(art->private);
-           free(art);
-           return NULL;
-       }
-    }
-    close(fd);
-
-    private->top = NULL;
-    private->sec = NULL;
-    private->ter = NULL;
-    private->artdir = NULL;
-    private->topde = NULL;
-    private->secde = NULL;
-    private->terde = NULL;
-    
-    if (amount == RETR_ALL) {
-       art->data = private->base;
-       art->len = private->len;
-       return art;
-    }
-    
-    if ((p = wire_findbody(private->base, private->len)) == NULL) {
-       SMseterror(SMERR_NOBODY, NULL);
-       if (innconf->articlemmap)
-           munmap(private->base, private->len);
-       else
-           free(private->base);
-       free(art->private);
-       free(art);
-       return NULL;
-    }
-
-    if (amount == RETR_HEAD) {
-       art->data = private->base;
-       art->len = p - private->base;
-       return art;
-    }
-
-    if (amount == RETR_BODY) {
-       art->data = p;
-       art->len = private->len - (p - private->base);
-       return art;
-    }
-    SMseterror(SMERR_UNDEFINED, "Invalid retrieve request");
-    if (innconf->articlemmap)
-       munmap(private->base, private->len);
-    else
-       free(private->base);
-    free(art->private);
-    free(art);
-    return NULL;
-}
-
-ARTHANDLE *timehash_retrieve(const TOKEN token, const RETRTYPE amount) {
-    int                 now;
-    int                 seqnum;
-    char                *path;
-    ARTHANDLE           *art;
-    static TOKEN       ret_token;
-    
-    if (token.type != TOKEN_TIMEHASH) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return NULL;
-    }
-
-    BreakToken(token, &now, &seqnum);
-    path = MakePath(now, seqnum, token.class);
-    if ((art = OpenArticle(path, amount)) != (ARTHANDLE *)NULL) {
-       art->arrived = now;
-       ret_token = token;
-       art->token = &ret_token;
-    }
-    free(path);
-    return art;
-}
-
-void timehash_freearticle(ARTHANDLE *article) {
-    PRIV_TIMEHASH       *private;
-
-    if (!article)
-       return;
-    
-    if (article->private) {
-       private = (PRIV_TIMEHASH *)article->private;
-       if (innconf->articlemmap)
-           munmap(private->base, private->len);
-       else
-           free(private->base);
-       if (private->top)
-           closedir(private->top);
-       if (private->sec)
-           closedir(private->sec);
-       if (private->ter)
-           closedir(private->ter);
-       if (private->artdir)
-           closedir(private->artdir);
-       free(private);
-    }
-    free(article);
-}
-
-bool timehash_cancel(TOKEN token) {
-    int                 now;
-    int                 seqnum;
-    char                *path;
-    int                 result;
-
-    BreakToken(token, &now, &seqnum);
-    path = MakePath(now, seqnum, token.class);
-    result = unlink(path);
-    free(path);
-    if (result < 0) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       return false;
-    }
-    return true;
-}
-
-static struct dirent *FindDir(DIR *dir, FINDTYPE type) {
-    struct dirent       *de;
-    
-    while ((de = readdir(dir)) != NULL) {
-        if (type == FIND_TOPDIR)
-           if ((strlen(de->d_name) == 7) &&
-               (strncmp(de->d_name, "time-", 5) == 0) &&
-               isxdigit((int)de->d_name[5]) &&
-               isxdigit((int)de->d_name[6]))
-               return de;
-
-       if (type == FIND_DIR)
-           if ((strlen(de->d_name) == 2) && isxdigit((int)de->d_name[0]) && isxdigit((int)de->d_name[1]))
-               return de;
-
-       if (type == FIND_ART)
-           if ((strlen(de->d_name) == 9) &&
-               isxdigit((int)de->d_name[0]) &&
-               isxdigit((int)de->d_name[1]) &&
-               isxdigit((int)de->d_name[2]) &&
-               isxdigit((int)de->d_name[3]) &&
-               isxdigit((int)de->d_name[5]) &&
-               isxdigit((int)de->d_name[6]) &&
-               isxdigit((int)de->d_name[7]) &&
-               isxdigit((int)de->d_name[8]) &&
-               (de->d_name[4] == '-'))
-               return de;
-       }
-
-    return NULL;
-}
-
-ARTHANDLE *timehash_next(const ARTHANDLE *article, const RETRTYPE amount) {
-    PRIV_TIMEHASH       priv;
-    PRIV_TIMEHASH       *newpriv;
-    char                *path;
-    struct dirent       *de;
-    ARTHANDLE           *art;
-    int                 seqnum;
-    size_t              length;
-
-    length = strlen(innconf->patharticles) + 32;
-    path = xmalloc(length);
-    if (article == NULL) {
-       priv.top = NULL;
-       priv.sec = NULL;
-       priv.ter = NULL;
-       priv.artdir = NULL;
-       priv.topde = NULL;
-       priv.secde = NULL;
-       priv.terde = NULL;
-    } else {
-       priv = *(PRIV_TIMEHASH *)article->private;
-       free(article->private);
-       free((void *)article);
-       if (priv.base != NULL) {
-           if (innconf->articlemmap)
-               munmap(priv.base, priv.len);
-           else
-               free(priv.base);
-       }
-    }
-
-    while (!priv.artdir || ((de = FindDir(priv.artdir, FIND_ART)) == NULL)) {
-       if (priv.artdir) {
-           closedir(priv.artdir);
-           priv.artdir = NULL;
-       }
-       while (!priv.ter || ((priv.terde = FindDir(priv.ter, FIND_DIR)) == NULL)) {
-           if (priv.ter) {
-               closedir(priv.ter);
-               priv.ter = NULL;
-           }
-           while (!priv.sec || ((priv.secde = FindDir(priv.sec, FIND_DIR)) == NULL)) {
-               if (priv.sec) {
-                   closedir(priv.sec);
-                   priv.sec = NULL;
-               }
-               if (!priv.top || ((priv.topde = FindDir(priv.top, FIND_TOPDIR)) == NULL)) {
-                   if (priv.top) {
-                       /* end of search */
-                       closedir(priv.top);
-                       priv.top = NULL;
-                       free(path);
-                       return NULL;
-                   }
-                   snprintf(path, length, "%s", innconf->patharticles);
-                   if ((priv.top = opendir(path)) == NULL) {
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       free(path);
-                       return NULL;
-                   }
-                   if ((priv.topde = FindDir(priv.top, FIND_TOPDIR)) == NULL) {
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       closedir(priv.top);
-                       free(path);
-                       return NULL;
-                   }
-               }
-               snprintf(path, length, "%s/%s", innconf->patharticles, priv.topde->d_name);
-               if ((priv.sec = opendir(path)) == NULL)
-                   continue;
-           }
-           snprintf(path, length, "%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name);
-           if ((priv.ter = opendir(path)) == NULL)
-               continue;
-       }
-       snprintf(path, length, "%s/%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name, priv.terde->d_name);
-       if ((priv.artdir = opendir(path)) == NULL)
-           continue;
-    }
-    if (de == NULL)
-       return NULL;
-    snprintf(path, length, "%s/%s/%s/%s/%s", innconf->patharticles, priv.topde->d_name, priv.secde->d_name, priv.terde->d_name, de->d_name);
-
-    art = OpenArticle(path, amount);
-    if (art == (ARTHANDLE *)NULL) {
-       art = xmalloc(sizeof(ARTHANDLE));
-       art->type = TOKEN_TIMEHASH;
-       art->data = NULL;
-       art->len = 0;
-       art->private = xmalloc(sizeof(PRIV_TIMEHASH));
-       newpriv = (PRIV_TIMEHASH *)art->private;
-       newpriv->base = NULL;
-    }
-    newpriv = (PRIV_TIMEHASH *)art->private;
-    newpriv->top = priv.top;
-    newpriv->sec = priv.sec;
-    newpriv->ter = priv.ter;
-    newpriv->artdir = priv.artdir;
-    newpriv->topde = priv.topde;
-    newpriv->secde = priv.secde;
-    newpriv->terde = priv.terde;
-    snprintf(path, length, "%s/%s/%s/%s", priv.topde->d_name, priv.secde->d_name, priv.terde->d_name, de->d_name);
-    art->token = PathToToken(path);
-    BreakToken(*art->token, (int *)&(art->arrived), &seqnum);
-    free(path);
-    return art;
-}
-
-bool timehash_ctl(PROBETYPE type, TOKEN *token UNUSED, void *value) {
-    struct artngnum *ann;
-
-    switch (type) {
-    case SMARTNGNUM:
-       if ((ann = (struct artngnum *)value) == NULL)
-           return false;
-       /* make SMprobe() call timehash_retrieve() */
-       ann->artnum = 0;
-       return true;
-    default:
-       return false;
-    }
-}
-
-bool
-timehash_flushcacheddata(FLUSHTYPE type UNUSED)
-{
-    return true;
-}
-
-void
-timehash_printfiles(FILE *file, TOKEN token, char **xref UNUSED,
-                    int ngroups UNUSED)
-{
-    int now, seqnum;
-    char *path;
-    
-    BreakToken(token, &now, &seqnum);
-    path = MakePath(now, seqnum, token.class);
-    fprintf(file, "%s\n", path);
-}
-
-void timehash_shutdown(void) {
-}
diff --git a/storage/timehash/timehash.h b/storage/timehash/timehash.h
deleted file mode 100644 (file)
index dc2e246..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*  $Id: timehash.h 4268 2001-01-04 06:02:50Z rra $
-**
-**  timehash based storing method header
-*/
-
-#ifndef __TIMEHASH_H__
-#define __TIMEHASH_H__
-
-#include "config.h"
-#include "interface.h"
-
-bool timehash_init(SMATTRIBUTE *attr);
-TOKEN timehash_store(const ARTHANDLE article, const STORAGECLASS class);
-ARTHANDLE *timehash_retrieve(const TOKEN token, const RETRTYPE amount);
-ARTHANDLE *timehash_next(const ARTHANDLE *article, const RETRTYPE amount);
-void timehash_freearticle(ARTHANDLE *article);
-bool timehash_cancel(TOKEN token);
-bool timehash_ctl(PROBETYPE type, TOKEN *token, void *value);
-bool timehash_flushcacheddata(FLUSHTYPE type);
-void timehash_printfiles(FILE *file, TOKEN token, char **xref, int ngroups);
-void timehash_shutdown(void);
-
-#endif
diff --git a/storage/tradindexed/ovmethod.config b/storage/tradindexed/ovmethod.config
deleted file mode 100644 (file)
index ec9f310..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-name          = tradindexed
-number        = 2
-sources       = tdx-cache.c tdx-group.c tdx-data.c tradindexed.c
-extra-sources = tdx-util.c
-programs      = tdx-util
diff --git a/storage/tradindexed/ovmethod.mk b/storage/tradindexed/ovmethod.mk
deleted file mode 100644 (file)
index 8038de4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-tradindexed/tdx-util.o: tradindexed/tdx-util.c
-       $(CC) $(CFLAGS) -c -o $@ tradindexed/tdx-util.c
-
-tradindexed/tdx-util: tradindexed/tdx-util.o libstorage.$(EXTLIB) $(LIBHIST)
-       $(LIBLD) $(LDFLAGS) -o $@ tradindexed/tdx-util.o \
-           $(LIBSTORAGE) $(LIBHIST) $(LIBINN) $(EXTSTORAGELIBS) $(LIBS)
diff --git a/storage/tradindexed/tdx-cache.c b/storage/tradindexed/tdx-cache.c
deleted file mode 100644 (file)
index 93abee6..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*  $Id: tdx-cache.c 5394 2002-04-04 22:55:24Z rra $
-**
-**  Cache functions for open overview data files.
-**
-**  This code maintains a cache of open overview data files to avoid some of
-**  the overhead involved in closing and reopening files.  All opens and
-**  closes should go through this code, and the hit ratio is tracked to check
-**  cache effectiveness.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <time.h>
-
-#include "inn/hashtab.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "storage.h"
-#include "tdx-private.h"
-
-/* Returned to callers as an opaque data type, this struct holds all of the
-   information about the cache. */
-struct cache {
-    struct hash *hashtable;
-    unsigned int count;
-    unsigned int max;
-    unsigned long queries;
-    unsigned long hits;
-};
-
-/* A cache entry, holding a group_data struct and some additional information
-   used to do cache lookups and to choose what to drop from the cache. */
-struct cache_entry {
-    struct group_data *data;
-    HASH hash;
-    time_t lastused;
-};
-
-
-/*
-**  The hash function for a cache_entry.  Just return as much of the group
-**  hash as can fit in an unsigned long.
-*/
-static unsigned long
-entry_hash(const void *key)
-{
-    const HASH *hash = key;
-    unsigned long bucket;
-
-    memcpy(&bucket, hash, sizeof(bucket));
-    return bucket;
-}
-
-
-/*
-**  Given a cache_entry, return its key.
-*/
-static const void *
-entry_key(const void *data)
-{
-    const struct cache_entry *entry = (const struct cache_entry *) data;
-
-    return &entry->hash;
-}
-
-
-/*
-**  Check to see if two entries are equal.
-*/
-static bool
-entry_equal(const void *key, const void *data)
-{
-    const HASH *hash = (const HASH *) key;
-    const struct cache_entry *entry = (const struct cache_entry *) data;
-
-    return (memcmp(hash, &entry->hash, sizeof(HASH)) == 0);
-}
-
-
-/*
-**  Free a cache entry.
-*/
-static void
-entry_delete(void *data)
-{
-    struct cache_entry *entry = (struct cache_entry *) data;
-
-    entry->data->refcount--;
-    if (entry->data->refcount == 0)
-        tdx_data_close(entry->data);
-    free(entry);
-}
-
-
-/*
-**  Called by hash_traverse, this function finds the oldest entry with the
-**  smallest refcount and stores it in the provided pointer so that it can be
-**  freed.  This is used when the cache is full to drop the least useful
-**  entry.
-*/
-static void
-entry_find_oldest(void *data, void *cookie)
-{
-    struct cache_entry *entry = (struct cache_entry *) data;
-    struct cache_entry **oldest = (struct cache_entry **) cookie;
-
-    if (*oldest == NULL) {
-        *oldest = entry;
-        return;
-    }
-    if (entry->data->refcount > (*oldest)->data->refcount)
-        return;
-    if (entry->lastused > (*oldest)->lastused)
-        return;
-    *oldest = data;
-}
-
-
-/*
-**  Create a new cache with the given size.
-*/
-struct cache *
-tdx_cache_create(unsigned int size)
-{
-    struct cache *cache;
-
-    cache = xmalloc(sizeof(struct cache));
-    cache->count = 0;
-    cache->max = size;
-    cache->queries = 0;
-    cache->hits = 0;
-    cache->hashtable = hash_create(size * 4 / 3, entry_hash, entry_key,
-                                   entry_equal, entry_delete);
-    return cache;
-}
-
-
-/*
-**  Look up a particular entry and return it.
-*/
-struct group_data *
-tdx_cache_lookup(struct cache *cache, HASH hash)
-{
-    struct cache_entry *entry;
-
-    cache->queries++;
-    entry = hash_lookup(cache->hashtable, &hash);
-    if (entry != NULL) {
-        cache->hits++;
-        entry->lastused = time(NULL);
-    }
-    return (entry == NULL) ? NULL : entry->data;
-}
-
-
-/*
-**  Insert a new entry, clearing out the oldest entry if the cache is
-**  currently full.
-*/
-void
-tdx_cache_insert(struct cache *cache, HASH hash, struct group_data *data)
-{
-    struct cache_entry *entry;
-
-    if (cache->count == cache->max) {
-        struct cache_entry *oldest = NULL;
-
-        hash_traverse(cache->hashtable, entry_find_oldest, &oldest);
-        if (oldest == NULL) {
-            warn("tradindexed: unable to find oldest cache entry");
-            return;
-        } else {
-            if (!hash_delete(cache->hashtable, &oldest->hash)) {
-                warn("tradindexed: cannot delete oldest cache entry");
-                return;
-            }
-        }
-        cache->count--;
-    }
-    entry = xmalloc(sizeof(struct cache_entry));
-    entry->data = data;
-    entry->hash = hash;
-    entry->lastused = time(NULL);
-    if (!hash_insert(cache->hashtable, &entry->hash, entry)) {
-        warn("tradindexed: duplicate cache entry for %s", HashToText(hash));
-        free(entry);
-    } else {
-        entry->data->refcount++;
-        cache->count++;
-    }
-}
-
-
-/*
-**  Delete an entry from the cache.
-*/
-void
-tdx_cache_delete(struct cache *cache, HASH hash)
-{
-    if (!hash_delete(cache->hashtable, &hash))
-        warn("tradindexed: unable to remove cache entry for %s",
-             HashToText(hash));
-}
-
-
-/*
-**  Delete the cache and all of the resources that it's holding open.
-*/
-void
-tdx_cache_free(struct cache *cache)
-{
-    hash_free(cache->hashtable);
-    free(cache);
-}
diff --git a/storage/tradindexed/tdx-data.c b/storage/tradindexed/tdx-data.c
deleted file mode 100644 (file)
index e64b927..0000000
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*  $Id: tdx-data.c 7598 2007-02-09 02:40:51Z eagle $
-**
-**  Overview data file handling for the tradindexed overview method.
-**
-**  Implements the handling of the .IDX and .DAT files for the tradindexed
-**  overview method.  The .IDX files are flat arrays of binary structs
-**  specifying the offset in the data file of the overview data for a given
-**  article as well as the length of that data and some additional meta-data
-**  about that article.  The .DAT files contain all of the overview data for
-**  that group in wire format.
-**
-**  Externally visible functions have a tdx_ prefix; internal functions do
-**  not.  (Externally visible unfortunately means everything that needs to be
-**  visible outside of this object file, not just interfaces exported to
-**  consumers of the overview API.)
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/mmap.h"
-#include "libinn.h"
-#include "ov.h"
-#include "ovinterface.h"
-#include "storage.h"
-#include "tdx-private.h"
-#include "tdx-structure.h"
-
-/* Returned to callers as an opaque data type, this holds the information
-   needed to manage a search in progress. */
-struct search {
-    ARTNUM limit;
-    ARTNUM current;
-    struct group_data *data;
-};
-
-/* Internal prototypes. */
-static char *group_path(const char *group);
-static int file_open(const char *base, const char *suffix, bool writable,
-                     bool append);
-static bool file_open_index(struct group_data *, const char *suffix);
-static bool file_open_data(struct group_data *, const char *suffix);
-static void *map_file(int fd, size_t length, const char *base,
-                      const char *suffix);
-static bool map_index(struct group_data *data);
-static bool map_data(struct group_data *data);
-static void unmap_index(struct group_data *data);
-static void unmap_data(struct group_data *data);
-static ARTNUM index_base(ARTNUM artnum);
-
-
-/*
-**  Determine the path to the data files for a particular group and return
-**  it.  Allocates memory which the caller is responsible for freeing.
-*/
-static char *
-group_path(const char *group)
-{
-    char *path, *p;
-    size_t length;
-    const char *gp;
-
-    /* The path of the data files for news.groups is dir/n/g/news.groups.  In
-       other words, the first letter of each component becomes a directory.
-       The length of the path is therefore the length of the base overview
-       directory path, one character for the slash, two characters for the
-       first letter and initial slash, two characters for each hierarchical
-       level of the group, and then the length of the group name.
-
-       For robustness, we want to handle leading or multiple consecutive
-       periods.  We only recognize a new hierarchical level after a string of
-       periods (which doesn't end the group name). */
-    length = strlen(innconf->pathoverview);
-    for (gp = group; *gp != '\0'; gp++)
-        if (*gp == '.') {
-            if (gp[1] == '.' || gp[0] == '\0')
-                continue;
-            length += 2;
-        }
-    length += 1 + 2 + strlen(group) + 1;
-    path = xmalloc(length);
-    strlcpy(path, innconf->pathoverview, length);
-    p = path + strlen(innconf->pathoverview);
-
-    /* Generate the hierarchical directories. */
-    if (*group != '.' && *group != '\0') {
-        *p++ = '/';
-        *p++ = *group;
-    }
-    for (gp = strchr(group, '.'); gp != NULL; gp = strchr(gp, '.')) {
-        gp++;
-        if (gp == group + 1)
-            continue;
-        if (*gp != '\0' && *gp != '.' && *gp != '/') {
-            *p++ = '/';
-            *p++ = *gp;
-        }
-    }
-    *p++ = '/';
-
-    /* Finally, append the group name to the generated path and then replace
-       all slashes with commas.  Commas have the advantage of being clearly
-       illegal in newsgroup names because of the syntax of the Newsgroups
-       header, but aren't shell metacharacters. */
-    strlcpy(p, group, length - (p - path));
-    for (; *p != '\0'; p++)
-        if (*p == '/')
-            *p = ',';
-    return path;
-}
-
-
-/*
-**  Open a data file for a group.  Takes the base portion of the file, the
-**  suffix, a bool saying whether or not the file is being opened for write,
-**  and a bool saying whether to open it for append.  Returns the file
-**  descriptor.
-*/
-static int
-file_open(const char *base, const char *suffix, bool writable, bool append)
-{
-    char *file;
-    int flags, fd;
-
-    file = concat(base, ".", suffix, (char *) 0);
-    flags = writable ? (O_RDWR | O_CREAT) : O_RDONLY;
-    if (append)
-        flags |= O_APPEND;
-    fd = open(file, flags, ARTFILE_MODE);
-    if (fd < 0 && writable && errno == ENOENT) {
-        char *p = strrchr(file, '/');
-
-        *p = '\0';
-        if (!MakeDirectory(file, true)) {
-            syswarn("tradindexed: cannot create directory %s", file);
-            free(file);
-            return -1;
-        }
-        *p = '/';
-        fd = open(file, flags, ARTFILE_MODE);
-    }
-    if (fd < 0) {
-        if (errno != ENOENT)
-            syswarn("tradindexed: cannot open %s", file);
-        free(file);
-        return -1;
-    }
-    free(file);
-    return fd;
-}
-
-
-/*
-**  Open the index file for a group.  Takes an optional suffix to use instead
-**  of IDX (used primarily for expiring).
-*/
-static bool
-file_open_index(struct group_data *data, const char *suffix)
-{
-    struct stat st;
-
-    if (suffix == NULL)
-        suffix = "IDX";
-    if (data->indexfd >= 0)
-        close(data->indexfd);
-    data->indexfd = file_open(data->path, suffix, data->writable, false);
-    if (data->indexfd < 0)
-        return false;
-    if (fstat(data->indexfd, &st) < 0) {
-        syswarn("tradindexed: cannot stat %s.%s", data->path, suffix);
-        close(data->indexfd);
-        return false;
-    }
-    data->indexinode = st.st_ino;
-    close_on_exec(data->indexfd, true);
-    return true;
-}
-
-
-/*
-**  Open the data file for a group.  Takes an optional suffix to use instead
-**  of DAT (used primarily for expiring).
-*/
-static bool
-file_open_data(struct group_data *data, const char *suffix)
-{
-    if (suffix == NULL)
-        suffix = "DAT";
-    if (data->datafd >= 0)
-        close(data->datafd);
-    data->datafd = file_open(data->path, suffix, data->writable, true);
-    if (data->datafd < 0)
-        return false;
-    close_on_exec(data->datafd, true);
-    return true;
-}
-
-
-/*
-**  Open a particular group.  Allocates a new struct group_data that should be
-**  passed to tdx_data_close() when the caller is done with it.
-*/
-struct group_data *
-tdx_data_new(const char *group, bool writable)
-{
-    struct group_data *data;
-
-    data = xmalloc(sizeof(struct group_data));
-    data->path = group_path(group);
-    data->writable = writable;
-    data->high = 0;
-    data->base = 0;
-    data->indexfd = -1;
-    data->datafd = -1;
-    data->index = NULL;
-    data->data = NULL;
-    data->indexlen = 0;
-    data->datalen = 0;
-    data->indexinode = 0;
-    data->refcount = 0;
-
-    return data;
-}
-
-
-/*
-**  Open the index and data files for a group.
-*/
-bool
-tdx_data_open_files(struct group_data *data)
-{
-    unmap_index(data);
-    unmap_data(data);
-    data->index = NULL;
-    data->data = NULL;
-    if (!file_open_index(data, NULL))
-        goto fail;
-    if (!file_open_data(data, NULL))
-        goto fail;
-    return true;
-
- fail:
-    if (data->indexfd >= 0)
-        close(data->indexfd);
-    if (data->datafd >= 0)
-        close(data->datafd);
-    return false;
-}
-
-
-/*
-**  Map a data file (either index or data), or read in all of the data in the
-**  file if we're avoiding mmap.  Takes the base and suffix of the file for
-**  error reporting.
-*/
-static void *
-map_file(int fd, size_t length, const char *base, const char *suffix)
-{
-    char *data;
-
-    if (length == 0)
-        return NULL;
-
-    if (!innconf->tradindexedmmap) {
-        ssize_t status;
-
-        data = xmalloc(length);
-        status = read(fd, data, length);
-        if ((size_t) status != length) {
-            syswarn("tradindexed: cannot read data file %s.%s", base, suffix);
-            free(data);
-            return NULL;
-        }
-    } else {
-        data = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
-        if (data == MAP_FAILED) {
-            syswarn("tradindexed: cannot mmap %s.%s", base, suffix);
-            return NULL;
-        }
-    }
-    return data;
-}
-
-
-/*
-**  Memory map the index file.
-*/
-static bool
-map_index(struct group_data *data)
-{
-    struct stat st;
-    int r;
-
-    r = fstat(data->indexfd, &st);
-    if (r == -1) {
-       if (errno == ESTALE) {
-           r = file_open_index(data, NULL);
-       } else {
-           syswarn("tradindexed: cannot stat %s.IDX", data->path);
-       }
-    }
-    if (r == -1)
-       return false;
-    data->indexlen = st.st_size;
-    data->index = map_file(data->indexfd, data->indexlen, data->path, "IDX");
-    return (data->index == NULL && data->indexlen > 0) ? false : true;
-}
-
-
-/*
-**  Memory map the data file.
-*/
-static bool
-map_data(struct group_data *data)
-{
-    struct stat st;
-    int r;
-
-    r = fstat(data->datafd, &st);
-    if (r == -1) {
-       if (errno == ESTALE) {
-           r = file_open_data(data, NULL);
-       } else {
-           syswarn("tradindexed: cannot stat %s.DAT", data->path);
-       }
-    }
-    if (r == -1)
-       return false;
-    data->datalen = st.st_size;
-    data->data = map_file(data->datafd, data->datalen, data->path, "DAT");
-    return (data->data == NULL && data->indexlen > 0) ? false : true;
-}
-
-
-/*
-**  Unmap a data file or free the memory copy if we're not using mmap.  Takes
-**  the memory to free or unmap, the length for munmap, and the name base and
-**  suffix for error reporting.
-*/
-static void
-unmap_file(void *data, off_t length, const char *base, const char *suffix)
-{
-    if (data == NULL)
-        return;
-    if (!innconf->tradindexedmmap)
-        free(data);
-    else {
-        if (munmap(data, length) < 0)
-            syswarn("tradindexed: cannot munmap %s.%s", base, suffix);
-    }
-    return;
-}
-
-/*
-**  Unmap the index file.
-*/
-static void
-unmap_index(struct group_data *data)
-{
-    unmap_file(data->index, data->indexlen, data->path, "IDX");
-    data->index = NULL;
-}
-
-
-/*
-**  Unmap the data file.
-*/
-static void
-unmap_data(struct group_data *data)
-{
-    unmap_file(data->data, data->datalen, data->path, "DAT");
-    data->data = NULL;
-}
-
-/*
-**  Determine if the file handle associated with the index table is stale
-*/
-static bool
-stale_index(struct group_data *data)
-{
-    struct stat st;
-    int r;
-
-    r = fstat(data->indexfd, &st);
-    return r == -1 && errno == ESTALE;
-}
-
-
-/*
-**  Determine if the file handle associated with the data table is stale
-*/
-static bool
-stale_data(struct group_data *data)
-{
-    struct stat st;
-    int r;
-
-    r = fstat(data->datafd, &st);
-    return r == -1 && errno == ESTALE;
-}
-
-
-/*
-**  Retrieves the article metainformation stored in the index table (all the
-**  stuff we can return without opening the data file).  Takes the article
-**  number and returns a pointer to the index entry.  Also takes the high
-**  water mark from the group index; this is used to decide whether to attempt
-**  remapping of the index file if the current high water mark is too low.
-*/
-const struct index_entry *
-tdx_article_entry(struct group_data *data, ARTNUM article, ARTNUM high)
-{
-    struct index_entry *entry;
-    ARTNUM offset;
-
-    if (article > data->high && high > data->high) {
-        unmap_index(data);
-        map_index(data);
-        data->high = high;
-    } else if (innconf->nfsreader && stale_index(data))
-        unmap_index(data);
-    if (data->index == NULL)
-        if (!map_index(data))
-            return NULL;
-
-    if (article < data->base)
-        return NULL;
-    offset = article - data->base;
-    if (offset >= data->indexlen / sizeof(struct index_entry))
-        return NULL;
-    entry = data->index + offset;
-    if (entry->length == 0)
-        return NULL;
-    return entry;
-}
-
-
-/*
-**  Begin an overview search.  In addition to the bounds of the search, we
-**  also take the high water mark from the group index; this is used to decide
-**  whether or not to attempt remapping of the index file if the current high
-**  water mark is too low.
-*/
-struct search *
-tdx_search_open(struct group_data *data, ARTNUM start, ARTNUM end, ARTNUM high)
-{
-    struct search *search;
-
-    if (end < data->base)
-        return NULL;
-    if (end < start)
-        return NULL;
-
-    if (end > data->high && high > data->high) {
-        unmap_index(data);
-        map_index(data);
-        data->high = high;
-    }
-    if (start > data->high)
-        return NULL;
-
-    if (innconf->nfsreader && stale_index(data))
-       unmap_index(data);
-    if (data->index == NULL)
-        if (!map_index(data))
-            return NULL;
-    if (innconf->nfsreader && stale_data(data))
-       unmap_data(data);
-    if (data->data == NULL)
-        if (!map_data(data))
-            return NULL;
-
-    search = xmalloc(sizeof(struct search));
-    search->limit = end - data->base;
-    search->current = (start < data->base) ? 0 : start - data->base;
-    search->data = data;
-    search->data->refcount++;
-
-    return search;
-}
-
-
-/*
-**  Return the next record in a search.
-*/
-bool
-tdx_search(struct search *search, struct article *artdata)
-{
-    struct index_entry *entry;
-    size_t max;
-
-    if (search == NULL || search->data == NULL)
-        return false;
-    if (search->data->index == NULL || search->data->data == NULL)
-        return false;
-
-    max = (search->data->indexlen / sizeof(struct index_entry)) - 1;
-    entry = search->data->index + search->current;
-    while (search->current <= search->limit && search->current <= max) {
-        if (entry->length != 0)
-            break;
-        search->current++;
-        entry++;
-    }
-    if (search->current > search->limit || search->current > max)
-        return false;
-
-    /* Make sure that the offset into the data file is sensible, and try
-       remapping the data file if the portion the offset is pointing to isn't
-       currently mapped.  Otherwise, warn about possible corruption and return
-       a miss. */
-    if (entry->offset + entry->length > search->data->datalen) {
-        unmap_data(search->data);
-        if (!map_data(search->data))
-            return false;
-    }
-    if (entry->offset + entry->length > search->data->datalen) {
-        warn("Invalid entry for article %lu in %s.IDX: offset %lu length %lu",
-             search->current + search->data->base, search->data->path,
-             (unsigned long) entry->offset, (unsigned long) entry->length);
-        return false;
-    }
-
-    artdata->number = search->current + search->data->base;
-    artdata->overview = search->data->data + entry->offset;
-    artdata->overlen = entry->length;
-    artdata->token = entry->token;
-    artdata->arrived = entry->arrived;
-    artdata->expires = entry->expires;
-
-    search->current++;
-    return true;
-}
-
-
-/*
-**  End an overview search.
-*/
-void
-tdx_search_close(struct search *search)
-{
-    if (search->data != NULL) {
-        search->data->refcount--;
-        if (search->data->refcount == 0)
-            tdx_data_close(search->data);
-    }
-    free(search);
-}
-
-
-/*
-**  Given an article number, return an index base appropriate for that article
-**  number.  This includes a degree of slop so that we don't have to
-**  constantly repack if the article numbers are clustered around a particular
-**  value but don't come in order.
-*/
-ARTNUM
-index_base(ARTNUM artnum)
-{
-    return (artnum > 128) ? (artnum - 128) : 1;
-}
-
-
-/*
-**  Store the data for a single article into the overview files for a group.
-**  Assumes any necessary repacking has already been done.  If the base value
-**  in the group_data structure is 0, assumes this is the first time we've
-**  written overview information to this group and sets it appropriately.
-*/
-bool
-tdx_data_store(struct group_data *data, const struct article *article)
-{
-    struct index_entry entry;
-    off_t offset;
-
-    if (!data->writable)
-        return false;
-    if (data->base == 0)
-        data->base = index_base(article->number);
-    if (data->base > article->number) {
-        warn("tradindexed: cannot add %lu to %s.IDX, base == %lu",
-             article->number, data->path, data->base);
-        return false;
-    }
-
-    /* Write out the data and fill in the index entry. */
-    memset(&entry, 0, sizeof(entry));
-    if (xwrite(data->datafd, article->overview, article->overlen) < 0) {
-        syswarn("tradindexed: cannot append %lu of data for %lu to %s.DAT",
-                (unsigned long) article->overlen, article->number,
-                data->path);
-        return false;
-    }
-    entry.offset = lseek(data->datafd, 0, SEEK_CUR);
-    if (entry.offset < 0) {
-        syswarn("tradindexed: cannot get offset for article %lu in %s.DAT",
-                article->number, data->path);
-        return false;
-    }
-    entry.length = article->overlen;
-    entry.offset -= entry.length;
-    entry.arrived = article->arrived;
-    entry.expires = article->expires;
-    entry.token = article->token;
-
-    /* Write out the index entry. */
-    offset = (article->number - data->base) * sizeof(struct index_entry);
-    if (xpwrite(data->indexfd, &entry, sizeof(entry), offset) < 0) {
-        syswarn("tradindexed: cannot write index record for %lu in %s.IDX",
-                article->number, data->path);
-        return false;
-    }
-    return true;
-}
-
-
-/*
-**  Start the process of packing a group (rewriting its index file so that it
-**  uses a different article base).  Takes the article number of an article
-**  that needs to be written to the index file and is below the current base.
-**  Returns the true success and false on failure, and sets data->base to the
-**  new article base and data->indexinode to the new inode number.  At the
-**  conclusion of this routine, the new index file has been created, but it
-**  has not yet been moved into place; that is done by tdx_data_pack_finish.
-*/
-bool
-tdx_data_pack_start(struct group_data *data, ARTNUM artnum)
-{
-    ARTNUM base;
-    unsigned long delta;
-    int fd;
-    char *idxfile;
-    struct stat st;
-
-    if (!data->writable)
-        return false;
-    if (data->base <= artnum) {
-        warn("tradindexed: tdx_data_pack_start called unnecessarily");
-        return false;
-    }
-
-    /* Open the new index file. */
-    base = index_base(artnum);
-    delta = data->base - base;
-    fd = file_open(data->path, "IDX-NEW", true, false);
-    if (fd < 0)
-        return false;
-    if (fstat(fd, &st) < 0) {
-        warn("tradindexed: cannot stat %s.IDX-NEW", data->path);
-        goto fail;
-    }
-
-    /* For convenience, memory map the old index file. */
-    unmap_index(data);
-    if (!map_index(data))
-        goto fail;
-
-    /* Write the contents of the old index file to the new index file. */
-    if (lseek(fd, delta * sizeof(struct index_entry), SEEK_SET) < 0) {
-        syswarn("tradindexed: cannot seek in %s.IDX-NEW", data->path);
-        goto fail;
-    }
-    if (xwrite(fd, data->index, data->indexlen) < 0) {
-        syswarn("tradindexed: cannot write to %s.IDX-NEW", data->path);
-        goto fail;
-    }
-    if (close(fd) < 0) {
-        syswarn("tradindexed: cannot close %s.IDX-NEW", data->path);
-        goto fail;
-    }
-    data->base = base;
-    data->indexinode = st.st_ino;
-    return true;
-
- fail:
-    if (fd >= 0) {
-        close(fd);
-        idxfile = concat(data->path, ".IDX-NEW", (char *) 0);
-        if (unlink(idxfile) < 0)
-            syswarn("tradindexed: cannot unlink %s", idxfile);
-        free(idxfile);
-    }
-    return false;
-}
-
-
-/*
-**  Finish the process of packing a group by replacing the new index with the
-**  old index.  Also reopen the index file and update indexinode to keep our
-**  caller from having to close and reopen the index file themselves.
-*/
-bool
-tdx_data_pack_finish(struct group_data *data)
-{
-    char *newidx, *idx;
-
-    if (!data->writable)
-        return false;
-    newidx = concat(data->path, ".IDX-NEW", (char *) 0);
-    idx = concat(data->path, ".IDX", (char *) 0);
-    if (rename(newidx, idx) < 0) {
-        syswarn("tradindexed: cannot rename %s to %s", newidx, idx);
-        unlink(newidx);
-        free(newidx);
-        free(idx);
-        return false;
-    } else {
-        free(newidx);
-        free(idx);
-        if (!file_open_index(data, NULL))
-            return false;
-        return true;
-    }
-}
-
-
-/*
-**  Open the data files for a group data rebuild, and return a struct
-**  group_data for the new files.  Calling this function doesn't interfere
-**  with the existing data for the group.  Either tdx_data_rebuild_abort or
-**  tdx_data_rebuild_finish should be called on the returned struct group_data
-**  when the caller is done.
-*/
-struct group_data *
-tdx_data_rebuild_start(const char *group)
-{
-    struct group_data *data;
-
-    data = tdx_data_new(group, true);
-    tdx_data_delete(group, "-NEW");
-    if (!file_open_index(data, "IDX-NEW"))
-        goto fail;
-    if (!file_open_data(data, "DAT-NEW"))
-        goto fail;
-    return data;
-
- fail:
-    tdx_data_delete(group, "-NEW");
-    tdx_data_close(data);
-    return NULL;
-}
-
-
-/*
-**  Finish a rebuild by renaming the new index and data files to their
-**  permanent names.
-*/
-bool
-tdx_data_rebuild_finish(const char *group)
-{
-    char *base, *newidx, *bakidx, *idx, *newdat, *dat;
-    bool saved = false;
-
-    base = group_path(group);
-    idx = concat(base, ".IDX", (char *) 0);
-    newidx = concat(base, ".IDX-NEW", (char *) 0);
-    bakidx = concat(base, ".IDX-BAK", (char *) 0);
-    dat = concat(base, ".DAT", (char *) 0);
-    newdat = concat(base, ".DAT-NEW", (char *) 0);
-    free(base);
-    if (rename(idx, bakidx) < 0) {
-        syswarn("tradindexed: cannot rename %s to %s", idx, bakidx);
-        goto fail;
-    } else {
-        saved = true;
-    }
-    if (rename(newidx, idx) < 0) {
-        syswarn("tradindexed: cannot rename %s to %s", newidx, idx);
-        goto fail;
-    }
-    if (rename(newdat, dat) < 0) {
-        syswarn("tradindexed: cannot rename %s to %s", newdat, dat);
-        goto fail;
-    }
-    if (unlink(bakidx) < 0)
-        syswarn("tradindexed: cannot remove backup %s", bakidx);
-    free(idx);
-    free(newidx);
-    free(bakidx);
-    free(dat);
-    free(newdat);
-    return true;
-
- fail:
-    if (saved && rename(bakidx, idx) < 0)
-        syswarn("tradindexed: cannot restore old index %s", bakidx);
-    free(idx);
-    free(newidx);
-    free(bakidx);
-    free(dat);
-    free(newdat);
-    return false;
-}
-
-
-/*
-**  Do the main work of expiring a group.  Step through each article in the
-**  group, only writing the unexpired entries out to the new group.  There's
-**  probably some room for optimization here for newsgroups that don't expire
-**  so that the files don't have to be rewritten, or newsgroups where all the
-**  data at the end of the file is still good and just needs to be moved
-**  as-is.
-*/
-bool
-tdx_data_expire_start(const char *group, struct group_data *data,
-                      struct group_entry *index, struct history *history)
-{
-    struct group_data *new_data;
-    struct search *search;
-    struct article article;
-    ARTNUM high;
-
-    new_data = tdx_data_rebuild_start(group);
-    if (new_data == NULL)
-        return false;
-    index->indexinode = new_data->indexinode;
-
-    /* Try to make sure that the search range is okay for even an empty group
-       so that we can treat all errors on opening a search as errors. */
-    high = index->high > 0 ? index->high : data->base;
-    new_data->high = high;
-    search = tdx_search_open(data, data->base, high, high);
-    if (search == NULL)
-        goto fail;
-
-    /* Loop through all of the articles in the group, adding the ones that are
-       still valid to the new index. */
-    while (tdx_search(search, &article)) {
-        ARTHANDLE *ah;
-
-        if (!SMprobe(EXPENSIVESTAT, &article.token, NULL) || OVstatall) {
-            ah = SMretrieve(article.token, RETR_STAT);
-            if (ah == NULL)
-                continue;
-            SMfreearticle(ah);
-        } else {
-            if (!OVhisthasmsgid(history, article.overview))
-                continue;
-        }
-        if (innconf->groupbaseexpiry)
-            if (OVgroupbasedexpire(article.token, group, article.overview,
-                                   article.overlen, article.arrived,
-                                   article.expires))
-                continue;
-        if (!tdx_data_store(new_data, &article))
-            goto fail;
-        if (index->base == 0) {
-            index->base = new_data->base;
-            index->low = article.number;
-        }
-        if (article.number > index->high)
-            index->high = article.number;
-        index->count++;
-    }
-
-    /* Done; the rest happens in tdx_data_rebuild_finish. */
-    tdx_data_close(new_data);
-    return true;
-
- fail:
-    tdx_data_delete(group, "-NEW");
-    tdx_data_close(new_data);
-    return false;
-}
-
-
-/*
-**  Close the data files for a group and free the data structure.
-*/
-void
-tdx_data_close(struct group_data *data)
-{
-    unmap_index(data);
-    unmap_data(data);
-    if (data->indexfd >= 0)
-        close(data->indexfd);
-    if (data->datafd >= 0)
-        close(data->datafd);
-    free(data->path);
-    free(data);
-}
-
-
-/*
-**  Delete the data files for a particular group, called when that group is
-**  deleted from the server.  Takes an optional suffix, which if present is
-**  appended to the ends of the file names (used by expire to delete the -NEW
-**  versions of the files).
-*/
-void
-tdx_data_delete(const char *group, const char *suffix)
-{
-    char *path, *idx, *dat;
-
-    path = group_path(group);
-    idx = concat(path, ".IDX", suffix, (char *) 0);
-    dat = concat(path, ".DAT", suffix, (char *) 0);
-    if (unlink(idx) < 0 && errno != ENOENT)
-        syswarn("tradindexed: cannot unlink %s", idx);
-    if (unlink(dat) < 0 && errno != ENOENT)
-        syswarn("tradindexed: cannot unlink %s", dat);
-    free(dat);
-    free(idx);
-    free(path);
-}
-
-
-/*
-**  RECOVERY AND AUDITING
-**
-**  All code below this point is not used in the normal operations of the
-**  overview method.  Instead, it's code to dump various data structures or
-**  audit them for consistency, used by recovery tools and inspection tools.
-*/
-
-/*
-**  Dump the index file for a given group in human-readable format.
-*/
-void
-tdx_data_index_dump(struct group_data *data, FILE *output)
-{
-    ARTNUM current;
-    struct index_entry *entry, *end;
-
-    if (data->index == NULL)
-        if (!map_index(data))
-            return;
-
-    current = data->base;
-    end = data->index + (data->indexlen / sizeof(struct index_entry));
-    for (entry = data->index; entry < end; entry++) {
-        fprintf(output, "%lu %lu %lu %lu %lu %s\n", current,
-                (unsigned long) entry->offset, (unsigned long) entry->length,
-                (unsigned long) entry->arrived,
-                (unsigned long) entry->expires, TokenToText(entry->token));
-        current++;
-    }
-}
-
-
-/*
-**  Audit a specific index entry for a particular article.  If there's
-**  anything wrong with it, we delete it; to repair a particular group, it's
-**  best to just regenerate it from scratch.
-*/
-static void
-entry_audit(struct group_data *data, struct index_entry *entry,
-            const char *group, ARTNUM article, bool fix)
-{
-    struct index_entry new_entry;
-    off_t offset;
-
-    if (entry->length < 0) {
-        warn("tradindexed: negative length %d in %s:%lu", entry->length,
-             group, article);
-        if (fix)
-            goto clear;
-        return;
-    }
-    if (entry->offset > data->datalen || entry->length > data->datalen) {
-        warn("tradindexed: offset %lu or length %lu out of bounds for %s:%lu",
-             (unsigned long) entry->offset, (unsigned long) entry->length,
-             group, article);
-        if (fix)
-            goto clear;
-        return;
-    }
-    if (entry->offset + entry->length > data->datalen) {
-        warn("tradindexed: offset %lu plus length %lu out of bounds for"
-             " %s:%lu", (unsigned long) entry->offset,
-             (unsigned long) entry->length, group, article);
-        if (fix)
-            goto clear;
-        return;
-    }
-    if (!overview_check(data->data + entry->offset, entry->length, article)) {
-        warn("tradindexed: malformed overview data for %s:%lu", group,
-             article);
-        if (fix)
-            goto clear;
-    }
-    return;
-
- clear:
-    new_entry = *entry;
-    new_entry.offset = 0;
-    new_entry.length = 0;
-    offset = (entry - data->index) * sizeof(struct index_entry);
-    if (xpwrite(data->indexfd, &new_entry, sizeof(new_entry), offset) != 0)
-        warn("tradindexed: unable to repair %s:%lu", group, article);
-}
-
-
-/*
-**  Audit the data for a particular group.  Takes the index entry from the
-**  group.index file and optionally corrects any problems with the data or the
-**  index entry based on the contents of the data.
-*/
-void
-tdx_data_audit(const char *group, struct group_entry *index, bool fix)
-{
-    struct group_data *data;
-    struct index_entry *entry;
-    long count;
-    off_t expected;
-    unsigned long entries, current;
-    ARTNUM low = 0;
-    bool changed = false;
-
-    data = tdx_data_new(group, true);
-    if (!tdx_data_open_files(data))
-        return;
-    if (!map_index(data))
-        goto end;
-    if (!map_data(data))
-        goto end;
-
-    /* Check the inode of the index. */
-    if (data->indexinode != index->indexinode) {
-        warn("tradindexed: index inode mismatch for %s: %lu != %lu", group,
-             (unsigned long) data->indexinode,
-             (unsigned long) index->indexinode);
-        if (fix) {
-            index->indexinode = data->indexinode;
-            changed = true;
-        }
-    }
-
-    /* Check the index size. */
-    entries = data->indexlen / sizeof(struct index_entry);
-    expected = entries * sizeof(struct index_entry);
-    if (data->indexlen != expected) {
-        warn("tradindexed: %lu bytes of trailing trash in %s.IDX",
-             (unsigned long)(data->indexlen - expected), data->path);
-        if (fix) {
-            unmap_index(data);
-            if (ftruncate(data->indexfd, expected) < 0)
-                syswarn("tradindexed: cannot truncate %s.IDX", data->path);
-            if (!map_index(data))
-                goto end;
-        }
-    }
-
-    /* Now iterate through all of the index entries.  In addition to checking
-       each one individually, also count the number of valid entries to check
-       the count in the index and verify that the low water mark is
-       correct. */
-    for (current = 0, count = 0; current < entries; current++) {
-        entry = &data->index[current];
-        if (entry->length == 0)
-            continue;
-        entry_audit(data, entry, group, index->base + current, fix);
-        if (entry->length != 0) {
-            if (low == 0)
-                low = index->base + current;
-            count++;
-        }
-    }
-    if (index->low != low && entries != 0) {
-        warn("tradindexed: low water mark incorrect for %s: %lu != %lu",
-             group, low, index->low);
-        if (fix) {
-            index->low = low;
-            changed = true;
-        }
-    }
-    if (index->count != count) {
-        warn("tradindexed: count incorrect for %s: %lu != %lu", group,
-             (unsigned long) count, (unsigned long) index->count);
-        if (fix) {
-            index->count = count;
-            changed = true;
-        }
-    }
-
-    /* All done.  Close things down and flush the data we changed, if
-       necessary. */
-    if (changed)
-        inn_mapcntl(index, sizeof(*index), MS_ASYNC);
-
- end:
-    tdx_data_close(data);
-}
diff --git a/storage/tradindexed/tdx-group.c b/storage/tradindexed/tdx-group.c
deleted file mode 100644 (file)
index 82af513..0000000
+++ /dev/null
@@ -1,1424 +0,0 @@
-/*  $Id: tdx-group.c 7598 2007-02-09 02:40:51Z eagle $
-**
-**  Group index handling for the tradindexed overview method.
-**
-**  Implements the handling of the group.index file for the tradindexed
-**  overview method.  This file contains an entry for every group and stores
-**  the high and low article marks and the base article numbers for each
-**  individual group index file.
-**
-**  Externally visible functions have a tdx_ prefix; internal functions do
-**  not.  (Externally visible unfortunately means everything that needs to be
-**  visible outside of this object file, not just interfaces exported to
-**  consumers of the overview API.)
-**
-**  This code has to support readers and writers sharing the same files, and
-**  we want to avoid locking where possible since locking may be very slow
-**  (such as over NFS).  Each group has two data files (and one has to get the
-**  right index file for a given data file or get mangled results) and one
-**  piece of data in the main index file required to interpret the individual
-**  index file, namely the article base of that index.
-**
-**  We can make the following assumptions:
-**
-**   - The high water mark for a group is monotonically increasing; in other
-**     words, the highest numbered article in a group won't ever decrease.
-**
-**   - While the article base may either increase or decrease, it will never
-**     change unless the inode of the index file on disk also changes, since
-**     changing the base requires rewriting the index file.
-**
-**   - No two files will have the same inode (this requirement should be safe
-**     even in strange Unix file formats, since the files are all in the same
-**     directory).
-**
-**  We therefore use the following procedure to update the data:  The high
-**  water mark may be changed at any time but surrounded in a write lock.  The
-**  base may only be changed as part of an index rebuild.  To do an index
-**  rebuild, we follow the following procedure:
-**
-**   1) Obtain a write lock on the group entry in the main index.
-**   2) Write out new index and data files to new temporary file names.
-**   3) Store the new index inode into the main index.
-**   4) Update the high, low, and base article numbers in the main index.
-**   5) Rename the data file to its correct name.
-**   6) Rename the index file to its correct name.
-**   7) Release the write lock.
-**
-**  We use the following procedure to read the data:
-**
-**   1) Open the group data files (both index and data).
-**   2) Store copies of the current high water mark and base in variables.
-**   3) Check to be sure the index inode matches the master index file.
-**
-**  If it does match, then we have a consistent set of data, since the high
-**  water mark and base values have to match the index we have (the inode
-**  value is updated first).  It may not be the most current set of data, but
-**  since we have those index and data files open, even if they're later
-**  rebuilt we'll continue looking at the same files.  They may have further
-**  data appended to them, but that's safe.
-**
-**  If the index inode doesn't match, someone's rebuilt the file while we were
-**  trying to open it.  Continue with the following procedure:
-**
-**   4) Close the data files that we opened.
-**   5) Obtain a read lock on the group entry in the main index.
-**   6) Reopen the data files.
-**   7) Grab the current high water mark and base.
-**   8) Release the read lock.
-**
-**  In other words, if there appears to be contention, we fall back to using
-**  locking so that we don't try to loop (which also avoids an infinite loop
-**  in the event of corruption of the main index).
-**
-**  Note that once we have a consistent set of data files open, we don't need
-**  to aggressively check for new data files until someone asks for an article
-**  outside the range of articles that we know about.  We may be working from
-**  outdated data files, but the most we'll miss is a cancel or an expiration
-**  run.  Overview data doesn't change; new data is appended and old data is
-**  expired.  We can afford to check only every once in a while, just to be
-**  sure that we're not going to hand out overview data for a bunch of expired
-**  articles.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#include "inn/hashtab.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/mmap.h"
-#include "inn/qio.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "paths.h"
-#include "tdx-private.h"
-#include "tdx-structure.h"
-
-/* Returned to callers as an opaque data type, this stashes all of the
-   information about an open group.index file. */
-struct group_index {
-    char *path;
-    int fd;
-    bool writable;
-    struct group_header *header;
-    struct group_entry *entries;
-    int count;
-};
-
-/* Forward declaration. */
-struct hashmap;
-
-/* Internal prototypes. */
-static int index_entry_count(size_t size);
-static size_t index_file_size(int count);
-static bool index_lock(int fd, enum inn_locktype type);
-static bool index_lock_group(int fd, ptrdiff_t offset, enum inn_locktype);
-static bool index_map(struct group_index *);
-static bool index_maybe_remap(struct group_index *, long loc);
-static void index_unmap(struct group_index *);
-static bool index_expand(struct group_index *);
-static long index_find(struct group_index *, const char *group);
-
-
-/*
-**  Given a file size, return the number of group entries that it contains.
-*/
-static int
-index_entry_count(size_t size)
-{
-    return (size - sizeof(struct group_header)) / sizeof(struct group_entry);
-}
-
-
-/*
-**  Given a number of group entries, return the required file size.
-*/
-static size_t
-index_file_size(int count)
-{
-    return sizeof(struct group_header) + count * sizeof(struct group_entry);
-}
-
-
-/*
-**  Lock the hash table for the group index, used to acquire global locks on
-**  the group index when updating it.
-*/
-static bool
-index_lock(int fd, enum inn_locktype type)
-{
-    bool status;
-
-    status = inn_lock_range(fd, type, true, 0, sizeof(struct group_header));
-    if (!status)
-        syswarn("tradindexed: cannot %s index hash table",
-                (type == INN_LOCK_UNLOCK) ? "unlock" : "lock");
-    return status;
-}
-
-
-/*
-**  Lock the group entry for a particular group.  Takes the offset of that
-**  group entry from the start of the group entries (not the start of the
-**  file; we have to add the size of the group header).  Used for coordinating
-**  updates of the data for a group.
-*/
-static bool
-index_lock_group(int fd, ptrdiff_t offset, enum inn_locktype type)
-{
-    bool status;
-    size_t size;
-
-    size = sizeof(struct group_entry);
-    offset = offset * size + sizeof(struct group_header);
-    status = inn_lock_range(fd, type, true, offset, size);
-    if (!status)
-        syswarn("tradindexed: cannot %s group entry at %lu",
-                (type == INN_LOCK_UNLOCK) ? "unlock" : "lock",
-                (unsigned long) offset);
-    return status;
-}
-
-
-/*
-**  Memory map (or read into memory) the key portions of the group.index
-**  file.  Takes a struct group_index to fill in and returns true on success
-**  and false on failure.
-*/
-static bool
-index_map(struct group_index *index)
-{
-    if (!innconf->tradindexedmmap && index->writable) {
-        warn("tradindexed: cannot open for writing without mmap");
-        return false;
-    }
-
-    if (!innconf->tradindexedmmap) {
-        ssize_t header_size;
-        ssize_t entry_size;
-
-        header_size = sizeof(struct group_header);
-        entry_size = index->count * sizeof(struct group_entry);
-        index->header = xmalloc(header_size);
-        index->entries = xmalloc(entry_size);
-        if (read(index->fd, index->header, header_size) != header_size) {
-            syswarn("tradindexed: cannot read header from %s", index->path);
-            goto fail;
-        }
-        if (read(index->fd, index->entries, entry_size) != entry_size) {
-            syswarn("tradindexed: cannot read entries from %s", index->path);
-            goto fail;
-        }
-        return true;
-
-    fail:
-        free(index->header);
-        free(index->entries);
-        index->header = NULL;
-        index->entries = NULL;
-        return false;
-
-    } else {
-        char *data;
-        size_t size;
-        int flag = PROT_READ;
-
-        if (index->writable)
-            flag = PROT_READ | PROT_WRITE;
-        size = index_file_size(index->count);
-        data = mmap(NULL, size, flag, MAP_SHARED, index->fd, 0);
-        if (data == MAP_FAILED) {
-            syswarn("tradindexed: cannot mmap %s", index->path);
-            return false;
-        }
-        index->header = (struct group_header *)(void *) data;
-        index->entries = (struct group_entry *)
-            (void *)(data + sizeof(struct group_header));
-        return true;
-    }
-}
-
-
-static bool
-file_open_group_index(struct group_index *index, struct stat *st)
-{
-    int open_mode;
-
-    index->header = NULL;
-    open_mode = index->writable ? O_RDWR | O_CREAT : O_RDONLY;
-    index->fd = open(index->path, open_mode, ARTFILE_MODE);
-    if (index->fd < 0) {
-        syswarn("tradindexed: cannot open %s", index->path);
-        goto fail;
-    }
-
-    if (fstat(index->fd, st) < 0) {
-        syswarn("tradindexed: cannot fstat %s", index->path);
-        goto fail;
-    }
-    close_on_exec(index->fd, true);
-    return true;
-
- fail:
-    if (index->fd >= 0) {
-        close(index->fd);
-        index->fd = -1;
-    }
-    return false;
-}
-
-
-/*
-**  Given a group location, remap the index file if our existing mapping isn't
-**  large enough to include that group.  (This can be the case when another
-**  writer is appending entries to the group index.)
-*/
-static bool
-index_maybe_remap(struct group_index *index, long loc)
-{
-    struct stat st;
-    int count;
-    int r;
-
-    if (loc < index->count)
-        return true;
-
-    /* Don't remap if remapping wouldn't actually help. */
-    r = fstat(index->fd, &st);
-    if (r == -1) {
-       if (errno == ESTALE) {
-           index_unmap(index);
-           if (!file_open_group_index(index, &st))
-               return false;
-       } else {
-           syswarn("tradindexed: cannot stat %s", index->path);
-           return false;
-       }
-    }
-    count = index_entry_count(st.st_size);
-    if (count < loc && index->header != NULL)
-        return true;
-
-    /* Okay, remapping will actually help. */
-    index_unmap(index);
-    index->count = count;
-    return index_map(index);
-}
-
-
-/*
-**  Unmap the index file, either in preparation for closing the overview
-**  method or to get ready to remap it.  We warn about failures to munmap but
-**  don't do anything about them; there isn't much that we can do.
-*/
-static void
-index_unmap(struct group_index *index)
-{
-    if (index->header == NULL)
-        return;
-    if (!innconf->tradindexedmmap) {
-        free(index->header);
-        free(index->entries);
-    } else {
-        if (munmap(index->header, index_file_size(index->count)) < 0)
-            syswarn("tradindexed: cannot munmap %s", index->path);
-    }
-    index->header = NULL;
-    index->entries = NULL;
-}
-
-
-/*
-**  Expand the group.index file to hold more entries; also used to build the
-**  initial file.  The caller is expected to lock the group index.
-*/
-static bool
-index_expand(struct group_index *index)
-{
-    int i;
-
-    index_unmap(index);
-    index->count += 1024;
-    if (ftruncate(index->fd, index_file_size(index->count)) < 0) {
-        syswarn("tradindexed: cannot expand %s", index->path);
-        return false;
-    }
-
-    /* If mapping the index fails, we've already extended it but we haven't
-       done anything with the new portion of the file.  That means that it's
-       all zeroes, which means that it contains index entries who all think
-       their next entry is entry 0.  We don't want to leave things in this
-       state (particularly if this was the first expansion of the index file,
-       in which case entry 0 points to entry 0 and our walking functions may
-       go into infinite loops.  Undo the file expansion. */
-    if (!index_map(index)) {
-        index->count -= 1024;
-        if (ftruncate(index->fd, index_file_size(index->count)) < 0) {
-            syswarn("tradindexed: cannot shrink %s", index->path);
-        }
-        return false;
-    }
-
-    /* If the magic isn't right, assume this is a new index file. */
-    if (index->header->magic != TDX_MAGIC) {
-        index->header->magic = TDX_MAGIC;
-        index->header->freelist.recno = -1;
-        for (i = 0; i < TDX_HASH_SIZE; i++)
-            index->header->hash[i].recno = -1;
-    }
-
-    /* Walk the new entries back to front, adding them to the free list. */
-    for (i = index->count - 1; i >= index->count - 1024; i--) {
-        index->entries[i].next = index->header->freelist;
-        index->header->freelist.recno = i;
-    }
-
-    inn_mapcntl(index->header, index_file_size(index->count), MS_ASYNC);
-    return true;
-}
-
-
-/*
-**  Open the group.index file and allocate a new struct for it, returning a
-**  pointer to that struct.  Takes a bool saying whether or not the overview
-**  should be opened for write.
-*/
-struct group_index *
-tdx_index_open(bool writable)
-{
-    struct group_index *index;
-    struct stat st;
-
-    index = xmalloc(sizeof(struct group_index));
-    index->path = concatpath(innconf->pathoverview, "group.index");
-    index->writable = writable;
-    if (!file_open_group_index(index, &st)) {
-       goto fail;
-    }
-    if ((size_t) st.st_size > sizeof(struct group_header)) {
-        index->count = index_entry_count(st.st_size);
-        if (!index_map(index))
-            goto fail;
-    } else {
-        index->count = 0;
-        if (index->writable) {
-            if (st.st_size > 0)
-                warn("tradindexed: recreating truncated %s", index->path);
-            if (!index_expand(index))
-                goto fail;
-        } else {
-            index->header = NULL;
-            index->entries = NULL;
-        }
-    }
-    return index;
-
- fail:
-    tdx_index_close(index);
-    return NULL;
-}
-
-
-/*
-**  Given a group name hash, return an index into the hash table in the
-**  group.index header.
-*/
-static long
-index_bucket(HASH hash)
-{
-    unsigned int bucket;
-
-    memcpy(&bucket, &hash, sizeof(bucket));
-    return bucket % TDX_HASH_SIZE;
-}
-
-
-/*
-**  Given a pointer to a group entry, return its location number.
-*/
-static long
-entry_loc(const struct group_index *index, const struct group_entry *entry)
-{
-    return entry - index->entries;
-}
-
-
-/*
-**  Splice out a particular group entry.  Takes the entry and a pointer to the
-**  location where a pointer to it is stored.
-*/
-static void
-entry_splice(struct group_entry *entry, int *parent)
-{
-    *parent = entry->next.recno;
-    entry->next.recno = -1;
-    inn_mapcntl(parent, sizeof(*parent), MS_ASYNC);
-}
-
-
-/*
-**  Add a new entry to the appropriate hash chain.
-*/
-static void
-index_add(struct group_index *index, struct group_entry *entry)
-{
-    long bucket, loc;
-
-    bucket = index_bucket(entry->hash);
-    loc = entry_loc(index, entry);
-    if (loc == index->header->hash[bucket].recno) {
-        warn("tradindexed: refusing to add a loop for %ld in bucket %ld",
-             loc, bucket);
-        return;
-    }
-    entry->next.recno = index->header->hash[bucket].recno;
-    index->header->hash[bucket].recno = entry_loc(index, entry);
-    inn_mapcntl(&index->header->hash[bucket], sizeof(struct loc), MS_ASYNC);
-    inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-}
-
-
-/*
-**  Find a group in the index file, returning the group number for that group
-**  or -1 if the group can't be found.
-*/
-static long
-index_find(struct group_index *index, const char *group)
-{
-    HASH hash;
-    long loc;
-
-    if (index->header == NULL || index->entries == NULL)
-        return -1;
-    hash = Hash(group, strlen(group));
-    if (innconf->nfsreader && !index_maybe_remap(index, LONG_MAX))
-       return -1;
-    loc = index->header->hash[index_bucket(hash)].recno;
-
-    while (loc >= 0 && loc < index->count) {
-        struct group_entry *entry;
-
-        if (loc > index->count && !index_maybe_remap(index, loc))
-            return -1;
-        entry = index->entries + loc;
-        if (entry->deleted == 0)
-            if (memcmp(&hash, &entry->hash, sizeof(hash)) == 0)
-                return loc;
-        if (loc == entry->next.recno) {
-            syswarn("tradindexed: index loop for entry %ld", loc);
-            return -1;
-        }
-        loc = entry->next.recno;
-    }
-    return -1;
-}
-
-
-/*
-**  Add a given entry to the free list.
-*/
-static void
-freelist_add(struct group_index *index, struct group_entry *entry)
-{
-    entry->next.recno = index->header->freelist.recno;
-    index->header->freelist.recno = entry_loc(index, entry);
-    inn_mapcntl(&index->header->freelist, sizeof(struct loc), MS_ASYNC);
-    inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-}
-
-
-/*
-**  Find an entry by hash value (rather than group name) and splice it out of
-**  whatever chain it might belong to.  This function is called by both
-**  index_unlink and index_audit_group.  Locking must be done by the caller.
-**  Returns the group location of the spliced group.
-*/
-static long
-index_unlink_hash(struct group_index *index, HASH hash)
-{
-    int *parent;
-    long current;
-
-    parent = &index->header->hash[index_bucket(hash)].recno;
-    current = *parent;
-
-    while (current >= 0 && current < index->count) {
-        struct group_entry *entry;
-
-        if (current > index->count && !index_maybe_remap(index, current))
-            return -1;
-        entry = &index->entries[current];
-        if (entry->deleted == 0)
-            if (memcmp(&hash, &entry->hash, sizeof(hash)) == 0) {
-                entry_splice(entry, parent);
-                return current;
-            }
-        if (current == entry->next.recno) {
-            syswarn("tradindexed: index loop for entry %ld", current);
-            return -1;
-        }
-        parent = &entry->next.recno;
-        current = *parent;
-    }
-    return -1;
-}
-
-
-/*
-**  Like index_find, but also removes that entry out of whatever chain it
-**  might belong to.  This function is called by tdx_index_delete.  Locking
-**  must be done by the caller.
-*/
-static long
-index_unlink(struct group_index *index, const char *group)
-{
-    HASH hash;
-
-    hash = Hash(group, strlen(group));
-    return index_unlink_hash(index, hash);
-}
-
-
-/*
-**  Return the information stored about a given group in the group index.
-*/
-struct group_entry *
-tdx_index_entry(struct group_index *index, const char *group)
-{
-    long loc;
-    struct group_entry *entry;
-
-    loc = index_find(index, group);
-    if (loc == -1)
-        return NULL;
-    entry = index->entries + loc;
-    if (innconf->tradindexedmmap && innconf->nfsreader)
-       inn_mapcntl(entry, sizeof *entry, MS_INVALIDATE);
-    return entry;
-}
-
-
-/*
-**  Add a new newsgroup to the group.index file.  Takes the newsgroup name,
-**  its high and low water marks, and the newsgroup flag.  Note that aliased
-**  newsgroups are not currently handled.  If the group already exists, just
-**  update the flag (not the high and low water marks).
-*/
-bool
-tdx_index_add(struct group_index *index, const char *group, ARTNUM low,
-              ARTNUM high, const char *flag)
-{
-    HASH hash;
-    long loc;
-    struct group_entry *entry;
-    struct group_data *data;
-
-    if (!index->writable)
-        return false;
-
-    /* If the group already exists, update the flag as necessary and then
-       we're all done. */
-    loc = index_find(index, group);
-    if (loc != -1) {
-        entry = &index->entries[loc];
-        if (entry->flag != *flag) {
-            entry->flag = *flag;
-            inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-        }
-        return true;
-    }
-
-    index_lock(index->fd, INN_LOCK_WRITE);
-
-    /* Find a free entry.  If we don't have any free space, make some. */
-    if (index->header->freelist.recno == -1)
-        if (!index_expand(index)) {
-            index_lock(index->fd, INN_LOCK_UNLOCK);
-            return false;
-        }
-    loc = index->header->freelist.recno;
-    index->header->freelist.recno = index->entries[loc].next.recno;
-    inn_mapcntl(&index->header->freelist, sizeof(struct loc), MS_ASYNC);
-
-    /* Initialize the entry. */
-    entry = &index->entries[loc];
-    hash = Hash(group, strlen(group));
-    entry->hash = hash;
-    entry->low = (low == 0 && high != 0) ? high + 1 : low;
-    entry->high = high;
-    entry->deleted = 0;
-    entry->base = 0;
-    entry->count = 0;
-    entry->flag = *flag;
-    data = tdx_data_new(group, index->writable);
-    if (!tdx_data_open_files(data))
-        warn("tradindexed: unable to create data files for %s", group);
-    entry->indexinode = data->indexinode;
-    tdx_data_close(data);
-    index_add(index, entry);
-
-    index_lock(index->fd, INN_LOCK_UNLOCK);
-    return true;
-}
-
-
-/*
-**  Delete a group index entry.
-*/
-bool
-tdx_index_delete(struct group_index *index, const char *group)
-{
-    long loc;
-    struct group_entry *entry;
-
-    if (!index->writable)
-        return false;
-
-    /* Lock the header for the entire operation, mostly as prevention against
-       interfering with ongoing audits (which lock while they're running). */
-    index_lock(index->fd, INN_LOCK_WRITE);
-
-    /* Splice out the entry and mark it as deleted. */
-    loc = index_unlink(index, group);
-    if (loc == -1) {
-        index_lock(index->fd, INN_LOCK_UNLOCK);
-        return false;
-    }
-    entry = &index->entries[loc];
-    entry->deleted = time(NULL);
-    HashClear(&entry->hash);
-
-    /* Add the entry to the free list. */
-    freelist_add(index, entry);
-    index_lock(index->fd, INN_LOCK_UNLOCK);
-
-    /* Delete the group data files for this group. */
-    tdx_data_delete(group, NULL);
-
-    return true;
-}
-
-
-/*
-**  Close an open handle to the group index file, freeing the group_index
-**  structure at the same time.  The argument to this function becomes invalid
-**  after this call.
-*/
-void
-tdx_index_close(struct group_index *index)
-{
-    index_unmap(index);
-    if (index->fd >= 0) {
-        close(index->fd);
-        index->fd = -1;
-    }
-    free(index->path);
-    free(index);
-}
-
-
-/*
-**  Open the data files for a particular group.  The interface to this has to
-**  be in this file because we have to lock the group and retry if the inode
-**  of the opened index file doesn't match the one recorded in the group index
-**  file.  Optionally take a pointer to the group index entry if the caller
-**  has already gone to the work of finding it.
-*/
-struct group_data *
-tdx_data_open(struct group_index *index, const char *group,
-              struct group_entry *entry)
-{
-    struct group_data *data;
-    ARTNUM high, base;
-    ptrdiff_t offset;
-
-    if (entry == NULL) {
-        entry = tdx_index_entry(index, group);
-        if (entry == NULL)
-            return NULL;
-    }
-    offset = entry - index->entries;
-    data = tdx_data_new(group, index->writable);
-
-    /* Check to see if the inode of the index file matches.  If it doesn't,
-       this probably means that as we were opening the index file, someone
-       else rewrote it (either expire or repack).  Obtain a lock and try
-       again.  If there's still a mismatch, go with what we get; there's some
-       sort of corruption.
-
-       This code is very sensitive to order and parallelism.  See the comment
-       at the beginning of this file for methodology. */
-    if (!tdx_data_open_files(data))
-        goto fail;
-    high = entry->high;
-    base = entry->base;
-    if (entry->indexinode != data->indexinode) {
-        index_lock_group(index->fd, offset, INN_LOCK_READ);
-        if (!tdx_data_open_files(data)) {
-            index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-            goto fail;
-        }
-        if (entry->indexinode != data->indexinode)
-            warn("tradindexed: index inode mismatch for %s", group);
-        high = entry->high;
-        base = entry->base;
-        index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-    }
-    data->high = high;
-    data->base = base;
-    return data;
-
- fail:
-    tdx_data_close(data);
-    return NULL;
-}
-
-
-/*
-**  Add an overview record for a particular article.  Takes the group entry,
-**  the open overview data structure, and the information about the article
-**  and returns true on success, false on failure.  This function calls
-**  tdx_data_store to do most of the real work and then updates the index
-**  information.
-*/
-bool
-tdx_data_add(struct group_index *index, struct group_entry *entry,
-             struct group_data *data, const struct article *article)
-{
-    ARTNUM old_base;
-    ino_t old_inode;
-    ptrdiff_t offset = entry - index->entries;
-
-    if (!index->writable)
-        return false;
-    index_lock_group(index->fd, offset, INN_LOCK_WRITE);
-
-    /* Make sure we have the most current data files and that we have the
-       right base article number. */
-    if (entry->indexinode != data->indexinode) {
-        if (!tdx_data_open_files(data))
-            goto fail;
-        if (entry->indexinode != data->indexinode)
-            warn("tradindexed: index inode mismatch for %s",
-                 HashToText(entry->hash));
-        data->base = entry->base;
-    }
-
-    /* If the article number is too low to store in the group index, repack
-       the group with a lower base index. */
-    if (entry->base > article->number) {
-        if (!tdx_data_pack_start(data, article->number))
-            goto fail;
-        old_inode = entry->indexinode;
-        old_base = entry->base;
-        entry->indexinode = data->indexinode;
-        entry->base = data->base;
-        inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-        if (!tdx_data_pack_finish(data)) {
-            entry->base = old_base;
-            entry->indexinode = old_inode;
-            inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-            goto fail;
-        }
-    }
-
-    /* Store the data. */
-    if (!tdx_data_store(data, article))
-        goto fail;
-    if (entry->base == 0)
-        entry->base = data->base;
-    if (entry->low == 0 || entry->low > article->number)
-        entry->low = article->number;
-    if (entry->high < article->number)
-        entry->high = article->number;
-    entry->count++;
-    inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-    index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-    return true;
-
- fail:
-    index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-    return false;
-}
-
-
-/*
-**  Start a rebuild of the group data for a newsgroup.  Right now, all this
-**  does is lock the group index entry.
-*/
-bool
-tdx_index_rebuild_start(struct group_index *index, struct group_entry *entry)
-{
-    ptrdiff_t offset;
-
-    offset = entry - index->entries;
-    return index_lock_group(index->fd, offset, INN_LOCK_WRITE);
-}
-
-
-/*
-**  Finish a rebuild of the group data for a newsgroup.  Takes the old and new
-**  entry and writes the data from the new entry into the group index, and
-**  then unlocks it.
-*/
-bool
-tdx_index_rebuild_finish(struct group_index *index, struct group_entry *entry,
-                         struct group_entry *new)
-{
-    ptrdiff_t offset;
-    ino_t new_inode;
-
-    new_inode = new->indexinode;
-    new->indexinode = entry->indexinode;
-    *entry = *new;
-    entry->indexinode = new_inode;
-    new->indexinode = new_inode;
-    inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-    offset = entry - index->entries;
-    index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-    return true;
-}
-
-
-/*
-**  Expire a single newsgroup.  Most of the work is done by tdx_data_expire*,
-**  but this routine has the responsibility to do locking (the same as would
-**  be done for repacking, since the group base may change) and updating the
-**  group entry.
-*/
-bool
-tdx_expire(const char *group, ARTNUM *low, struct history *history)
-{
-    struct group_index *index;
-    struct group_entry *entry;
-    struct group_entry new_entry;
-    struct group_data *data = NULL;
-    ptrdiff_t offset;
-    ARTNUM old_base;
-    ino_t old_inode;
-
-    index = tdx_index_open(true);
-    if (index == NULL)
-        return false;
-    entry = tdx_index_entry(index, group);
-    if (entry == NULL) {
-        tdx_index_close(index);
-        return false;
-    }
-    tdx_index_rebuild_start(index, entry);
-
-    /* tdx_data_expire_start builds the new IDX and DAT files and fills in the
-       struct group_entry that was passed to it.  tdx_data_rebuild_finish does
-       the renaming of the new files to the final file names. */
-    new_entry = *entry;
-    new_entry.low = 0;
-    new_entry.count = 0;
-    new_entry.base = 0;
-    data = tdx_data_open(index, group, entry);
-    if (data == NULL)
-        goto fail;
-    if (!tdx_data_expire_start(group, data, &new_entry, history))
-        goto fail;
-    old_inode = entry->indexinode;
-    old_base = entry->base;
-    entry->indexinode = new_entry.indexinode;
-    entry->base = new_entry.base;
-    inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-    tdx_data_close(data);
-    if (!tdx_data_rebuild_finish(group)) {
-        entry->base = old_base;
-        entry->indexinode = old_inode;
-        inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-        goto fail;
-    }
-
-    /* Almost done.  Update the group index.  If there are no articles in the
-       group, the low water mark should be one more than the high water
-       mark. */
-    if (new_entry.low == 0)
-        new_entry.low = new_entry.high + 1;
-    tdx_index_rebuild_finish(index, entry, &new_entry);
-    if (low != NULL)
-        *low = entry->low;
-    tdx_index_close(index);
-    return true;
-
- fail:
-    offset = entry - index->entries;
-    index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-    if (data != NULL)
-        tdx_data_close(data);
-    tdx_index_close(index);
-    return false;
-}
-
-
-/*
-**  RECOVERY AND AUDITING
-**
-**  All code below this point is not used in the normal operations of the
-**  overview method.  Instead, it's code to dump various data structures or
-**  audit them for consistency, used by recovery tools and inspection tools.
-*/
-
-/* Holds a newsgroup name and its hash, used to form a hash table mapping
-   newsgroup hash values to the actual names. */
-struct hashmap {
-    HASH hash;
-    char *name;
-    char flag;
-};
-
-/* Holds information needed by hash traversal functions.  Right now, this is
-   just the pointer to the group index and a flag saying whether to fix
-   problems or not. */
-struct audit_data {
-    struct group_index *index;
-    bool fix;
-};
-
-
-/*
-**  Hash table functions for the mapping from group hashes to names.
-*/
-static unsigned long
-hashmap_hash(const void *entry)
-{
-    unsigned long hash;
-    const struct hashmap *group = entry;
-
-    memcpy(&hash, &group->hash, sizeof(hash));
-    return hash;
-}
-
-
-static const void *
-hashmap_key(const void *entry)
-{
-    return &((const struct hashmap *) entry)->hash;
-}
-
-
-static bool
-hashmap_equal(const void *key, const void *entry)
-{
-    const HASH *first = key;
-    const HASH *second;
-
-    second = &((const struct hashmap *) entry)->hash;
-    return memcmp(first, second, sizeof(HASH)) == 0;
-}
-
-
-static void
-hashmap_delete(void *entry)
-{
-    struct hashmap *group = entry;
-
-    free(group->name);
-    free(group);
-}
-
-
-/*
-**  Construct a hash table of group hashes to group names by scanning the
-**  active file.  Returns the constructed hash table.
-*/
-static struct hash *
-hashmap_load(void)
-{
-    struct hash *hash;
-    QIOSTATE *active;
-    char *activepath, *line;
-    struct cvector *data = NULL;
-    struct stat st;
-    size_t hash_size;
-    struct hashmap *group;
-    HASH grouphash;
-
-    activepath = concatpath(innconf->pathdb, _PATH_ACTIVE);
-    active = QIOopen(activepath);
-    free(activepath);
-    if (active == NULL)
-        return NULL;
-    if (fstat(QIOfileno(active), &st) < 0)
-        hash_size = 32 * 1024;
-    else
-        hash_size = st.st_size / 30;
-    hash = hash_create(hash_size, hashmap_hash, hashmap_key, hashmap_equal,
-                       hashmap_delete);
-
-    line = QIOread(active);
-    while (line != NULL) {
-        data = cvector_split_space(line, data);
-        if (data->count != 4) {
-            warn("tradindexed: malformed active file line %s", line);
-            continue;
-        }
-        group = xmalloc(sizeof(struct hashmap));
-        group->name = xstrdup(data->strings[0]);
-        group->flag = data->strings[3][0];
-        grouphash = Hash(group->name, strlen(group->name));
-        memcpy(&group->hash, &grouphash, sizeof(HASH));
-        hash_insert(hash, &group->hash, group);
-        line = QIOread(active);
-    }
-    cvector_free(data);
-    QIOclose(active);
-    return hash;
-}
-
-
-/*
-**  Print the stored information about a single group in human-readable form
-**  to stdout.  The format is:
-**
-**    name high low base count flag deleted inode
-**
-**  all on one line.  Name is passed into this function.
-*/
-void
-tdx_index_print(const char *name, const struct group_entry *entry,
-                FILE *output)
-{
-    fprintf(output, "%s %lu %lu %lu %lu %c %lu %lu\n", name, entry->high,
-            entry->low, entry->base, (unsigned long) entry->count,
-            entry->flag, (unsigned long) entry->deleted,
-            (unsigned long) entry->indexinode);
-}
-
-
-/*
-**  Dump the complete contents of the group.index file in human-readable form
-**  to the specified file, one line per group.
-*/
-void
-tdx_index_dump(struct group_index *index, FILE *output)
-{
-    int bucket;
-    long current;
-    struct group_entry *entry;
-    struct hash *hashmap;
-    struct hashmap *group;
-    char *name;
-
-    if (index->header == NULL || index->entries == NULL)
-        return;
-    hashmap = hashmap_load();
-    for (bucket = 0; bucket < TDX_HASH_SIZE; bucket++) {
-        current = index->header->hash[bucket].recno;
-        while (current != -1) {
-            if (!index_maybe_remap(index, current))
-                return;
-            entry = index->entries + current;
-            name = NULL;
-            if (hashmap != NULL) {
-                group = hash_lookup(hashmap, &entry->hash);
-                if (group != NULL)
-                    name = group->name;
-            }
-            if (name == NULL)
-                name = HashToText(entry->hash);
-            tdx_index_print(name, entry, output);
-            if (current == entry->next.recno) {
-                warn("tradindexed: index loop for entry %ld", current);
-                return;
-            }
-            current = entry->next.recno;
-        }
-    }
-    if (hashmap != NULL)
-        hash_free(hashmap);
-}
-
-
-/*
-**  Audit a particular group entry location to ensure that it points to a
-**  valid entry within the group index file.  Takes a pointer to the location,
-**  the number of the location, a pointer to the group entry if any (if not,
-**  the location is assumed to be part of the header hash table), and a flag
-**  saying whether to fix problems that are found.
-*/
-static void
-index_audit_loc(struct group_index *index, int *loc, long number,
-                struct group_entry *entry, bool fix)
-{
-    bool error = false;
-
-    if (*loc >= index->count) {
-        warn("tradindexed: out of range index %d in %s %ld",
-             *loc, (entry == NULL ? "bucket" : "entry"), number);
-        error = true;
-    }
-    if (*loc < 0 && *loc != -1) {
-        warn("tradindexed: invalid negative index %d in %s %ld",
-             *loc, (entry == NULL ? "bucket" : "entry"), number);
-        error = true;
-    }
-    if (entry != NULL && *loc == number) {
-        warn("tradindexed: index loop for entry %ld", number);
-        error = true;
-    }
-
-    if (fix && error) {
-        *loc = -1;
-        inn_mapcntl(loc, sizeof(*loc), MS_ASYNC);
-    }
-}
-
-
-/*
-**  Check an entry to see if it was actually deleted.  Make sure that all the
-**  information is consistent with a deleted group if it's not and the fix
-**  flag is set.
-*/
-static void
-index_audit_deleted(struct group_entry *entry, long number, bool fix)
-{
-    if (entry->deleted != 0 && !HashEmpty(entry->hash)) {
-        warn("tradindexed: entry %ld has a delete time but a non-zero hash",
-             number);
-        if (fix) {
-            HashClear(&entry->hash);
-            inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-        }
-    }
-}
-
-
-/*
-**  Audit the group header for any inconsistencies.  This checks the
-**  reachability of all of the group entries, makes sure that deleted entries
-**  are on the free list, and otherwise checks the linked structure of the
-**  whole file.  The data in individual entries is not examined.  If the
-**  second argument is true, also attempt to fix inconsistencies.
-*/
-static void
-index_audit_header(struct group_index *index, bool fix)
-{
-    long bucket, current;
-    struct group_entry *entry;
-    int *parent, *next;
-    bool *reachable;
-
-    /* First, walk all of the regular hash buckets, making sure that all of
-       the group location pointers are valid and sane, that all groups that
-       have been deleted are correctly marked as such, and that all groups are
-       in their correct hash chain.  Build reachability information as we go,
-       used later to ensure that all group entries are reachable. */
-    reachable = xcalloc(index->count, sizeof(bool));
-    for (bucket = 0; bucket < TDX_HASH_SIZE; bucket++) {
-        parent = &index->header->hash[bucket].recno;
-        index_audit_loc(index, parent, bucket, NULL, fix);
-        current = *parent;
-        while (current >= 0 && current < index->count) {
-            entry = &index->entries[current];
-            next = &entry->next.recno;
-            if (entry->deleted == 0 && bucket != index_bucket(entry->hash)) {
-                warn("tradindexed: entry %ld is in bucket %ld instead of its"
-                     " correct bucket %ld", current, bucket,
-                     index_bucket(entry->hash));
-                if (fix) {
-                    entry_splice(entry, parent);
-                    next = parent;
-                }
-            } else {
-                if (reachable[current])
-                    warn("tradindexed: entry %ld is reachable from multiple"
-                         " paths", current);
-                reachable[current] = true;
-            }
-            index_audit_deleted(entry, current, fix);
-            index_audit_loc(index, &entry->next.recno, current, entry, fix);
-            if (entry->deleted != 0) {
-                warn("tradindexed: entry %ld is deleted but not in the free"
-                     " list", current);
-                if (fix) {
-                    entry_splice(entry, parent);
-                    next = parent;
-                    reachable[current] = false;
-                }
-            }
-            if (*next == current)
-                break;
-            parent = next;
-            current = *parent;
-        }
-    }
-
-    /* Now, walk the free list.  Make sure that each group in the free list is
-       actually deleted, and update the reachability information. */
-    index_audit_loc(index, &index->header->freelist.recno, 0, NULL, fix);
-    parent = &index->header->freelist.recno;
-    current = *parent;
-    while (current >= 0 && current < index->count) {
-        entry = &index->entries[current];
-        index_audit_deleted(entry, current, fix);
-        reachable[current] = true;
-        if (!HashEmpty(entry->hash) && entry->deleted == 0) {
-            warn("tradindexed: undeleted entry %ld in free list", current);
-            if (fix) {
-                entry_splice(entry, parent);
-                reachable[current] = false;
-            }
-        }
-        index_audit_loc(index, &entry->next.recno, current, entry, fix);
-        if (entry->next.recno == current)
-            break;
-        parent = &entry->next.recno;
-        current = *parent;
-    }
-
-    /* Finally, check all of the unreachable entries and if fix is true, try
-       to reattach them in the appropriate location. */
-    for (current = 0; current < index->count; current++)
-        if (!reachable[current]) {
-            warn("tradindexed: unreachable entry %ld", current);
-            if (fix) {
-                entry = &index->entries[current];
-                if (!HashEmpty(entry->hash) && entry->deleted == 0)
-                    index_add(index, entry);
-                else {
-                    HashClear(&entry->hash);
-                    entry->deleted = 0;
-                    freelist_add(index, entry);
-                }
-            }
-        }
-
-    /* All done. */
-    free(reachable);
-}
-
-
-/*
-**  Audit a particular group entry for any inconsistencies.  This doesn't
-**  check any of the structure, or whether the group is deleted, just the data
-**  as stored in the group data files (mostly by calling tdx_data_audit to do
-**  the real work).  Note that while the low water mark may be updated, the
-**  high water mark is left unchanged.
-*/
-static void
-index_audit_group(struct group_index *index, struct group_entry *entry,
-                  struct hash *hashmap, bool fix)
-{
-    struct hashmap *group;
-    ptrdiff_t offset;
-
-    offset = entry - index->entries;
-    index_lock_group(index->fd, offset, INN_LOCK_WRITE);
-    group = hash_lookup(hashmap, &entry->hash);
-    if (group == NULL) {
-        warn("tradindexed: group %ld not found in active file",
-             entry_loc(index, entry));
-        if (fix) {
-            index_unlink_hash(index, entry->hash);
-            HashClear(&entry->hash);
-            entry->deleted = time(NULL);
-            freelist_add(index, entry);
-        }
-    } else {
-        if (entry->flag != group->flag) {
-            entry->flag = group->flag;
-            inn_mapcntl(entry, sizeof(*entry), MS_ASYNC);
-        }
-        tdx_data_audit(group->name, entry, fix);
-    }
-    index_lock_group(index->fd, offset, INN_LOCK_UNLOCK);
-}
-
-
-/*
-**  Check to be sure that a given group exists in the overview index, and if
-**  missing, adds it.  Assumes that the index isn't locked, since it calls the
-**  normal functions for adding new groups (this should only be called after
-**  the index has already been repaired, for the same reason).  Called as a
-**  hash traversal function, walking the hash table of groups from the active
-**  file.
-*/
-static void
-index_audit_active(void *value, void *cookie)
-{
-    struct hashmap *group = value;
-    struct audit_data *data = cookie;
-    struct group_entry *entry;
-
-    entry = tdx_index_entry(data->index, group->name);
-    if (entry == NULL) {
-        warn("tradindexed: group %s missing from overview", group->name);
-        if (data->fix)
-            tdx_index_add(data->index, group->name, 0, 0, &group->flag);
-    }
-}
-
-
-/*
-**  Audit the group index for any inconsistencies.  If the argument is true,
-**  also attempt to fix those inconsistencies.
-*/
-void
-tdx_index_audit(bool fix)
-{
-    struct group_index *index;
-    struct stat st;
-    off_t expected;
-    int count;
-    struct hash *hashmap;
-    long bucket;
-    struct group_entry *entry;
-    struct audit_data data;
-
-    index = tdx_index_open(true);
-    if (index == NULL)
-        return;
-
-    /* Keep a lock on the header through the whole audit process.  This will
-       stall any newgroups or rmgroups, but not normal article reception.  We
-       don't want the structure of the group entries changing out from under
-       us, although we don't mind if the data does until we're validating that
-       particular group. */
-    index_lock(index->fd, INN_LOCK_WRITE);
-
-    /* Make sure the size looks sensible. */
-    if (fstat(index->fd, &st) < 0) {
-        syswarn("tradindexed: cannot fstat %s", index->path);
-        return;
-    }
-    count = index_entry_count(st.st_size);
-    expected = index_file_size(count);
-    if (expected != st.st_size) {
-        syswarn("tradindexed: %ld bytes of trailing trash in %s",
-                (unsigned long) (st.st_size - expected), index->path);
-        if (fix)
-            if (ftruncate(index->fd, expected) < 0)
-                syswarn("tradindexed: cannot truncate %s", index->path);
-    }
-    index_maybe_remap(index, count);
-
-    /* Okay everything is now mapped and happy.  Validate the header. */
-    index_audit_header(index, fix);
-    index_lock(index->fd, INN_LOCK_UNLOCK);
-
-    /* Walk all the group entries and check them individually.  To do this, we
-       need to map hashes to group names, so load a hash of the active file to
-       do that resolution. */
-    hashmap = hashmap_load();
-    data.index = index;
-    data.fix = fix;
-    hash_traverse(hashmap, index_audit_active, &data);
-    for (bucket = 0; bucket < index->count; bucket++) {
-        entry = &index->entries[bucket];
-        if (HashEmpty(entry->hash) || entry->deleted != 0)
-            continue;
-        index_audit_group(index, entry, hashmap, fix);
-    }
-    if (hashmap != NULL)
-        hash_free(hashmap);
-}
diff --git a/storage/tradindexed/tdx-private.h b/storage/tradindexed/tdx-private.h
deleted file mode 100644 (file)
index 42e4701..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*  $Id: tdx-private.h 5465 2002-05-06 05:46:15Z rra $
-**
-**  Private APIs for the tradindexed overview method.
-*/
-
-#ifndef INN_TDX_PRIVATE_H
-#define INN_TDX_PRIVATE_H 1
-
-#include "config.h"
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "libinn.h"
-#include "storage.h"
-
-/* Forward declarations to avoid unnecessary includes. */
-struct history;
-
-/* Opaque data structure used by the cache. */
-struct cache;
-
-/* Opaque data structure returned by group index functions. */
-struct group_index;
-
-/* Opaque data structure returned by search functions. */
-struct search;
-
-/* All of the information about an open set of group data files. */
-struct group_data {
-    char *path;
-    bool writable;
-    ARTNUM high;
-    ARTNUM base;
-    int indexfd;
-    int datafd;
-    struct index_entry *index;
-    char *data;
-    off_t indexlen;
-    off_t datalen;
-    ino_t indexinode;
-    int refcount;
-};
-
-/* All of the data about an article, used as the return of the search
-   functions.  This is just cleaner than passing back all of the information
-   that's used by the regular interface. */
-struct article {
-    ARTNUM number;
-    const char *overview;
-    size_t overlen;
-    TOKEN token;
-    time_t arrived;
-    time_t expires;
-};
-
-BEGIN_DECLS
-
-/* tdx-cache.c */
-
-/* Create a new cache with the given number of entries. */
-struct cache *tdx_cache_create(unsigned int size);
-
-/* Look up a given newsgroup hash in the cache, returning the group_data
-   struct for its open data files if present. */
-struct group_data *tdx_cache_lookup(struct cache *, HASH);
-
-/* Insert a new group_data struct into the cache. */
-void tdx_cache_insert(struct cache *, HASH, struct group_data *);
-
-/* Delete a group entry from the cache. */
-void tdx_cache_delete(struct cache *, HASH);
-
-/* Free the cache and its resources. */
-void tdx_cache_free(struct cache *);
-
-
-/* tdx-group.c */
-
-/* Open the group index and return an opaque data structure to use for further
-   queries. */
-struct group_index *tdx_index_open(bool writable);
-
-/* Return the stored information about a single newsgroup. */
-struct group_entry *tdx_index_entry(struct group_index *, const char *group);
-
-/* Print the contents of a single group entry in human-readable form. */
-void tdx_index_print(const char *name, const struct group_entry *, FILE *);
-
-/* Add a new newsgroup to the index file. */
-bool tdx_index_add(struct group_index *, const char *group, ARTNUM low,
-                   ARTNUM high, const char *flag);
-
-/* Delete a newsgroup from the index file. */
-bool tdx_index_delete(struct group_index *, const char *group);
-
-/* Dump the contents of the index file to stdout in human-readable form. */
-void tdx_index_dump(struct group_index *, FILE *);
-
-/* Audit all of the overview data, optionally trying to fix it. */
-void tdx_index_audit(bool fix);
-
-/* Close the open index file and dispose of the opaque data structure. */
-void tdx_index_close(struct group_index *);
-
-/* Open the overview information for a particular group. */
-struct group_data *tdx_data_open(struct group_index *, const char *group,
-                                 struct group_entry *);
-
-/* Add a new overview entry. */
-bool tdx_data_add(struct group_index *, struct group_entry *,
-                  struct group_data *, const struct article *);
-
-/* Handle rebuilds of the data for a particular group.  Call _start first and
-   then _finish when done, with the new group_entry information. */
-bool tdx_index_rebuild_start(struct group_index *, struct group_entry *);
-bool tdx_index_rebuild_finish(struct group_index *, struct group_entry *,
-                              struct group_entry *new);
-
-/* Expire a single group. */
-bool tdx_expire(const char *group, ARTNUM *low, struct history *);
-
-
-/* tdx-data.c */
-
-/* Create a new group data structure. */
-struct group_data *tdx_data_new(const char *group, bool writable);
-
-/* Open the data files for a group. */
-bool tdx_data_open_files(struct group_data *);
-
-/* Return the metadata about a particular article in a group. */
-const struct index_entry *tdx_article_entry(struct group_data *,
-                                            ARTNUM article, ARTNUM high);
-
-/* Create, perform, and close a search. */
-struct search *tdx_search_open(struct group_data *, ARTNUM start, ARTNUM end,
-                               ARTNUM high);
-bool tdx_search(struct search *, struct article *);
-void tdx_search_close(struct search *);
-
-/* Store article data. */
-bool tdx_data_store(struct group_data *, const struct article *);
-
-/* Start a repack of the files for a newsgroup. */
-bool tdx_data_pack_start(struct group_data *, ARTNUM);
-
-/* Complete a repack of the files for a newsgroup. */
-bool tdx_data_pack_finish(struct group_data *);
-
-/* Manage a rebuild of the data files for a particular group.  Until
-   tdx_data_rebuild_finish is called, anything stored into the returned struct
-   group_data will have no effect on the data for that group.  Does not handle
-   updating the index entries; that must be done separately. */
-struct group_data *tdx_data_rebuild_start(const char *group);
-bool tdx_data_rebuild_finish(const char *group);
-
-/* Start the expiration of a newsgroup and do most of the work, filling out
-   the provided group_entry struct.  Complete with tdx_data_rebuild_finish. */
-bool tdx_data_expire_start(const char *group, struct group_data *,
-                           struct group_entry *, struct history *);
-
-/* Dump the contents of the index file for a group. */
-void tdx_data_index_dump(struct group_data *, FILE *);
-
-/* Audit the data for a particular group, optionally trying to fix it. */
-void tdx_data_audit(const char *group, struct group_entry *, bool fix);
-
-/* Close the open data files for a group and free the structure. */
-void tdx_data_close(struct group_data *);
-
-/* Delete the data files for a group. */
-void tdx_data_delete(const char *group, const char *suffix);
-
-END_DECLS
-
-#endif /* INN_TDX_PRIVATE_H */
diff --git a/storage/tradindexed/tdx-structure.h b/storage/tradindexed/tdx-structure.h
deleted file mode 100644 (file)
index af9868c..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*  $Id: tdx-structure.h 5327 2002-03-16 00:33:55Z rra $
-**
-**  Data structures for the tradindexed overview method.
-**
-**  This header defines the data structures used by the tradindexed overview
-**  method.  Currently, these data structures are read and written directly to
-**  disk (and the disk files are therefore endian-dependent and possibly
-**  architecture-dependent due to structure padding).  This will eventually be
-**  fixed.
-**
-**  The structure of a tradindexed overview spool is as follows:  At the root
-**  of the spool is a group.index file composed of a struct group_header
-**  followed by some number of struct group_entry's, one for each group plus
-**  possibly some number of free entries linked to a free list that's headed
-**  in the struct index_header.  Each entry corresponds to a particular
-**  newsgroup carried by the server and stores the high and low article
-**  numbers for that group, its status flag, and the base of the index file
-**  for each group.
-**
-**  The storage of the group.index file implements a hash table with chaining;
-**  in other words, there is a table indexed by hash value stored in the
-**  header that points to the starts of the chains, new entries are appended
-**  to the end of the file and added to the hash table, and if they collide
-**  with an existing entry are instead linked to the appropriate hash chain.
-**
-**  The overview information for each group is stored in a pair of files named
-**  <group>.IDX and <group>.DAT.  These files are found in a subdirectory
-**  formed by taking the first letter of component of the newsgroup name as
-**  a directory name; in other words, news.announce.newgroups overview data is
-**  stored in <pathoverview>/n/a/n/news.announce.newgroups.{IDX,DAT}.  The
-**  .DAT file contains the individual overview entries, one per line, stored
-**  in wire format (in other words, suitable for dumping directly across the
-**  network to a client in response to an XOVER command).  The overview data
-**  stored in that file may be out of order.
-**
-**  The .IDX file consists of a series of struct index_entry's, one for each
-**  overview entry stored in the .DAT file.  Each index entry stores the
-**  offset of the data for one article in the .DAT file and its length, along
-**  with some additional metainformation about the article used to drive
-**  article expiration.  The .IDX file is addressed like an array; the first
-**  entry corresponds to the article with the number stored in the base field
-**  of the group_entry for that newsgroup in the group.index file and each
-**  entry stores the data for the next consecutive article.  Index entries may
-**  be tagged as deleted if that article has been deleted or expired.
-*/
-
-#ifndef INN_TDX_STRUCTURE_H
-#define INN_TDX_STRUCTURE_H 1
-
-#include "config.h"
-#include <sys/types.h>
-
-#include "libinn.h"
-#include "storage.h"
-
-/* A location in group.index (this many records past the end of the header of
-   the file).  There's no reason for this to be a struct, but that can't be
-   changed until the format of the group.index file is changed to be
-   architecture-independent since putting it into a struct may have changed
-   the alignment or padding on some architectures. */
-struct loc {
-    int recno;
-};
-
-/* The hard-coded constant size of the hash table for group.index.  This need
-   not be a power of two and has no special constraints.  Changing this at
-   present will break backward compatibility with group.index files written by
-   previous versions of the code. */
-#define TDX_HASH_SIZE   (16 * 1024)
-
-/* A magic number for the group.index file so that we can later change the
-   format in a backward-compatible fashion. */
-#define TDX_MAGIC       (~(0xf1f0f33d))
-
-/* The header at the top of group.index.  magic contains GROUPHEADERMAGIC
-   always; hash contains pointers to the heads of the entry chains, and
-   freelist points to a linked list of free entries (entries that were used
-   for groups that have since been deleted). */
-struct group_header {
-    int         magic;
-    struct loc  hash[TDX_HASH_SIZE];
-    struct loc  freelist;
-};
-
-/* An entry for a particular group.  Note that a good bit of active file
-   information is duplicated here, and depending on the portion of INN asking
-   questions, sometimes the main active file is canonical and sometimes the
-   overview data is canonical.  This needs to be rethought at some point.
-
-   Groups are matched based on the MD5 hash of their name.  This may prove
-   inadequate in the future.  Ideally, INN really needs to assign unique
-   numbers to each group, which could then be used here as well as in
-   tradspool rather than having to do hacks like using a hash of the group
-   name or constructing one's own number to name mapping like tradspool does.
-   Unfortunately, this ideally requires a non-backward-compatible change to
-   the active file format.
-
-   Several of these elements aren't used.  This structure, like the others,
-   cannot be changed until the whole format of the group.index file is changed
-   since it's currently read as binary structs directly from disk. */
-struct group_entry {
-    HASH        hash;           /* MD5 hash of the group name. */
-    HASH        alias;          /* Intended to point to the group this group
-                                   is an alias for.  Not currently used. */
-    ARTNUM      high;           /* High article number in the group. */
-    ARTNUM      low;            /* Low article number in the group. */
-    ARTNUM      base;           /* Article number of the first entry in the
-                                   .IDX index file for the group. */
-    int         count;          /* Number of articles in group. */
-    int         flag;           /* Posting/moderation status. */
-    time_t      deleted;        /* When this group was deleted, or 0 if the
-                                   group is still valid. */    
-    ino_t       indexinode;     /* The inode of the index file for the group,
-                                   used to detect when the file has been
-                                   recreated and swapped out. */
-    struct loc  next;           /* Next block in this chain. */
-};
-
-/* An entry in the per-group .IDX index file. */
-struct index_entry {
-    off_t       offset;
-    int         length;
-    time_t      arrived;
-    time_t      expires;        /* Expiration time from Expires: header. */
-    TOKEN       token;
-};
-
-#endif /* INN_TDX_STRUCTURE_H */
diff --git a/storage/tradindexed/tdx-util.c b/storage/tradindexed/tdx-util.c
deleted file mode 100644 (file)
index c1b004b..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*  $Id: tdx-util.c 6289 2003-04-09 04:16:16Z rra $
-**
-**  Utility for managing a tradindexed overview spool.
-**
-**  This utility can manipulate a tradindexed overview spool in various ways,
-**  including some ways that are useful for recovery from crashes.  It allows
-**  the user to view the contents of the various data structures that
-**  tradindexed stores on disk.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <pwd.h>
-#include <sys/stat.h>
-
-#include "inn/buffer.h"
-#include "inn/history.h"
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "ov.h"
-#include "ovinterface.h"
-#include "paths.h"
-#include "tdx-private.h"
-#include "tdx-structure.h"
-
-/*
-**  Dump the main index data, either all of it or that for a particular group
-**  if the group argument is non-NULL.
-*/
-static void
-dump_index(const char *group)
-{
-    struct group_index *index;
-
-    index = tdx_index_open(OV_READ);
-    if (index == NULL)
-        return;
-    if (group == NULL)
-        tdx_index_dump(index, stdout);
-    else {
-        const struct group_entry *entry;
-
-        entry = tdx_index_entry(index, group);
-        if (entry == NULL) {
-            warn("cannot find group %s", group);
-            return;
-        }
-        tdx_index_print(group, entry, stdout);
-    }
-    tdx_index_close(index);
-}
-
-
-/*
-**  Dump the data index file for a particular group.
-*/
-static void
-dump_group_index(const char *group)
-{
-    struct group_index *index;
-    struct group_entry *entry;
-    struct group_data *data;
-
-    index = tdx_index_open(OV_READ);
-    if (index == NULL)
-        return;
-    entry = tdx_index_entry(index, group);
-    if (entry == NULL) {
-        warn("cannot find group %s in the index", group);
-        return;
-    }
-    data = tdx_data_open(index, group, entry);
-    if (data == NULL) {
-        warn("cannot open group %s", group);
-        return;
-    }
-    tdx_data_index_dump(data, stdout);
-    tdx_data_close(data);
-    tdx_index_close(index);
-}
-
-
-/*
-**  Dump the overview data for a particular group.  If number is 0, dump the
-**  overview data for all current articles; otherwise, only dump the data for
-**  that particular article.  Include the article number, token, arrived time,
-**  and expires time (if any) in the overview data as additional fields.
-*/
-static void
-dump_overview(const char *group, ARTNUM number)
-{
-    struct group_index *index;
-    struct group_data *data;
-    struct group_entry *entry;
-    struct article article;
-    struct search *search;
-    char datestring[256];
-
-    index = tdx_index_open(OV_READ);
-    if (index == NULL)
-        return;
-    entry = tdx_index_entry(index, group);
-    if (entry == NULL) {
-        warn("cannot find group %s", group);
-        return;
-    }
-    data = tdx_data_open(index, group, entry);
-    if (data == NULL) {
-        warn("cannot open group %s", group);
-        return;
-    }
-    data->refcount++;
-
-    if (number != 0)
-        search = tdx_search_open(data, number, number, entry->high);
-    else
-        search = tdx_search_open(data, entry->low, entry->high, entry->high);
-    if (search == NULL) {
-        if (number != 0)
-            puts("Article not found");
-        else
-            warn("cannot open search in %s: %lu - %lu", group, entry->low,
-                 entry->high);
-        return;
-    }
-    while (tdx_search(search, &article)) {
-        fwrite(article.overview, article.overlen - 2, 1, stdout);
-        printf("\tArticle: %lu\tToken: %s", article.number,
-               TokenToText(article.token));
-        makedate(article.arrived, true, datestring, sizeof(datestring));
-        printf("\tArrived: %s", datestring);
-        if (article.expires != 0) {
-            makedate(article.expires, true, datestring, sizeof(datestring));
-            printf("\tExpires: %s", datestring);
-        }
-        printf("\n");
-    }
-    tdx_search_close(search);
-    tdx_data_close(data);
-    tdx_index_close(index);
-}
-
-
-/*
-**  Check a string to see if its a valid number.
-*/
-static bool
-check_number(const char *string)
-{
-    const char *p;
-
-    for (p = string; *p != '\0'; p++)
-        if (!CTYPE(isdigit, *p))
-            return false;
-    return true;
-}
-
-
-/*
-**  Find the message ID in the group overview data and return a copy of it.
-**  Caller is responsible for freeing.
-*/
-static char *
-extract_messageid(const char *overview)
-{
-    const char *p, *end;
-    int count;
-
-    for (p = overview, count = 0; count < 4; count++) {
-        p = strchr(p + 1, '\t');
-        if (p == NULL)
-            return NULL;
-    }
-    p++;
-    end = strchr(p, '\t');
-    if (end == NULL)
-        return NULL;
-    return xstrndup(p, end - p);
-}
-
-
-/*
-**  Compare two file names assuming they're numbers, used to sort the list of
-**  articles numerically.  Suitable for use as a comparison function for
-**  qsort.
-*/
-static int
-file_compare(const void *p1, const void *p2)
-{
-    const char *file1 = *((const char * const *) p1);
-    const char *file2 = *((const char * const *) p2);
-    ARTNUM n1, n2;
-
-    n1 = strtoul(file1, NULL, 10);
-    n2 = strtoul(file2, NULL, 10);
-    if (n1 > n2)
-        return 1;
-    else if (n1 < n2)
-        return -1;
-    else
-        return 0;
-}
-
-
-/*
-**  Get a list of articles in a directory, sorted by article number.
-*/
-static struct vector *
-article_list(const char *directory)
-{
-    DIR *articles;
-    struct dirent *file;
-    struct vector *list;
-
-    list = vector_new();
-    articles = opendir(directory);
-    if (articles == NULL)
-        sysdie("cannot open directory %s", directory);
-    while ((file = readdir(articles)) != NULL) {
-        if (!check_number(file->d_name))
-            continue;
-        vector_add(list, file->d_name);
-    }
-    closedir(articles);
-
-    qsort(list->strings, list->count, sizeof(list->strings[0]), file_compare);
-    return list;
-}
-
-
-/*
-**  Rebuild the overview data for a particular group.  Takes a path to a
-**  directory containing all the articles, as individual files, that should be
-**  in that group.  The names of the files should be the article numbers in
-**  the group.
-*/
-static void
-group_rebuild(const char *group, const char *path)
-{
-    char *filename, *histpath, *article, *wireformat, *p;
-    size_t size, file;
-    int flags, length;
-    struct buffer *overview = NULL;
-    struct vector *extra, *files;
-    struct history *history;
-    struct group_index *index;
-    struct group_data *data;
-    struct group_entry *entry, info;
-    struct article artdata;
-    struct stat st;
-
-    index = tdx_index_open(OV_READ);
-    if (index == NULL)
-        die("cannot open group index");
-    entry = tdx_index_entry(index, group);
-    if (entry == NULL) {
-        if (!tdx_index_add(index, group, 1, 0, "y"))
-            die("cannot create group %s", group);
-        entry = tdx_index_entry(index, group);
-        if (entry == NULL)
-            die("cannot find group %s", group);
-    }
-    info = *entry;
-    data = tdx_data_rebuild_start(group);
-    if (data == NULL)
-        die("cannot start data rebuild for %s", group);
-    if (!tdx_index_rebuild_start(index, entry))
-        die("cannot start index rebuild for %s", group);
-
-    histpath = concatpath(innconf->pathdb, _PATH_HISTORY);
-    flags = HIS_RDONLY | HIS_ONDISK;
-    history = HISopen(histpath, innconf->hismethod, flags);
-    if (history == NULL)
-        sysdie("cannot open history %s", histpath);
-    free(histpath);
-
-    extra = overview_extra_fields();
-    files = article_list(path);
-
-    info.count = 0;
-    info.high = 0;
-    info.low = 0;
-    for (file = 0; file < files->count; file++) {
-        filename = concatpath(path, files->strings[file]);
-        article = ReadInFile(filename, &st);
-        size = st.st_size;
-        if (article == NULL) {
-            syswarn("cannot read in %s", filename);
-            free(filename);
-            continue;
-        }
-
-        /* Check to see if the article is not in wire format.  If it isn't,
-           convert it.  We only check the first line ending. */
-        p = strchr(article, '\n');
-        if (p != NULL && (p == article || p[-1] != '\r')) {
-            wireformat = ToWireFmt(article, size, (size_t *)&length);
-            free(article);
-            article = wireformat;
-            size = length;
-        }
-
-        artdata.number = strtoul(files->strings[file], NULL, 10);
-        if (artdata.number > info.high)
-            info.high = artdata.number;
-        if (artdata.number < info.low || info.low == 0)
-            info.low = artdata.number;
-        info.count++;
-        overview = overview_build(artdata.number, article, size, extra,
-                                  overview);
-        artdata.overview = overview->data;
-        artdata.overlen = overview->left;
-        p = extract_messageid(overview->data);
-        if (p == NULL) {
-            warn("cannot find message ID in %s", filename);
-            free(filename);
-            free(article);
-            continue;
-        }
-        if (HISlookup(history, p, &artdata.arrived, NULL, &artdata.expires,
-                      &artdata.token)) {
-            if (!tdx_data_store(data, &artdata))
-                warn("cannot store data for %s", filename);
-        } else {
-            warn("cannot find article %s in history", p);
-        }
-        free(p);
-        free(filename);
-        free(article);
-    }
-    vector_free(files);
-    vector_free(extra);
-
-    info.indexinode = data->indexinode;
-    info.base = data->base;
-    if (!tdx_index_rebuild_finish(index, entry, &info))
-        die("cannot update group index for %s", group);
-    if (!tdx_data_rebuild_finish(group))
-        die("cannot finish rebuilding data for group %s", group);
-    tdx_data_close(data);
-    HISclose(history);
-}
-
-
-/*
-**  Change to the news user if possible, and if not, die.  Used for operations
-**  that may change the overview files so as not to mess up the ownership.
-*/
-static void
-setuid_news(void)
-{
-    struct passwd *pwd;
-
-    pwd = getpwnam(NEWSUSER);
-    if (pwd == NULL)
-        die("can't resolve %s to a UID (account doesn't exist?)", NEWSUSER);
-    if (getuid() == 0)
-        setuid(pwd->pw_uid);
-    if (getuid() != pwd->pw_uid)
-        die("must be run as %s", NEWSUSER);
-}
-
-
-/*
-**  Main routine.  Load inn.conf, parse the arguments, and dispatch to the
-**  appropriate function.
-*/
-int
-main(int argc, char *argv[])
-{
-    int option;
-    char mode = '\0';
-    const char *newsgroup = NULL;
-    const char *path = NULL;
-    ARTNUM article = 0;
-
-    message_program_name = "tdx-util";
-
-    if (!innconf_read(NULL))
-        exit(1);
-
-    /* Parse options. */
-    opterr = 0;
-    while ((option = getopt(argc, argv, "a:n:p:AFR:gio")) != EOF) {
-        switch (option) {
-        case 'a':
-            article = strtoul(optarg, NULL, 10);
-            if (article == 0)
-                die("invalid article number %s", optarg);
-            break;
-        case 'n':
-            newsgroup = optarg;
-            break;
-        case 'p':
-            innconf->pathoverview = xstrdup(optarg);
-            break;
-        case 'A':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'A';
-            break;
-        case 'F':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'F';
-            break;
-        case 'R':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'R';
-            path = optarg;
-            break;
-        case 'g':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'g';
-            break;
-        case 'i':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'i';
-            break;
-        case 'o':
-            if (mode != '\0')
-                die("only one mode option allowed");
-            mode = 'o';
-            break;
-        default:
-            die("invalid option %c", optopt);
-            break;
-        }
-    }
-
-    /* Modes g and o require a group be specified. */
-    if ((mode == 'g' || mode == 'o' || mode == 'R') && newsgroup == NULL)
-        die("group must be specified for -%c", mode);
-
-    /* Run the specified function. */
-    switch (mode) {
-    case 'A':
-        tdx_index_audit(false);
-        break;
-    case 'F':
-        setuid_news();
-        tdx_index_audit(true);
-        break;
-    case 'R':
-        setuid_news();
-        group_rebuild(newsgroup, path);
-        break;
-    case 'i':
-        dump_index(newsgroup);
-        break;
-    case 'g':
-        dump_group_index(newsgroup);
-        break;
-    case 'o':
-        dump_overview(newsgroup, article);
-        break;
-    default:
-        die("a mode option must be specified");
-        break;
-    }
-    exit(0);
-}
diff --git a/storage/tradindexed/tradindexed.c b/storage/tradindexed/tradindexed.c
deleted file mode 100644 (file)
index b21cd0b..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*  $Id: tradindexed.c 7138 2005-03-16 18:15:51Z hkehoe $
-**
-**  Interface implementation for the tradindexed overview method.
-**
-**  This code converts between the internal interface used by the tradindexed
-**  implementation and the interface expected by the INN overview API.  The
-**  internal interface is in some cases better suited to the data structures
-**  that the tradindexed overview method uses, and this way the internal
-**  interface can be kept isolated from the external interface.  (There are
-**  also some operations that can be performed entirely in the interface
-**  layer.)
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "ov.h"
-#include "storage.h"
-#include "tdx-private.h"
-#include "tdx-structure.h"
-#include "tradindexed.h"
-
-/* This structure holds all of the data about the open overview files.  We can
-   eventually pass one of these structures back to the caller of open when the
-   overview API is more object-oriented. */
-struct tradindexed {
-    struct group_index *index;
-    struct cache *cache;
-    bool cutoff;
-};
-
-/* Global data about the open tradindexed method. */
-static struct tradindexed *tradindexed;
-
-
-/*
-**  Helper function to open a group_data structure via the cache, inserting it
-**  into the cache if it wasn't found in the cache.
-*/
-static struct group_data *
-data_cache_open(struct tradindexed *global, const char *group,
-                struct group_entry *entry)
-{
-    struct group_data *data;
-
-    data = tdx_cache_lookup(global->cache, entry->hash);
-    if (data == NULL) {
-        data = tdx_data_open(global->index, group, entry);
-        if (data == NULL)
-            return NULL;
-        tdx_cache_insert(global->cache, entry->hash, data);
-    }
-    return data;
-}
-
-
-/*
-**  Helper function to reopen the data files and remove the old entry from the
-**  cache if we think that might help better fulfill a search.
-*/
-static struct group_data *
-data_cache_reopen(struct tradindexed *global, const char *group,
-                  struct group_entry *entry)
-{
-    struct group_data *data;
-
-    tdx_cache_delete(global->cache, entry->hash);
-    data = tdx_data_open(global->index, group, entry);
-    if (data == NULL)
-        return NULL;
-    tdx_cache_insert(global->cache, entry->hash, data);
-    return data;
-}
-
-
-/*
-**  Open the overview method.
-*/
-bool
-tradindexed_open(int mode)
-{
-    unsigned int cache_size, fdlimit;
-
-    if (tradindexed != NULL) {
-        warn("tradindexed: overview method already open");
-        return false;
-    }
-    tradindexed = xmalloc(sizeof(struct tradindexed));
-    tradindexed->index = tdx_index_open((mode & OV_WRITE) ? true : false);
-    tradindexed->cutoff = false;
-
-    /* Use a cache size of two for read-only connections.  We may want to
-       rethink the limitation of the cache for reading later based on
-       real-world experience. */
-    cache_size = (mode & OV_WRITE) ? innconf->overcachesize : 1;
-    fdlimit = getfdlimit();
-    if (fdlimit > 0 && fdlimit < cache_size * 2) {
-        warn("tradindexed: not enough file descriptors for an overview cache"
-             " size of %u; increase rlimitnofile or decrease overcachesize"
-             " to at most %u", cache_size, fdlimit / 2);
-        cache_size = (fdlimit > 2) ? fdlimit / 2 : 1;
-    }
-    tradindexed->cache = tdx_cache_create(cache_size);
-
-    return (tradindexed->index == NULL) ? false : true;
-}
-
-
-/*
-**  Get statistics about a group.  Convert between the multiple pointer API
-**  and the structure API used internally.
-*/
-bool
-tradindexed_groupstats(char *group, int *low, int *high, int *count,
-                       int *flag)
-{
-    const struct group_entry *entry;
-
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-    entry = tdx_index_entry(tradindexed->index, group);
-    if (entry == NULL)
-        return false;
-    if (low != NULL)
-        *low = entry->low;
-    if (high != NULL)
-        *high = entry->high;
-    if (count != NULL)
-        *count = entry->count;
-    if (flag != NULL)
-        *flag = entry->flag;
-    return true;
-}
-
-
-/*
-**  Add a new newsgroup to the index.
-*/
-bool
-tradindexed_groupadd(char *group, ARTNUM low, ARTNUM high, char *flag)
-{
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-    return tdx_index_add(tradindexed->index, group, low, high, flag);
-}
-
-
-/*
-**  Delete a newsgroup from the index.
-*/
-bool
-tradindexed_groupdel(char *group)
-{
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-    return tdx_index_delete(tradindexed->index, group);
-}
-
-
-/*
-**  Add data about a single article.  Convert between the multiple argument
-**  API and the structure API used internally, and also implement low article
-**  cutoff if that was requested.
-*/
-bool
-tradindexed_add(char *group, ARTNUM artnum, TOKEN token, char *data,
-                int length, time_t arrived, time_t expires)
-{
-    struct article article;
-    struct group_data *group_data;
-    struct group_entry *entry;
-
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-
-    /* Get the group index entry and don't do any work if cutoff is set and
-       the article number is lower than the low water mark for the group. */
-    entry = tdx_index_entry(tradindexed->index, group);
-    if (entry == NULL)
-        return true;
-    if (tradindexed->cutoff && entry->low > artnum)
-        return true;
-
-    /* Fill out the article data structure. */
-    article.number = artnum;
-    article.overview = data;
-    article.overlen = length;
-    article.token = token;
-    article.arrived = arrived;
-    article.expires = expires;
-
-    /* Open the appropriate data structures, using the cache. */
-    group_data = data_cache_open(tradindexed, group, entry);
-    if (group_data == NULL)
-        return false;
-    return tdx_data_add(tradindexed->index, entry, group_data, &article);
-}
-
-
-/*
-**  Cancel an article.  At present, tradindexed can't do anything with this
-**  information because we lack a mapping from the token to newsgroup names
-**  and article numbers, so we just silently return true and let expiration
-**  take care of this.
-*/
-bool
-tradindexed_cancel(TOKEN token UNUSED)
-{
-    return true;
-}
-
-
-/*
-**  Open an overview search.  Open the appropriate group and then start a
-**  search in it.
-*/
-void *
-tradindexed_opensearch(char *group, int low, int high)
-{
-    struct group_entry *entry;
-    struct group_data *data;
-
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return NULL;
-    }
-    entry = tdx_index_entry(tradindexed->index, group);
-    if (entry == NULL)
-        return NULL;
-    data = data_cache_open(tradindexed, group, entry);
-    if (data == NULL)
-        return NULL;
-    if (entry->base != data->base)
-        if (data->base > (ARTNUM) low && entry->base < data->base) {
-            data = data_cache_reopen(tradindexed, group, entry);
-            if (data == NULL)
-                return NULL;
-        }
-    return tdx_search_open(data, low, high, entry->high);
-}
-
-
-/*
-**  Get the next article returned by a search.  Convert between the multiple
-**  pointer API and the structure API we use internally.
-*/
-bool
-tradindexed_search(void *handle, ARTNUM *artnum, char **data, int *length,
-                   TOKEN *token, time_t *arrived)
-{
-    struct article article;
-
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-    if (!tdx_search(handle, &article))
-        return false;
-    if (artnum != NULL)
-        *artnum = article.number;
-    if (data != NULL)
-        *data = (char *) article.overview;
-    if (length != NULL)
-        *length = article.overlen;
-    if (token != NULL)
-        *token = article.token;
-    if (arrived != NULL)
-        *arrived = article.arrived;
-    return true;
-}
-
-
-/*
-**  Close an overview search.
-*/
-void
-tradindexed_closesearch(void *handle)
-{
-    tdx_search_close(handle);
-}
-
-
-/*
-**  Get information for a single article.  Open the appropriate group and then
-**  convert from the pointer API to the struct API used internally.
-*/
-bool
-tradindexed_getartinfo(char *group, ARTNUM artnum, TOKEN *token)
-{
-    struct group_entry *entry;
-    struct group_data *data;
-    const struct index_entry *index_entry;
-
-    if (tradindexed == NULL || tradindexed->index == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-    entry = tdx_index_entry(tradindexed->index, group);
-    if (entry == NULL)
-        return false;
-    data = data_cache_open(tradindexed, group, entry);
-    if (data == NULL)
-        return false;
-    if (entry->base != data->base)
-        if (data->base > artnum && entry->base <= artnum) {
-            data = data_cache_reopen(tradindexed, group, entry);
-            if (data == NULL)
-                return false;
-        }
-    index_entry = tdx_article_entry(data, artnum, entry->high);
-    if (index_entry == NULL)
-        return false;
-    if (token != NULL)
-        *token = index_entry->token;
-    return true;
-}
-
-
-/*
-**  Expire a single newsgroup.
-*/
-bool
-tradindexed_expiregroup(char *group, int *low, struct history *history)
-{
-    ARTNUM new_low;
-    bool status;
-
-    /* tradindexed doesn't have any periodic cleanup. */
-    if (group == NULL)
-        return true;
-
-    status = tdx_expire(group, &new_low, history);
-    if (status && low != NULL)
-        *low = (int) new_low;
-    return status;
-}
-
-
-/*
-**  Set various options or query various paramaters for the overview method.
-**  The interface is, at present, not particularly sane.
-*/
-bool
-tradindexed_ctl(OVCTLTYPE type, void *val)
-{
-    int *i;
-    bool *b;
-    OVSORTTYPE *sort;
-
-    if (tradindexed == NULL) {
-        warn("tradindexed: overview method not initialized");
-        return false;
-    }
-
-    switch (type) {
-    case OVSPACE:
-        i = (int *) val;
-        *i = -1;
-        return true;
-    case OVSORT:
-        sort = (OVSORTTYPE *) val;
-        *sort = OVNEWSGROUP;
-        return true;
-    case OVCUTOFFLOW:
-        b = (bool *) val;
-        tradindexed->cutoff = *b;
-        return true;
-    case OVSTATICSEARCH:
-        i = (int *) val;
-        *i = false;
-        return true;
-    case OVCACHEKEEP:
-    case OVCACHEFREE:
-        b = (bool *) val;
-        *b = false;
-        return true;
-    default:
-        return false;
-    }
-}
-
-
-/*
-**  Close the overview method.
-*/
-void
-tradindexed_close(void)
-{
-    if (tradindexed != NULL) {
-        if (tradindexed->index != NULL)
-            tdx_index_close(tradindexed->index);
-        if (tradindexed->cache != NULL)
-            tdx_cache_free(tradindexed->cache);
-        free(tradindexed);
-        tradindexed = NULL;
-    }
-}
diff --git a/storage/tradindexed/tradindexed.h b/storage/tradindexed/tradindexed.h
deleted file mode 100644 (file)
index ffb2908..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*  $Id: tradindexed.h 5324 2002-03-15 21:09:33Z rra $
-**
-**  Public interface for the tradindexed overview method.
-**
-**  The exact API specified here must match the expectations of the overview
-**  API.  Any changes here have to be made to all the overview methods at the
-**  same time.
-*/
-
-#ifndef TRADINDEXED_H
-#define TRADINDEXED_H 1
-
-#include "config.h"
-#include <sys/types.h>
-
-#include "ov.h"
-#include "storage.h"
-
-BEGIN_DECLS
-
-bool tradindexed_open(int mode);
-bool tradindexed_groupstats(char *group, int *low, int *high, int *count,
-                            int *flag);
-bool tradindexed_groupadd(char *group, ARTNUM low, ARTNUM high, char *flag);
-bool tradindexed_groupdel(char *group);
-bool tradindexed_add(char *group, ARTNUM artnum, TOKEN token, char *data,
-                     int length, time_t arrived, time_t expires);
-bool tradindexed_cancel(TOKEN token);
-void *tradindexed_opensearch(char *group, int low, int high);
-bool tradindexed_search(void *handle, ARTNUM *artnum, char **data,
-                        int *length, TOKEN *token, time_t *arrived);
-void tradindexed_closesearch(void *handle);
-bool tradindexed_getartinfo(char *group, ARTNUM artnum, TOKEN *token);
-bool tradindexed_expiregroup(char *group, int *low, struct history *);
-bool tradindexed_ctl(OVCTLTYPE type, void *val);
-void tradindexed_close(void);
-
-END_DECLS
-
-#endif /* TRADINDEXED_H */
diff --git a/storage/tradspool/README.tradspool b/storage/tradspool/README.tradspool
deleted file mode 100644 (file)
index d40e19b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-This storage manager attempts to implement the 'traditional' INN storage
-layout, i.e a message crossposted to alt.fan.james-brister and rec.pets.wombats
-will be written as a file in
-       <patharticles>/alt/fan/james-brister/nnnnn
-and a symlink pointing to the above file in
-       <patharticles>/rec/pets/wombats/mmmmmm
-where nnnnn and mmmmmm are the article numbers that article has in each of 
-those two newsgroups.  (Actually in the traditional spool form the link
-could be either a symlink or a regular link).
-
-The storage token data for a tradspool stored article is a 16-byte block.
-The storage token contains two ints; the first one is a number
-telling what the name of the "primary" newsgroup is for this article, the
-second one telling what article number the article has in that newsgroup.
-The mapping between newsgroup name and number is given by a database in
-the file
-       <pathspool>/ts.ng.db
-; this file is a straight ASCII file listing newsgroup names and
-numbers, and will be automatically generated by innd if one does not
-exist already.  This database is read in automatically by any program
-that uses this storage manager module, and is updated by innd whenever
-a new newsgroup is encountered.  Other programs (like innfeed) check
-the mod time of that database every 5 minutes to see if they need to
-recheck it for any new newsgroups that might have been added.  Should
-the database become corrupted, simply shutting down news, removing the
-database, and doing a makehistory will recreate the database.  It
-should, in principle, be possible to write a perl script to recreate
-just the database from just the spool files and history files without
-doing a full makehistory. 
-
-Currently the storage manager code works, although not perhaps as fast 
-as it could.   The expiration code is somewhat unwieldy; since the storage
-token does not have enough space to hold all the newsgroups an article 
-is posted to, when expiration is done SMCancel() has to open the article
-to find out what other newsgroups the article is posted to.  Eurggh. 
-Suggestions for a better scheme are welcome. 
-
-Other problems of note: the storage manager code has no way to get to the 
-'DoLinks' (-L) flag setting of innd, so currently you can't use the
-"crosspost" program with tradspool.  I guess the proper thing to do would be
-to make DoLinks a config option in storage.conf instead, but I haven't
-done that yet. 
-
diff --git a/storage/tradspool/method.config b/storage/tradspool/method.config
deleted file mode 100644 (file)
index 100865d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = tradspool
-number  = 5
-sources = tradspool.c
diff --git a/storage/tradspool/tradspool.c b/storage/tradspool/tradspool.c
deleted file mode 100644 (file)
index 0df3598..0000000
+++ /dev/null
@@ -1,1313 +0,0 @@
-/*  $Id: tradspool.c 7412 2005-10-09 03:44:35Z eagle $
-**
-**  Storage manager module for traditional spool format.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <time.h>
-
-/* Needed for htonl() and friends on AIX 4.1. */
-#include <netinet/in.h>
-    
-#include "inn/innconf.h"
-#include "inn/qio.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "paths.h"
-
-#include "methods.h"
-#include "tradspool.h"
-
-typedef struct {
-    char               *artbase; /* start of the article data -- may be mmaped */
-    unsigned int       artlen; /* art length. */
-    int        nextindex;
-    char               *curdirname;
-    DIR                        *curdir;
-    struct _ngtent     *ngtp;
-    bool               mmapped;
-} PRIV_TRADSPOOL;
-
-/*
-** The 64-bit hashed representation of a ng name that gets stashed in each token. 
-*/
-
-#define HASHEDNGLEN 8
-typedef struct {
-    char hash[HASHEDNGLEN];
-} HASHEDNG;
-
-/*
-** We have two structures here for facilitating newsgroup name->number mapping
-** and number->name mapping.  NGTable is a hash table based on hashing the
-** newsgroup name, and is used to give the name->number mapping.  NGTree is
-** a binary tree, indexed by newsgroup number, used for the number->name
-** mapping.
-*/
-
-#define NGT_SIZE  2048
-
-typedef struct _ngtent {
-    char *ngname;
-/*    HASHEDNG hash; XXX */
-    unsigned long ngnumber;
-    struct _ngtent *next;
-    struct _ngtreenode *node;
-} NGTENT;
-
-typedef struct _ngtreenode {
-    unsigned long ngnumber;
-    struct _ngtreenode *left, *right;
-    NGTENT *ngtp;
-} NGTREENODE;
-
-NGTENT *NGTable[NGT_SIZE];
-unsigned long MaxNgNumber = 0;
-NGTREENODE *NGTree;
-
-bool NGTableUpdated; /* set to true if we've added any entries since reading 
-                       in the database file */
-
-/* 
-** Convert all .s to /s in a newsgroup name.  Modifies the passed string 
-** inplace.
-*/
-static void
-DeDotify(char *ngname) {
-    char *p = ngname;
-
-    for ( ; *p ; ++p) {
-       if (*p == '.') *p = '/';
-    }
-    return;
-}
-
-/*
-** Hash a newsgroup name to an 8-byte.  Basically, we convert all .s to 
-** /s (so it doesn't matter if we're passed the spooldir name or newsgroup
-** name) and then call Hash to MD5 the mess, then take 4 bytes worth of 
-** data from the front of the hash.  This should be good enough for our
-** purposes. 
-*/
-
-static HASHEDNG 
-HashNGName(char *ng) {
-    HASH hash;
-    HASHEDNG return_hash;
-    char *p;
-
-    p = xstrdup(ng);
-    DeDotify(p);
-    hash = Hash(p, strlen(p));
-    free(p);
-
-    memcpy(return_hash.hash, hash.hash, HASHEDNGLEN);
-
-    return return_hash;
-}
-
-#if 0 /* XXX */
-/* compare two hashes */
-static int
-CompareHash(HASHEDNG *h1, HASHEDNG *h2) {
-    int i;
-    for (i = 0 ; i < HASHEDNGLEN ; ++i) {
-       if (h1->hash[i] != h2->hash[i]) {
-           return h1->hash[i] - h2->hash[i];
-       }
-    }
-    return 0;
-}
-#endif
-
-/* Add a new newsgroup name to the NG table. */
-static void
-AddNG(char *ng, unsigned long number) {
-    char *p;
-    unsigned int h;
-    HASHEDNG hash;
-    NGTENT *ngtp, **ngtpp;
-    NGTREENODE *newnode, *curnode, **nextnode;
-
-    p = xstrdup(ng);
-    DeDotify(p); /* canonicalize p to standard (/) form. */
-    hash = HashNGName(p);
-
-    h = (unsigned char)hash.hash[0];
-    h = h + (((unsigned char)hash.hash[1])<<8);
-
-    h = h % NGT_SIZE;
-
-    ngtp = NGTable[h];
-    ngtpp = &NGTable[h];
-    while (true) {
-       if (ngtp == NULL) {
-           /* ng wasn't in table, add new entry. */
-           NGTableUpdated = true;
-
-           ngtp = xmalloc(sizeof(NGTENT));
-           ngtp->ngname = p; /* note: we store canonicalized name */
-           /* ngtp->hash = hash XXX */
-           ngtp->next = NULL;
-
-           /* assign a new NG number if needed (not given) */
-           if (number == 0) {
-               number = ++MaxNgNumber;
-           }
-           ngtp->ngnumber = number;
-
-           /* link new table entry into the hash table chain. */
-           *ngtpp = ngtp;
-
-           /* Now insert an appropriate record into the binary tree */
-           newnode = xmalloc(sizeof(NGTREENODE));
-           newnode->left = newnode->right = (NGTREENODE *) NULL;
-           newnode->ngnumber = number;
-           newnode->ngtp = ngtp;
-           ngtp->node = newnode;
-
-           if (NGTree == NULL) {
-               /* tree was empty, so put our one element in and return */
-               NGTree = newnode;
-               return;
-           } else {
-               nextnode = &NGTree;
-               while (*nextnode) {
-                   curnode = *nextnode;
-                   if (curnode->ngnumber < number) {
-                       nextnode = &curnode->right;
-                   } else if (curnode->ngnumber > number) {
-                       nextnode = &curnode->left;
-                   } else {
-                       /* Error, same number is already in NGtree (shouldn't happen!) */
-                       syslog(L_ERROR, "tradspool: AddNG: duplicate newsgroup number in NGtree: %ld(%s)", number, p);
-                       return;
-                   }
-               }
-               *nextnode = newnode;
-               return;
-           }
-       } else if (strcmp(ngtp->ngname, p) == 0) {
-           /* entry in table already, so return */
-           free(p);
-           return;
-#if 0 /* XXX */
-       } else if (CompareHash(&ngtp->hash, &hash) == 0) {
-           /* eep! we hit a hash collision. */
-           syslog(L_ERROR, "tradspool: AddNG: Hash collison %s/%s", ngtp->ngname, p);
-           free(p);
-           return;
-#endif 
-       } else {
-           /* not found yet, so advance to next entry in chain */
-           ngtpp = &(ngtp->next);
-           ngtp = ngtp->next;
-       }
-    }
-}
-
-/* find a newsgroup table entry, given only the name. */
-static NGTENT *
-FindNGByName(char *ngname) {
-    NGTENT *ngtp;
-    unsigned int h;
-    HASHEDNG hash;
-    char *p;
-
-    p = xstrdup(ngname);
-    DeDotify(p); /* canonicalize p to standard (/) form. */
-    hash = HashNGName(p);
-
-    h = (unsigned char)hash.hash[0];
-    h = h + (((unsigned char)hash.hash[1])<<8);
-
-    h = h % NGT_SIZE;
-
-    ngtp = NGTable[h];
-
-    while (ngtp) {
-       if (strcmp(p, ngtp->ngname) == 0) {
-           free(p);
-           return ngtp;
-       }
-       ngtp = ngtp->next;
-    }
-    free(p);
-    return NULL; 
-}
-
-/* find a newsgroup/spooldir name, given only the newsgroup number */
-static char *
-FindNGByNum(unsigned long ngnumber) {
-    NGTENT *ngtp;
-    NGTREENODE *curnode;
-
-    curnode = NGTree;
-
-    while (curnode) {
-       if (curnode->ngnumber == ngnumber) {
-           ngtp = curnode->ngtp;
-           return ngtp->ngname;
-       }
-       if (curnode->ngnumber < ngnumber) {
-           curnode = curnode->right;
-       } else {
-           curnode = curnode->left;
-       }
-    }
-    /* not in tree, return NULL */
-    return NULL; 
-}
-
-#define _PATH_TRADSPOOLNGDB "tradspool.map"
-#define _PATH_NEWTSNGDB "tradspool.map.new"
-
-
-/* dump DB to file. */
-static void
-DumpDB(void)
-{
-    char *fname, *fnamenew;
-    NGTENT *ngtp;
-    unsigned int i;
-    FILE *out;
-
-    if (!SMopenmode) return; /* don't write if we're not in read/write mode. */
-    if (!NGTableUpdated) return; /* no need to dump new DB */
-
-    fname = concatpath(innconf->pathspool, _PATH_TRADSPOOLNGDB);
-    fnamenew = concatpath(innconf->pathspool, _PATH_NEWTSNGDB);
-
-    if ((out = fopen(fnamenew, "w")) == NULL) {
-       syslog(L_ERROR, "tradspool: DumpDB: can't write %s: %m", fnamenew);
-       free(fname);
-       free(fnamenew);
-       return;
-    }
-    for (i = 0 ; i < NGT_SIZE ; ++i) {
-       ngtp = NGTable[i];
-       for ( ; ngtp ; ngtp = ngtp->next) {
-           fprintf(out, "%s %lu\n", ngtp->ngname, ngtp->ngnumber);
-       }
-    }
-    if (fclose(out) < 0) {
-       syslog(L_ERROR, "tradspool: DumpDB: can't close %s: %m", fnamenew);
-       free(fname);
-       free(fnamenew);
-       return;
-    }
-    if (rename(fnamenew, fname) < 0) {
-       syslog(L_ERROR, "tradspool: can't rename %s", fnamenew);
-       free(fname);
-       free(fnamenew);
-       return;
-    }
-    free(fname);
-    free(fnamenew);
-    NGTableUpdated = false; /* reset modification flag. */
-    return;
-}
-
-/* 
-** init NGTable from saved database file and from active.  Note that
-** entries in the database file get added first,  and get their specifications
-** of newsgroup number from there. 
-*/
-
-static bool
-ReadDBFile(void)
-{
-    char *fname;
-    QIOSTATE *qp;
-    char *line;
-    char *p;
-    unsigned long number;
-
-    fname = concatpath(innconf->pathspool, _PATH_TRADSPOOLNGDB);
-    if ((qp = QIOopen(fname)) == NULL) {
-       /* only warn if db not found. */
-       syslog(L_NOTICE, "tradspool: %s not found", fname);
-    } else {
-       while ((line = QIOread(qp)) != NULL) {
-           p = strchr(line, ' ');
-           if (p == NULL) {
-               syslog(L_FATAL, "tradspool: corrupt line in active %s", line);
-               QIOclose(qp);
-               free(fname);
-               return false;
-           }
-           *p++ = 0;
-           number = atol(p);
-           AddNG(line, number);
-           if (MaxNgNumber < number) MaxNgNumber = number;
-       }
-       QIOclose(qp);
-    }
-    free(fname);
-    return true;
-}
-
-static bool
-ReadActiveFile(void)
-{
-    char *fname;
-    QIOSTATE *qp;
-    char *line;
-    char *p;
-
-    fname = concatpath(innconf->pathdb, _PATH_ACTIVE);
-    if ((qp = QIOopen(fname)) == NULL) {
-       syslog(L_FATAL, "tradspool: can't open %s", fname);
-       free(fname);
-       return false;
-    }
-
-    while ((line = QIOread(qp)) != NULL) {
-       p = strchr(line, ' ');
-       if (p == NULL) {
-           syslog(L_FATAL, "tradspool: corrupt line in active %s", line);
-           QIOclose(qp);
-           free(fname);
-           return false;
-       }
-       *p = 0;
-       AddNG(line, 0);
-    }
-    QIOclose(qp);
-    free(fname);
-    /* dump any newly added changes to database */
-    DumpDB();
-    return true;
-}
-
-static bool
-InitNGTable(void)
-{
-    if (!ReadDBFile()) return false;
-
-    /*
-    ** set NGTableUpdated to false; that way we know if the load of active or
-    ** any AddNGs later on did in fact add new entries to the db.
-    */
-    NGTableUpdated = false; 
-    if (!SMopenmode)
-       /* don't read active unless write mode. */
-       return true;
-    return ReadActiveFile(); 
-}
-
-/* 
-** Routine called to check every so often to see if we need to reload the
-** database and add in any new groups that have been added.   This is primarily
-** for the benefit of innfeed in funnel mode, which otherwise would never
-** get word that any new newsgroups had been added. 
-*/
-
-#define RELOAD_TIME_CHECK 600
-
-static void
-CheckNeedReloadDB(bool force)
-{
-    static TIMEINFO lastcheck, oldlastcheck, now;
-    struct stat sb;
-    char *fname;
-
-    if (GetTimeInfo(&now) < 0) return; /* anyone ever seen gettimeofday fail? :-) */
-    if (!force && lastcheck.time + RELOAD_TIME_CHECK > now.time) return;
-
-    oldlastcheck = lastcheck;
-    lastcheck = now;
-
-    fname = concatpath(innconf->pathspool, _PATH_TRADSPOOLNGDB);
-    if (stat(fname, &sb) < 0) {
-       free(fname);
-       return;
-    }
-    free(fname);
-    if (sb.st_mtime > oldlastcheck.time) {
-       /* add any newly added ngs to our in-memory copy of the db. */
-       ReadDBFile();
-    }
-}
-
-/* Init routine, called by SMinit */
-
-bool
-tradspool_init(SMATTRIBUTE *attr) {
-    if (attr == NULL) {
-       syslog(L_ERROR, "tradspool: attr is NULL");
-       SMseterror(SMERR_INTERNAL, "attr is NULL");
-       return false;
-    }
-    if (!innconf->storeonxref) {
-       syslog(L_ERROR, "tradspool: storeonxref needs to be true");
-       SMseterror(SMERR_INTERNAL, "storeonxref needs to be true");
-       return false;
-    }
-    attr->selfexpire = false;
-    attr->expensivestat = true;
-    return InitNGTable();
-}
-
-/* Make a token for an article given the primary newsgroup name and article # */
-static TOKEN
-MakeToken(char *ng, unsigned long artnum, STORAGECLASS class) {
-    TOKEN token;
-    NGTENT *ngtp;
-    unsigned long num;
-
-    memset(&token, '\0', sizeof(token));
-
-    token.type = TOKEN_TRADSPOOL;
-    token.class = class;
-
-    /* 
-    ** if not already in the NG Table, be sure to add this ng! This way we
-    ** catch things like newsgroups added since startup. 
-    */
-    if ((ngtp = FindNGByName(ng)) == NULL) {
-       AddNG(ng, 0);
-       DumpDB(); /* flush to disk so other programs can see the change */
-       ngtp = FindNGByName(ng);
-    } 
-
-    num = ngtp->ngnumber;
-    num = htonl(num);
-
-    memcpy(token.token, &num, sizeof(num));
-    artnum = htonl(artnum);
-    memcpy(&token.token[sizeof(num)], &artnum, sizeof(artnum));
-    return token;
-}
-
-/* 
-** Convert a token back to a pathname. 
-*/
-static char *
-TokenToPath(TOKEN token) {
-    unsigned long ngnum;
-    unsigned long artnum;
-    char *ng, *path;
-    size_t length;
-
-    CheckNeedReloadDB(false);
-
-    memcpy(&ngnum, &token.token[0], sizeof(ngnum));
-    memcpy(&artnum, &token.token[sizeof(ngnum)], sizeof(artnum));
-    artnum = ntohl(artnum);
-    ngnum = ntohl(ngnum);
-
-    ng = FindNGByNum(ngnum);
-    if (ng == NULL) {
-       CheckNeedReloadDB(true);
-       ng = FindNGByNum(ngnum);
-       if (ng == NULL)
-           return NULL;
-    }
-
-    length = strlen(ng) + 20 + strlen(innconf->patharticles);
-    path = xmalloc(length);
-    snprintf(path, length, "%s/%s/%lu", innconf->patharticles, ng, artnum);
-    return path;
-}
-
-/*
-** Crack an Xref line apart into separate strings, each of the form "ng:artnum".
-** Return in "num" the number of newsgroups found. 
-*/
-static char **
-CrackXref(char *xref, unsigned int *lenp) {
-    char *p;
-    char **xrefs;
-    char *q;
-    unsigned int len, xrefsize;
-
-    len = 0;
-    xrefsize = 5;
-    xrefs = xmalloc(xrefsize * sizeof(char *));
-
-    /* no path element should exist, nor heading white spaces exist */
-    p = xref;
-    while (true) {
-       /* check for EOL */
-       /* shouldn't ever hit null w/o hitting a \r\n first, but best to be paranoid */
-       if (*p == '\n' || *p == '\r' || *p == 0) {
-           /* hit EOL, return. */
-           *lenp = len;
-           return xrefs;
-       }
-       /* skip to next space or EOL */
-       for (q=p; *q && *q != ' ' && *q != '\n' && *q != '\r' ; ++q) ;
-
-        xrefs[len] = xstrndup(p, q - p);
-
-       if (++len == xrefsize) {
-           /* grow xrefs if needed. */
-           xrefsize *= 2;
-            xrefs = xrealloc(xrefs, xrefsize * sizeof(char *));
-       }
-
-       p = q;
-       /* skip spaces */
-       for ( ; *p == ' ' ; p++) ;
-    }
-}
-
-TOKEN
-tradspool_store(const ARTHANDLE article, const STORAGECLASS class) {
-    char **xrefs;
-    char *xrefhdr;
-    TOKEN token;
-    unsigned int numxrefs;
-    char *ng, *p, *onebuffer;
-    unsigned long artnum;
-    char *path, *linkpath, *dirname;
-    int fd;
-    size_t used;
-    char *nonwfarticle; /* copy of article converted to non-wire format */
-    unsigned int i;
-    size_t length, nonwflen;
-    
-    xrefhdr = article.groups;
-    if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
-       token.type = TOKEN_EMPTY;
-       SMseterror(SMERR_UNDEFINED, "bogus Xref: header");
-       if (xrefs != NULL)
-           free(xrefs);
-       return token;
-    }
-
-    if ((p = strchr(xrefs[0], ':')) == NULL) {
-       token.type = TOKEN_EMPTY;
-       SMseterror(SMERR_UNDEFINED, "bogus Xref: header");
-       for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-       free(xrefs);
-       return token;
-    }
-    *p++ = '\0';
-    ng = xrefs[0];
-    DeDotify(ng);
-    artnum = atol(p);
-    
-    token = MakeToken(ng, artnum, class);
-
-    length = strlen(innconf->patharticles) + strlen(ng) + 32;
-    path = xmalloc(length);
-    snprintf(path, length, "%s/%s/%lu", innconf->patharticles, ng, artnum);
-
-    /* following chunk of code boldly stolen from timehash.c  :-) */
-    if ((fd = open(path, O_CREAT|O_EXCL|O_WRONLY, ARTFILE_MODE)) < 0) {
-       p = strrchr(path, '/');
-       *p = '\0';
-       if (!MakeDirectory(path, true)) {
-           syslog(L_ERROR, "tradspool: could not make directory %s %m", path);
-           token.type = TOKEN_EMPTY;
-           free(path);
-           SMseterror(SMERR_UNDEFINED, NULL);
-           for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-           free(xrefs);
-           return token;
-       } else {
-           *p = '/';
-           if ((fd = open(path, O_CREAT|O_EXCL|O_WRONLY, ARTFILE_MODE)) < 0) {
-               SMseterror(SMERR_UNDEFINED, NULL);
-               syslog(L_ERROR, "tradspool: could not open %s %m", path);
-               token.type = TOKEN_EMPTY;
-               free(path);
-               for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-               free(xrefs);
-               return token;
-           }
-       }
-    }
-    if (innconf->wireformat) {
-       if (xwritev(fd, article.iov, article.iovcnt) != (ssize_t) article.len) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool error writing %s %m", path);
-           close(fd);
-           token.type = TOKEN_EMPTY;
-           unlink(path);
-           free(path);
-           for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-           free(xrefs);
-           return token;
-       }
-    } else {
-       onebuffer = xmalloc(article.len);
-       for (used = i = 0 ; i < article.iovcnt ; i++) {
-           memcpy(&onebuffer[used], article.iov[i].iov_base, article.iov[i].iov_len);
-           used += article.iov[i].iov_len;
-       }
-       nonwfarticle = FromWireFmt(onebuffer, used, &nonwflen);
-       free(onebuffer);
-       if (write(fd, nonwfarticle, nonwflen) != (ssize_t) nonwflen) {
-           free(nonwfarticle);
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool error writing %s %m", path);
-           close(fd);
-           token.type = TOKEN_EMPTY;
-           unlink(path);
-           free(path);
-           for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-           free(xrefs);
-           return token;
-       }
-       free(nonwfarticle);
-    }
-    close(fd);
-
-    /* 
-    ** blah, this is ugly.  Have to make symlinks under other pathnames for
-    ** backwards compatiblility purposes. 
-    */
-
-    if (numxrefs > 1) {
-       for (i = 1; i < numxrefs ; ++i) {
-           if ((p = strchr(xrefs[i], ':')) == NULL) continue;
-           *p++ = '\0';
-           ng = xrefs[i];
-           DeDotify(ng);
-           artnum = atol(p);
-
-            length = strlen(innconf->patharticles) + strlen(ng) + 32;
-           linkpath = xmalloc(length);
-           snprintf(linkpath, length, "%s/%s/%lu", innconf->patharticles,
-                     ng, artnum);
-           if (link(path, linkpath) < 0) {
-               p = strrchr(linkpath, '/');
-               *p = '\0';
-               dirname = xstrdup(linkpath);
-               *p = '/';
-               if (!MakeDirectory(dirname, true) || link(path, linkpath) < 0) {
-#if !defined(HAVE_SYMLINK)
-                   SMseterror(SMERR_UNDEFINED, NULL);
-                   syslog(L_ERROR, "tradspool: could not link %s to %s %m", path, linkpath);
-                   token.type = TOKEN_EMPTY;
-                   free(dirname);
-                   free(linkpath);
-                   free(path);
-                   for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-                   free(xrefs);
-                   return token;
-#else
-                   if (symlink(path, linkpath) < 0) {
-                       SMseterror(SMERR_UNDEFINED, NULL);
-                       syslog(L_ERROR, "tradspool: could not symlink %s to %s %m", path, linkpath);
-                       token.type = TOKEN_EMPTY;
-                       free(dirname);
-                       free(linkpath);
-                       free(path);
-                       for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-                       free(xrefs);
-                       return token;
-                   }
-#endif  /* !defined(HAVE_SYMLINK) */
-               }
-               free(dirname);
-           }
-           free(linkpath);
-       }
-    }
-    free(path);
-    for (i = 0 ; i < numxrefs; ++i) free(xrefs[i]);
-    free(xrefs);
-    return token;
-}
-
-static ARTHANDLE *
-OpenArticle(const char *path, RETRTYPE amount) {
-    int fd;
-    PRIV_TRADSPOOL *private;
-    char *p;
-    struct stat sb;
-    ARTHANDLE *art;
-    char *wfarticle;
-    size_t wflen;
-
-    if (amount == RETR_STAT) {
-       if (access(path, R_OK) < 0) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           return NULL;
-       }
-       art = xmalloc(sizeof(ARTHANDLE));
-       art->type = TOKEN_TRADSPOOL;
-       art->data = NULL;
-       art->len = 0;
-       art->private = NULL;
-       return art;
-    }
-
-    if ((fd = open(path, O_RDONLY)) < 0) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       return NULL;
-    }
-
-    art = xmalloc(sizeof(ARTHANDLE));
-    art->type = TOKEN_TRADSPOOL;
-
-    if (fstat(fd, &sb) < 0) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       syslog(L_ERROR, "tradspool: could not fstat article: %m");
-       free(art);
-       close(fd);
-       return NULL;
-    }
-
-    art->arrived = sb.st_mtime;
-
-    private = xmalloc(sizeof(PRIV_TRADSPOOL));
-    art->private = (void *)private;
-    private->artlen = sb.st_size;
-    if (innconf->articlemmap) {
-       if ((private->artbase = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool: could not mmap article: %m");
-           free(art->private);
-           free(art);
-           close(fd);
-           return NULL;
-       }
-        if (amount == RETR_ALL)
-            madvise(private->artbase, sb.st_size, MADV_WILLNEED);
-        else
-            madvise(private->artbase, sb.st_size, MADV_SEQUENTIAL);
-
-       /* consider coexisting both wireformatted and nonwireformatted */
-       p = memchr(private->artbase, '\n', private->artlen);
-       if (p == NULL || p == private->artbase) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool: could not mmap article: %m");
-           munmap(private->artbase, private->artlen);
-           free(art->private);
-           free(art);
-           close(fd);
-           return NULL;
-       }
-       if (p[-1] == '\r') {
-           private->mmapped = true;
-       } else {
-           wfarticle = ToWireFmt(private->artbase, private->artlen, &wflen);
-           munmap(private->artbase, private->artlen);
-           private->artbase = wfarticle;
-           private->artlen = wflen;
-           private->mmapped = false;
-       }
-    } else {
-       private->mmapped = false;
-       private->artbase = xmalloc(private->artlen);
-       if (read(fd, private->artbase, private->artlen) < 0) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool: could not read article: %m");
-           free(private->artbase);
-           free(art->private);
-           free(art);
-           close(fd);
-           return NULL;
-       }
-       p = memchr(private->artbase, '\n', private->artlen);
-       if (p == NULL || p == private->artbase) {
-           SMseterror(SMERR_UNDEFINED, NULL);
-           syslog(L_ERROR, "tradspool: could not mmap article: %m");
-           free(art->private);
-           free(art);
-           close(fd);
-           return NULL;
-       }
-       if (p[-1] != '\r') {
-           /* need to make a wireformat copy of the article */
-           wfarticle = ToWireFmt(private->artbase, private->artlen, &wflen);
-           free(private->artbase);
-           private->artbase = wfarticle;
-           private->artlen = wflen;
-       }
-    }
-    close(fd);
-    
-    private->ngtp = NULL;
-    private->curdir = NULL;
-    private->curdirname = NULL;
-    private->nextindex = -1;
-
-    if (amount == RETR_ALL) {
-       art->data = private->artbase;
-       art->len = private->artlen;
-       return art;
-    }
-    
-    if (((p = wire_findbody(private->artbase, private->artlen)) == NULL)) {
-       if (private->mmapped)
-           munmap(private->artbase, private->artlen);
-       else
-           free(private->artbase);
-       SMseterror(SMERR_NOBODY, NULL);
-       free(art->private);
-       free(art);
-       return NULL;
-    }
-
-    if (amount == RETR_HEAD) {
-       art->data = private->artbase;
-       art->len = p - private->artbase;
-       return art;
-    }
-
-    if (amount == RETR_BODY) {
-       art->data = p;
-       art->len = private->artlen - (p - private->artbase);
-       return art;
-    }
-    SMseterror(SMERR_UNDEFINED, "Invalid retrieve request");
-    if (private->mmapped)
-       munmap(private->artbase, private->artlen);
-    else
-       free(private->artbase);
-    free(art->private);
-    free(art);
-    return NULL;
-}
-
-    
-ARTHANDLE *
-tradspool_retrieve(const TOKEN token, const RETRTYPE amount) {
-    char *path;
-    ARTHANDLE *art;
-    static TOKEN ret_token;
-
-    if (token.type != TOKEN_TRADSPOOL) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return NULL;
-    }
-
-    if ((path = TokenToPath(token)) == NULL) {
-       SMseterror(SMERR_NOENT, NULL);
-       return NULL;
-    }
-    if ((art = OpenArticle(path, amount)) != (ARTHANDLE *)NULL) {
-        ret_token = token;
-        art->token = &ret_token;
-    }
-    free(path);
-    return art;
-}
-
-void
-tradspool_freearticle(ARTHANDLE *article)
-{
-    PRIV_TRADSPOOL *private;
-
-    if (article == NULL)
-        return;
-
-    if (article->private) {
-       private = (PRIV_TRADSPOOL *) article->private;
-       if (private->mmapped)
-           munmap(private->artbase, private->artlen);
-       else
-           free(private->artbase);
-       if (private->curdir)
-           closedir(private->curdir);
-       free(private->curdirname);
-        free(private);
-    }
-    free(article);
-}
-
-bool 
-tradspool_cancel(TOKEN token) {
-    char **xrefs;
-    char *xrefhdr;
-    ARTHANDLE *article;
-    unsigned int numxrefs;
-    char *ng, *p;
-    char *path, *linkpath;
-    unsigned int i;
-    bool result = true;
-    unsigned long artnum;
-    size_t length;
-
-    if ((path = TokenToPath(token)) == NULL) {
-       SMseterror(SMERR_UNDEFINED, NULL);
-       free(path);
-       return false;
-    }
-    /*
-    **  Ooooh, this is gross.  To find the symlinks pointing to this article,
-    ** we open the article and grab its Xref line (since the token isn't long
-    ** enough to store this info on its own).   This is *not* going to do 
-    ** good things for performance of fastrm...  -- rmtodd
-    */
-    if ((article = OpenArticle(path, RETR_HEAD)) == NULL) {
-       free(path);
-       SMseterror(SMERR_UNDEFINED, NULL);
-        return false;
-    }
-
-    xrefhdr = wire_findheader(article->data, article->len, "Xref");
-    if (xrefhdr == NULL) {
-       /* for backwards compatibility; there is no Xref unless crossposted
-          for 1.4 and 1.5 */
-       if (unlink(path) < 0) result = false;
-       free(path);
-       tradspool_freearticle(article);
-        return result;
-    }
-
-    if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
-        if (xrefs != NULL)
-            free(xrefs);
-       free(path);
-       tradspool_freearticle(article);
-        SMseterror(SMERR_UNDEFINED, NULL);
-        return false;
-    }
-
-    tradspool_freearticle(article);
-    for (i = 1 ; i < numxrefs ; ++i) {
-       if ((p = strchr(xrefs[i], ':')) == NULL) continue;
-       *p++ = '\0';
-       ng = xrefs[i];
-       DeDotify(ng);
-       artnum = atol(p);
-
-        length = strlen(innconf->patharticles) + strlen(ng) + 32;
-       linkpath = xmalloc(length);
-       snprintf(linkpath, length, "%s/%s/%lu", innconf->patharticles, ng,
-                 artnum);
-       /* repeated unlinkings of a crossposted article may fail on account
-          of the file no longer existing without it truly being an error */
-       if (unlink(linkpath) < 0)
-           if (errno != ENOENT || i == 1)
-               result = false;
-       free(linkpath);
-    }
-    if (unlink(path) < 0)
-       if (errno != ENOENT || numxrefs == 1)
-           result = false;
-    free(path);
-    for (i = 0 ; i < numxrefs ; ++i) free(xrefs[i]);
-    free(xrefs);
-    return result;
-}
-
-   
-/*
-** Find entries for possible articles in dir. "dir" (directory name "dirname").
-** The dirname is needed so we can do stats in the directory to disambiguate
-** files from symlinks and directories.
-*/
-
-static struct dirent *
-FindDir(DIR *dir, char *dirname) {
-    struct dirent *de;
-    int i;
-    bool flag;
-    char *path;
-    struct stat sb;
-    size_t length;
-    unsigned char namelen;
-
-    while ((de = readdir(dir)) != NULL) {
-       namelen = strlen(de->d_name);
-       for (i = 0, flag = true ; i < namelen ; ++i) {
-           if (!CTYPE(isdigit, de->d_name[i])) {
-               flag = false;
-               break;
-           }
-       }
-       if (!flag) continue; /* if not all digits, skip this entry. */
-
-        length = strlen(dirname) + namelen + 2;
-       path = xmalloc(length);
-        strlcpy(path, dirname, length);
-        strlcat(path, "/", length);
-        strlcat(path, de->d_name, length);
-
-       if (lstat(path, &sb) < 0) {
-           free(path);
-           continue;
-       }
-       free(path);
-       if (!S_ISREG(sb.st_mode)) continue;
-       return de;
-    }
-    return NULL;
-}
-
-ARTHANDLE *tradspool_next(const ARTHANDLE *article, const RETRTYPE amount) {
-    PRIV_TRADSPOOL priv;
-    PRIV_TRADSPOOL *newpriv;
-    char *path, *linkpath;
-    struct dirent *de;
-    ARTHANDLE *art;
-    unsigned long artnum;
-    unsigned int i;
-    static TOKEN token;
-    char **xrefs;
-    char *xrefhdr, *ng, *p, *expires, *x;
-    unsigned int numxrefs;
-    STORAGE_SUB        *sub;
-    size_t length;
-
-    if (article == NULL) {
-       priv.ngtp = NULL;
-       priv.curdir = NULL;
-       priv.curdirname = NULL;
-       priv.nextindex = -1;
-    } else {
-       priv = *(PRIV_TRADSPOOL *) article->private;
-       free(article->private);
-       free((void*)article);
-       if (priv.artbase != NULL) {
-           if (priv.mmapped)
-               munmap(priv.artbase, priv.artlen);
-           else
-               free(priv.artbase);
-       }
-    }
-
-    while (!priv.curdir || ((de = FindDir(priv.curdir, priv.curdirname)) == NULL)) {
-       if (priv.curdir) {
-           closedir(priv.curdir);
-           priv.curdir = NULL;
-           free(priv.curdirname);
-           priv.curdirname = NULL;
-       }
-
-       /*
-       ** advance ngtp to the next entry, if it exists, otherwise start 
-       ** searching down another ngtable hashchain. 
-       */
-       while (priv.ngtp == NULL || (priv.ngtp = priv.ngtp->next) == NULL) {
-           /*
-           ** note that at the start of a search nextindex is -1, so the inc.
-           ** makes nextindex 0, as it should be.
-           */
-           priv.nextindex++;
-           if (priv.nextindex >= NGT_SIZE) {
-               /* ran off the end of the table, so return. */
-               return NULL;
-           }
-           priv.ngtp = NGTable[priv.nextindex];
-           if (priv.ngtp != NULL)
-               break;
-       }
-
-        priv.curdirname = concatpath(innconf->patharticles, priv.ngtp->ngname);
-       priv.curdir = opendir(priv.curdirname);
-    }
-
-    path = concatpath(priv.curdirname, de->d_name);
-    i = strlen(priv.curdirname);
-    /* get the article number while we're here, we'll need it later. */
-    artnum = atol(&path[i+1]);
-
-    art = OpenArticle(path, amount);
-    if (art == (ARTHANDLE *)NULL) {
-       art = xmalloc(sizeof(ARTHANDLE));
-       art->type = TOKEN_TRADSPOOL;
-       art->data = NULL;
-       art->len = 0;
-       art->private = xmalloc(sizeof(PRIV_TRADSPOOL));
-       art->expires = 0;
-       art->groups = NULL;
-       art->groupslen = 0;
-       newpriv = (PRIV_TRADSPOOL *) art->private;
-       newpriv->artbase = NULL;
-    } else {
-       /* Skip linked (not symlinked) crossposted articles.
-
-           This algorithm is rather questionable; it only works if the first
-           group/number combination listed in the Xref header is the
-           canonical path.  This will always be true for spools created by
-           this implementation, but for traditional INN 1.x servers,
-           articles are expired indepedently from each group and may expire
-           out of the first listed newsgroup before other groups.  This
-           algorithm will orphan such articles, not adding them to history.
-
-           The bit of skipping articles by setting the length of the article
-           to zero is also rather suspect, and I'm not sure what
-           implications that might have for the callers of SMnext.
-
-           Basically, this whole area really needs to be rethought. */
-       xrefhdr = wire_findheader(art->data, art->len, "Xref");
-       if (xrefhdr != NULL) {
-           if ((xrefs = CrackXref(xrefhdr, &numxrefs)) == NULL || numxrefs == 0) {
-               art->len = 0;
-           } else {
-               /* assumes first one is the original */
-               if ((p = strchr(xrefs[1], ':')) != NULL) {
-                   *p++ = '\0';
-                   ng = xrefs[1];
-                   DeDotify(ng);
-                   artnum = atol(p);
-
-                    length = strlen(innconf->patharticles) + strlen(ng) + 32;
-                   linkpath = xmalloc(length);
-                   snprintf(linkpath, length, "%s/%s/%lu",
-                             innconf->patharticles, ng, artnum);
-                   if (strcmp(path, linkpath) != 0) {
-                       /* this is linked article, skip it */
-                       art->len = 0;
-                   }
-                   free(linkpath);
-               }
-           }
-           for (i = 0 ; i < numxrefs ; ++i) free(xrefs[i]);
-           free(xrefs);
-           if (innconf->storeonxref) {
-               /* skip path element */
-               if ((xrefhdr = strchr(xrefhdr, ' ')) == NULL) {
-                   art->groups = NULL;
-                   art->groupslen = 0;
-               } else {
-                   for (xrefhdr++; *xrefhdr == ' '; xrefhdr++);
-                   art->groups = xrefhdr;
-                   for (p = xrefhdr ; (*p != '\n') && (*p != '\r') ; p++);
-                   art->groupslen = p - xrefhdr;
-               }
-           }
-       }
-       if (xrefhdr == NULL || !innconf->storeonxref) {
-            ng = wire_findheader(art->data, art->len, "Newsgroups");
-           if (ng == NULL) {
-               art->groups = NULL;
-               art->groupslen = 0;
-           } else {
-               art->groups = ng;
-               for (p = ng ; (*p != '\n') && (*p != '\r') ; p++);
-               art->groupslen = p - ng;
-           }
-       }
-        expires = wire_findheader(art->data, art->len, "Expires");
-        if (expires == NULL) {
-           art->expires = 0;
-       } else {
-            /* optionally parse expire header */
-            for (p = expires + 1; (*p != '\n') && (*(p - 1) != '\r'); p++);
-            x = xmalloc(p - expires);
-            memcpy(x, expires, p - expires - 1);
-            x[p - expires - 1] = '\0';
-
-            art->expires = parsedate(x, NULL);
-            if (art->expires == -1)
-                art->expires = 0;
-            else
-                art->expires -= time(0);
-            free(x);
-        }
-       /* for backwards compatibility; assumes no Xref unless crossposted
-          for 1.4 and 1.5: just fall through */
-    }
-    newpriv = (PRIV_TRADSPOOL *) art->private;
-    newpriv->nextindex = priv.nextindex;
-    newpriv->curdir = priv.curdir;
-    newpriv->curdirname = priv.curdirname;
-    newpriv->ngtp = priv.ngtp;
-    
-    if ((sub = SMgetsub(*art)) == NULL || sub->type != TOKEN_TRADSPOOL) {
-       /* maybe storage.conf is modified, after receiving article */
-       token = MakeToken(priv.ngtp->ngname, artnum, 0);
-
-        /* Only log an error if art->len is non-zero, since otherwise we get
-           all the ones skipped via the hard-link skipping algorithm
-           commented above. */
-        if (art->len > 0)
-            syslog(L_ERROR, "tradspool: can't determine class: %s: %s",
-                   TokenToText(token), SMerrorstr);
-    } else {
-       token = MakeToken(priv.ngtp->ngname, artnum, sub->class);
-    }
-    art->token = &token;
-    free(path);
-    return art;
-}
-
-static void
-FreeNGTree(void)
-{
-    unsigned int i;
-    NGTENT *ngtp, *nextngtp;
-
-    for (i = 0 ; i < NGT_SIZE ; i++) {
-        ngtp = NGTable[i];
-        for ( ; ngtp != NULL ; ngtp = nextngtp) {
-           nextngtp = ngtp->next;
-           free(ngtp->ngname);
-           free(ngtp->node);
-           free(ngtp);
-       }
-       NGTable[i] = NULL;
-    }
-    MaxNgNumber = 0;
-    NGTree = NULL;
-}
-
-bool tradspool_ctl(PROBETYPE type, TOKEN *token, void *value) {
-    struct artngnum *ann;
-    unsigned long ngnum;
-    unsigned long artnum;
-    char *ng, *p;
-
-    switch (type) { 
-    case SMARTNGNUM:
-       if ((ann = (struct artngnum *)value) == NULL)
-           return false;
-       CheckNeedReloadDB(false);
-       memcpy(&ngnum, &token->token[0], sizeof(ngnum));
-       memcpy(&artnum, &token->token[sizeof(ngnum)], sizeof(artnum));
-       artnum = ntohl(artnum);
-       ngnum = ntohl(ngnum);
-       ng = FindNGByNum(ngnum);
-       if (ng == NULL) {
-           CheckNeedReloadDB(true);
-           ng = FindNGByNum(ngnum);
-           if (ng == NULL)
-               return false;
-       }
-       ann->groupname = xstrdup(ng);
-        for (p = ann->groupname; *p != 0; p++)
-            if (*p == '/')
-                *p = '.';
-       ann->artnum = (ARTNUM)artnum;
-       return true;
-    default:
-       return false;
-    }       
-}
-
-bool
-tradspool_flushcacheddata(FLUSHTYPE type UNUSED)
-{
-    return true;
-}
-
-void
-tradspool_printfiles(FILE *file, TOKEN token UNUSED, char **xref, int ngroups)
-{
-    int i;
-    char *path, *p;
-
-    for (i = 0; i < ngroups; i++) {
-        path = xstrdup(xref[i]);
-        for (p = path; *p != '\0'; p++)
-            if (*p == '.' || *p == ':')
-                *p = '/';
-        fprintf(file, "%s\n", path);
-        free(path);
-    }
-}
-
-void
-tradspool_shutdown(void) {
-    DumpDB();
-    FreeNGTree();
-}
diff --git a/storage/tradspool/tradspool.h b/storage/tradspool/tradspool.h
deleted file mode 100644 (file)
index 582e740..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-** $Id: tradspool.h 4269 2001-01-04 06:04:10Z rra $
-** tradspool -- storage manager for traditional spool format.
-*/
-
-#ifndef __TRADSPOOL_H__
-#define __TRADSPOOL_H__
-
-#include "config.h"
-#include "interface.h"
-
-bool tradspool_init(SMATTRIBUTE *attr);
-TOKEN tradspool_store(const ARTHANDLE article, const STORAGECLASS class);
-ARTHANDLE *tradspool_retrieve(const TOKEN token, const RETRTYPE amount);
-ARTHANDLE *tradspool_next(const ARTHANDLE *article, const RETRTYPE amount);
-void tradspool_freearticle(ARTHANDLE *article);
-bool tradspool_cancel(TOKEN token);
-bool tradspool_ctl(PROBETYPE type, TOKEN *token, void *value);
-bool tradspool_flushcacheddata(FLUSHTYPE type);
-void tradspool_printfiles(FILE *file, TOKEN token, char **xref, int ngroups);
-void tradspool_shutdown(void);
-
-#endif
diff --git a/storage/trash/method.config b/storage/trash/method.config
deleted file mode 100644 (file)
index f7b73cb..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-name    = trash
-number  = 0
-sources = trash.c
diff --git a/storage/trash/trash.c b/storage/trash/trash.c
deleted file mode 100644 (file)
index 7dfe1bf..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*  $Id: trash.c 6124 2003-01-14 06:03:29Z rra $
-**
-**  Trashing articles method
-*/
-#include "config.h"
-#include "clibrary.h"
-#include "libinn.h"
-#include "methods.h"
-
-#include "trash.h"
-
-bool
-trash_init(SMATTRIBUTE *attr)
-{
-    if (attr == NULL) {
-       SMseterror(SMERR_INTERNAL, "attr is NULL");
-       return false;
-    }
-    attr->selfexpire = true;
-    attr->expensivestat = false;
-    return true;
-}
-
-TOKEN
-trash_store(const ARTHANDLE article, const STORAGECLASS class)
-{
-    TOKEN               token;
-
-    if (article.token == (TOKEN *)NULL)
-       memset(&token, '\0', sizeof(token));
-    else {
-       memcpy(&token, article.token, sizeof(token));
-       memset(&token.token, '\0', STORAGE_TOKEN_LENGTH);
-    }
-    token.type = TOKEN_TRASH;
-    token.class = class;
-    return token;
-}
-
-ARTHANDLE *
-trash_retrieve(const TOKEN token, const RETRTYPE amount UNUSED)
-{
-    if (token.type != TOKEN_TRASH) {
-       SMseterror(SMERR_INTERNAL, NULL);
-       return (ARTHANDLE *)NULL;
-    }
-    SMseterror(SMERR_NOENT, NULL);
-    return (ARTHANDLE *)NULL;
-}
-
-void
-trash_freearticle(ARTHANDLE *article UNUSED)
-{
-}
-
-bool
-trash_cancel(TOKEN token UNUSED)
-{
-    SMseterror(SMERR_NOENT, NULL);
-    return false;
-}
-
-bool
-trash_ctl(PROBETYPE type, TOKEN *token UNUSED, void *value UNUSED)
-{
-    switch (type) {
-    case SMARTNGNUM:
-    default:
-       return false;
-    }
-}
-
-bool
-trash_flushcacheddata(FLUSHTYPE type UNUSED)
-{
-    return true;
-}
-
-void
-trash_printfiles(FILE *file UNUSED, TOKEN token UNUSED, char **xref UNUSED,
-                 int ngroups UNUSED)
-{
-}
-
-ARTHANDLE *
-trash_next(const ARTHANDLE *article UNUSED, const RETRTYPE amount UNUSED)
-{
-    return NULL;
-}
-
-void
-trash_shutdown(void)
-{
-}
diff --git a/storage/trash/trash.h b/storage/trash/trash.h
deleted file mode 100644 (file)
index e19a77b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*  $Id: trash.h 4267 2001-01-04 06:02:02Z rra $
-**
-**  trashing articles method header
-*/
-
-#ifndef __TRASH_H__
-#define __TRASH_H__
-
-#include "config.h"
-#include "interface.h"
-
-bool trash_init(SMATTRIBUTE *attr);
-TOKEN trash_store(const ARTHANDLE article, const STORAGECLASS class);
-ARTHANDLE *trash_retrieve(const TOKEN token, const RETRTYPE amount);
-ARTHANDLE *trash_next(const ARTHANDLE *article, const RETRTYPE amount);
-void trash_freearticle(ARTHANDLE *article);
-bool trash_cancel(TOKEN token);
-bool trash_ctl(PROBETYPE type, TOKEN *token, void *value);
-bool trash_flushcacheddata(FLUSHTYPE type);
-void trash_printfiles(FILE *file, TOKEN token, char **xref, int ngroups);
-void trash_shutdown(void);
-
-#endif
diff --git a/support/config.guess b/support/config.guess
deleted file mode 100755 (executable)
index c7607c7..0000000
+++ /dev/null
@@ -1,1526 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-#   Free Software Foundation, Inc.
-
-timestamp='2008-04-14'
-
-# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, 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.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help" >&2
-       exit 1 ;;
-    * )
-       break ;;
-  esac
-done
-
-if test $# != 0; then
-  echo "$me: too many arguments$help" >&2
-  exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
-       for c in cc gcc c89 c99 ; do
-         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
-            CC_FOR_BUILD="$c"; break ;
-         fi ;
-       done ;
-       if test x"$CC_FOR_BUILD" = x ; then
-         CC_FOR_BUILD=no_compiler_found ;
-       fi
-       ;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
-       PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
-    *:NetBSD:*:*)
-       # NetBSD (nbsd) targets should (where applicable) match one or
-       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
-       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
-       # switched to ELF, *-*-netbsd* would select the old
-       # object file format.  This provides both forward
-       # compatibility and a consistent mechanism for selecting the
-       # object file format.
-       #
-       # Note: NetBSD doesn't particularly care about the vendor
-       # portion of the name.  We always set it to "unknown".
-       sysctl="sysctl -n hw.machine_arch"
-       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
-       case "${UNAME_MACHINE_ARCH}" in
-           armeb) machine=armeb-unknown ;;
-           arm*) machine=arm-unknown ;;
-           sh3el) machine=shl-unknown ;;
-           sh3eb) machine=sh-unknown ;;
-           sh5el) machine=sh5le-unknown ;;
-           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
-       esac
-       # The Operating System including object format, if it has switched
-       # to ELF recently, or will in the future.
-       case "${UNAME_MACHINE_ARCH}" in
-           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-               eval $set_cc_for_build
-               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-                       | grep __ELF__ >/dev/null
-               then
-                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
-                   # Return netbsd for either.  FIX?
-                   os=netbsd
-               else
-                   os=netbsdelf
-               fi
-               ;;
-           *)
-               os=netbsd
-               ;;
-       esac
-       # The OS release
-       # Debian GNU/NetBSD machines have a different userland, and
-       # thus, need a distinct triplet. However, they do not need
-       # kernel version information, so it can be replaced with a
-       # suitable tag, in the style of linux-gnu.
-       case "${UNAME_VERSION}" in
-           Debian*)
-               release='-gnu'
-               ;;
-           *)
-               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
-               ;;
-       esac
-       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
-       # contains redundant information, the shorter form:
-       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-       echo "${machine}-${os}${release}"
-       exit ;;
-    *:OpenBSD:*:*)
-       UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
-       exit ;;
-    *:ekkoBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
-       exit ;;
-    *:SolidBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
-       exit ;;
-    macppc:MirBSD:*:*)
-       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
-       exit ;;
-    *:MirBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
-       exit ;;
-    alpha:OSF1:*:*)
-       case $UNAME_RELEASE in
-       *4.0)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-               ;;
-       *5.*)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
-               ;;
-       esac
-       # According to Compaq, /usr/sbin/psrinfo has been available on
-       # OSF/1 and Tru64 systems produced since 1995.  I hope that
-       # covers most systems running today.  This code pipes the CPU
-       # types through head -n 1, so we only detect the type of CPU 0.
-       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-       case "$ALPHA_CPU_TYPE" in
-           "EV4 (21064)")
-               UNAME_MACHINE="alpha" ;;
-           "EV4.5 (21064)")
-               UNAME_MACHINE="alpha" ;;
-           "LCA4 (21066/21068)")
-               UNAME_MACHINE="alpha" ;;
-           "EV5 (21164)")
-               UNAME_MACHINE="alphaev5" ;;
-           "EV5.6 (21164A)")
-               UNAME_MACHINE="alphaev56" ;;
-           "EV5.6 (21164PC)")
-               UNAME_MACHINE="alphapca56" ;;
-           "EV5.7 (21164PC)")
-               UNAME_MACHINE="alphapca57" ;;
-           "EV6 (21264)")
-               UNAME_MACHINE="alphaev6" ;;
-           "EV6.7 (21264A)")
-               UNAME_MACHINE="alphaev67" ;;
-           "EV6.8CB (21264C)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.8AL (21264B)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.8CX (21264D)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.9A (21264/EV69A)")
-               UNAME_MACHINE="alphaev69" ;;
-           "EV7 (21364)")
-               UNAME_MACHINE="alphaev7" ;;
-           "EV7.9 (21364A)")
-               UNAME_MACHINE="alphaev79" ;;
-       esac
-       # A Pn.n version is a patched version.
-       # A Vn.n version is a released version.
-       # A Tn.n version is a released field test version.
-       # A Xn.n version is an unreleased experimental baselevel.
-       # 1.2 uses "1.2" for uname -r.
-       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       exit ;;
-    Alpha\ *:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # Should we change UNAME_MACHINE based on the output of uname instead
-       # of the specific Alpha model?
-       echo alpha-pc-interix
-       exit ;;
-    21064:Windows_NT:50:3)
-       echo alpha-dec-winnt3.5
-       exit ;;
-    Amiga*:UNIX_System_V:4.0:*)
-       echo m68k-unknown-sysv4
-       exit ;;
-    *:[Aa]miga[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-amigaos
-       exit ;;
-    *:[Mm]orph[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-morphos
-       exit ;;
-    *:OS/390:*:*)
-       echo i370-ibm-openedition
-       exit ;;
-    *:z/VM:*:*)
-       echo s390-ibm-zvmoe
-       exit ;;
-    *:OS400:*:*)
-        echo powerpc-ibm-os400
-       exit ;;
-    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-       echo arm-acorn-riscix${UNAME_RELEASE}
-       exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
-       echo arm-unknown-riscos
-       exit ;;
-    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-       echo hppa1.1-hitachi-hiuxmpp
-       exit ;;
-    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
-       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-       if test "`(/bin/universe) 2>/dev/null`" = att ; then
-               echo pyramid-pyramid-sysv3
-       else
-               echo pyramid-pyramid-bsd
-       fi
-       exit ;;
-    NILE*:*:*:dcosx)
-       echo pyramid-pyramid-svr4
-       exit ;;
-    DRS?6000:unix:4.0:6*)
-       echo sparc-icl-nx6
-       exit ;;
-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
-       case `/usr/bin/uname -p` in
-           sparc) echo sparc-icl-nx7; exit ;;
-       esac ;;
-    sun4H:SunOS:5.*:*)
-       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:6*:*)
-       # According to config.sub, this is the proper way to canonicalize
-       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
-       # it's likely to be more like Solaris than SunOS4.
-       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:*:*)
-       case "`/usr/bin/arch -k`" in
-           Series*|S4*)
-               UNAME_RELEASE=`uname -v`
-               ;;
-       esac
-       # Japanese Language versions have a version number like `4.1.3-JL'.
-       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-       exit ;;
-    sun3*:SunOS:*:*)
-       echo m68k-sun-sunos${UNAME_RELEASE}
-       exit ;;
-    sun*:*:4.2BSD:*)
-       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
-       case "`/bin/arch`" in
-           sun3)
-               echo m68k-sun-sunos${UNAME_RELEASE}
-               ;;
-           sun4)
-               echo sparc-sun-sunos${UNAME_RELEASE}
-               ;;
-       esac
-       exit ;;
-    aushp:SunOS:*:*)
-       echo sparc-auspex-sunos${UNAME_RELEASE}
-       exit ;;
-    # The situation for MiNT is a little confusing.  The machine name
-    # can be virtually everything (everything which is not
-    # "atarist" or "atariste" at least should have a processor
-    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
-    # to the lowercase version "mint" (or "freemint").  Finally
-    # the system name "TOS" denotes a system which is actually not
-    # MiNT.  But MiNT is downward compatible to TOS, so this should
-    # be no problem.
-    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-       exit ;;
-    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
-    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-       exit ;;
-    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
-    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
-    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
-    m68k:machten:*:*)
-       echo m68k-apple-machten${UNAME_RELEASE}
-       exit ;;
-    powerpc:machten:*:*)
-       echo powerpc-apple-machten${UNAME_RELEASE}
-       exit ;;
-    RISC*:Mach:*:*)
-       echo mips-dec-mach_bsd4.3
-       exit ;;
-    RISC*:ULTRIX:*:*)
-       echo mips-dec-ultrix${UNAME_RELEASE}
-       exit ;;
-    VAX*:ULTRIX*:*:*)
-       echo vax-dec-ultrix${UNAME_RELEASE}
-       exit ;;
-    2020:CLIX:*:* | 2430:CLIX:*:*)
-       echo clipper-intergraph-clix${UNAME_RELEASE}
-       exit ;;
-    mips:*:*:UMIPS | mips:*:*:RISCos)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-       int main (int argc, char *argv[]) {
-#else
-       int main (argc, argv) int argc; char *argv[]; {
-#endif
-       #if defined (host_mips) && defined (MIPSEB)
-       #if defined (SYSTYPE_SYSV)
-         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
-       #endif
-       #if defined (SYSTYPE_SVR4)
-         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
-       #endif
-       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
-       #endif
-       #endif
-         exit (-1);
-       }
-EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c &&
-         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-         SYSTEM_NAME=`$dummy $dummyarg` &&
-           { echo "$SYSTEM_NAME"; exit; }
-       echo mips-mips-riscos${UNAME_RELEASE}
-       exit ;;
-    Motorola:PowerMAX_OS:*:*)
-       echo powerpc-motorola-powermax
-       exit ;;
-    Motorola:*:4.3:PL8-*)
-       echo powerpc-harris-powermax
-       exit ;;
-    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-       echo powerpc-harris-powermax
-       exit ;;
-    Night_Hawk:Power_UNIX:*:*)
-       echo powerpc-harris-powerunix
-       exit ;;
-    m88k:CX/UX:7*:*)
-       echo m88k-harris-cxux7
-       exit ;;
-    m88k:*:4*:R4*)
-       echo m88k-motorola-sysv4
-       exit ;;
-    m88k:*:3*:R3*)
-       echo m88k-motorola-sysv3
-       exit ;;
-    AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
-       then
-           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-              [ ${TARGET_BINARY_INTERFACE}x = x ]
-           then
-               echo m88k-dg-dgux${UNAME_RELEASE}
-           else
-               echo m88k-dg-dguxbcs${UNAME_RELEASE}
-           fi
-       else
-           echo i586-dg-dgux${UNAME_RELEASE}
-       fi
-       exit ;;
-    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
-       echo m88k-dolphin-sysv3
-       exit ;;
-    M88*:*:R3*:*)
-       # Delta 88k system running SVR3
-       echo m88k-motorola-sysv3
-       exit ;;
-    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-       echo m88k-tektronix-sysv3
-       exit ;;
-    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-       echo m68k-tektronix-bsd
-       exit ;;
-    *:IRIX*:*:*)
-       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-       exit ;;
-    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
-    i*86:AIX:*:*)
-       echo i386-ibm-aix
-       exit ;;
-    ia64:AIX:*:*)
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
-       else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-       fi
-       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
-       exit ;;
-    *:AIX:2:3)
-       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-               eval $set_cc_for_build
-               sed 's/^                //' << EOF >$dummy.c
-               #include <sys/systemcfg.h>
-
-               main()
-                       {
-                       if (!__power_pc())
-                               exit(1);
-                       puts("powerpc-ibm-aix3.2.5");
-                       exit(0);
-                       }
-EOF
-               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
-               then
-                       echo "$SYSTEM_NAME"
-               else
-                       echo rs6000-ibm-aix3.2.5
-               fi
-       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-               echo rs6000-ibm-aix3.2.4
-       else
-               echo rs6000-ibm-aix3.2
-       fi
-       exit ;;
-    *:AIX:*:[456])
-       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
-               IBM_ARCH=rs6000
-       else
-               IBM_ARCH=powerpc
-       fi
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
-       else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-       fi
-       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-       exit ;;
-    *:AIX:*:*)
-       echo rs6000-ibm-aix
-       exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
-       echo romp-ibm-bsd4.4
-       exit ;;
-    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-       exit ;;                             # report: romp-ibm BSD 4.3
-    *:BOSX:*:*)
-       echo rs6000-bull-bosx
-       exit ;;
-    DPX/2?00:B.O.S.:*:*)
-       echo m68k-bull-sysv3
-       exit ;;
-    9000/[34]??:4.3bsd:1.*:*)
-       echo m68k-hp-bsd
-       exit ;;
-    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-       echo m68k-hp-bsd4.4
-       exit ;;
-    9000/[34678]??:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       case "${UNAME_MACHINE}" in
-           9000/31? )            HP_ARCH=m68000 ;;
-           9000/[34]?? )         HP_ARCH=m68k ;;
-           9000/[678][0-9][0-9])
-               if [ -x /usr/bin/getconf ]; then
-                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
-                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
-               fi
-               if [ "${HP_ARCH}" = "" ]; then
-                   eval $set_cc_for_build
-                   sed 's/^              //' << EOF >$dummy.c
-
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
-
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
-
-                  switch (cpu)
-               {
-               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-               case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-                   switch (bits)
-                       {
-                       case 64: puts ("hppa2.0w"); break;
-                       case 32: puts ("hppa2.0n"); break;
-                       default: puts ("hppa2.0"); break;
-                       } break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-                   puts ("hppa2.0"); break;
-              #endif
-               default: puts ("hppa1.0"); break;
-               }
-                  exit (0);
-              }
-EOF
-                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
-                   test -z "$HP_ARCH" && HP_ARCH=hppa
-               fi ;;
-       esac
-       if [ ${HP_ARCH} = "hppa2.0w" ]
-       then
-           eval $set_cc_for_build
-
-           # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
-           # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
-           # generating 64-bit code.  GNU and HP use different nomenclature:
-           #
-           # $ CC_FOR_BUILD=cc ./config.guess
-           # => hppa2.0w-hp-hpux11.23
-           # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
-           # => hppa64-hp-hpux11.23
-
-           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-               grep __LP64__ >/dev/null
-           then
-               HP_ARCH="hppa2.0w"
-           else
-               HP_ARCH="hppa64"
-           fi
-       fi
-       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-       exit ;;
-    ia64:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       echo ia64-hp-hpux${HPUX_REV}
-       exit ;;
-    3050*:HI-UX:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #include <unistd.h>
-       int
-       main ()
-       {
-         long cpu = sysconf (_SC_CPU_VERSION);
-         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
-            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
-            results, however.  */
-         if (CPU_IS_PA_RISC (cpu))
-           {
-             switch (cpu)
-               {
-                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
-                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
-                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
-                 default: puts ("hppa-hitachi-hiuxwe2"); break;
-               }
-           }
-         else if (CPU_IS_HP_MC68K (cpu))
-           puts ("m68k-hitachi-hiuxwe2");
-         else puts ("unknown-hitachi-hiuxwe2");
-         exit (0);
-       }
-EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
-               { echo "$SYSTEM_NAME"; exit; }
-       echo unknown-hitachi-hiuxwe2
-       exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
-       echo hppa1.1-hp-bsd
-       exit ;;
-    9000/8??:4.3bsd:*:*)
-       echo hppa1.0-hp-bsd
-       exit ;;
-    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-       echo hppa1.0-hp-mpeix
-       exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
-       echo hppa1.1-hp-osf
-       exit ;;
-    hp8??:OSF1:*:*)
-       echo hppa1.0-hp-osf
-       exit ;;
-    i*86:OSF1:*:*)
-       if [ -x /usr/sbin/sysversion ] ; then
-           echo ${UNAME_MACHINE}-unknown-osf1mk
-       else
-           echo ${UNAME_MACHINE}-unknown-osf1
-       fi
-       exit ;;
-    parisc*:Lites*:*:*)
-       echo hppa1.1-hp-lites
-       exit ;;
-    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-       echo c1-convex-bsd
-        exit ;;
-    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-        exit ;;
-    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-       echo c34-convex-bsd
-        exit ;;
-    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-       echo c38-convex-bsd
-        exit ;;
-    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-       echo c4-convex-bsd
-        exit ;;
-    CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*[A-Z]90:*:*:*)
-       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
-       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-             -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*TS:*:*:*)
-       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*T3E:*:*:*)
-       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*SV1:*:*:*)
-       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
-    5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-       exit ;;
-    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-       exit ;;
-    sparc*:BSD/OS:*:*)
-       echo sparc-unknown-bsdi${UNAME_RELEASE}
-       exit ;;
-    *:BSD/OS:*:*)
-       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-       exit ;;
-    *:FreeBSD:*:*)
-       case ${UNAME_MACHINE} in
-           pc98)
-               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           amd64)
-               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           *)
-               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-       esac
-       exit ;;
-    i*:CYGWIN*:*)
-       echo ${UNAME_MACHINE}-pc-cygwin
-       exit ;;
-    *:MINGW*:*)
-       echo ${UNAME_MACHINE}-pc-mingw32
-       exit ;;
-    i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
-       exit ;;
-    i*:PW*:*)
-       echo ${UNAME_MACHINE}-pc-pw32
-       exit ;;
-    *:Interix*:[3456]*)
-       case ${UNAME_MACHINE} in
-           x86)
-               echo i586-pc-interix${UNAME_RELEASE}
-               exit ;;
-           EM64T | authenticamd)
-               echo x86_64-unknown-interix${UNAME_RELEASE}
-               exit ;;
-           IA64)
-               echo ia64-unknown-interix${UNAME_RELEASE}
-               exit ;;
-       esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-       echo i${UNAME_MACHINE}-pc-mks
-       exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-       # UNAME_MACHINE based on the output of uname instead of i386?
-       echo i586-pc-interix
-       exit ;;
-    i*:UWIN*:*)
-       echo ${UNAME_MACHINE}-pc-uwin
-       exit ;;
-    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-       echo x86_64-unknown-cygwin
-       exit ;;
-    p*:CYGWIN*:*)
-       echo powerpcle-unknown-cygwin
-       exit ;;
-    prep*:SunOS:5.*:*)
-       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    *:GNU:*:*)
-       # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-       exit ;;
-    *:GNU/*:*:*)
-       # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
-       exit ;;
-    i*86:Minix:*:*)
-       echo ${UNAME_MACHINE}-pc-minix
-       exit ;;
-    arm*:Linux:*:*)
-       eval $set_cc_for_build
-       if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
-           | grep -q __ARM_EABI__
-       then
-           echo ${UNAME_MACHINE}-unknown-linux-gnu
-       else
-           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
-       fi
-       exit ;;
-    avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    cris:Linux:*:*)
-       echo cris-axis-linux-gnu
-       exit ;;
-    crisv32:Linux:*:*)
-       echo crisv32-axis-linux-gnu
-       exit ;;
-    frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
-       exit ;;
-    ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    mips:Linux:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #undef CPU
-       #undef mips
-       #undef mipsel
-       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-       CPU=mipsel
-       #else
-       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-       CPU=mips
-       #else
-       CPU=
-       #endif
-       #endif
-EOF
-       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-           /^CPU/{
-               s: ::g
-               p
-           }'`"
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
-       ;;
-    mips64:Linux:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #undef CPU
-       #undef mips64
-       #undef mips64el
-       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-       CPU=mips64el
-       #else
-       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-       CPU=mips64
-       #else
-       CPU=
-       #endif
-       #endif
-EOF
-       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-           /^CPU/{
-               s: ::g
-               p
-           }'`"
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
-       ;;
-    or32:Linux:*:*)
-       echo or32-unknown-linux-gnu
-       exit ;;
-    ppc:Linux:*:*)
-       echo powerpc-unknown-linux-gnu
-       exit ;;
-    ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-gnu
-       exit ;;
-    alpha:Linux:*:*)
-       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-         EV5)   UNAME_MACHINE=alphaev5 ;;
-         EV56)  UNAME_MACHINE=alphaev56 ;;
-         PCA56) UNAME_MACHINE=alphapca56 ;;
-         PCA57) UNAME_MACHINE=alphapca56 ;;
-         EV6)   UNAME_MACHINE=alphaev6 ;;
-         EV67)  UNAME_MACHINE=alphaev67 ;;
-         EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
-       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
-       exit ;;
-    parisc:Linux:*:* | hppa:Linux:*:*)
-       # Look for CPU level
-       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-gnu ;;
-         PA8*) echo hppa2.0-unknown-linux-gnu ;;
-         *)    echo hppa-unknown-linux-gnu ;;
-       esac
-       exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-gnu
-       exit ;;
-    s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux
-       exit ;;
-    sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-gnu
-       exit ;;
-    x86_64:Linux:*:*)
-       echo x86_64-unknown-linux-gnu
-       exit ;;
-    xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    i*86:Linux:*:*)
-       # The BFD linker knows what the default object file format is, so
-       # first see if it will tell us. cd to the root directory to prevent
-       # problems with other programs or directories called `ld' in the path.
-       # Set LC_ALL=C to ensure ld outputs messages in English.
-       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
-                        | sed -ne '/supported targets:/!d
-                                   s/[         ][      ]*/ /g
-                                   s/.*supported targets: *//
-                                   s/ .*//
-                                   p'`
-        case "$ld_supported_targets" in
-         elf32-i386)
-               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
-               ;;
-         a.out-i386-linux)
-               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-               exit ;;
-         "")
-               # Either a pre-BFD a.out linker (linux-gnuoldld) or
-               # one that does not give us useful --help.
-               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
-               exit ;;
-       esac
-       # Determine whether the default compiler is a.out or elf
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #include <features.h>
-       #ifdef __ELF__
-       # ifdef __GLIBC__
-       #  if __GLIBC__ >= 2
-       LIBC=gnu
-       #  else
-       LIBC=gnulibc1
-       #  endif
-       # else
-       LIBC=gnulibc1
-       # endif
-       #else
-       #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-       LIBC=gnu
-       #else
-       LIBC=gnuaout
-       #endif
-       #endif
-       #ifdef __dietlibc__
-       LIBC=dietlibc
-       #endif
-EOF
-       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-           /^LIBC/{
-               s: ::g
-               p
-           }'`"
-       test x"${LIBC}" != x && {
-               echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
-               exit
-       }
-       test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
-       ;;
-    i*86:DYNIX/ptx:4*:*)
-       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
-       # earlier versions are messed up and put the nodename in both
-       # sysname and nodename.
-       echo i386-sequent-sysv4
-       exit ;;
-    i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
-       # I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
-       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-       exit ;;
-    i*86:OS/2:*:*)
-       # If we were able to find `uname', then EMX Unix compatibility
-       # is probably installed.
-       echo ${UNAME_MACHINE}-pc-os2-emx
-       exit ;;
-    i*86:XTS-300:*:STOP)
-       echo ${UNAME_MACHINE}-unknown-stop
-       exit ;;
-    i*86:atheos:*:*)
-       echo ${UNAME_MACHINE}-unknown-atheos
-       exit ;;
-    i*86:syllable:*:*)
-       echo ${UNAME_MACHINE}-pc-syllable
-       exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
-       echo i386-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    i*86:*DOS:*:*)
-       echo ${UNAME_MACHINE}-pc-msdosdjgpp
-       exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
-       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
-       else
-               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
-       fi
-       exit ;;
-    i*86:*:5:[678]*)
-       # UnixWare 7.x, OpenUNIX and OpenServer 6.
-       case `/bin/uname -X | grep "^Machine"` in
-           *486*)           UNAME_MACHINE=i486 ;;
-           *Pentium)        UNAME_MACHINE=i586 ;;
-           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
-       esac
-       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-       exit ;;
-    i*86:*:3.2:*)
-       if test -f /usr/options/cb.name; then
-               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
-       elif /bin/uname -X 2>/dev/null >/dev/null ; then
-               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
-               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
-               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
-                       && UNAME_MACHINE=i586
-               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
-                       && UNAME_MACHINE=i686
-               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
-                       && UNAME_MACHINE=i686
-               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
-       else
-               echo ${UNAME_MACHINE}-pc-sysv32
-       fi
-       exit ;;
-    pc:*:*:*)
-       # Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-       echo i386-pc-msdosdjgpp
-        exit ;;
-    Intel:Mach:3*:*)
-       echo i386-pc-mach3
-       exit ;;
-    paragon:*:*:*)
-       echo i860-intel-osf1
-       exit ;;
-    i860:*:4.*:*) # i860-SVR4
-       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
-       else # Add other i860-SVR4 vendors below as they are discovered.
-         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
-       fi
-       exit ;;
-    mini*:CTIX:SYS*5:*)
-       # "miniframe"
-       echo m68010-convergent-sysv
-       exit ;;
-    mc68k:UNIX:SYSTEM5:3.51m)
-       echo m68k-convergent-sysv
-       exit ;;
-    M680?0:D-NIX:5.3:*)
-       echo m68k-diab-dnix
-       exit ;;
-    M68*:*:R3V[5678]*:*)
-       test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
-       OS_REL=''
-       test -r /etc/.relid \
-       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
-    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
-    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-       echo m68k-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    mc68030:UNIX_System_V:4.*:*)
-       echo m68k-atari-sysv4
-       exit ;;
-    TSUNAMI:LynxOS:2.*:*)
-       echo sparc-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    rs6000:LynxOS:2.*:*)
-       echo rs6000-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
-       echo powerpc-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    SM[BE]S:UNIX_SV:*:*)
-       echo mips-dde-sysv${UNAME_RELEASE}
-       exit ;;
-    RM*:ReliantUNIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
-    RM*:SINIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
-    *:SINIX-*:*:*)
-       if uname -p 2>/dev/null >/dev/null ; then
-               UNAME_MACHINE=`(uname -p) 2>/dev/null`
-               echo ${UNAME_MACHINE}-sni-sysv4
-       else
-               echo ns32k-sni-sysv
-       fi
-       exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit ;;
-    *:UNIX_System_V:4*:FTX*)
-       # From Gerald Hewes <hewes@openmarket.com>.
-       # How about differentiating between stratus architectures? -djm
-       echo hppa1.1-stratus-sysv4
-       exit ;;
-    *:*:*:FTX*)
-       # From seanf@swdc.stratus.com.
-       echo i860-stratus-sysv4
-       exit ;;
-    i*86:VOS:*:*)
-       # From Paul.Green@stratus.com.
-       echo ${UNAME_MACHINE}-stratus-vos
-       exit ;;
-    *:VOS:*:*)
-       # From Paul.Green@stratus.com.
-       echo hppa1.1-stratus-vos
-       exit ;;
-    mc68*:A/UX:*:*)
-       echo m68k-apple-aux${UNAME_RELEASE}
-       exit ;;
-    news*:NEWS-OS:6*:*)
-       echo mips-sony-newsos6
-       exit ;;
-    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-       if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
-       else
-               echo mips-unknown-sysv${UNAME_RELEASE}
-       fi
-        exit ;;
-    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
-       echo powerpc-be-beos
-       exit ;;
-    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
-       echo powerpc-apple-beos
-       exit ;;
-    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
-       echo i586-pc-beos
-       exit ;;
-    BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
-       echo i586-pc-haiku
-       exit ;;
-    SX-4:SUPER-UX:*:*)
-       echo sx4-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-5:SUPER-UX:*:*)
-       echo sx5-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-6:SUPER-UX:*:*)
-       echo sx6-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-7:SUPER-UX:*:*)
-       echo sx7-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-8:SUPER-UX:*:*)
-       echo sx8-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-8R:SUPER-UX:*:*)
-       echo sx8r-nec-superux${UNAME_RELEASE}
-       exit ;;
-    Power*:Rhapsody:*:*)
-       echo powerpc-apple-rhapsody${UNAME_RELEASE}
-       exit ;;
-    *:Rhapsody:*:*)
-       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-       exit ;;
-    *:Darwin:*:*)
-       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       case $UNAME_PROCESSOR in
-           unknown) UNAME_PROCESSOR=powerpc ;;
-       esac
-       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
-       exit ;;
-    *:procnto*:*:* | *:QNX:[0123456789]*:*)
-       UNAME_PROCESSOR=`uname -p`
-       if test "$UNAME_PROCESSOR" = "x86"; then
-               UNAME_PROCESSOR=i386
-               UNAME_MACHINE=pc
-       fi
-       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
-       exit ;;
-    *:QNX:*:4*)
-       echo i386-pc-qnx
-       exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
-       echo nse-tandem-nsk${UNAME_RELEASE}
-       exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
-       echo nsr-tandem-nsk${UNAME_RELEASE}
-       exit ;;
-    *:NonStop-UX:*:*)
-       echo mips-compaq-nonstopux
-       exit ;;
-    BS2000:POSIX*:*:*)
-       echo bs2000-siemens-sysv
-       exit ;;
-    DS/*:UNIX_System_V:*:*)
-       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-       exit ;;
-    *:Plan9:*:*)
-       # "uname -m" is not consistent, so use $cputype instead. 386
-       # is converted to i386 for consistency with other x86
-       # operating systems.
-       if test "$cputype" = "386"; then
-           UNAME_MACHINE=i386
-       else
-           UNAME_MACHINE="$cputype"
-       fi
-       echo ${UNAME_MACHINE}-unknown-plan9
-       exit ;;
-    *:TOPS-10:*:*)
-       echo pdp10-unknown-tops10
-       exit ;;
-    *:TENEX:*:*)
-       echo pdp10-unknown-tenex
-       exit ;;
-    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-       echo pdp10-dec-tops20
-       exit ;;
-    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-       echo pdp10-xkl-tops20
-       exit ;;
-    *:TOPS-20:*:*)
-       echo pdp10-unknown-tops20
-       exit ;;
-    *:ITS:*:*)
-       echo pdp10-unknown-its
-       exit ;;
-    SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
-       exit ;;
-    *:DragonFly:*:*)
-       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-       exit ;;
-    *:*VMS:*:*)
-       UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "${UNAME_MACHINE}" in
-           A*) echo alpha-dec-vms ; exit ;;
-           I*) echo ia64-dec-vms ; exit ;;
-           V*) echo vax-dec-vms ; exit ;;
-       esac ;;
-    *:XENIX:*:SysV)
-       echo i386-pc-xenix
-       exit ;;
-    i*86:skyos:*:*)
-       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
-       exit ;;
-    i*86:rdos:*:*)
-       echo ${UNAME_MACHINE}-pc-rdos
-       exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-          "4"
-#else
-         ""
-#endif
-         ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-       printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-       printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include <sys/param.h>
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-       { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-       echo c1-convex-bsd
-       exit ;;
-    c2*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-       exit ;;
-    c34*)
-       echo c34-convex-bsd
-       exit ;;
-    c38*)
-       echo c38-convex-bsd
-       exit ;;
-    c4*)
-       echo c4-convex-bsd
-       exit ;;
-    esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo               = `(hostinfo) 2>/dev/null`
-/bin/universe          = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch              = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/support/config.sub b/support/config.sub
deleted file mode 100755 (executable)
index 63bfff0..0000000
+++ /dev/null
@@ -1,1669 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-#   Free Software Foundation, Inc.
-
-timestamp='2008-04-14'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, 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.
-
-
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support.  The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help"
-       exit 1 ;;
-
-    *local*)
-       # First pass through any local machine types.
-       echo $1
-       exit ;;
-
-    * )
-       break ;;
-  esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
-    exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
-    exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-       -sun*os*)
-               # Prevent following clause from handling this invalid input.
-               ;;
-       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray)
-               os=
-               basic_machine=$1
-               ;;
-       -sim | -cisco | -oki | -wec | -winbond)
-               os=
-               basic_machine=$1
-               ;;
-       -scout)
-               ;;
-       -wrs)
-               os=-vxworks
-               basic_machine=$1
-               ;;
-       -chorusos*)
-               os=-chorusos
-               basic_machine=$1
-               ;;
-       -chorusrdb)
-               os=-chorusrdb
-               basic_machine=$1
-               ;;
-       -hiux*)
-               os=-hiuxwe2
-               ;;
-       -sco6)
-               os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5)
-               os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco4)
-               os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2.[4-9]*)
-               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2v[4-9]*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5v6*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco*)
-               os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -isc)
-               os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -clix*)
-               basic_machine=clipper-intergraph
-               ;;
-       -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -lynx*)
-               os=-lynxos
-               ;;
-       -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
-               ;;
-       -psos*)
-               os=-psos
-               ;;
-       -mint | -mint[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-       | bfin \
-       | c4x | clipper \
-       | d10v | d30v | dlx | dsp16xx \
-       | fido | fr30 | frv \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | i370 | i860 | i960 | ia64 \
-       | ip2k | iq2000 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | mt \
-       | msp430 \
-       | nios | nios2 \
-       | ns16k | ns32k \
-       | or32 \
-       | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
-       | pyramid \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu | strongarm \
-       | tahoe | thumb | tic4x | tic80 | tron \
-       | v850 | v850e \
-       | we32k \
-       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-       | z8k)
-               basic_machine=$basic_machine-unknown
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12)
-               # Motorola 68HC11/12.
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-               ;;
-       ms1)
-               basic_machine=mt-unknown
-               ;;
-
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-         basic_machine=$basic_machine-pc
-         ;;
-       # Object if more than one company name word.
-       *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-       # Recognize the basic CPU types with company name.
-       580-* \
-       | a29k-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
-       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* | avr32-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-       | clipper-* | craynv-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mt-* \
-       | msp430-* \
-       | nios-* | nios2-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
-       | pyramid-* \
-       | romp-* | rs6000-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
-       | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
-       | tron-* \
-       | v850-* | v850e-* | vax-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-*)
-               ;;
-       # Recognize the basic CPU types without company name, with glob match.
-       xtensa*)
-               basic_machine=$basic_machine-unknown
-               ;;
-       # Recognize the various machine names and aliases which stand
-       # for a CPU type and a company and sometimes even an OS.
-       386bsd)
-               basic_machine=i386-unknown
-               os=-bsd
-               ;;
-       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
-               ;;
-       3b*)
-               basic_machine=we32k-att
-               ;;
-       a29khif)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       abacus)
-               basic_machine=abacus-unknown
-               ;;
-       adobe68k)
-               basic_machine=m68010-adobe
-               os=-scout
-               ;;
-       alliant | fx80)
-               basic_machine=fx80-alliant
-               ;;
-       altos | altos3068)
-               basic_machine=m68k-altos
-               ;;
-       am29k)
-               basic_machine=a29k-none
-               os=-bsd
-               ;;
-       amd64)
-               basic_machine=x86_64-pc
-               ;;
-       amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       amdahl)
-               basic_machine=580-amdahl
-               os=-sysv
-               ;;
-       amiga | amiga-*)
-               basic_machine=m68k-unknown
-               ;;
-       amigaos | amigados)
-               basic_machine=m68k-unknown
-               os=-amigaos
-               ;;
-       amigaunix | amix)
-               basic_machine=m68k-unknown
-               os=-sysv4
-               ;;
-       apollo68)
-               basic_machine=m68k-apollo
-               os=-sysv
-               ;;
-       apollo68bsd)
-               basic_machine=m68k-apollo
-               os=-bsd
-               ;;
-       aux)
-               basic_machine=m68k-apple
-               os=-aux
-               ;;
-       balance)
-               basic_machine=ns32k-sequent
-               os=-dynix
-               ;;
-       blackfin)
-               basic_machine=bfin-unknown
-               os=-linux
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=-unicos
-               ;;
-       convex-c1)
-               basic_machine=c1-convex
-               os=-bsd
-               ;;
-       convex-c2)
-               basic_machine=c2-convex
-               os=-bsd
-               ;;
-       convex-c32)
-               basic_machine=c32-convex
-               os=-bsd
-               ;;
-       convex-c34)
-               basic_machine=c34-convex
-               os=-bsd
-               ;;
-       convex-c38)
-               basic_machine=c38-convex
-               os=-bsd
-               ;;
-       cray | j90)
-               basic_machine=j90-cray
-               os=-unicos
-               ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
-       cr16)
-               basic_machine=cr16-unknown
-               os=-elf
-               ;;
-       crds | unos)
-               basic_machine=m68k-crds
-               ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
-               ;;
-       crx)
-               basic_machine=crx-unknown
-               os=-elf
-               ;;
-       da30 | da30-*)
-               basic_machine=m68k-da30
-               ;;
-       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-               basic_machine=mips-dec
-               ;;
-       decsystem10* | dec10*)
-               basic_machine=pdp10-dec
-               os=-tops10
-               ;;
-       decsystem20* | dec20*)
-               basic_machine=pdp10-dec
-               os=-tops20
-               ;;
-       delta | 3300 | motorola-3300 | motorola-delta \
-             | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       delta88)
-               basic_machine=m88k-motorola
-               os=-sysv3
-               ;;
-       dicos)
-               basic_machine=i686-pc
-               os=-dicos
-               ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=-bosx
-               ;;
-       dpx2* | dpx2*-bull)
-               basic_machine=m68k-bull
-               os=-sysv3
-               ;;
-       ebmon29k)
-               basic_machine=a29k-amd
-               os=-ebmon
-               ;;
-       elxsi)
-               basic_machine=elxsi-elxsi
-               os=-bsd
-               ;;
-       encore | umax | mmax)
-               basic_machine=ns32k-encore
-               ;;
-       es1800 | OSE68k | ose68k | ose | OSE)
-               basic_machine=m68k-ericsson
-               os=-ose
-               ;;
-       fx2800)
-               basic_machine=i860-alliant
-               ;;
-       genix)
-               basic_machine=ns32k-ns
-               ;;
-       gmicro)
-               basic_machine=tron-gmicro
-               os=-sysv
-               ;;
-       go32)
-               basic_machine=i386-pc
-               os=-go32
-               ;;
-       h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       h8300hms)
-               basic_machine=h8300-hitachi
-               os=-hms
-               ;;
-       h8300xray)
-               basic_machine=h8300-hitachi
-               os=-xray
-               ;;
-       h8500hms)
-               basic_machine=h8500-hitachi
-               os=-hms
-               ;;
-       harris)
-               basic_machine=m88k-harris
-               os=-sysv3
-               ;;
-       hp300-*)
-               basic_machine=m68k-hp
-               ;;
-       hp300bsd)
-               basic_machine=m68k-hp
-               os=-bsd
-               ;;
-       hp300hpux)
-               basic_machine=m68k-hp
-               os=-hpux
-               ;;
-       hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
-               ;;
-       hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
-               ;;
-       hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k78[0-9] | hp78[0-9])
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
-       hppaosf)
-               basic_machine=hppa1.1-hp
-               os=-osf
-               ;;
-       hppro)
-               basic_machine=hppa1.1-hp
-               os=-proelf
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
-               ;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-       i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv32
-               ;;
-       i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv4
-               ;;
-       i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv
-               ;;
-       i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-solaris2
-               ;;
-       i386mach)
-               basic_machine=i386-mach
-               os=-mach
-               ;;
-       i386-vsta | vsta)
-               basic_machine=i386-unknown
-               os=-vsta
-               ;;
-       iris | iris4d)
-               basic_machine=mips-sgi
-               case $os in
-                   -irix*)
-                       ;;
-                   *)
-                       os=-irix4
-                       ;;
-               esac
-               ;;
-       isi68 | isi)
-               basic_machine=m68k-isi
-               os=-sysv
-               ;;
-       m68knommu)
-               basic_machine=m68k-unknown
-               os=-linux
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
-       magnum | m3230)
-               basic_machine=mips-mips
-               os=-sysv
-               ;;
-       merlin)
-               basic_machine=ns32k-utek
-               os=-sysv
-               ;;
-       mingw32)
-               basic_machine=i386-pc
-               os=-mingw32
-               ;;
-       mingw32ce)
-               basic_machine=arm-unknown
-               os=-mingw32ce
-               ;;
-       miniframe)
-               basic_machine=m68000-convergent
-               ;;
-       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-       mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-               ;;
-       monitor)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       morphos)
-               basic_machine=powerpc-unknown
-               os=-morphos
-               ;;
-       msdos)
-               basic_machine=i386-pc
-               os=-msdos
-               ;;
-       ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-               ;;
-       mvs)
-               basic_machine=i370-ibm
-               os=-mvs
-               ;;
-       ncr3000)
-               basic_machine=i486-ncr
-               os=-sysv4
-               ;;
-       netbsd386)
-               basic_machine=i386-unknown
-               os=-netbsd
-               ;;
-       netwinder)
-               basic_machine=armv4l-rebel
-               os=-linux
-               ;;
-       news | news700 | news800 | news900)
-               basic_machine=m68k-sony
-               os=-newsos
-               ;;
-       news1000)
-               basic_machine=m68030-sony
-               os=-newsos
-               ;;
-       news-3600 | risc-news)
-               basic_machine=mips-sony
-               os=-newsos
-               ;;
-       necv70)
-               basic_machine=v70-nec
-               os=-sysv
-               ;;
-       next | m*-next )
-               basic_machine=m68k-next
-               case $os in
-                   -nextstep* )
-                       ;;
-                   -ns2*)
-                     os=-nextstep2
-                       ;;
-                   *)
-                     os=-nextstep3
-                       ;;
-               esac
-               ;;
-       nh3000)
-               basic_machine=m68k-harris
-               os=-cxux
-               ;;
-       nh[45]000)
-               basic_machine=m88k-harris
-               os=-cxux
-               ;;
-       nindy960)
-               basic_machine=i960-intel
-               os=-nindy
-               ;;
-       mon960)
-               basic_machine=i960-intel
-               os=-mon960
-               ;;
-       nonstopux)
-               basic_machine=mips-compaq
-               os=-nonstopux
-               ;;
-       np1)
-               basic_machine=np1-gould
-               ;;
-       nsr-tandem)
-               basic_machine=nsr-tandem
-               ;;
-       op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
-               os=-proelf
-               ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
-       os400)
-               basic_machine=powerpc-ibm
-               os=-os400
-               ;;
-       OSE68000 | ose68000)
-               basic_machine=m68000-ericsson
-               os=-ose
-               ;;
-       os68k)
-               basic_machine=m68k-none
-               os=-os68k
-               ;;
-       pa-hitachi)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       paragon)
-               basic_machine=i860-intel
-               os=-osf
-               ;;
-       parisc)
-               basic_machine=hppa-unknown
-               os=-linux
-               ;;
-       parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       pbd)
-               basic_machine=sparc-tti
-               ;;
-       pbb)
-               basic_machine=m68k-tti
-               ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
-               ;;
-       pc98)
-               basic_machine=i386-pc
-               ;;
-       pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
-               ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
-               ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
-               ;;
-       pentium4)
-               basic_machine=i786-pc
-               ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pn)
-               basic_machine=pn-gould
-               ;;
-       power)  basic_machine=power-ibm
-               ;;
-       ppc)    basic_machine=powerpc-unknown
-               ;;
-       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
-               basic_machine=powerpcle-unknown
-               ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64)  basic_machine=powerpc64-unknown
-               ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
-               basic_machine=powerpc64le-unknown
-               ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ps2)
-               basic_machine=i386-ibm
-               ;;
-       pw32)
-               basic_machine=i586-unknown
-               os=-pw32
-               ;;
-       rdos)
-               basic_machine=i386-pc
-               os=-rdos
-               ;;
-       rom68k)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       rm[46]00)
-               basic_machine=mips-siemens
-               ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
-               ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
-               ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
-               ;;
-       sa29200)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
-               ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
-               ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=-elf
-               ;;
-       sei)
-               basic_machine=mips-sei
-               os=-seiux
-               ;;
-       sequent)
-               basic_machine=i386-sequent
-               ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
-       sh5el)
-               basic_machine=sh5le-unknown
-               ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
-               basic_machine=sparclite-wrs
-               os=-vxworks
-               ;;
-       sps7)
-               basic_machine=m68k-bull
-               os=-sysv2
-               ;;
-       spur)
-               basic_machine=spur-unknown
-               ;;
-       st2000)
-               basic_machine=m68k-tandem
-               ;;
-       stratus)
-               basic_machine=i860-stratus
-               os=-sysv4
-               ;;
-       sun2)
-               basic_machine=m68000-sun
-               ;;
-       sun2os3)
-               basic_machine=m68000-sun
-               os=-sunos3
-               ;;
-       sun2os4)
-               basic_machine=m68000-sun
-               os=-sunos4
-               ;;
-       sun3os3)
-               basic_machine=m68k-sun
-               os=-sunos3
-               ;;
-       sun3os4)
-               basic_machine=m68k-sun
-               os=-sunos4
-               ;;
-       sun4os3)
-               basic_machine=sparc-sun
-               os=-sunos3
-               ;;
-       sun4os4)
-               basic_machine=sparc-sun
-               os=-sunos4
-               ;;
-       sun4sol2)
-               basic_machine=sparc-sun
-               os=-solaris2
-               ;;
-       sun3 | sun3-*)
-               basic_machine=m68k-sun
-               ;;
-       sun4)
-               basic_machine=sparc-sun
-               ;;
-       sun386 | sun386i | roadrunner)
-               basic_machine=i386-sun
-               ;;
-       sv1)
-               basic_machine=sv1-cray
-               os=-unicos
-               ;;
-       symmetry)
-               basic_machine=i386-sequent
-               os=-dynix
-               ;;
-       t3e)
-               basic_machine=alphaev5-cray
-               os=-unicos
-               ;;
-       t90)
-               basic_machine=t90-cray
-               os=-unicos
-               ;;
-       tic54x | c54x*)
-               basic_machine=tic54x-unknown
-               os=-coff
-               ;;
-       tic55x | c55x*)
-               basic_machine=tic55x-unknown
-               os=-coff
-               ;;
-       tic6x | c6x*)
-               basic_machine=tic6x-unknown
-               os=-coff
-               ;;
-       tile*)
-               basic_machine=tile-unknown
-               os=-linux-gnu
-               ;;
-       tx39)
-               basic_machine=mipstx39-unknown
-               ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
-               ;;
-       toad1)
-               basic_machine=pdp10-xkl
-               os=-tops20
-               ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
-               ;;
-       tpf)
-               basic_machine=s390x-ibm
-               os=-tpf
-               ;;
-       udi29k)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       ultra3)
-               basic_machine=a29k-nyu
-               os=-sym1
-               ;;
-       v810 | necv810)
-               basic_machine=v810-nec
-               os=-none
-               ;;
-       vaxv)
-               basic_machine=vax-dec
-               os=-sysv
-               ;;
-       vms)
-               basic_machine=vax-dec
-               os=-vms
-               ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
-       vxworks960)
-               basic_machine=i960-wrs
-               os=-vxworks
-               ;;
-       vxworks68)
-               basic_machine=m68k-wrs
-               os=-vxworks
-               ;;
-       vxworks29k)
-               basic_machine=a29k-wrs
-               os=-vxworks
-               ;;
-       w65*)
-               basic_machine=w65-wdc
-               os=-none
-               ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=-proelf
-               ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
-               ;;
-       ymp)
-               basic_machine=ymp-cray
-               os=-unicos
-               ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       none)
-               basic_machine=none-none
-               os=-none
-               ;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-       w89k)
-               basic_machine=hppa1.1-winbond
-               ;;
-       op50n)
-               basic_machine=hppa1.1-oki
-               ;;
-       op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
-       rs6000)
-               basic_machine=rs6000-ibm
-               ;;
-       vax)
-               basic_machine=vax-dec
-               ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
-       pdp11)
-               basic_machine=pdp11-dec
-               ;;
-       we32k)
-               basic_machine=we32k-att
-               ;;
-       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
-               basic_machine=sh-unknown
-               ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
-       cydra)
-               basic_machine=cydra-cydrome
-               ;;
-       orion)
-               basic_machine=orion-highlevel
-               ;;
-       orion105)
-               basic_machine=clipper-highlevel
-               ;;
-       mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
-               ;;
-       pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       *-unknown)
-               # Make sure to match an already-canonicalized machine name.
-               ;;
-       *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
-               ;;
-       *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
-               ;;
-       *)
-               ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
-       # -solaris* is a basic system type, with this one exception.
-       -solaris1 | -solaris1.*)
-               os=`echo $os | sed -e 's|solaris1|sunos4|'`
-               ;;
-       -solaris)
-               os=-solaris2
-               ;;
-       -svr4*)
-               os=-sysv4
-               ;;
-       -unixware*)
-               os=-sysv4.2uw
-               ;;
-       -gnu/linux*)
-               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
-               ;;
-       # First accept the basic system types.
-       # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
-       # -sysv* is not here because it comes later, after sysvr4.
-       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* \
-             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -openbsd* | -solidbsd* \
-             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* \
-             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
-       # Remember, each alternative MUST END IN *, to match a version number.
-               ;;
-       -qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
-                       ;;
-                   *)
-                       os=-nto$os
-                       ;;
-               esac
-               ;;
-       -nto-qnx*)
-               ;;
-       -nto*)
-               os=`echo $os | sed -e 's|nto|nto-qnx|'`
-               ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
-               ;;
-       -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
-               ;;
-       -linux-dietlibc)
-               os=-linux-dietlibc
-               ;;
-       -linux*)
-               os=`echo $os | sed -e 's|linux|linux-gnu|'`
-               ;;
-       -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
-               ;;
-       -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
-               ;;
-       -opened*)
-               os=-openedition
-               ;;
-        -os400*)
-               os=-os400
-               ;;
-       -wince*)
-               os=-wince
-               ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
-       -utek*)
-               os=-bsd
-               ;;
-       -dynix*)
-               os=-bsd
-               ;;
-       -acis*)
-               os=-aos
-               ;;
-       -atheos*)
-               os=-atheos
-               ;;
-       -syllable*)
-               os=-syllable
-               ;;
-       -386bsd)
-               os=-bsd
-               ;;
-       -ctix* | -uts*)
-               os=-sysv
-               ;;
-       -nova*)
-               os=-rtmk-nova
-               ;;
-       -ns2 )
-               os=-nextstep2
-               ;;
-       -nsk*)
-               os=-nsk
-               ;;
-       # Preserve the version number of sinix5.
-       -sinix5.*)
-               os=`echo $os | sed -e 's|sinix|sysv|'`
-               ;;
-       -sinix*)
-               os=-sysv4
-               ;;
-        -tpf*)
-               os=-tpf
-               ;;
-       -triton*)
-               os=-sysv3
-               ;;
-       -oss*)
-               os=-sysv3
-               ;;
-       -svr4)
-               os=-sysv4
-               ;;
-       -svr3)
-               os=-sysv3
-               ;;
-       -sysvr4)
-               os=-sysv4
-               ;;
-       # This must come after -sysvr4.
-       -sysv*)
-               ;;
-       -ose*)
-               os=-ose
-               ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
-       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-               os=-mint
-               ;;
-       -aros*)
-               os=-aros
-               ;;
-       -kaos*)
-               os=-kaos
-               ;;
-       -zvmoe)
-               os=-zvmoe
-               ;;
-       -dicos*)
-               os=-dicos
-               ;;
-       -none)
-               ;;
-       *)
-               # Get rid of the `-' at the beginning of $os.
-               os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system.  Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
-        score-*)
-               os=-elf
-               ;;
-        spu-*)
-               os=-elf
-               ;;
-       *-acorn)
-               os=-riscix1.2
-               ;;
-       arm*-rebel)
-               os=-linux
-               ;;
-       arm*-semi)
-               os=-aout
-               ;;
-        c4x-* | tic4x-*)
-               os=-coff
-               ;;
-       # This must come before the *-dec entry.
-       pdp10-*)
-               os=-tops20
-               ;;
-       pdp11-*)
-               os=-none
-               ;;
-       *-dec | vax-*)
-               os=-ultrix4.2
-               ;;
-       m68*-apollo)
-               os=-domain
-               ;;
-       i386-sun)
-               os=-sunos4.0.2
-               ;;
-       m68000-sun)
-               os=-sunos3
-               # This also exists in the configure program, but was not the
-               # default.
-               # os=-sunos4
-               ;;
-       m68*-cisco)
-               os=-aout
-               ;;
-        mep-*)
-               os=-elf
-               ;;
-       mips*-cisco)
-               os=-elf
-               ;;
-       mips*-*)
-               os=-elf
-               ;;
-       or32-*)
-               os=-coff
-               ;;
-       *-tti)  # must be before sparc entry or we get the wrong os.
-               os=-sysv3
-               ;;
-       sparc-* | *-sun)
-               os=-sunos4.1.1
-               ;;
-       *-be)
-               os=-beos
-               ;;
-       *-haiku)
-               os=-haiku
-               ;;
-       *-ibm)
-               os=-aix
-               ;;
-       *-knuth)
-               os=-mmixware
-               ;;
-       *-wec)
-               os=-proelf
-               ;;
-       *-winbond)
-               os=-proelf
-               ;;
-       *-oki)
-               os=-proelf
-               ;;
-       *-hp)
-               os=-hpux
-               ;;
-       *-hitachi)
-               os=-hiux
-               ;;
-       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-               os=-sysv
-               ;;
-       *-cbm)
-               os=-amigaos
-               ;;
-       *-dg)
-               os=-dgux
-               ;;
-       *-dolphin)
-               os=-sysv3
-               ;;
-       m68k-ccur)
-               os=-rtu
-               ;;
-       m88k-omron*)
-               os=-luna
-               ;;
-       *-next )
-               os=-nextstep
-               ;;
-       *-sequent)
-               os=-ptx
-               ;;
-       *-crds)
-               os=-unos
-               ;;
-       *-ns)
-               os=-genix
-               ;;
-       i370-*)
-               os=-mvs
-               ;;
-       *-next)
-               os=-nextstep3
-               ;;
-       *-gould)
-               os=-sysv
-               ;;
-       *-highlevel)
-               os=-bsd
-               ;;
-       *-encore)
-               os=-bsd
-               ;;
-       *-sgi)
-               os=-irix
-               ;;
-       *-siemens)
-               os=-sysv4
-               ;;
-       *-masscomp)
-               os=-rtu
-               ;;
-       f30[01]-fujitsu | f700-fujitsu)
-               os=-uxpv
-               ;;
-       *-rom68k)
-               os=-coff
-               ;;
-       *-*bug)
-               os=-coff
-               ;;
-       *-apple)
-               os=-macos
-               ;;
-       *-atari*)
-               os=-mint
-               ;;
-       *)
-               os=-none
-               ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
-               case $os in
-                       -riscix*)
-                               vendor=acorn
-                               ;;
-                       -sunos*)
-                               vendor=sun
-                               ;;
-                       -aix*)
-                               vendor=ibm
-                               ;;
-                       -beos*)
-                               vendor=be
-                               ;;
-                       -hpux*)
-                               vendor=hp
-                               ;;
-                       -mpeix*)
-                               vendor=hp
-                               ;;
-                       -hiux*)
-                               vendor=hitachi
-                               ;;
-                       -unos*)
-                               vendor=crds
-                               ;;
-                       -dgux*)
-                               vendor=dg
-                               ;;
-                       -luna*)
-                               vendor=omron
-                               ;;
-                       -genix*)
-                               vendor=ns
-                               ;;
-                       -mvs* | -opened*)
-                               vendor=ibm
-                               ;;
-                       -os400*)
-                               vendor=ibm
-                               ;;
-                       -ptx*)
-                               vendor=sequent
-                               ;;
-                       -tpf*)
-                               vendor=ibm
-                               ;;
-                       -vxsim* | -vxworks* | -windiss*)
-                               vendor=wrs
-                               ;;
-                       -aux*)
-                               vendor=apple
-                               ;;
-                       -hms*)
-                               vendor=hitachi
-                               ;;
-                       -mpw* | -macos*)
-                               vendor=apple
-                               ;;
-                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-                               vendor=atari
-                               ;;
-                       -vos*)
-                               vendor=stratus
-                               ;;
-               esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
-               ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/support/fixscript.in b/support/fixscript.in
deleted file mode 100644 (file)
index edd52fe..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#! @_PATH_SH@
-
-##  $Id: fixscript.in 2805 1999-11-27 07:23:49Z rra $
-##
-##  Fix interpretor paths and INN variable load paths.
-##
-##  Scripts shipped with INN always have the invocation path for the
-##  interpretor on the first line and the command to load INN variable
-##  settings into the script on the second line.  For example, for a Bourne
-##  shell script:
-##
-##      #!/bin/sh
-##      . /var/news/lib/innshellvars
-##
-##  This script takes as input such a script and outputs the same script
-##  with the first two lines replaced to have the correct path to the
-##  interpretor and to the INN variable library, as determined by configure.
-##
-##  If the script is invoked with the -i flag, only fix the interpretor
-##  path and don't modify the second line of the file to include the
-##  appropriate innshellvars.
-
-SED='@_PATH_SED@'
-
-PERLPATH='@_PATH_PERL@'
-SHPATH='@_PATH_SH@'
-LIBDIR='@LIBDIR@'
-
-options=true
-addlib=true
-while $options ; do
-    case X"$1" in
-    X-i) addlib=false  ;;
-    *)   options=false ;;
-    esac
-    $options && shift
-done
-
-input="$1"
-if [ -z "$input" ] ; then
-    echo "No input file specified" >&2
-    exit 1
-fi
-
-output="$2"
-if [ -z "$output" ] ; then
-    output=`echo "$input" | sed 's/\.in$//'`
-fi
-if [ x"$input" = x"$output" ] ; then
-    echo "No output file specified and input file doesn't end in .in" >&2
-    exit 1
-fi
-
-interpretor=`head -1 "$input"`
-case "$interpretor" in
-*/sh|*SH*)
-    path="$SHPATH"
-    lib=". $LIBDIR/innshellvars"
-    ;;
-*/perl*|*PERL*)
-    path=`echo "$interpretor" | sed 's%^#! *[^ ][^ ]*%'"$PERLPATH%"`
-    lib="require '$LIBDIR/innshellvars.pl';"
-    ;;
-*)
-    echo "Unknown interpretor $interpretor" >&2
-    exit 1
-    ;;
-esac
-
-echo "#! $path"          >  "$output"
-if $addlib ; then
-    echo "$lib"          >> "$output"
-    "$SED" 1,2d "$input" >> "$output"
-else
-    "$SED" 1d "$input"   >> "$output"
-fi
-chmod 755 "$output"
diff --git a/support/indent b/support/indent
deleted file mode 100755 (executable)
index 6b9213e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#! /bin/sh
-
-##  $Id: indent 5165 2002-03-02 01:43:53Z rra $
-##
-##  Run indent on source files with INN options.
-##
-##  This is a simple wrapper around GNU indent to call it with all of the
-##  options suitable for INN's coding style and typedefs.  These options
-##  are also documented in HACKING.  Assumes indent is on the user's path.
-##
-##  The order of options matches the order in which they're described in
-##  the GNU indent info manual.  In order, each line sets options for:
-##  blank lines, comments, statements, declarations, indentation, breaking
-##  long lines, and typedefs used by INN.
-##
-##  Note that the resulting output should not be used without manual review,
-##  nor should this script be run automatically.  indent still has a few
-##  bugs, tends to mangle case statements written compactly, and varies from
-##  the prevailing INN style in a few ways that can't be changed.
-
-indent \
-    -bad -bap -nsob \
-    -fca -lc78 -cd32 -cp1 \
-    -br -ce -cdw -cli0 -ss -npcs -cs \
-    -di1 -nbc -psl -brs \
-    -i4 -ci4 -lp -ts8 -nut -ip5 -lps \
-    -l78 -bbo -hnl \
-    -T off_t -T size_t -T uint32_t -T time_t -T FILE \
-    $*
diff --git a/support/install-sh b/support/install-sh
deleted file mode 100755 (executable)
index 7931d0d..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.  It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-# Modified for INN by adding the -B option to request saving of the original
-# file (if install is overwriting an existing file).  -B takes an argument,
-# the suffix to use.  INN invokes this script as install-sh -B .OLD.  Also
-# modified to use cp -p instead of just cp to install programs when invoked
-# as install -c.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-backupsuffix=""
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-       -B) backupsuffix="$2"
-           shift
-           shift
-           continue;;
-
-       -c) instcmd="$cpprog -p"
-           shift
-           continue;;
-
-       -d) dir_arg=true
-           shift
-           continue;;
-
-       -m) chmodcmd="$chmodprog $2"
-           shift
-           shift
-           continue;;
-
-       -o) chowncmd="$chownprog $2"
-           shift
-           shift
-           continue;;
-
-       -g) chgrpcmd="$chgrpprog $2"
-           shift
-           shift
-           continue;;
-
-       -s) stripcmd="$stripprog"
-           shift
-           continue;;
-
-       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
-           shift
-           continue;;
-
-       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-           shift
-           continue;;
-
-       *)  if [ x"$src" = x ]
-           then
-               src=$1
-           else
-               # this colon is to work around a 386BSD /bin/sh bug
-               :
-               dst=$1
-           fi
-           shift
-           continue;;
-    esac
-done
-
-if [ x"$src" = x ]
-then
-       echo "install:  no input file specified"
-       exit 1
-else
-       true
-fi
-
-# For Cygwin compatibility.
-if [ -x "$src".exe ]; then
-       src=${src}.exe
-fi
-
-if [ x"$dir_arg" != x ]; then
-       dst=$src
-       src=""
-       
-       if [ -d $dst ]; then
-               instcmd=:
-               chmodcmd=""
-               chowncmd=""
-       else
-               instcmd=mkdir
-       fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-       if [ -f $src -o -d $src ]
-       then
-               true
-       else
-               echo "install:  $src does not exist"
-               exit 1
-       fi
-       
-       if [ x"$dst" = x ]
-       then
-               echo "install:  no destination specified"
-               exit 1
-       else
-               true
-       fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-       if [ -d $dst ]
-       then
-               dst="$dst"/`basename $src`
-       else
-               true
-       fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='   
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
-       pathcomp="${pathcomp}${1}"
-       shift
-
-       if [ ! -d "${pathcomp}" ] ;
-        then
-               $mkdirprog "${pathcomp}"
-       else
-               true
-       fi
-
-       pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
-       $doit $instcmd $dst &&
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
-       if [ x"$transformarg" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               dstfile=`basename $dst $transformbasename | 
-                       sed $transformarg`$transformbasename
-       fi
-
-# don't allow the sed command to completely eliminate the filename
-
-       if [ x"$dstfile" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               true
-       fi
-
-# Make a temp file name in the proper directory.
-
-       dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
-       $doit $instcmd $src $dsttmp &&
-
-       trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.  If $backupsuffix
-# is set, rename the existing file if it exists; otherwise, just
-# remove it.
-
-       if [ x"$backupsuffix" != x ] && [ -f "$dstdir/$dstfile" ]; then
-               $doit $mvcmd $dstdir/$dstfile $dstdir/$dstfile$backupsuffix
-       else
-               $doit $rmcmd -f $dstdir/$dstfile
-       fi &&
-
-       $doit $mvcmd $dsttmp $dstdir/$dstfile 
-
-fi &&
-
-
-exit 0
diff --git a/support/ltmain.sh b/support/ltmain.sh
deleted file mode 100644 (file)
index 9d81a07..0000000
+++ /dev/null
@@ -1,4995 +0,0 @@
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun configure.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file has been modified from the standard libtool version to
-# recognize the additional -O, -G, and -b flags that INN's install program
-# recognizes; apart from that, it's identical to the stock libtool
-# distribution.
-
-# Check that we have a working $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, and then maybe $echo will work.
-  exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit 0
-fi
-
-# The name of this program.
-progname=`$echo "$0" | sed 's%^.*/%%'`
-modename="$progname"
-
-# Constants.
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION=1.4.2
-TIMESTAMP=" (1.922.2.53 2001/09/11 03:18:52)"
-
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-SP2NL='tr \040 \012'
-NL2SP='tr \015\012 \040\040'
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-if test "${LC_ALL+set}" = set; then
-  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
-fi
-if test "${LANG+set}" = set; then
-  save_LANG="$LANG"; LANG=C; export LANG
-fi
-
-# Make sure IFS has a sensible default
-: ${IFS="      "}
-
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-  echo "$modename: not configured to build any kind of library" 1>&2
-  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit 1
-fi
-
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-
-# Parse our command line options once, thoroughly.
-while test $# -gt 0
-do
-  arg="$1"
-  shift
-
-  case $arg in
-  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) optarg= ;;
-  esac
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$prev"; then
-    case $prev in
-    execute_dlfiles)
-      execute_dlfiles="$execute_dlfiles $arg"
-      ;;
-    *)
-      eval "$prev=\$arg"
-      ;;
-    esac
-
-    prev=
-    prevopt=
-    continue
-  fi
-
-  # Have we seen a non-optional argument yet?
-  case $arg in
-  --help)
-    show_help=yes
-    ;;
-
-  --version)
-    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
-    exit 0
-    ;;
-
-  --config)
-    sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
-    exit 0
-    ;;
-
-  --debug)
-    echo "$progname: enabling shell trace mode"
-    set -x
-    ;;
-
-  --dry-run | -n)
-    run=:
-    ;;
-
-  --features)
-    echo "host: $host"
-    if test "$build_libtool_libs" = yes; then
-      echo "enable shared libraries"
-    else
-      echo "disable shared libraries"
-    fi
-    if test "$build_old_libs" = yes; then
-      echo "enable static libraries"
-    else
-      echo "disable static libraries"
-    fi
-    exit 0
-    ;;
-
-  --finish) mode="finish" ;;
-
-  --mode) prevopt="--mode" prev=mode ;;
-  --mode=*) mode="$optarg" ;;
-
-  --quiet | --silent)
-    show=:
-    ;;
-
-  -dlopen)
-    prevopt="-dlopen"
-    prev=execute_dlfiles
-    ;;
-
-  -*)
-    $echo "$modename: unrecognized option \`$arg'" 1>&2
-    $echo "$help" 1>&2
-    exit 1
-    ;;
-
-  *)
-    nonopt="$arg"
-    break
-    ;;
-  esac
-done
-
-if test -n "$prevopt"; then
-  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
-  $echo "$help" 1>&2
-  exit 1
-fi
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-if test -z "$show_help"; then
-
-  # Infer the operation mode.
-  if test -z "$mode"; then
-    case $nonopt in
-    *cc | *++ | gcc* | *-gcc*)
-      mode=link
-      for arg
-      do
-       case $arg in
-       -c)
-          mode=compile
-          break
-          ;;
-       esac
-      done
-      ;;
-    *db | *dbx | *strace | *truss)
-      mode=execute
-      ;;
-    *install*|cp|mv)
-      mode=install
-      ;;
-    *rm)
-      mode=uninstall
-      ;;
-    *)
-      # If we have no mode, but dlfiles were specified, then do execute mode.
-      test -n "$execute_dlfiles" && mode=execute
-
-      # Just use the default operation mode.
-      if test -z "$mode"; then
-       if test -n "$nonopt"; then
-         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
-       else
-         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
-       fi
-      fi
-      ;;
-    esac
-  fi
-
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
-    $echo "$help" 1>&2
-    exit 1
-  fi
-
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$modename --help --mode=$mode' for more information."
-
-  # These modes are in order of execution frequency so that they run quickly.
-  case $mode in
-  # libtool compile mode
-  compile)
-    modename="$modename: compile"
-    # Get the compilation command and the source file.
-    base_compile=
-    prev=
-    lastarg=
-    srcfile="$nonopt"
-    suppress_output=
-
-    user_target=no
-    for arg
-    do
-      case $prev in
-      "") ;;
-      xcompiler)
-       # Aesthetically quote the previous argument.
-       prev=
-       lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-
-       case $arg in
-       # Double-quote args containing other shell metacharacters.
-       # Many Bourne shells cannot handle close brackets correctly
-       # in scan sets, so we specify it separately.
-       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
-         arg="\"$arg\""
-         ;;
-       esac
-
-       # Add the previous argument to base_compile.
-       if test -z "$base_compile"; then
-         base_compile="$lastarg"
-       else
-         base_compile="$base_compile $lastarg"
-       fi
-       continue
-       ;;
-      esac
-
-      # Accept any command-line options.
-      case $arg in
-      -o)
-       if test "$user_target" != "no"; then
-         $echo "$modename: you cannot specify \`-o' more than once" 1>&2
-         exit 1
-       fi
-       user_target=next
-       ;;
-
-      -static)
-       build_old_libs=yes
-       continue
-       ;;
-
-      -prefer-pic)
-       pic_mode=yes
-       continue
-       ;;
-
-      -prefer-non-pic)
-       pic_mode=no
-       continue
-       ;;
-
-      -Xcompiler)
-       prev=xcompiler
-       continue
-       ;;
-
-      -Wc,*)
-       args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
-       lastarg=
-       save_ifs="$IFS"; IFS=','
-       for arg in $args; do
-         IFS="$save_ifs"
-
-         # Double-quote args containing other shell metacharacters.
-         # Many Bourne shells cannot handle close brackets correctly
-         # in scan sets, so we specify it separately.
-         case $arg in
-           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
-           arg="\"$arg\""
-           ;;
-         esac
-         lastarg="$lastarg $arg"
-       done
-       IFS="$save_ifs"
-       lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
-
-       # Add the arguments to base_compile.
-       if test -z "$base_compile"; then
-         base_compile="$lastarg"
-       else
-         base_compile="$base_compile $lastarg"
-       fi
-       continue
-       ;;
-      esac
-
-      case $user_target in
-      next)
-       # The next one is the -o target name
-       user_target=yes
-       continue
-       ;;
-      yes)
-       # We got the output file
-       user_target=set
-       libobj="$arg"
-       continue
-       ;;
-      esac
-
-      # Accept the current argument as the source file.
-      lastarg="$srcfile"
-      srcfile="$arg"
-
-      # Aesthetically quote the previous argument.
-
-      # Backslashify any backslashes, double quotes, and dollar signs.
-      # These are the only characters that are still specially
-      # interpreted inside of double-quoted scrings.
-      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
-
-      # Double-quote args containing other shell metacharacters.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      case $lastarg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-       lastarg="\"$lastarg\""
-       ;;
-      esac
-
-      # Add the previous argument to base_compile.
-      if test -z "$base_compile"; then
-       base_compile="$lastarg"
-      else
-       base_compile="$base_compile $lastarg"
-      fi
-    done
-
-    case $user_target in
-    set)
-      ;;
-    no)
-      # Get the name of the library object.
-      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
-      ;;
-    *)
-      $echo "$modename: you must specify a target with \`-o'" 1>&2
-      exit 1
-      ;;
-    esac
-
-    # Recognize several different file suffixes.
-    # If the user specifies -o file.o, it is replaced with file.lo
-    xform='[cCFSfmso]'
-    case $libobj in
-    *.ada) xform=ada ;;
-    *.adb) xform=adb ;;
-    *.ads) xform=ads ;;
-    *.asm) xform=asm ;;
-    *.c++) xform=c++ ;;
-    *.cc) xform=cc ;;
-    *.cpp) xform=cpp ;;
-    *.cxx) xform=cxx ;;
-    *.f90) xform=f90 ;;
-    *.for) xform=for ;;
-    esac
-
-    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
-
-    case $libobj in
-    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
-    *)
-      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
-      exit 1
-      ;;
-    esac
-
-    if test -z "$base_compile"; then
-      $echo "$modename: you must specify a compilation command" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    # Delete any leftover library objects.
-    if test "$build_old_libs" = yes; then
-      removelist="$obj $libobj"
-    else
-      removelist="$libobj"
-    fi
-
-    $run $rm $removelist
-    trap "$run $rm $removelist; exit 1" 1 2 15
-
-    # On Cygwin there's no "real" PIC flag so we must build both object types
-    case $host_os in
-    cygwin* | mingw* | pw32* | os2*)
-      pic_mode=default
-      ;;
-    esac
-    if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then
-      # non-PIC code in shared libraries is not supported
-      pic_mode=default
-    fi
-
-    # Calculate the filename of the output object if compiler does
-    # not support -o with -c
-    if test "$compiler_c_o" = no; then
-      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
-      lockfile="$output_obj.lock"
-      removelist="$removelist $output_obj $lockfile"
-      trap "$run $rm $removelist; exit 1" 1 2 15
-    else
-      need_locks=no
-      lockfile=
-    fi
-
-    # Lock this critical section if it is needed
-    # We use this script file to make the link, it avoids creating a new file
-    if test "$need_locks" = yes; then
-      until $run ln "$0" "$lockfile" 2>/dev/null; do
-       $show "Waiting for $lockfile to be removed"
-       sleep 2
-      done
-    elif test "$need_locks" = warn; then
-      if test -f "$lockfile"; then
-       echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-       $run $rm $removelist
-       exit 1
-      fi
-      echo $srcfile > "$lockfile"
-    fi
-
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
-    fi
-
-    # Only build a PIC object if we are building libtool libraries.
-    if test "$build_libtool_libs" = yes; then
-      # Without this assignment, base_compile gets emptied.
-      fbsd_hideous_sh_bug=$base_compile
-
-      if test "$pic_mode" != no; then
-       # All platforms use -DPIC, to notify preprocessed assembler code.
-       command="$base_compile $srcfile $pic_flag -DPIC"
-      else
-       # Don't build PIC code
-       command="$base_compile $srcfile"
-      fi
-      if test "$build_old_libs" = yes; then
-       lo_libobj="$libobj"
-       dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
-       if test "X$dir" = "X$libobj"; then
-         dir="$objdir"
-       else
-         dir="$dir/$objdir"
-       fi
-       libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
-
-       if test -d "$dir"; then
-         $show "$rm $libobj"
-         $run $rm $libobj
-       else
-         $show "$mkdir $dir"
-         $run $mkdir $dir
-         status=$?
-         if test $status -ne 0 && test ! -d $dir; then
-           exit $status
-         fi
-       fi
-      fi
-      if test "$compiler_o_lo" = yes; then
-       output_obj="$libobj"
-       command="$command -o $output_obj"
-      elif test "$compiler_c_o" = yes; then
-       output_obj="$obj"
-       command="$command -o $output_obj"
-      fi
-
-      $run $rm "$output_obj"
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-       test -n "$output_obj" && $run $rm $removelist
-       exit 1
-      fi
-
-      if test "$need_locks" = warn &&
-        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
-       echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-       $run $rm $removelist
-       exit 1
-      fi
-
-      # Just move the object if needed, then go on to compile the next one
-      if test x"$output_obj" != x"$libobj"; then
-       $show "$mv $output_obj $libobj"
-       if $run $mv $output_obj $libobj; then :
-       else
-         error=$?
-         $run $rm $removelist
-         exit $error
-       fi
-      fi
-
-      # If we have no pic_flag, then copy the object into place and finish.
-      if (test -z "$pic_flag" || test "$pic_mode" != default) &&
-        test "$build_old_libs" = yes; then
-       # Rename the .lo from within objdir to obj
-       if test -f $obj; then
-         $show $rm $obj
-         $run $rm $obj
-       fi
-
-       $show "$mv $libobj $obj"
-       if $run $mv $libobj $obj; then :
-       else
-         error=$?
-         $run $rm $removelist
-         exit $error
-       fi
-
-       xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
-       if test "X$xdir" = "X$obj"; then
-         xdir="."
-       else
-         xdir="$xdir"
-       fi
-       baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
-       libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
-       # Now arrange that obj and lo_libobj become the same file
-       $show "(cd $xdir && $LN_S $baseobj $libobj)"
-       if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
-         # Unlock the critical section if it was locked
-         if test "$need_locks" != no; then
-           $run $rm "$lockfile"
-         fi
-         exit 0
-       else
-         error=$?
-         $run $rm $removelist
-         exit $error
-       fi
-      fi
-
-      # Allow error messages only from the first compilation.
-      suppress_output=' >/dev/null 2>&1'
-    fi
-
-    # Only build a position-dependent object if we build old libraries.
-    if test "$build_old_libs" = yes; then
-      if test "$pic_mode" != yes; then
-       # Don't build PIC code
-       command="$base_compile $srcfile"
-      else
-       # All platforms use -DPIC, to notify preprocessed assembler code.
-       command="$base_compile $srcfile $pic_flag -DPIC"
-      fi
-      if test "$compiler_c_o" = yes; then
-       command="$command -o $obj"
-       output_obj="$obj"
-      fi
-
-      # Suppress compiler output if we already did a PIC compilation.
-      command="$command$suppress_output"
-      $run $rm "$output_obj"
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-       $run $rm $removelist
-       exit 1
-      fi
-
-      if test "$need_locks" = warn &&
-        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
-       echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-       $run $rm $removelist
-       exit 1
-      fi
-
-      # Just move the object if needed
-      if test x"$output_obj" != x"$obj"; then
-       $show "$mv $output_obj $obj"
-       if $run $mv $output_obj $obj; then :
-       else
-         error=$?
-         $run $rm $removelist
-         exit $error
-       fi
-      fi
-
-      # Create an invalid libtool object if no PIC, so that we do not
-      # accidentally link it into a program.
-      if test "$build_libtool_libs" != yes; then
-       $show "echo timestamp > $libobj"
-       $run eval "echo timestamp > \$libobj" || exit $?
-      else
-       # Move the .lo from within objdir
-       $show "$mv $libobj $lo_libobj"
-       if $run $mv $libobj $lo_libobj; then :
-       else
-         error=$?
-         $run $rm $removelist
-         exit $error
-       fi
-      fi
-    fi
-
-    # Unlock the critical section if it was locked
-    if test "$need_locks" != no; then
-      $run $rm "$lockfile"
-    fi
-
-    exit 0
-    ;;
-
-  # libtool link mode
-  link | relink)
-    modename="$modename: link"
-    case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-      # It is impossible to link a dll without this setting, and
-      # we shouldn't force the makefile maintainer to figure out
-      # which system we are compiling for in order to pass an extra
-      # flag for every libtool invokation.
-      # allow_undefined=no
-
-      # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll which has undefined symbols, in which case not
-      # even a static library is built.  For now, we need to specify
-      # -no-undefined on the libtool link line when we can be certain
-      # that all symbols are satisfied, otherwise we get a static library.
-      allow_undefined=yes
-      ;;
-    *)
-      allow_undefined=yes
-      ;;
-    esac
-    libtool_args="$nonopt"
-    compile_command="$nonopt"
-    finalize_command="$nonopt"
-
-    compile_rpath=
-    finalize_rpath=
-    compile_shlibpath=
-    finalize_shlibpath=
-    convenience=
-    old_convenience=
-    deplibs=
-    old_deplibs=
-    compiler_flags=
-    linker_flags=
-    dllsearchpath=
-    lib_search_path=`pwd`
-
-    avoid_version=no
-    dlfiles=
-    dlprefiles=
-    dlself=no
-    export_dynamic=no
-    export_symbols=
-    export_symbols_regex=
-    generated=
-    libobjs=
-    ltlibs=
-    module=no
-    no_install=no
-    objs=
-    prefer_static_libs=no
-    preload=no
-    prev=
-    prevarg=
-    release=
-    rpath=
-    xrpath=
-    perm_rpath=
-    temp_rpath=
-    thread_safe=no
-    vinfo=
-
-    # We need to know -static, to get the right output filenames.
-    for arg
-    do
-      case $arg in
-      -all-static | -static)
-       if test "X$arg" = "X-all-static"; then
-         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
-           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
-         fi
-         if test -n "$link_static_flag"; then
-           dlopen_self=$dlopen_self_static
-         fi
-       else
-         if test -z "$pic_flag" && test -n "$link_static_flag"; then
-           dlopen_self=$dlopen_self_static
-         fi
-       fi
-       build_libtool_libs=no
-       build_old_libs=yes
-       prefer_static_libs=yes
-       break
-       ;;
-      esac
-    done
-
-    # See if our shared archives depend on static archives.
-    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
-
-    # Go through the arguments, transforming them on the way.
-    while test $# -gt 0; do
-      arg="$1"
-      shift
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-       qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
-       ;;
-      *) qarg=$arg ;;
-      esac
-      libtool_args="$libtool_args $qarg"
-
-      # If the previous option needs an argument, assign it.
-      if test -n "$prev"; then
-       case $prev in
-       output)
-         compile_command="$compile_command @OUTPUT@"
-         finalize_command="$finalize_command @OUTPUT@"
-         ;;
-       esac
-
-       case $prev in
-       dlfiles|dlprefiles)
-         if test "$preload" = no; then
-           # Add the symbol object into the linking commands.
-           compile_command="$compile_command @SYMFILE@"
-           finalize_command="$finalize_command @SYMFILE@"
-           preload=yes
-         fi
-         case $arg in
-         *.la | *.lo) ;;  # We handle these cases below.
-         force)
-           if test "$dlself" = no; then
-             dlself=needless
-             export_dynamic=yes
-           fi
-           prev=
-           continue
-           ;;
-         self)
-           if test "$prev" = dlprefiles; then
-             dlself=yes
-           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
-             dlself=yes
-           else
-             dlself=needless
-             export_dynamic=yes
-           fi
-           prev=
-           continue
-           ;;
-         *)
-           if test "$prev" = dlfiles; then
-             dlfiles="$dlfiles $arg"
-           else
-             dlprefiles="$dlprefiles $arg"
-           fi
-           prev=
-           continue
-           ;;
-         esac
-         ;;
-       expsyms)
-         export_symbols="$arg"
-         if test ! -f "$arg"; then
-           $echo "$modename: symbol file \`$arg' does not exist"
-           exit 1
-         fi
-         prev=
-         continue
-         ;;
-       expsyms_regex)
-         export_symbols_regex="$arg"
-         prev=
-         continue
-         ;;
-       release)
-         release="-$arg"
-         prev=
-         continue
-         ;;
-       rpath | xrpath)
-         # We need an absolute path.
-         case $arg in
-         [\\/]* | [A-Za-z]:[\\/]*) ;;
-         *)
-           $echo "$modename: only absolute run-paths are allowed" 1>&2
-           exit 1
-           ;;
-         esac
-         if test "$prev" = rpath; then
-           case "$rpath " in
-           *" $arg "*) ;;
-           *) rpath="$rpath $arg" ;;
-           esac
-         else
-           case "$xrpath " in
-           *" $arg "*) ;;
-           *) xrpath="$xrpath $arg" ;;
-           esac
-         fi
-         prev=
-         continue
-         ;;
-       xcompiler)
-         compiler_flags="$compiler_flags $qarg"
-         prev=
-         compile_command="$compile_command $qarg"
-         finalize_command="$finalize_command $qarg"
-         continue
-         ;;
-       xlinker)
-         linker_flags="$linker_flags $qarg"
-         compiler_flags="$compiler_flags $wl$qarg"
-         prev=
-         compile_command="$compile_command $wl$qarg"
-         finalize_command="$finalize_command $wl$qarg"
-         continue
-         ;;
-       *)
-         eval "$prev=\"\$arg\""
-         prev=
-         continue
-         ;;
-       esac
-      fi # test -n $prev
-
-      prevarg="$arg"
-
-      case $arg in
-      -all-static)
-       if test -n "$link_static_flag"; then
-         compile_command="$compile_command $link_static_flag"
-         finalize_command="$finalize_command $link_static_flag"
-       fi
-       continue
-       ;;
-
-      -allow-undefined)
-       # FIXME: remove this flag sometime in the future.
-       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
-       continue
-       ;;
-
-      -avoid-version)
-       avoid_version=yes
-       continue
-       ;;
-
-      -dlopen)
-       prev=dlfiles
-       continue
-       ;;
-
-      -dlpreopen)
-       prev=dlprefiles
-       continue
-       ;;
-
-      -export-dynamic)
-       export_dynamic=yes
-       continue
-       ;;
-
-      -export-symbols | -export-symbols-regex)
-       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-         $echo "$modename: more than one -exported-symbols argument is not allowed"
-         exit 1
-       fi
-       if test "X$arg" = "X-export-symbols"; then
-         prev=expsyms
-       else
-         prev=expsyms_regex
-       fi
-       continue
-       ;;
-
-      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
-      # so, if we see these flags be careful not to treat them like -L
-      -L[A-Z][A-Z]*:*)
-       case $with_gcc/$host in
-       no/*-*-irix*)
-         compile_command="$compile_command $arg"
-         finalize_command="$finalize_command $arg"
-         ;;
-       esac
-       continue
-       ;;
-
-      -L*)
-       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
-       # We need an absolute path.
-       case $dir in
-       [\\/]* | [A-Za-z]:[\\/]*) ;;
-       *)
-         absdir=`cd "$dir" && pwd`
-         if test -z "$absdir"; then
-           $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-           exit 1
-         fi
-         dir="$absdir"
-         ;;
-       esac
-       case "$deplibs " in
-       *" -L$dir "*) ;;
-       *)
-         deplibs="$deplibs -L$dir"
-         lib_search_path="$lib_search_path $dir"
-         ;;
-       esac
-       case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-         case :$dllsearchpath: in
-         *":$dir:"*) ;;
-         *) dllsearchpath="$dllsearchpath:$dir";;
-         esac
-         ;;
-       esac
-       continue
-       ;;
-
-      -l*)
-       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
-         case $host in
-         *-*-cygwin* | *-*-pw32* | *-*-beos*)
-           # These systems don't actually have a C or math library (as such)
-           continue
-           ;;
-         *-*-mingw* | *-*-os2*)
-           # These systems don't actually have a C library (as such)
-           test "X$arg" = "X-lc" && continue
-           ;;
-         *-*-openbsd*)
-           # Do not include libc due to us having libc/libc_r.
-           test "X$arg" = "X-lc" && continue
-           ;;
-         esac
-        elif test "X$arg" = "X-lc_r"; then
-         case $host in
-         *-*-openbsd*)
-           # Do not include libc_r directly, use -pthread flag.
-           continue
-           ;;
-         esac
-       fi
-       deplibs="$deplibs $arg"
-       continue
-       ;;
-
-      -module)
-       module=yes
-       continue
-       ;;
-
-      -no-fast-install)
-       fast_install=no
-       continue
-       ;;
-
-      -no-install)
-       case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-         # The PATH hackery in wrapper scripts is required on Windows
-         # in order for the loader to find any dlls it needs.
-         $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
-         $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
-         fast_install=no
-         ;;
-       *) no_install=yes ;;
-       esac
-       continue
-       ;;
-
-      -no-undefined)
-       allow_undefined=no
-       continue
-       ;;
-
-      -o) prev=output ;;
-
-      -release)
-       prev=release
-       continue
-       ;;
-
-      -rpath)
-       prev=rpath
-       continue
-       ;;
-
-      -R)
-       prev=xrpath
-       continue
-       ;;
-
-      -R*)
-       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
-       # We need an absolute path.
-       case $dir in
-       [\\/]* | [A-Za-z]:[\\/]*) ;;
-       *)
-         $echo "$modename: only absolute run-paths are allowed" 1>&2
-         exit 1
-         ;;
-       esac
-       case "$xrpath " in
-       *" $dir "*) ;;
-       *) xrpath="$xrpath $dir" ;;
-       esac
-       continue
-       ;;
-
-      -static)
-       # The effects of -static are defined in a previous loop.
-       # We used to do the same as -all-static on platforms that
-       # didn't have a PIC flag, but the assumption that the effects
-       # would be equivalent was wrong.  It would break on at least
-       # Digital Unix and AIX.
-       continue
-       ;;
-
-      -thread-safe)
-       thread_safe=yes
-       continue
-       ;;
-
-      -version-info)
-       prev=vinfo
-       continue
-       ;;
-
-      -Wc,*)
-       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
-       arg=
-       save_ifs="$IFS"; IFS=','
-       for flag in $args; do
-         IFS="$save_ifs"
-         case $flag in
-           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
-           flag="\"$flag\""
-           ;;
-         esac
-         arg="$arg $wl$flag"
-         compiler_flags="$compiler_flags $flag"
-       done
-       IFS="$save_ifs"
-       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-       ;;
-
-      -Wl,*)
-       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
-       arg=
-       save_ifs="$IFS"; IFS=','
-       for flag in $args; do
-         IFS="$save_ifs"
-         case $flag in
-           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
-           flag="\"$flag\""
-           ;;
-         esac
-         arg="$arg $wl$flag"
-         compiler_flags="$compiler_flags $wl$flag"
-         linker_flags="$linker_flags $flag"
-       done
-       IFS="$save_ifs"
-       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-       ;;
-
-      -Xcompiler)
-       prev=xcompiler
-       continue
-       ;;
-
-      -Xlinker)
-       prev=xlinker
-       continue
-       ;;
-
-      # Some other compiler flag.
-      -* | +*)
-       # Unknown arguments in both finalize_command and compile_command need
-       # to be aesthetically quoted because they are evaled later.
-       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-       case $arg in
-       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
-         arg="\"$arg\""
-         ;;
-       esac
-       ;;
-
-      *.lo | *.$objext)
-       # A library or standard object.
-       if test "$prev" = dlfiles; then
-         # This file was specified with -dlopen.
-         if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-           dlfiles="$dlfiles $arg"
-           prev=
-           continue
-         else
-           # If libtool objects are unsupported, then we need to preload.
-           prev=dlprefiles
-         fi
-       fi
-
-       if test "$prev" = dlprefiles; then
-         # Preload the old-style object.
-         dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
-         prev=
-       else
-         case $arg in
-         *.lo) libobjs="$libobjs $arg" ;;
-         *) objs="$objs $arg" ;;
-         esac
-       fi
-       ;;
-
-      *.$libext)
-       # An archive.
-       deplibs="$deplibs $arg"
-       old_deplibs="$old_deplibs $arg"
-       continue
-       ;;
-
-      *.la)
-       # A libtool-controlled library.
-
-       if test "$prev" = dlfiles; then
-         # This library was specified with -dlopen.
-         dlfiles="$dlfiles $arg"
-         prev=
-       elif test "$prev" = dlprefiles; then
-         # The library was specified with -dlpreopen.
-         dlprefiles="$dlprefiles $arg"
-         prev=
-       else
-         deplibs="$deplibs $arg"
-       fi
-       continue
-       ;;
-
-      # Some other compiler argument.
-      *)
-       # Unknown arguments in both finalize_command and compile_command need
-       # to be aesthetically quoted because they are evaled later.
-       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-       case $arg in
-       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
-         arg="\"$arg\""
-         ;;
-       esac
-       ;;
-      esac # arg
-
-      # Now actually substitute the argument into the commands.
-      if test -n "$arg"; then
-       compile_command="$compile_command $arg"
-       finalize_command="$finalize_command $arg"
-      fi
-    done # argument parsing loop
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
-      eval arg=\"$export_dynamic_flag_spec\"
-      compile_command="$compile_command $arg"
-      finalize_command="$finalize_command $arg"
-    fi
-
-    # calculate the name of the file, without its directory
-    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
-    libobjs_save="$libobjs"
-
-    if test -n "$shlibpath_var"; then
-      # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
-    else
-      shlib_search_path=
-    fi
-    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
-    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
-
-    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$output_objdir" = "X$output"; then
-      output_objdir="$objdir"
-    else
-      output_objdir="$output_objdir/$objdir"
-    fi
-    # Create the object directory.
-    if test ! -d $output_objdir; then
-      $show "$mkdir $output_objdir"
-      $run $mkdir $output_objdir
-      status=$?
-      if test $status -ne 0 && test ! -d $output_objdir; then
-       exit $status
-      fi
-    fi
-
-    # Determine the type of output
-    case $output in
-    "")
-      $echo "$modename: you must specify an output file" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-      ;;
-    *.$libext) linkmode=oldlib ;;
-    *.lo | *.$objext) linkmode=obj ;;
-    *.la) linkmode=lib ;;
-    *) linkmode=prog ;; # Anything else should be a program.
-    esac
-
-    specialdeplibs=
-    libs=
-    # Find all interdependent deplibs by searching for libraries
-    # that are linked more than once (e.g. -la -lb -la)
-    for deplib in $deplibs; do
-      case "$libs " in
-      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-      esac
-      libs="$libs $deplib"
-    done
-    deplibs=
-    newdependency_libs=
-    newlib_search_path=
-    need_relink=no # whether we're linking any uninstalled libtool libraries
-    notinst_deplibs= # not-installed libtool libraries
-    notinst_path= # paths that contain not-installed libtool libraries
-    case $linkmode in
-    lib)
-       passes="conv link"
-       for file in $dlfiles $dlprefiles; do
-         case $file in
-         *.la) ;;
-         *)
-           $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
-           exit 1
-           ;;
-         esac
-       done
-       ;;
-    prog)
-       compile_deplibs=
-       finalize_deplibs=
-       alldeplibs=no
-       newdlfiles=
-       newdlprefiles=
-       passes="conv scan dlopen dlpreopen link"
-       ;;
-    *)  passes="conv"
-       ;;
-    esac
-    for pass in $passes; do
-      if test $linkmode = prog; then
-       # Determine which files to process
-       case $pass in
-       dlopen)
-         libs="$dlfiles"
-         save_deplibs="$deplibs" # Collect dlpreopened libraries
-         deplibs=
-         ;;
-       dlpreopen) libs="$dlprefiles" ;;
-       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
-       esac
-      fi
-      for deplib in $libs; do
-       lib=
-       found=no
-       case $deplib in
-       -l*)
-         if test $linkmode = oldlib && test $linkmode = obj; then
-           $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
-           continue
-         fi
-         if test $pass = conv; then
-           deplibs="$deplib $deplibs"
-           continue
-         fi
-         name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
-         for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
-           # Search the libtool library
-           lib="$searchdir/lib${name}.la"
-           if test -f "$lib"; then
-             found=yes
-             break
-           fi
-         done
-         if test "$found" != yes; then
-           # deplib doesn't seem to be a libtool library
-           if test "$linkmode,$pass" = "prog,link"; then
-             compile_deplibs="$deplib $compile_deplibs"
-             finalize_deplibs="$deplib $finalize_deplibs"
-           else
-             deplibs="$deplib $deplibs"
-             test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs"
-           fi
-           continue
-         fi
-         ;; # -l
-       -L*)
-         case $linkmode in
-         lib)
-           deplibs="$deplib $deplibs"
-           test $pass = conv && continue
-           newdependency_libs="$deplib $newdependency_libs"
-           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-           ;;
-         prog)
-           if test $pass = conv; then
-             deplibs="$deplib $deplibs"
-             continue
-           fi
-           if test $pass = scan; then
-             deplibs="$deplib $deplibs"
-             newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-           else
-             compile_deplibs="$deplib $compile_deplibs"
-             finalize_deplibs="$deplib $finalize_deplibs"
-           fi
-           ;;
-         *)
-           $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2
-           ;;
-         esac # linkmode
-         continue
-         ;; # -L
-       -R*)
-         if test $pass = link; then
-           dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
-           # Make sure the xrpath contains only unique directories.
-           case "$xrpath " in
-           *" $dir "*) ;;
-           *) xrpath="$xrpath $dir" ;;
-           esac
-         fi
-         deplibs="$deplib $deplibs"
-         continue
-         ;;
-       *.la) lib="$deplib" ;;
-       *.$libext)
-         if test $pass = conv; then
-           deplibs="$deplib $deplibs"
-           continue
-         fi
-         case $linkmode in
-         lib)
-           if test "$deplibs_check_method" != pass_all; then
-             echo
-             echo "*** Warning: This library needs some functionality provided by $deplib."
-             echo "*** I have the capability to make that library automatically link in when"
-             echo "*** you link to this library.  But I can only do this if you have a"
-             echo "*** shared version of the library, which you do not appear to have."
-           else
-             echo
-             echo "*** Warning: Linking the shared library $output against the"
-             echo "*** static library $deplib is not portable!"
-             deplibs="$deplib $deplibs"
-           fi
-           continue
-           ;;
-         prog)
-           if test $pass != link; then
-             deplibs="$deplib $deplibs"
-           else
-             compile_deplibs="$deplib $compile_deplibs"
-             finalize_deplibs="$deplib $finalize_deplibs"
-           fi
-           continue
-           ;;
-         esac # linkmode
-         ;; # *.$libext
-       *.lo | *.$objext)
-         if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
-           # If there is no dlopen support or we're linking statically,
-           # we need to preload.
-           newdlprefiles="$newdlprefiles $deplib"
-           compile_deplibs="$deplib $compile_deplibs"
-           finalize_deplibs="$deplib $finalize_deplibs"
-         else
-           newdlfiles="$newdlfiles $deplib"
-         fi
-         continue
-         ;;
-       %DEPLIBS%)
-         alldeplibs=yes
-         continue
-         ;;
-       esac # case $deplib
-       if test $found = yes || test -f "$lib"; then :
-       else
-         $echo "$modename: cannot find the library \`$lib'" 1>&2
-         exit 1
-       fi
-
-       # Check to see that this really is a libtool archive.
-       if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-       else
-         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-         exit 1
-       fi
-
-       ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-       test "X$ladir" = "X$lib" && ladir="."
-
-       dlname=
-       dlopen=
-       dlpreopen=
-       libdir=
-       library_names=
-       old_library=
-       # If the library was installed with an old release of libtool,
-       # it will not redefine variable installed.
-       installed=yes
-
-       # Read the .la file
-       case $lib in
-       */* | *\\*) . $lib ;;
-       *) . ./$lib ;;
-       esac
-
-       if test "$linkmode,$pass" = "lib,link" ||
-          test "$linkmode,$pass" = "prog,scan" ||
-          { test $linkmode = oldlib && test $linkmode = obj; }; then
-          # Add dl[pre]opened files of deplib
-         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
-         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
-       fi
-
-       if test $pass = conv; then
-         # Only check for convenience libraries
-         deplibs="$lib $deplibs"
-         if test -z "$libdir"; then
-           if test -z "$old_library"; then
-             $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-             exit 1
-           fi
-           # It is a libtool convenience library, so add in its objects.
-           convenience="$convenience $ladir/$objdir/$old_library"
-           old_convenience="$old_convenience $ladir/$objdir/$old_library"
-           tmp_libs=
-           for deplib in $dependency_libs; do
-             deplibs="$deplib $deplibs"
-             case "$tmp_libs " in
-             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-             esac
-             tmp_libs="$tmp_libs $deplib"
-           done
-         elif test $linkmode != prog && test $linkmode != lib; then
-           $echo "$modename: \`$lib' is not a convenience library" 1>&2
-           exit 1
-         fi
-         continue
-       fi # $pass = conv
-
-       # Get the name of the library we link against.
-       linklib=
-       for l in $old_library $library_names; do
-         linklib="$l"
-       done
-       if test -z "$linklib"; then
-         $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-         exit 1
-       fi
-
-       # This library was specified with -dlopen.
-       if test $pass = dlopen; then
-         if test -z "$libdir"; then
-           $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
-           exit 1
-         fi
-         if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
-           # If there is no dlname, no dlopen support or we're linking
-           # statically, we need to preload.
-           dlprefiles="$dlprefiles $lib"
-         else
-           newdlfiles="$newdlfiles $lib"
-         fi
-         continue
-       fi # $pass = dlopen
-
-       # We need an absolute path.
-       case $ladir in
-       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
-       *)
-         abs_ladir=`cd "$ladir" && pwd`
-         if test -z "$abs_ladir"; then
-           $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
-           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
-           abs_ladir="$ladir"
-         fi
-         ;;
-       esac
-       laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-
-       # Find the relevant object directory and library name.
-       if test "X$installed" = Xyes; then
-         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-           $echo "$modename: warning: library \`$lib' was moved." 1>&2
-           dir="$ladir"
-           absdir="$abs_ladir"
-           libdir="$abs_ladir"
-         else
-           dir="$libdir"
-           absdir="$libdir"
-         fi
-       else
-         dir="$ladir/$objdir"
-         absdir="$abs_ladir/$objdir"
-         # Remove this search path later
-         notinst_path="$notinst_path $abs_ladir"
-       fi # $installed = yes
-       name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-
-       # This library was specified with -dlpreopen.
-       if test $pass = dlpreopen; then
-         if test -z "$libdir"; then
-           $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
-           exit 1
-         fi
-         # Prefer using a static library (so that no silly _DYNAMIC symbols
-         # are required to link).
-         if test -n "$old_library"; then
-           newdlprefiles="$newdlprefiles $dir/$old_library"
-         # Otherwise, use the dlname, so that lt_dlopen finds it.
-         elif test -n "$dlname"; then
-           newdlprefiles="$newdlprefiles $dir/$dlname"
-         else
-           newdlprefiles="$newdlprefiles $dir/$linklib"
-         fi
-       fi # $pass = dlpreopen
-
-       if test -z "$libdir"; then
-         # Link the convenience library
-         if test $linkmode = lib; then
-           deplibs="$dir/$old_library $deplibs"
-         elif test "$linkmode,$pass" = "prog,link"; then
-           compile_deplibs="$dir/$old_library $compile_deplibs"
-           finalize_deplibs="$dir/$old_library $finalize_deplibs"
-         else
-           deplibs="$lib $deplibs"
-         fi
-         continue
-       fi
-
-       if test $linkmode = prog && test $pass != link; then
-         newlib_search_path="$newlib_search_path $ladir"
-         deplibs="$lib $deplibs"
-
-         linkalldeplibs=no
-         if test "$link_all_deplibs" != no || test -z "$library_names" ||
-            test "$build_libtool_libs" = no; then
-           linkalldeplibs=yes
-         fi
-
-         tmp_libs=
-         for deplib in $dependency_libs; do
-           case $deplib in
-           -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
-           esac
-           # Need to link against all dependency_libs?
-           if test $linkalldeplibs = yes; then
-             deplibs="$deplib $deplibs"
-           else
-             # Need to hardcode shared library paths
-             # or/and link against static libraries
-             newdependency_libs="$deplib $newdependency_libs"
-           fi
-           case "$tmp_libs " in
-           *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-           esac
-           tmp_libs="$tmp_libs $deplib"
-         done # for deplib
-         continue
-       fi # $linkmode = prog...
-
-       link_static=no # Whether the deplib will be linked statically
-       if test -n "$library_names" &&
-          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
-         # Link against this shared library
-
-         if test "$linkmode,$pass" = "prog,link" ||
-          { test $linkmode = lib && test $hardcode_into_libs = yes; }; then
-           # Hardcode the library path.
-           # Skip directories that are in the system default run-time
-           # search path.
-           case " $sys_lib_dlsearch_path " in
-           *" $absdir "*) ;;
-           *)
-             case "$compile_rpath " in
-             *" $absdir "*) ;;
-             *) compile_rpath="$compile_rpath $absdir"
-             esac
-             ;;
-           esac
-           case " $sys_lib_dlsearch_path " in
-           *" $libdir "*) ;;
-           *)
-             case "$finalize_rpath " in
-             *" $libdir "*) ;;
-             *) finalize_rpath="$finalize_rpath $libdir"
-             esac
-             ;;
-           esac
-           if test $linkmode = prog; then
-             # We need to hardcode the library path
-             if test -n "$shlibpath_var"; then
-               # Make sure the rpath contains only unique directories.
-               case "$temp_rpath " in
-               *" $dir "*) ;;
-               *" $absdir "*) ;;
-               *) temp_rpath="$temp_rpath $dir" ;;
-               esac
-             fi
-           fi
-         fi # $linkmode,$pass = prog,link...
-
-         if test "$alldeplibs" = yes &&
-            { test "$deplibs_check_method" = pass_all ||
-              { test "$build_libtool_libs" = yes &&
-                test -n "$library_names"; }; }; then
-           # We only need to search for static libraries
-           continue
-         fi
-
-         if test "$installed" = no; then
-           notinst_deplibs="$notinst_deplibs $lib"
-           need_relink=yes
-         fi
-
-         if test -n "$old_archive_from_expsyms_cmds"; then
-           # figure out the soname
-           set dummy $library_names
-           realname="$2"
-           shift; shift
-           libname=`eval \\$echo \"$libname_spec\"`
-           # use dlname if we got it. it's perfectly good, no?
-           if test -n "$dlname"; then
-             soname="$dlname"
-           elif test -n "$soname_spec"; then
-             # bleh windows
-             case $host in
-             *cygwin*)
-               major=`expr $current - $age`
-               versuffix="-$major"
-               ;;
-             esac
-             eval soname=\"$soname_spec\"
-           else
-             soname="$realname"
-           fi
-
-           # Make a new name for the extract_expsyms_cmds to use
-           soroot="$soname"
-           soname=`echo $soroot | sed -e 's/^.*\///'`
-           newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a"
-
-           # If the library has no export list, then create one now
-           if test -f "$output_objdir/$soname-def"; then :
-           else
-             $show "extracting exported symbol list from \`$soname'"
-             save_ifs="$IFS"; IFS='~'
-             eval cmds=\"$extract_expsyms_cmds\"
-             for cmd in $cmds; do
-               IFS="$save_ifs"
-               $show "$cmd"
-               $run eval "$cmd" || exit $?
-             done
-             IFS="$save_ifs"
-           fi
-
-           # Create $newlib
-           if test -f "$output_objdir/$newlib"; then :; else
-             $show "generating import library for \`$soname'"
-             save_ifs="$IFS"; IFS='~'
-             eval cmds=\"$old_archive_from_expsyms_cmds\"
-             for cmd in $cmds; do
-               IFS="$save_ifs"
-               $show "$cmd"
-               $run eval "$cmd" || exit $?
-             done
-             IFS="$save_ifs"
-           fi
-           # make sure the library variables are pointing to the new library
-           dir=$output_objdir
-           linklib=$newlib
-         fi # test -n $old_archive_from_expsyms_cmds
-
-         if test $linkmode = prog || test "$mode" != relink; then
-           add_shlibpath=
-           add_dir=
-           add=
-           lib_linked=yes
-           case $hardcode_action in
-           immediate | unsupported)
-             if test "$hardcode_direct" = no; then
-               add="$dir/$linklib"
-             elif test "$hardcode_minus_L" = no; then
-               case $host in
-               *-*-sunos*) add_shlibpath="$dir" ;;
-               esac
-               add_dir="-L$dir"
-               add="-l$name"
-             elif test "$hardcode_shlibpath_var" = no; then
-               add_shlibpath="$dir"
-               add="-l$name"
-             else
-               lib_linked=no
-             fi
-             ;;
-           relink)
-             if test "$hardcode_direct" = yes; then
-               add="$dir/$linklib"
-             elif test "$hardcode_minus_L" = yes; then
-               add_dir="-L$dir"
-               add="-l$name"
-             elif test "$hardcode_shlibpath_var" = yes; then
-               add_shlibpath="$dir"
-               add="-l$name"
-             else
-               lib_linked=no
-             fi
-             ;;
-           *) lib_linked=no ;;
-           esac
-
-           if test "$lib_linked" != yes; then
-             $echo "$modename: configuration error: unsupported hardcode properties"
-             exit 1
-           fi
-
-           if test -n "$add_shlibpath"; then
-             case :$compile_shlibpath: in
-             *":$add_shlibpath:"*) ;;
-             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
-             esac
-           fi
-           if test $linkmode = prog; then
-             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
-             test -n "$add" && compile_deplibs="$add $compile_deplibs"
-           else
-             test -n "$add_dir" && deplibs="$add_dir $deplibs"
-             test -n "$add" && deplibs="$add $deplibs"
-             if test "$hardcode_direct" != yes && \
-                test "$hardcode_minus_L" != yes && \
-                test "$hardcode_shlibpath_var" = yes; then
-               case :$finalize_shlibpath: in
-               *":$libdir:"*) ;;
-               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-               esac
-             fi
-           fi
-         fi
-
-         if test $linkmode = prog || test "$mode" = relink; then
-           add_shlibpath=
-           add_dir=
-           add=
-           # Finalize command for both is simple: just hardcode it.
-           if test "$hardcode_direct" = yes; then
-             add="$libdir/$linklib"
-           elif test "$hardcode_minus_L" = yes; then
-             add_dir="-L$libdir"
-             add="-l$name"
-           elif test "$hardcode_shlibpath_var" = yes; then
-             case :$finalize_shlibpath: in
-             *":$libdir:"*) ;;
-             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-             esac
-             add="-l$name"
-           else
-             # We cannot seem to hardcode it, guess we'll fake it.
-             add_dir="-L$libdir"
-             add="-l$name"
-           fi
-
-           if test $linkmode = prog; then
-             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
-             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
-           else
-             test -n "$add_dir" && deplibs="$add_dir $deplibs"
-             test -n "$add" && deplibs="$add $deplibs"
-           fi
-         fi
-       elif test $linkmode = prog; then
-         if test "$alldeplibs" = yes &&
-            { test "$deplibs_check_method" = pass_all ||
-              { test "$build_libtool_libs" = yes &&
-                test -n "$library_names"; }; }; then
-           # We only need to search for static libraries
-           continue
-         fi
-
-         # Try to link the static library
-         # Here we assume that one of hardcode_direct or hardcode_minus_L
-         # is not unsupported.  This is valid on all known static and
-         # shared platforms.
-         if test "$hardcode_direct" != unsupported; then
-           test -n "$old_library" && linklib="$old_library"
-           compile_deplibs="$dir/$linklib $compile_deplibs"
-           finalize_deplibs="$dir/$linklib $finalize_deplibs"
-         else
-           compile_deplibs="-l$name -L$dir $compile_deplibs"
-           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
-         fi
-       elif test "$build_libtool_libs" = yes; then
-         # Not a shared library
-         if test "$deplibs_check_method" != pass_all; then
-           # We're trying link a shared library against a static one
-           # but the system doesn't support it.
-
-           # Just print a warning and add the library to dependency_libs so
-           # that the program can be linked against the static library.
-           echo
-           echo "*** Warning: This library needs some functionality provided by $lib."
-           echo "*** I have the capability to make that library automatically link in when"
-           echo "*** you link to this library.  But I can only do this if you have a"
-           echo "*** shared version of the library, which you do not appear to have."
-           if test "$module" = yes; then
-             echo "*** Therefore, libtool will create a static module, that should work "
-             echo "*** as long as the dlopening application is linked with the -dlopen flag."
-             if test -z "$global_symbol_pipe"; then
-               echo
-               echo "*** However, this would only work if libtool was able to extract symbol"
-               echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-               echo "*** not find such a program.  So, this module is probably useless."
-               echo "*** \`nm' from GNU binutils and a full rebuild may help."
-             fi
-             if test "$build_old_libs" = no; then
-               build_libtool_libs=module
-               build_old_libs=yes
-             else
-               build_libtool_libs=no
-             fi
-           fi
-         else
-           convenience="$convenience $dir/$old_library"
-           old_convenience="$old_convenience $dir/$old_library"
-           deplibs="$dir/$old_library $deplibs"
-           link_static=yes
-         fi
-       fi # link shared/static library?
-
-       if test $linkmode = lib; then
-         if test -n "$dependency_libs" &&
-            { test $hardcode_into_libs != yes || test $build_old_libs = yes ||
-              test $link_static = yes; }; then
-           # Extract -R from dependency_libs
-           temp_deplibs=
-           for libdir in $dependency_libs; do
-             case $libdir in
-             -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
-                  case " $xrpath " in
-                  *" $temp_xrpath "*) ;;
-                  *) xrpath="$xrpath $temp_xrpath";;
-                  esac;;
-             *) temp_deplibs="$temp_deplibs $libdir";;
-             esac
-           done
-           dependency_libs="$temp_deplibs"
-         fi
-
-         newlib_search_path="$newlib_search_path $absdir"
-         # Link against this library
-         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
-         # ... and its dependency_libs
-         tmp_libs=
-         for deplib in $dependency_libs; do
-           newdependency_libs="$deplib $newdependency_libs"
-           case "$tmp_libs " in
-           *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-           esac
-           tmp_libs="$tmp_libs $deplib"
-         done
-
-         if test $link_all_deplibs != no; then
-           # Add the search paths of all dependency libraries
-           for deplib in $dependency_libs; do
-             case $deplib in
-             -L*) path="$deplib" ;;
-             *.la)
-               dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
-               test "X$dir" = "X$deplib" && dir="."
-               # We need an absolute path.
-               case $dir in
-               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
-               *)
-                 absdir=`cd "$dir" && pwd`
-                 if test -z "$absdir"; then
-                   $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
-                   absdir="$dir"
-                 fi
-                 ;;
-               esac
-               if grep "^installed=no" $deplib > /dev/null; then
-                 path="-L$absdir/$objdir"
-               else
-                 eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-                 if test -z "$libdir"; then
-                   $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-                   exit 1
-                 fi
-                 if test "$absdir" != "$libdir"; then
-                   $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
-                 fi
-                 path="-L$absdir"
-               fi
-               ;;
-             *) continue ;;
-             esac
-             case " $deplibs " in
-             *" $path "*) ;;
-             *) deplibs="$deplibs $path" ;;
-             esac
-           done
-         fi # link_all_deplibs != no
-       fi # linkmode = lib
-      done # for deplib in $libs
-      if test $pass = dlpreopen; then
-       # Link the dlpreopened libraries before other libraries
-       for deplib in $save_deplibs; do
-         deplibs="$deplib $deplibs"
-       done
-      fi
-      if test $pass != dlopen; then
-       test $pass != scan && dependency_libs="$newdependency_libs"
-       if test $pass != conv; then
-         # Make sure lib_search_path contains only unique directories.
-         lib_search_path=
-         for dir in $newlib_search_path; do
-           case "$lib_search_path " in
-           *" $dir "*) ;;
-           *) lib_search_path="$lib_search_path $dir" ;;
-           esac
-         done
-         newlib_search_path=
-       fi
-
-       if test "$linkmode,$pass" != "prog,link"; then
-         vars="deplibs"
-       else
-         vars="compile_deplibs finalize_deplibs"
-       fi
-       for var in $vars dependency_libs; do
-         # Add libraries to $var in reverse order
-         eval tmp_libs=\"\$$var\"
-         new_libs=
-         for deplib in $tmp_libs; do
-           case $deplib in
-           -L*) new_libs="$deplib $new_libs" ;;
-           *)
-             case " $specialdeplibs " in
-             *" $deplib "*) new_libs="$deplib $new_libs" ;;
-             *)
-               case " $new_libs " in
-               *" $deplib "*) ;;
-               *) new_libs="$deplib $new_libs" ;;
-               esac
-               ;;
-             esac
-             ;;
-           esac
-         done
-         tmp_libs=
-         for deplib in $new_libs; do
-           case $deplib in
-           -L*)
-             case " $tmp_libs " in
-             *" $deplib "*) ;;
-             *) tmp_libs="$tmp_libs $deplib" ;;
-             esac
-             ;;
-           *) tmp_libs="$tmp_libs $deplib" ;;
-           esac
-         done
-         eval $var=\"$tmp_libs\"
-       done # for var
-      fi
-      if test "$pass" = "conv" &&
-       { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then
-       libs="$deplibs" # reset libs
-       deplibs=
-      fi
-    done # for pass
-    if test $linkmode = prog; then
-      dlfiles="$newdlfiles"
-      dlprefiles="$newdlprefiles"
-    fi
-
-    case $linkmode in
-    oldlib)
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-       $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$release"; then
-       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
-      fi
-
-      # Now set the variables for building old libraries.
-      build_libtool_libs=no
-      oldlibs="$output"
-      objs="$objs$old_deplibs"
-      ;;
-
-    lib)
-      # Make sure we only generate libraries of the form `libNAME.la'.
-      case $outputname in
-      lib*)
-       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-       eval libname=\"$libname_spec\"
-       ;;
-      *)
-       if test "$module" = no; then
-         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-       fi
-       if test "$need_lib_prefix" != no; then
-         # Add the "lib" prefix for modules if required
-         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-         eval libname=\"$libname_spec\"
-       else
-         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-       fi
-       ;;
-      esac
-
-      if test -n "$objs"; then
-       if test "$deplibs_check_method" != pass_all; then
-         $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
-         exit 1
-       else
-         echo
-         echo "*** Warning: Linking the shared library $output against the non-libtool"
-         echo "*** objects $objs is not portable!"
-         libobjs="$libobjs $objs"
-       fi
-      fi
-
-      if test "$dlself" != no; then
-       $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
-      fi
-
-      set dummy $rpath
-      if test $# -gt 2; then
-       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
-      fi
-      install_libdir="$2"
-
-      oldlibs=
-      if test -z "$rpath"; then
-       if test "$build_libtool_libs" = yes; then
-         # Building a libtool convenience library.
-         libext=al
-         oldlibs="$output_objdir/$libname.$libext $oldlibs"
-         build_libtool_libs=convenience
-         build_old_libs=yes
-       fi
-
-       if test -n "$vinfo"; then
-         $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
-       fi
-
-       if test -n "$release"; then
-         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
-       fi
-      else
-
-       # Parse the version information argument.
-       save_ifs="$IFS"; IFS=':'
-       set dummy $vinfo 0 0 0
-       IFS="$save_ifs"
-
-       if test -n "$8"; then
-         $echo "$modename: too many parameters to \`-version-info'" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-       fi
-
-       current="$2"
-       revision="$3"
-       age="$4"
-
-       # Check that each of the things are valid numbers.
-       case $current in
-       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
-       *)
-         $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
-         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-         exit 1
-         ;;
-       esac
-
-       case $revision in
-       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
-       *)
-         $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
-         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-         exit 1
-         ;;
-       esac
-
-       case $age in
-       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
-       *)
-         $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
-         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-         exit 1
-         ;;
-       esac
-
-       if test $age -gt $current; then
-         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
-         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-         exit 1
-       fi
-
-       # Calculate the version variables.
-       major=
-       versuffix=
-       verstring=
-       case $version_type in
-       none) ;;
-
-       darwin)
-         # Like Linux, but with the current version available in
-         # verstring for coding it into the library header
-         major=.`expr $current - $age`
-         versuffix="$major.$age.$revision"
-         # Darwin ld doesn't like 0 for these options...
-         minor_current=`expr $current + 1`
-         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-         ;;
-
-       freebsd-aout)
-         major=".$current"
-         versuffix=".$current.$revision";
-         ;;
-
-       freebsd-elf)
-         major=".$current"
-         versuffix=".$current";
-         ;;
-
-       irix)
-         major=`expr $current - $age + 1`
-         verstring="sgi$major.$revision"
-
-         # Add in all the interfaces that we are compatible with.
-         loop=$revision
-         while test $loop != 0; do
-           iface=`expr $revision - $loop`
-           loop=`expr $loop - 1`
-           verstring="sgi$major.$iface:$verstring"
-         done
-
-         # Before this point, $major must not contain `.'.
-         major=.$major
-         versuffix="$major.$revision"
-         ;;
-
-       linux)
-         major=.`expr $current - $age`
-         versuffix="$major.$age.$revision"
-         ;;
-
-       osf)
-         major=`expr $current - $age`
-         versuffix=".$current.$age.$revision"
-         verstring="$current.$age.$revision"
-
-         # Add in all the interfaces that we are compatible with.
-         loop=$age
-         while test $loop != 0; do
-           iface=`expr $current - $loop`
-           loop=`expr $loop - 1`
-           verstring="$verstring:${iface}.0"
-         done
-
-         # Make executables depend on our current version.
-         verstring="$verstring:${current}.0"
-         ;;
-
-       sunos)
-         major=".$current"
-         versuffix=".$current.$revision"
-         ;;
-
-       windows)
-         # Use '-' rather than '.', since we only want one
-         # extension on DOS 8.3 filesystems.
-         major=`expr $current - $age`
-         versuffix="-$major"
-         ;;
-
-       *)
-         $echo "$modename: unknown library version type \`$version_type'" 1>&2
-         echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-         exit 1
-         ;;
-       esac
-
-       # Clear the version info if we defaulted, and they specified a release.
-       if test -z "$vinfo" && test -n "$release"; then
-         major=
-         verstring="0.0"
-         case $version_type in
-         darwin)
-           # we can't check for "0.0" in archive_cmds due to quoting
-           # problems, so we reset it completely
-           verstring=""
-           ;;
-         *)
-           verstring="0.0"
-           ;;
-         esac
-         if test "$need_version" = no; then
-           versuffix=
-         else
-           versuffix=".0.0"
-         fi
-       fi
-
-       # Remove version info from name if versioning should be avoided
-       if test "$avoid_version" = yes && test "$need_version" = no; then
-         major=
-         versuffix=
-         verstring=""
-       fi
-
-       # Check to see if the archive will have undefined symbols.
-       if test "$allow_undefined" = yes; then
-         if test "$allow_undefined_flag" = unsupported; then
-           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
-           build_libtool_libs=no
-           build_old_libs=yes
-         fi
-       else
-         # Don't allow undefined symbols.
-         allow_undefined_flag="$no_undefined_flag"
-       fi
-      fi
-
-      if test "$mode" != relink; then
-       # Remove our outputs.
-       $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
-       $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
-      fi
-
-      # Now set the variables for building old libraries.
-      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-       oldlibs="$oldlibs $output_objdir/$libname.$libext"
-
-       # Transform .lo files to .o files.
-       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
-      fi
-
-      # Eliminate all temporary directories.
-      for path in $notinst_path; do
-       lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'`
-       deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'`
-       dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'`
-      done
-
-      if test -n "$xrpath"; then
-       # If the user specified any rpath flags, then add them.
-       temp_xrpath=
-       for libdir in $xrpath; do
-         temp_xrpath="$temp_xrpath -R$libdir"
-         case "$finalize_rpath " in
-         *" $libdir "*) ;;
-         *) finalize_rpath="$finalize_rpath $libdir" ;;
-         esac
-       done
-       if test $hardcode_into_libs != yes || test $build_old_libs = yes; then
-         dependency_libs="$temp_xrpath $dependency_libs"
-       fi
-      fi
-
-      # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles="$dlfiles"
-      dlfiles=
-      for lib in $old_dlfiles; do
-       case " $dlprefiles $dlfiles " in
-       *" $lib "*) ;;
-       *) dlfiles="$dlfiles $lib" ;;
-       esac
-      done
-
-      # Make sure dlprefiles contains only unique files
-      old_dlprefiles="$dlprefiles"
-      dlprefiles=
-      for lib in $old_dlprefiles; do
-       case "$dlprefiles " in
-       *" $lib "*) ;;
-       *) dlprefiles="$dlprefiles $lib" ;;
-       esac
-      done
-
-      if test "$build_libtool_libs" = yes; then
-       if test -n "$rpath"; then
-         case $host in
-         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
-           # these systems don't actually have a c library (as such)!
-           ;;
-         *-*-rhapsody* | *-*-darwin1.[012])
-           # Rhapsody C library is in the System framework
-           deplibs="$deplibs -framework System"
-           ;;
-         *-*-netbsd*)
-           # Don't link with libc until the a.out ld.so is fixed.
-           ;;
-         *-*-openbsd*)
-           # Do not include libc due to us having libc/libc_r.
-           ;;
-         *)
-           # Add libc to deplibs on all other systems if necessary.
-           if test $build_libtool_need_lc = "yes"; then
-             deplibs="$deplibs -lc"
-           fi
-           ;;
-         esac
-       fi
-
-       # Transform deplibs into only deplibs that can be linked in shared.
-       name_save=$name
-       libname_save=$libname
-       release_save=$release
-       versuffix_save=$versuffix
-       major_save=$major
-       # I'm not sure if I'm treating the release correctly.  I think
-       # release should show up in the -l (ie -lgmp5) so we don't want to
-       # add it in twice.  Is that correct?
-       release=""
-       versuffix=""
-       major=""
-       newdeplibs=
-       droppeddeps=no
-       case $deplibs_check_method in
-       pass_all)
-         # Don't check for shared/static.  Everything works.
-         # This might be a little naive.  We might want to check
-         # whether the library exists or not.  But this is on
-         # osf3 & osf4 and I'm not really sure... Just
-         # implementing what was already the behaviour.
-         newdeplibs=$deplibs
-         ;;
-       test_compile)
-         # This code stresses the "libraries are programs" paradigm to its
-         # limits. Maybe even breaks it.  We compile a program, linking it
-         # against the deplibs as a proxy for the library.  Then we can check
-         # whether they linked in statically or dynamically with ldd.
-         $rm conftest.c
-         cat > conftest.c <<EOF
-         int main() { return 0; }
-EOF
-         $rm conftest
-         $CC -o conftest conftest.c $deplibs
-         if test $? -eq 0 ; then
-           ldd_output=`ldd conftest`
-           for i in $deplibs; do
-             name="`expr $i : '-l\(.*\)'`"
-             # If $name is empty we are operating on a -L argument.
-             if test -n "$name" && test "$name" != "0"; then
-               libname=`eval \\$echo \"$libname_spec\"`
-               deplib_matches=`eval \\$echo \"$library_names_spec\"`
-               set dummy $deplib_matches
-               deplib_match=$2
-               if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-                 newdeplibs="$newdeplibs $i"
-               else
-                 droppeddeps=yes
-                 echo
-                 echo "*** Warning: This library needs some functionality provided by $i."
-                 echo "*** I have the capability to make that library automatically link in when"
-                 echo "*** you link to this library.  But I can only do this if you have a"
-                 echo "*** shared version of the library, which you do not appear to have."
-               fi
-             else
-               newdeplibs="$newdeplibs $i"
-             fi
-           done
-         else
-           # Error occured in the first compile.  Let's try to salvage the situation:
-           # Compile a seperate program for each library.
-           for i in $deplibs; do
-             name="`expr $i : '-l\(.*\)'`"
-            # If $name is empty we are operating on a -L argument.
-             if test -n "$name" && test "$name" != "0"; then
-               $rm conftest
-               $CC -o conftest conftest.c $i
-               # Did it work?
-               if test $? -eq 0 ; then
-                 ldd_output=`ldd conftest`
-                 libname=`eval \\$echo \"$libname_spec\"`
-                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
-                 set dummy $deplib_matches
-                 deplib_match=$2
-                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-                   newdeplibs="$newdeplibs $i"
-                 else
-                   droppeddeps=yes
-                   echo
-                   echo "*** Warning: This library needs some functionality provided by $i."
-                   echo "*** I have the capability to make that library automatically link in when"
-                   echo "*** you link to this library.  But I can only do this if you have a"
-                   echo "*** shared version of the library, which you do not appear to have."
-                 fi
-               else
-                 droppeddeps=yes
-                 echo
-                 echo "*** Warning!  Library $i is needed by this library but I was not able to"
-                 echo "***  make it link in!  You will probably need to install it or some"
-                 echo "*** library that it depends on before this library will be fully"
-                 echo "*** functional.  Installing it before continuing would be even better."
-               fi
-             else
-               newdeplibs="$newdeplibs $i"
-             fi
-           done
-         fi
-         ;;
-       file_magic*)
-         set dummy $deplibs_check_method
-         file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-         for a_deplib in $deplibs; do
-           name="`expr $a_deplib : '-l\(.*\)'`"
-           # If $name is empty we are operating on a -L argument.
-           if test -n "$name" && test "$name" != "0"; then
-             libname=`eval \\$echo \"$libname_spec\"`
-             for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-                   potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-                   for potent_lib in $potential_libs; do
-                     # Follow soft links.
-                     if ls -lLd "$potent_lib" 2>/dev/null \
-                        | grep " -> " >/dev/null; then
-                       continue
-                     fi
-                     # The statement above tries to avoid entering an
-                     # endless loop below, in case of cyclic links.
-                     # We might still enter an endless loop, since a link
-                     # loop can be closed while we follow links,
-                     # but so what?
-                     potlib="$potent_lib"
-                     while test -h "$potlib" 2>/dev/null; do
-                       potliblink=`ls -ld $potlib | sed 's/.* -> //'`
-                       case $potliblink in
-                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
-                       esac
-                     done
-                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
-                        | sed 10q \
-                        | egrep "$file_magic_regex" > /dev/null; then
-                       newdeplibs="$newdeplibs $a_deplib"
-                       a_deplib=""
-                       break 2
-                     fi
-                   done
-             done
-             if test -n "$a_deplib" ; then
-               droppeddeps=yes
-               echo
-               echo "*** Warning: This library needs some functionality provided by $a_deplib."
-               echo "*** I have the capability to make that library automatically link in when"
-               echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have."
-             fi
-           else
-             # Add a -L argument.
-             newdeplibs="$newdeplibs $a_deplib"
-           fi
-         done # Gone through all deplibs.
-         ;;
-       match_pattern*)
-         set dummy $deplibs_check_method
-         match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-         for a_deplib in $deplibs; do
-           name="`expr $a_deplib : '-l\(.*\)'`"
-           # If $name is empty we are operating on a -L argument.
-           if test -n "$name" && test "$name" != "0"; then
-             libname=`eval \\$echo \"$libname_spec\"`
-             for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-               potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-               for potent_lib in $potential_libs; do
-                 if eval echo \"$potent_lib\" 2>/dev/null \
-                     | sed 10q \
-                     | egrep "$match_pattern_regex" > /dev/null; then
-                   newdeplibs="$newdeplibs $a_deplib"
-                   a_deplib=""
-                   break 2
-                 fi
-               done
-             done
-             if test -n "$a_deplib" ; then
-               droppeddeps=yes
-               echo
-               echo "*** Warning: This library needs some functionality provided by $a_deplib."
-               echo "*** I have the capability to make that library automatically link in when"
-               echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have."
-             fi
-           else
-             # Add a -L argument.
-             newdeplibs="$newdeplibs $a_deplib"
-           fi
-         done # Gone through all deplibs.
-         ;;
-       none | unknown | *)
-         newdeplibs=""
-         if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
-              -e 's/ -[LR][^ ]*//g' -e 's/[    ]//g' |
-            grep . >/dev/null; then
-           echo
-           if test "X$deplibs_check_method" = "Xnone"; then
-             echo "*** Warning: inter-library dependencies are not supported in this platform."
-           else
-             echo "*** Warning: inter-library dependencies are not known to be supported."
-           fi
-           echo "*** All declared inter-library dependencies are being dropped."
-           droppeddeps=yes
-         fi
-         ;;
-       esac
-       versuffix=$versuffix_save
-       major=$major_save
-       release=$release_save
-       libname=$libname_save
-       name=$name_save
-
-       case $host in
-       *-*-rhapsody* | *-*-darwin1.[012])
-         # On Rhapsody replace the C library is the System framework
-         newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
-         ;;
-       esac
-
-       if test "$droppeddeps" = yes; then
-         if test "$module" = yes; then
-           echo
-           echo "*** Warning: libtool could not satisfy all declared inter-library"
-           echo "*** dependencies of module $libname.  Therefore, libtool will create"
-           echo "*** a static module, that should work as long as the dlopening"
-           echo "*** application is linked with the -dlopen flag."
-           if test -z "$global_symbol_pipe"; then
-             echo
-             echo "*** However, this would only work if libtool was able to extract symbol"
-             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-             echo "*** not find such a program.  So, this module is probably useless."
-             echo "*** \`nm' from GNU binutils and a full rebuild may help."
-           fi
-           if test "$build_old_libs" = no; then
-             oldlibs="$output_objdir/$libname.$libext"
-             build_libtool_libs=module
-             build_old_libs=yes
-           else
-             build_libtool_libs=no
-           fi
-         else
-           echo "*** The inter-library dependencies that have been dropped here will be"
-           echo "*** automatically added whenever a program is linked with this library"
-           echo "*** or is declared to -dlopen it."
-
-           if test $allow_undefined = no; then
-             echo
-             echo "*** Since this library must not contain undefined symbols,"
-             echo "*** because either the platform does not support them or"
-             echo "*** it was explicitly requested with -no-undefined,"
-             echo "*** libtool will only create a static version of it."
-             if test "$build_old_libs" = no; then
-               oldlibs="$output_objdir/$libname.$libext"
-               build_libtool_libs=module
-               build_old_libs=yes
-             else
-               build_libtool_libs=no
-             fi
-           fi
-         fi
-       fi
-       # Done checking deplibs!
-       deplibs=$newdeplibs
-      fi
-
-      # All the library-specific variables (install_libdir is set above).
-      library_names=
-      old_library=
-      dlname=
-
-      # Test again, we may have decided not to build it any more
-      if test "$build_libtool_libs" = yes; then
-       if test $hardcode_into_libs = yes; then
-         # Hardcode the library paths
-         hardcode_libdirs=
-         dep_rpath=
-         rpath="$finalize_rpath"
-         test "$mode" != relink && rpath="$compile_rpath$rpath"
-         for libdir in $rpath; do
-           if test -n "$hardcode_libdir_flag_spec"; then
-             if test -n "$hardcode_libdir_separator"; then
-               if test -z "$hardcode_libdirs"; then
-                 hardcode_libdirs="$libdir"
-               else
-                 # Just accumulate the unique libdirs.
-                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-                   ;;
-                 *)
-                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-                   ;;
-                 esac
-               fi
-             else
-               eval flag=\"$hardcode_libdir_flag_spec\"
-               dep_rpath="$dep_rpath $flag"
-             fi
-           elif test -n "$runpath_var"; then
-             case "$perm_rpath " in
-             *" $libdir "*) ;;
-             *) perm_rpath="$perm_rpath $libdir" ;;
-             esac
-           fi
-         done
-         # Substitute the hardcoded libdirs into the rpath.
-         if test -n "$hardcode_libdir_separator" &&
-            test -n "$hardcode_libdirs"; then
-           libdir="$hardcode_libdirs"
-           eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-         fi
-         if test -n "$runpath_var" && test -n "$perm_rpath"; then
-           # We should set the runpath_var.
-           rpath=
-           for dir in $perm_rpath; do
-             rpath="$rpath$dir:"
-           done
-           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
-         fi
-         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
-       fi
-
-       shlibpath="$finalize_shlibpath"
-       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
-       if test -n "$shlibpath"; then
-         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
-       fi
-
-       # Get the real and link names of the library.
-       eval library_names=\"$library_names_spec\"
-       set dummy $library_names
-       realname="$2"
-       shift; shift
-
-       if test -n "$soname_spec"; then
-         eval soname=\"$soname_spec\"
-       else
-         soname="$realname"
-       fi
-       test -z "$dlname" && dlname=$soname
-
-       lib="$output_objdir/$realname"
-       for link
-       do
-         linknames="$linknames $link"
-       done
-
-       # Ensure that we have .o objects for linkers which dislike .lo
-       # (e.g. aix) in case we are running --disable-static
-       for obj in $libobjs; do
-         xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
-         if test "X$xdir" = "X$obj"; then
-           xdir="."
-         else
-           xdir="$xdir"
-         fi
-         baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-         oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
-         if test ! -f $xdir/$oldobj; then
-           $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
-           $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
-         fi
-       done
-
-       # Use standard objects if they are pic
-       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-
-       # Prepare the list of exported symbols
-       if test -z "$export_symbols"; then
-         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
-           $show "generating symbol list for \`$libname.la'"
-           export_symbols="$output_objdir/$libname.exp"
-           $run $rm $export_symbols
-           eval cmds=\"$export_symbols_cmds\"
-           save_ifs="$IFS"; IFS='~'
-           for cmd in $cmds; do
-             IFS="$save_ifs"
-             $show "$cmd"
-             $run eval "$cmd" || exit $?
-           done
-           IFS="$save_ifs"
-           if test -n "$export_symbols_regex"; then
-             $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
-             $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
-             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
-             $run eval '$mv "${export_symbols}T" "$export_symbols"'
-           fi
-         fi
-       fi
-
-       if test -n "$export_symbols" && test -n "$include_expsyms"; then
-         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
-       fi
-
-       if test -n "$convenience"; then
-         if test -n "$whole_archive_flag_spec"; then
-           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-         else
-           gentop="$output_objdir/${outputname}x"
-           $show "${rm}r $gentop"
-           $run ${rm}r "$gentop"
-           $show "mkdir $gentop"
-           $run mkdir "$gentop"
-           status=$?
-           if test $status -ne 0 && test ! -d "$gentop"; then
-             exit $status
-           fi
-           generated="$generated $gentop"
-
-           for xlib in $convenience; do
-             # Extract the objects.
-             case $xlib in
-             [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
-             *) xabs=`pwd`"/$xlib" ;;
-             esac
-             xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
-             xdir="$gentop/$xlib"
-
-             $show "${rm}r $xdir"
-             $run ${rm}r "$xdir"
-             $show "mkdir $xdir"
-             $run mkdir "$xdir"
-             status=$?
-             if test $status -ne 0 && test ! -d "$xdir"; then
-               exit $status
-             fi
-             $show "(cd $xdir && $AR x $xabs)"
-             $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
-
-             libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
-           done
-         fi
-       fi
-
-       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
-         eval flag=\"$thread_safe_flag_spec\"
-         linker_flags="$linker_flags $flag"
-       fi
-
-       # Make a backup of the uninstalled library when relinking
-       if test "$mode" = relink; then
-         $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
-       fi
-
-       # Do each of the archive commands.
-       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-         eval cmds=\"$archive_expsym_cmds\"
-       else
-         eval cmds=\"$archive_cmds\"
-       fi
-       save_ifs="$IFS"; IFS='~'
-       for cmd in $cmds; do
-         IFS="$save_ifs"
-         $show "$cmd"
-         $run eval "$cmd" || exit $?
-       done
-       IFS="$save_ifs"
-
-       # Restore the uninstalled library and exit
-       if test "$mode" = relink; then
-         $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
-         exit 0
-       fi
-
-       # Create links to the real library.
-       for linkname in $linknames; do
-         if test "$realname" != "$linkname"; then
-           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
-           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
-         fi
-       done
-
-       # If -module or -export-dynamic was specified, set the dlname.
-       if test "$module" = yes || test "$export_dynamic" = yes; then
-         # On all known operating systems, these are identical.
-         dlname="$soname"
-       fi
-      fi
-      ;;
-
-    obj)
-      if test -n "$deplibs"; then
-       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$release"; then
-       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
-      fi
-
-      case $output in
-      *.lo)
-       if test -n "$objs$old_deplibs"; then
-         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
-         exit 1
-       fi
-       libobj="$output"
-       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
-       ;;
-      *)
-       libobj=
-       obj="$output"
-       ;;
-      esac
-
-      # Delete the old objects.
-      $run $rm $obj $libobj
-
-      # Objects from convenience libraries.  This assumes
-      # single-version convenience libraries.  Whenever we create
-      # different ones for PIC/non-PIC, this we'll have to duplicate
-      # the extraction.
-      reload_conv_objs=
-      gentop=
-      # reload_cmds runs $LD directly, so let us get rid of
-      # -Wl from whole_archive_flag_spec
-      wl=
-
-      if test -n "$convenience"; then
-       if test -n "$whole_archive_flag_spec"; then
-         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
-       else
-         gentop="$output_objdir/${obj}x"
-         $show "${rm}r $gentop"
-         $run ${rm}r "$gentop"
-         $show "mkdir $gentop"
-         $run mkdir "$gentop"
-         status=$?
-         if test $status -ne 0 && test ! -d "$gentop"; then
-           exit $status
-         fi
-         generated="$generated $gentop"
-
-         for xlib in $convenience; do
-           # Extract the objects.
-           case $xlib in
-           [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
-           *) xabs=`pwd`"/$xlib" ;;
-           esac
-           xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
-           xdir="$gentop/$xlib"
-
-           $show "${rm}r $xdir"
-           $run ${rm}r "$xdir"
-           $show "mkdir $xdir"
-           $run mkdir "$xdir"
-           status=$?
-           if test $status -ne 0 && test ! -d "$xdir"; then
-             exit $status
-           fi
-           $show "(cd $xdir && $AR x $xabs)"
-           $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
-
-           reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
-         done
-       fi
-      fi
-
-      # Create the old-style object.
-      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
-
-      output="$obj"
-      eval cmds=\"$reload_cmds\"
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-       IFS="$save_ifs"
-       $show "$cmd"
-       $run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-
-      # Exit if we aren't doing a library object file.
-      if test -z "$libobj"; then
-       if test -n "$gentop"; then
-         $show "${rm}r $gentop"
-         $run ${rm}r $gentop
-       fi
-
-       exit 0
-      fi
-
-      if test "$build_libtool_libs" != yes; then
-       if test -n "$gentop"; then
-         $show "${rm}r $gentop"
-         $run ${rm}r $gentop
-       fi
-
-       # Create an invalid libtool object if no PIC, so that we don't
-       # accidentally link it into a program.
-       $show "echo timestamp > $libobj"
-       $run eval "echo timestamp > $libobj" || exit $?
-       exit 0
-      fi
-
-      if test -n "$pic_flag" || test "$pic_mode" != default; then
-       # Only do commands if we really have different PIC objects.
-       reload_objs="$libobjs $reload_conv_objs"
-       output="$libobj"
-       eval cmds=\"$reload_cmds\"
-       save_ifs="$IFS"; IFS='~'
-       for cmd in $cmds; do
-         IFS="$save_ifs"
-         $show "$cmd"
-         $run eval "$cmd" || exit $?
-       done
-       IFS="$save_ifs"
-      else
-       # Just create a symlink.
-       $show $rm $libobj
-       $run $rm $libobj
-       xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
-       if test "X$xdir" = "X$libobj"; then
-         xdir="."
-       else
-         xdir="$xdir"
-       fi
-       baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
-       oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
-       $show "(cd $xdir && $LN_S $oldobj $baseobj)"
-       $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
-      fi
-
-      if test -n "$gentop"; then
-       $show "${rm}r $gentop"
-       $run ${rm}r $gentop
-      fi
-
-      exit 0
-      ;;
-
-    prog)
-      case $host in
-       *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;;
-      esac
-      if test -n "$vinfo"; then
-       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
-      fi
-
-      if test -n "$release"; then
-       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
-      fi
-
-      if test "$preload" = yes; then
-       if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
-          test "$dlopen_self_static" = unknown; then
-         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
-       fi
-      fi
-
-      case $host in
-      *-*-rhapsody* | *-*-darwin1.[012])
-       # On Rhapsody replace the C library is the System framework
-       compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-       finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-       ;;
-      esac
-
-      compile_command="$compile_command $compile_deplibs"
-      finalize_command="$finalize_command $finalize_deplibs"
-
-      if test -n "$rpath$xrpath"; then
-       # If the user specified any rpath flags, then add them.
-       for libdir in $rpath $xrpath; do
-         # This is the magic to use -rpath.
-         case "$finalize_rpath " in
-         *" $libdir "*) ;;
-         *) finalize_rpath="$finalize_rpath $libdir" ;;
-         esac
-       done
-      fi
-
-      # Now hardcode the library paths
-      rpath=
-      hardcode_libdirs=
-      for libdir in $compile_rpath $finalize_rpath; do
-       if test -n "$hardcode_libdir_flag_spec"; then
-         if test -n "$hardcode_libdir_separator"; then
-           if test -z "$hardcode_libdirs"; then
-             hardcode_libdirs="$libdir"
-           else
-             # Just accumulate the unique libdirs.
-             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-               ;;
-             *)
-               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-               ;;
-             esac
-           fi
-         else
-           eval flag=\"$hardcode_libdir_flag_spec\"
-           rpath="$rpath $flag"
-         fi
-       elif test -n "$runpath_var"; then
-         case "$perm_rpath " in
-         *" $libdir "*) ;;
-         *) perm_rpath="$perm_rpath $libdir" ;;
-         esac
-       fi
-       case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-         case :$dllsearchpath: in
-         *":$libdir:"*) ;;
-         *) dllsearchpath="$dllsearchpath:$libdir";;
-         esac
-         ;;
-       esac
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-        test -n "$hardcode_libdirs"; then
-       libdir="$hardcode_libdirs"
-       eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      compile_rpath="$rpath"
-
-      rpath=
-      hardcode_libdirs=
-      for libdir in $finalize_rpath; do
-       if test -n "$hardcode_libdir_flag_spec"; then
-         if test -n "$hardcode_libdir_separator"; then
-           if test -z "$hardcode_libdirs"; then
-             hardcode_libdirs="$libdir"
-           else
-             # Just accumulate the unique libdirs.
-             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-               ;;
-             *)
-               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-               ;;
-             esac
-           fi
-         else
-           eval flag=\"$hardcode_libdir_flag_spec\"
-           rpath="$rpath $flag"
-         fi
-       elif test -n "$runpath_var"; then
-         case "$finalize_perm_rpath " in
-         *" $libdir "*) ;;
-         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
-         esac
-       fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-        test -n "$hardcode_libdirs"; then
-       libdir="$hardcode_libdirs"
-       eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      finalize_rpath="$rpath"
-
-      if test -n "$libobjs" && test "$build_old_libs" = yes; then
-       # Transform all the library objects into standard objects.
-       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-      fi
-
-      dlsyms=
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-       if test -n "$NM" && test -n "$global_symbol_pipe"; then
-         dlsyms="${outputname}S.c"
-       else
-         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
-       fi
-      fi
-
-      if test -n "$dlsyms"; then
-       case $dlsyms in
-       "") ;;
-       *.c)
-         # Discover the nlist of each of the dlfiles.
-         nlist="$output_objdir/${outputname}.nm"
-
-         $show "$rm $nlist ${nlist}S ${nlist}T"
-         $run $rm "$nlist" "${nlist}S" "${nlist}T"
-
-         # Parse the name list into a source file.
-         $show "creating $output_objdir/$dlsyms"
-
-         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
-
-/* External symbol declarations for the compiler. */\
-"
-
-         if test "$dlself" = yes; then
-           $show "generating symbol list for \`$output'"
-
-           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
-
-           # Add our own program objects to the symbol list.
-           progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-           for arg in $progfiles; do
-             $show "extracting global C symbols from \`$arg'"
-             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-           done
-
-           if test -n "$exclude_expsyms"; then
-             $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
-             $run eval '$mv "$nlist"T "$nlist"'
-           fi
-
-           if test -n "$export_symbols_regex"; then
-             $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
-             $run eval '$mv "$nlist"T "$nlist"'
-           fi
-
-           # Prepare the list of exported symbols
-           if test -z "$export_symbols"; then
-             export_symbols="$output_objdir/$output.exp"
-             $run $rm $export_symbols
-             $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
-           else
-             $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
-             $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
-             $run eval 'mv "$nlist"T "$nlist"'
-           fi
-         fi
-
-         for arg in $dlprefiles; do
-           $show "extracting global C symbols from \`$arg'"
-           name=`echo "$arg" | sed -e 's%^.*/%%'`
-           $run eval 'echo ": $name " >> "$nlist"'
-           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-         done
-
-         if test -z "$run"; then
-           # Make sure we have at least an empty file.
-           test -f "$nlist" || : > "$nlist"
-
-           if test -n "$exclude_expsyms"; then
-             egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
-             $mv "$nlist"T "$nlist"
-           fi
-
-           # Try sorting and uniquifying the output.
-           if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
-             :
-           else
-             grep -v "^: " < "$nlist" > "$nlist"S
-           fi
-
-           if test -f "$nlist"S; then
-             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
-           else
-             echo '/* NONE */' >> "$output_objdir/$dlsyms"
-           fi
-
-           $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#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[] =
-{\
-"
-
-           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
-
-           $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
-  return lt_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
-         fi
-
-         pic_flag_for_symtable=
-         case $host in
-         # compiling the symbol table file with pic_flag works around
-         # a FreeBSD bug that causes programs to crash when -lm is
-         # linked before any other PIC object.  But we must not use
-         # pic_flag when linking with -static.  The problem exists in
-         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
-           case "$compile_command " in
-           *" -static "*) ;;
-           *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
-           esac;;
-         *-*-hpux*)
-           case "$compile_command " in
-           *" -static "*) ;;
-           *) pic_flag_for_symtable=" $pic_flag -DPIC";;
-           esac
-         esac
-
-         # Now compile the dynamic symbol file.
-         $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-         $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
-
-         # Clean up the generated files.
-         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
-         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
-
-         # Transform the symbol file into the correct name.
-         compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-         finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-         ;;
-       *)
-         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
-         exit 1
-         ;;
-       esac
-      else
-       # We keep going just in case the user didn't refer to
-       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
-       # really was required.
-
-       # Nullify the symbol file.
-       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
-       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
-      fi
-
-      if test $need_relink = no || test "$build_libtool_libs" != yes; then
-       # Replace the output file specification.
-       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-       link_command="$compile_command$compile_rpath"
-
-       # We have no uninstalled library dependencies, so finalize right now.
-       $show "$link_command"
-       $run eval "$link_command"
-       status=$?
-
-       # Delete the generated files.
-       if test -n "$dlsyms"; then
-         $show "$rm $output_objdir/${outputname}S.${objext}"
-         $run $rm "$output_objdir/${outputname}S.${objext}"
-       fi
-
-       exit $status
-      fi
-
-      if test -n "$shlibpath_var"; then
-       # We should set the shlibpath_var
-       rpath=
-       for dir in $temp_rpath; do
-         case $dir in
-         [\\/]* | [A-Za-z]:[\\/]*)
-           # Absolute path.
-           rpath="$rpath$dir:"
-           ;;
-         *)
-           # Relative path: add a thisdir entry.
-           rpath="$rpath\$thisdir/$dir:"
-           ;;
-         esac
-       done
-       temp_rpath="$rpath"
-      fi
-
-      if test -n "$compile_shlibpath$finalize_shlibpath"; then
-       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
-      fi
-      if test -n "$finalize_shlibpath"; then
-       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
-      fi
-
-      compile_var=
-      finalize_var=
-      if test -n "$runpath_var"; then
-       if test -n "$perm_rpath"; then
-         # We should set the runpath_var.
-         rpath=
-         for dir in $perm_rpath; do
-           rpath="$rpath$dir:"
-         done
-         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
-       fi
-       if test -n "$finalize_perm_rpath"; then
-         # We should set the runpath_var.
-         rpath=
-         for dir in $finalize_perm_rpath; do
-           rpath="$rpath$dir:"
-         done
-         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
-       fi
-      fi
-
-      if test "$no_install" = yes; then
-       # We don't need to create a wrapper script.
-       link_command="$compile_var$compile_command$compile_rpath"
-       # Replace the output file specification.
-       link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-       # Delete the old output file.
-       $run $rm $output
-       # Link the executable and exit
-       $show "$link_command"
-       $run eval "$link_command" || exit $?
-       exit 0
-      fi
-
-      if test "$hardcode_action" = relink; then
-       # Fast installation is not supported
-       link_command="$compile_var$compile_command$compile_rpath"
-       relink_command="$finalize_var$finalize_command$finalize_rpath"
-
-       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
-       $echo "$modename: \`$output' will be relinked during installation" 1>&2
-      else
-       if test "$fast_install" != no; then
-         link_command="$finalize_var$compile_command$finalize_rpath"
-         if test "$fast_install" = yes; then
-           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
-         else
-           # fast_install is set to needless
-           relink_command=
-         fi
-       else
-         link_command="$compile_var$compile_command$compile_rpath"
-         relink_command="$finalize_var$finalize_command$finalize_rpath"
-       fi
-      fi
-
-      # Replace the output file specification.
-      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-
-      # Delete the old output files.
-      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
-      $show "$link_command"
-      $run eval "$link_command" || exit $?
-
-      # Now create the wrapper script.
-      $show "creating $output"
-
-      # Quote the relink command for shipping.
-      if test -n "$relink_command"; then
-       # Preserve any variables that may affect compiler behavior
-       for var in $variables_saved_for_relink; do
-         if eval test -z \"\${$var+set}\"; then
-           relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-         elif eval var_value=\$$var; test -z "$var_value"; then
-           relink_command="$var=; export $var; $relink_command"
-         else
-           var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-           relink_command="$var=\"$var_value\"; export $var; $relink_command"
-         fi
-       done
-       relink_command="cd `pwd`; $relink_command"
-       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Quote $echo for shipping.
-      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
-       case $0 in
-       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
-       *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
-       esac
-       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Only actually do things if our run command is non-null.
-      if test -z "$run"; then
-       # win32 will think the script is a binary if it has
-       # a .exe suffix, so we strip it off here.
-       case $output in
-         *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
-       esac
-       # test for cygwin because mv fails w/o .exe extensions
-       case $host in
-         *cygwin*) exeext=.exe ;;
-         *) exeext= ;;
-       esac
-       $rm $output
-       trap "$rm $output; exit 1" 1 2 15
-
-       $echo > $output "\
-#! $SHELL
-
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
-
-relink_command=\"$relink_command\"
-
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
-  # install mode needs the following variable:
-  notinst_deplibs='$notinst_deplibs'
-else
-  # When we are sourced in execute mode, \$file and \$echo are already set.
-  if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    echo=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$echo works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$echo will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
-"
-       $echo >> $output "\
-
-  # Find the directory that this script lives in.
-  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
-  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
-
-  # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
-  while test -n \"\$file\"; do
-    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
-
-    # If there was a directory component, then change thisdir.
-    if test \"x\$destdir\" != \"x\$file\"; then
-      case \"\$destdir\" in
-      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
-      *) thisdir=\"\$thisdir/\$destdir\" ;;
-      esac
-    fi
-
-    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
-  done
-
-  # Try to get the absolute directory name.
-  absdir=\`cd \"\$thisdir\" && pwd\`
-  test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
-
-       if test "$fast_install" = yes; then
-         echo >> $output "\
-  program=lt-'$outputname'$exeext
-  progdir=\"\$thisdir/$objdir\"
-
-  if test ! -f \"\$progdir/\$program\" || \\
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
-       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
-
-    file=\"\$\$-\$program\"
-
-    if test ! -d \"\$progdir\"; then
-      $mkdir \"\$progdir\"
-    else
-      $rm \"\$progdir/\$file\"
-    fi"
-
-         echo >> $output "\
-
-    # relink executable if necessary
-    if test -n \"\$relink_command\"; then
-      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
-      else
-       $echo \"\$relink_command_output\" >&2
-       $rm \"\$progdir/\$file\"
-       exit 1
-      fi
-    fi
-
-    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
-    { $rm \"\$progdir/\$program\";
-      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
-    $rm \"\$progdir/\$file\"
-  fi"
-       else
-         echo >> $output "\
-  program='$outputname'
-  progdir=\"\$thisdir/$objdir\"
-"
-       fi
-
-       echo >> $output "\
-
-  if test -f \"\$progdir/\$program\"; then"
-
-       # Export our shlibpath_var if we have one.
-       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
-         $echo >> $output "\
-    # Add our own library path to $shlibpath_var
-    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
-
-    # Some systems cannot cope with colon-terminated $shlibpath_var
-    # The second colon is a workaround for a bug in BeOS R4 sed
-    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
-
-    export $shlibpath_var
-"
-       fi
-
-       # fixup the dll searchpath if we need to.
-       if test -n "$dllsearchpath"; then
-         $echo >> $output "\
-    # Add the dll search path components to the executable PATH
-    PATH=$dllsearchpath:\$PATH
-"
-       fi
-
-       $echo >> $output "\
-    if test \"\$libtool_execute_magic\" != \"$magic\"; then
-      # Run the actual program with our arguments.
-"
-       case $host in
-       # win32 systems need to use the prog path for dll
-       # lookup to work
-       *-*-cygwin* | *-*-pw32*)
-         $echo >> $output "\
-      exec \$progdir/\$program \${1+\"\$@\"}
-"
-         ;;
-
-       # Backslashes separate directories on plain windows
-       *-*-mingw | *-*-os2*)
-         $echo >> $output "\
-      exec \$progdir\\\\\$program \${1+\"\$@\"}
-"
-         ;;
-
-       *)
-         $echo >> $output "\
-      # Export the path to the program.
-      PATH=\"\$progdir:\$PATH\"
-      export PATH
-
-      exec \$program \${1+\"\$@\"}
-"
-         ;;
-       esac
-       $echo >> $output "\
-      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
-      exit 1
-    fi
-  else
-    # The program doesn't exist.
-    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
-    \$echo \"This script is just a wrapper for \$program.\" 1>&2
-    echo \"See the $PACKAGE documentation for more information.\" 1>&2
-    exit 1
-  fi
-fi\
-"
-       chmod +x $output
-      fi
-      exit 0
-      ;;
-    esac
-
-    # See if we need to build an old-fashioned archive.
-    for oldlib in $oldlibs; do
-
-      if test "$build_libtool_libs" = convenience; then
-       oldobjs="$libobjs_save"
-       addlibs="$convenience"
-       build_libtool_libs=no
-      else
-       if test "$build_libtool_libs" = module; then
-         oldobjs="$libobjs_save"
-         build_libtool_libs=no
-       else
-         oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
-       fi
-       addlibs="$old_convenience"
-      fi
-
-      if test -n "$addlibs"; then
-       gentop="$output_objdir/${outputname}x"
-       $show "${rm}r $gentop"
-       $run ${rm}r "$gentop"
-       $show "mkdir $gentop"
-       $run mkdir "$gentop"
-       status=$?
-       if test $status -ne 0 && test ! -d "$gentop"; then
-         exit $status
-       fi
-       generated="$generated $gentop"
-
-       # Add in members from convenience archives.
-       for xlib in $addlibs; do
-         # Extract the objects.
-         case $xlib in
-         [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
-         *) xabs=`pwd`"/$xlib" ;;
-         esac
-         xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
-         xdir="$gentop/$xlib"
-
-         $show "${rm}r $xdir"
-         $run ${rm}r "$xdir"
-         $show "mkdir $xdir"
-         $run mkdir "$xdir"
-         status=$?
-         if test $status -ne 0 && test ! -d "$xdir"; then
-           exit $status
-         fi
-         $show "(cd $xdir && $AR x $xabs)"
-         $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
-
-         oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
-       done
-      fi
-
-      # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
-       eval cmds=\"$old_archive_from_new_cmds\"
-      else
-       # Ensure that we have .o objects in place in case we decided
-       # not to build a shared library, and have fallen back to building
-       # static libs even though --disable-static was passed!
-       for oldobj in $oldobjs; do
-         if test ! -f $oldobj; then
-           xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
-           if test "X$xdir" = "X$oldobj"; then
-             xdir="."
-           else
-             xdir="$xdir"
-           fi
-           baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
-           obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
-           $show "(cd $xdir && ${LN_S} $obj $baseobj)"
-           $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
-         fi
-       done
-
-       eval cmds=\"$old_archive_cmds\"
-      fi
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-       IFS="$save_ifs"
-       $show "$cmd"
-       $run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$generated"; then
-      $show "${rm}r$generated"
-      $run ${rm}r$generated
-    fi
-
-    # Now create the libtool archive.
-    case $output in
-    *.la)
-      old_library=
-      test "$build_old_libs" = yes && old_library="$libname.$libext"
-      $show "creating $output"
-
-      # Preserve any variables that may affect compiler behavior
-      for var in $variables_saved_for_relink; do
-       if eval test -z \"\${$var+set}\"; then
-         relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-       elif eval var_value=\$$var; test -z "$var_value"; then
-         relink_command="$var=; export $var; $relink_command"
-       else
-         var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-         relink_command="$var=\"$var_value\"; export $var; $relink_command"
-       fi
-      done
-      # Quote the link command for shipping.
-      relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args"
-      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-
-      # Only create the output if not a dry run.
-      if test -z "$run"; then
-       for installed in no yes; do
-         if test "$installed" = yes; then
-           if test -z "$install_libdir"; then
-             break
-           fi
-           output="$output_objdir/$outputname"i
-           # Replace all uninstalled libtool libraries with the installed ones
-           newdependency_libs=
-           for deplib in $dependency_libs; do
-             case $deplib in
-             *.la)
-               name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
-               eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-               if test -z "$libdir"; then
-                 $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-                 exit 1
-               fi
-               newdependency_libs="$newdependency_libs $libdir/$name"
-               ;;
-             *) newdependency_libs="$newdependency_libs $deplib" ;;
-             esac
-           done
-           dependency_libs="$newdependency_libs"
-           newdlfiles=
-           for lib in $dlfiles; do
-             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-             eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-             if test -z "$libdir"; then
-               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-               exit 1
-             fi
-             newdlfiles="$newdlfiles $libdir/$name"
-           done
-           dlfiles="$newdlfiles"
-           newdlprefiles=
-           for lib in $dlprefiles; do
-             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-             eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-             if test -z "$libdir"; then
-               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-               exit 1
-             fi
-             newdlprefiles="$newdlprefiles $libdir/$name"
-           done
-           dlprefiles="$newdlprefiles"
-         fi
-         $rm $output
-         # place dlname in correct position for cygwin
-         tdlname=$dlname
-         case $host,$output,$installed,$module,$dlname in
-           *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
-         esac
-         $echo > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='$tdlname'
-
-# Names of this library.
-library_names='$library_names'
-
-# The name of the static archive.
-old_library='$old_library'
-
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
-
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
-
-# Is this an already installed library?
-installed=$installed
-
-# Files to dlopen/dlpreopen
-dlopen='$dlfiles'
-dlpreopen='$dlprefiles'
-
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'"
-         if test "$installed" = no && test $need_relink = yes; then
-           $echo >> $output "\
-relink_command=\"$relink_command\""
-         fi
-       done
-      fi
-
-      # Do a symbolic link so that the libtool archive can be found in
-      # LD_LIBRARY_PATH before the program is installed.
-      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
-      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
-      ;;
-    esac
-    exit 0
-    ;;
-
-  # libtool install mode
-  install)
-    modename="$modename: install"
-
-    # There may be an optional sh(1) argument at the beginning of
-    # install_prog (especially on Windows NT).
-    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
-       # Allow the use of GNU shtool's install command.
-       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
-      # Aesthetically quote it.
-      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
-       arg="\"$arg\""
-       ;;
-      esac
-      install_prog="$arg "
-      arg="$1"
-      shift
-    else
-      install_prog=
-      arg="$nonopt"
-    fi
-
-    # The real first argument should be the name of the installation program.
-    # Aesthetically quote it.
-    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-    case $arg in
-    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
-      arg="\"$arg\""
-      ;;
-    esac
-    install_prog="$install_prog$arg"
-
-    # We need to accept at least all the BSD install flags.
-    dest=
-    files=
-    opts=
-    prev=
-    install_type=
-    isdir=no
-    stripme=
-    for arg
-    do
-      if test -n "$dest"; then
-       files="$files $dest"
-       dest="$arg"
-       continue
-      fi
-
-      case $arg in
-      -d) isdir=yes ;;
-      -f) prev="-f" ;;
-      -g) prev="-g" ;;
-      -m) prev="-m" ;;
-      -o) prev="-o" ;;
-
-      # Added to support INN's install program.
-      -O) prev="-O" ;;
-      -G) prev="-G" ;;
-      -B) prev="-B" ;;
-
-      -s)
-       stripme=" -s"
-       continue
-       ;;
-      -*) ;;
-
-      *)
-       # If the previous option needed an argument, then skip it.
-       if test -n "$prev"; then
-         prev=
-       else
-         dest="$arg"
-         continue
-       fi
-       ;;
-      esac
-
-      # Aesthetically quote the argument.
-      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
-       arg="\"$arg\""
-       ;;
-      esac
-      install_prog="$install_prog $arg"
-    done
-
-    if test -z "$install_prog"; then
-      $echo "$modename: you must specify an install program" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prev' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test -z "$files"; then
-      if test -z "$dest"; then
-       $echo "$modename: no file or destination specified" 1>&2
-      else
-       $echo "$modename: you must specify a destination" 1>&2
-      fi
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    # Strip any trailing slash from the destination.
-    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
-
-    # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=yes
-    if test "$isdir" = yes; then
-      destdir="$dest"
-      destname=
-    else
-      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
-      test "X$destdir" = "X$dest" && destdir=.
-      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
-
-      # Not a directory, so check to see that there is only one file specified.
-      set dummy $files
-      if test $# -gt 2; then
-       $echo "$modename: \`$dest' is not a directory" 1>&2
-       $echo "$help" 1>&2
-       exit 1
-      fi
-    fi
-    case $destdir in
-    [\\/]* | [A-Za-z]:[\\/]*) ;;
-    *)
-      for file in $files; do
-       case $file in
-       *.lo) ;;
-       *)
-         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-         ;;
-       esac
-      done
-      ;;
-    esac
-
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
-
-    staticlibs=
-    future_libdirs=
-    current_libdirs=
-    for file in $files; do
-
-      # Do each installation.
-      case $file in
-      *.$libext)
-       # Do the static libraries later.
-       staticlibs="$staticlibs $file"
-       ;;
-
-      *.la)
-       # Check to see that this really is a libtool archive.
-       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-       else
-         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-       fi
-
-       library_names=
-       old_library=
-       relink_command=
-       # If there is no directory component, then add one.
-       case $file in
-       */* | *\\*) . $file ;;
-       *) . ./$file ;;
-       esac
-
-       # Add the libdir to current_libdirs if it is the destination.
-       if test "X$destdir" = "X$libdir"; then
-         case "$current_libdirs " in
-         *" $libdir "*) ;;
-         *) current_libdirs="$current_libdirs $libdir" ;;
-         esac
-       else
-         # Note the libdir as a future libdir.
-         case "$future_libdirs " in
-         *" $libdir "*) ;;
-         *) future_libdirs="$future_libdirs $libdir" ;;
-         esac
-       fi
-
-       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
-       test "X$dir" = "X$file/" && dir=
-       dir="$dir$objdir"
-
-       if test -n "$relink_command"; then
-         $echo "$modename: warning: relinking \`$file'" 1>&2
-         $show "$relink_command"
-         if $run eval "$relink_command"; then :
-         else
-           $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-           continue
-         fi
-       fi
-
-       # See the names of the shared library.
-       set dummy $library_names
-       if test -n "$2"; then
-         realname="$2"
-         shift
-         shift
-
-         srcname="$realname"
-         test -n "$relink_command" && srcname="$realname"T
-
-         # Install the shared library and build the symlinks.
-         $show "$install_prog $dir/$srcname $destdir/$realname"
-         $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
-         if test -n "$stripme" && test -n "$striplib"; then
-           $show "$striplib $destdir/$realname"
-           $run eval "$striplib $destdir/$realname" || exit $?
-         fi
-
-         if test $# -gt 0; then
-           # Delete the old symlinks, and create new ones.
-           for linkname
-           do
-             if test "$linkname" != "$realname"; then
-               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-             fi
-           done
-         fi
-
-         # Do each command in the postinstall commands.
-         lib="$destdir/$realname"
-         eval cmds=\"$postinstall_cmds\"
-         save_ifs="$IFS"; IFS='~'
-         for cmd in $cmds; do
-           IFS="$save_ifs"
-           $show "$cmd"
-           $run eval "$cmd" || exit $?
-         done
-         IFS="$save_ifs"
-       fi
-
-       # Install the pseudo-library for information purposes.
-       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-       instname="$dir/$name"i
-       $show "$install_prog $instname $destdir/$name"
-       $run eval "$install_prog $instname $destdir/$name" || exit $?
-
-       # Maybe install the static library, too.
-       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
-       ;;
-
-      *.lo)
-       # Install (i.e. copy) a libtool object.
-
-       # Figure out destination file name, if it wasn't already specified.
-       if test -n "$destname"; then
-         destfile="$destdir/$destname"
-       else
-         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-         destfile="$destdir/$destfile"
-       fi
-
-       # Deduce the name of the destination old-style object file.
-       case $destfile in
-       *.lo)
-         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
-         ;;
-       *.$objext)
-         staticdest="$destfile"
-         destfile=
-         ;;
-       *)
-         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-         ;;
-       esac
-
-       # Install the libtool object if requested.
-       if test -n "$destfile"; then
-         $show "$install_prog $file $destfile"
-         $run eval "$install_prog $file $destfile" || exit $?
-       fi
-
-       # Install the old object if enabled.
-       if test "$build_old_libs" = yes; then
-         # Deduce the name of the old-style object file.
-         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
-
-         $show "$install_prog $staticobj $staticdest"
-         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
-       fi
-       exit 0
-       ;;
-
-      *)
-       # Figure out destination file name, if it wasn't already specified.
-       if test -n "$destname"; then
-         destfile="$destdir/$destname"
-       else
-         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-         destfile="$destdir/$destfile"
-       fi
-
-       # Do a test to see if this is really a libtool program.
-       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-         notinst_deplibs=
-         relink_command=
-
-         # If there is no directory component, then add one.
-         case $file in
-         */* | *\\*) . $file ;;
-         *) . ./$file ;;
-         esac
-
-         # Check the variables that should have been set.
-         if test -z "$notinst_deplibs"; then
-           $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
-           exit 1
-         fi
-
-         finalize=yes
-         for lib in $notinst_deplibs; do
-           # Check to see that each library is installed.
-           libdir=
-           if test -f "$lib"; then
-             # If there is no directory component, then add one.
-             case $lib in
-             */* | *\\*) . $lib ;;
-             *) . ./$lib ;;
-             esac
-           fi
-           libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
-           if test -n "$libdir" && test ! -f "$libfile"; then
-             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
-             finalize=no
-           fi
-         done
-
-         relink_command=
-         # If there is no directory component, then add one.
-         case $file in
-         */* | *\\*) . $file ;;
-         *) . ./$file ;;
-         esac
-
-         outputname=
-         if test "$fast_install" = no && test -n "$relink_command"; then
-           if test "$finalize" = yes && test -z "$run"; then
-             tmpdir="/tmp"
-             test -n "$TMPDIR" && tmpdir="$TMPDIR"
-             tmpdir="$tmpdir/libtool-$$"
-             if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
-             else
-               $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
-               continue
-             fi
-             file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-             outputname="$tmpdir/$file"
-             # Replace the output file specification.
-             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
-
-             $show "$relink_command"
-             if $run eval "$relink_command"; then :
-             else
-               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-               ${rm}r "$tmpdir"
-               continue
-             fi
-             file="$outputname"
-           else
-             $echo "$modename: warning: cannot relink \`$file'" 1>&2
-           fi
-         else
-           # Install the binary that we compiled earlier.
-           file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
-         fi
-       fi
-
-       # remove .exe since cygwin /usr/bin/install will append another
-       # one anyways
-       case $install_prog,$host in
-       /usr/bin/install*,*cygwin*)
-         case $file:$destfile in
-         *.exe:*.exe)
-           # this is ok
-           ;;
-         *.exe:*)
-           destfile=$destfile.exe
-           ;;
-         *:*.exe)
-           destfile=`echo $destfile | sed -e 's,.exe$,,'`
-           ;;
-         esac
-         ;;
-       esac
-       $show "$install_prog$stripme $file $destfile"
-       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
-       test -n "$outputname" && ${rm}r "$tmpdir"
-       ;;
-      esac
-    done
-
-    for file in $staticlibs; do
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-
-      # Set up the ranlib parameters.
-      oldlib="$destdir/$name"
-
-      $show "$install_prog $file $oldlib"
-      $run eval "$install_prog \$file \$oldlib" || exit $?
-
-      if test -n "$stripme" && test -n "$striplib"; then
-       $show "$old_striplib $oldlib"
-       $run eval "$old_striplib $oldlib" || exit $?
-      fi
-
-      # Do each command in the postinstall commands.
-      eval cmds=\"$old_postinstall_cmds\"
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-       IFS="$save_ifs"
-       $show "$cmd"
-       $run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$future_libdirs"; then
-      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
-    fi
-
-    if test -n "$current_libdirs"; then
-      # Maybe just do a dry run.
-      test -n "$run" && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL $0 --finish$current_libdirs'
-    else
-      exit 0
-    fi
-    ;;
-
-  # libtool finish mode
-  finish)
-    modename="$modename: finish"
-    libdirs="$nonopt"
-    admincmds=
-
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
-      for dir
-      do
-       libdirs="$libdirs $dir"
-      done
-
-      for libdir in $libdirs; do
-       if test -n "$finish_cmds"; then
-         # Do each command in the finish commands.
-         eval cmds=\"$finish_cmds\"
-         save_ifs="$IFS"; IFS='~'
-         for cmd in $cmds; do
-           IFS="$save_ifs"
-           $show "$cmd"
-           $run eval "$cmd" || admincmds="$admincmds
-       $cmd"
-         done
-         IFS="$save_ifs"
-       fi
-       if test -n "$finish_eval"; then
-         # Do the single finish_eval.
-         eval cmds=\"$finish_eval\"
-         $run eval "$cmds" || admincmds="$admincmds
-       $cmds"
-       fi
-      done
-    fi
-
-    # Exit here if they wanted silent mode.
-    test "$show" = ":" && exit 0
-
-    echo "----------------------------------------------------------------------"
-    echo "Libraries have been installed in:"
-    for libdir in $libdirs; do
-      echo "   $libdir"
-    done
-    echo
-    echo "If you ever happen to want to link against installed libraries"
-    echo "in a given directory, LIBDIR, you must either use libtool, and"
-    echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
-    echo "flag during linking and do at least one of the following:"
-    if test -n "$shlibpath_var"; then
-      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
-      echo "     during execution"
-    fi
-    if test -n "$runpath_var"; then
-      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
-      echo "     during linking"
-    fi
-    if test -n "$hardcode_libdir_flag_spec"; then
-      libdir=LIBDIR
-      eval flag=\"$hardcode_libdir_flag_spec\"
-
-      echo "   - use the \`$flag' linker flag"
-    fi
-    if test -n "$admincmds"; then
-      echo "   - have your system administrator run these commands:$admincmds"
-    fi
-    if test -f /etc/ld.so.conf; then
-      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
-    fi
-    echo
-    echo "See any operating system documentation about shared libraries for"
-    echo "more information, such as the ld(1) and ld.so(8) manual pages."
-    echo "----------------------------------------------------------------------"
-    exit 0
-    ;;
-
-  # libtool execute mode
-  execute)
-    modename="$modename: execute"
-
-    # The first argument is the command name.
-    cmd="$nonopt"
-    if test -z "$cmd"; then
-      $echo "$modename: you must specify a COMMAND" 1>&2
-      $echo "$help"
-      exit 1
-    fi
-
-    # Handle -dlopen flags immediately.
-    for file in $execute_dlfiles; do
-      if test ! -f "$file"; then
-       $echo "$modename: \`$file' is not a file" 1>&2
-       $echo "$help" 1>&2
-       exit 1
-      fi
-
-      dir=
-      case $file in
-      *.la)
-       # Check to see that this really is a libtool archive.
-       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-       else
-         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-         $echo "$help" 1>&2
-         exit 1
-       fi
-
-       # Read the libtool library.
-       dlname=
-       library_names=
-
-       # If there is no directory component, then add one.
-       case $file in
-       */* | *\\*) . $file ;;
-       *) . ./$file ;;
-       esac
-
-       # Skip this library if it cannot be dlopened.
-       if test -z "$dlname"; then
-         # Warn if it was a shared library.
-         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
-         continue
-       fi
-
-       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-       test "X$dir" = "X$file" && dir=.
-
-       if test -f "$dir/$objdir/$dlname"; then
-         dir="$dir/$objdir"
-       else
-         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
-         exit 1
-       fi
-       ;;
-
-      *.lo)
-       # Just add the directory containing the .lo file.
-       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-       test "X$dir" = "X$file" && dir=.
-       ;;
-
-      *)
-       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
-       continue
-       ;;
-      esac
-
-      # Get the absolute pathname.
-      absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir="$absdir"
-
-      # Now add the directory to shlibpath_var.
-      if eval "test -z \"\$$shlibpath_var\""; then
-       eval "$shlibpath_var=\"\$dir\""
-      else
-       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
-      fi
-    done
-
-    # This variable tells wrapper scripts just to set shlibpath_var
-    # rather than running their programs.
-    libtool_execute_magic="$magic"
-
-    # Check if any of the arguments is a wrapper script.
-    args=
-    for file
-    do
-      case $file in
-      -*) ;;
-      *)
-       # Do a test to see if this is really a libtool program.
-       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-         # If there is no directory component, then add one.
-         case $file in
-         */* | *\\*) . $file ;;
-         *) . ./$file ;;
-         esac
-
-         # Transform arg to wrapped name.
-         file="$progdir/$program"
-       fi
-       ;;
-      esac
-      # Quote arguments (to preserve shell metacharacters).
-      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
-      args="$args \"$file\""
-    done
-
-    if test -z "$run"; then
-      if test -n "$shlibpath_var"; then
-       # Export the shlibpath_var.
-       eval "export $shlibpath_var"
-      fi
-
-      # Restore saved enviroment variables
-      if test "${save_LC_ALL+set}" = set; then
-       LC_ALL="$save_LC_ALL"; export LC_ALL
-      fi
-      if test "${save_LANG+set}" = set; then
-       LANG="$save_LANG"; export LANG
-      fi
-
-      # Now prepare to actually exec the command.
-      exec_cmd='"$cmd"$args'
-    else
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-       eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
-       $echo "export $shlibpath_var"
-      fi
-      $echo "$cmd$args"
-      exit 0
-    fi
-    ;;
-
-  # libtool clean and uninstall mode
-  clean | uninstall)
-    modename="$modename: $mode"
-    rm="$nonopt"
-    files=
-    rmforce=
-    exit_status=0
-
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
-
-    for arg
-    do
-      case $arg in
-      -f) rm="$rm $arg"; rmforce=yes ;;
-      -*) rm="$rm $arg" ;;
-      *) files="$files $arg" ;;
-      esac
-    done
-
-    if test -z "$rm"; then
-      $echo "$modename: you must specify an RM program" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    rmdirs=
-
-    for file in $files; do
-      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-      if test "X$dir" = "X$file"; then
-       dir=.
-       objdir="$objdir"
-      else
-       objdir="$dir/$objdir"
-      fi
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-      test $mode = uninstall && objdir="$dir"
-
-      # Remember objdir for removal later, being careful to avoid duplicates
-      if test $mode = clean; then
-       case " $rmdirs " in
-         *" $objdir "*) ;;
-         *) rmdirs="$rmdirs $objdir" ;;
-       esac
-      fi
-
-      # Don't error if the file doesn't exist and rm -f was used.
-      if (test -L "$file") >/dev/null 2>&1 \
-       || (test -h "$file") >/dev/null 2>&1 \
-       || test -f "$file"; then
-       :
-      elif test -d "$file"; then
-       exit_status=1
-       continue
-      elif test "$rmforce" = yes; then
-       continue
-      fi
-
-      rmfiles="$file"
-
-      case $name in
-      *.la)
-       # Possibly a libtool archive, so verify it.
-       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-         . $dir/$name
-
-         # Delete the libtool libraries and symlinks.
-         for n in $library_names; do
-           rmfiles="$rmfiles $objdir/$n"
-         done
-         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
-         test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
-
-         if test $mode = uninstall; then
-           if test -n "$library_names"; then
-             # Do each command in the postuninstall commands.
-             eval cmds=\"$postuninstall_cmds\"
-             save_ifs="$IFS"; IFS='~'
-             for cmd in $cmds; do
-               IFS="$save_ifs"
-               $show "$cmd"
-               $run eval "$cmd"
-               if test $? != 0 && test "$rmforce" != yes; then
-                 exit_status=1
-               fi
-             done
-             IFS="$save_ifs"
-           fi
-
-           if test -n "$old_library"; then
-             # Do each command in the old_postuninstall commands.
-             eval cmds=\"$old_postuninstall_cmds\"
-             save_ifs="$IFS"; IFS='~'
-             for cmd in $cmds; do
-               IFS="$save_ifs"
-               $show "$cmd"
-               $run eval "$cmd"
-               if test $? != 0 && test "$rmforce" != yes; then
-                 exit_status=1
-               fi
-             done
-             IFS="$save_ifs"
-           fi
-           # FIXME: should reinstall the best remaining shared library.
-         fi
-       fi
-       ;;
-
-      *.lo)
-       if test "$build_old_libs" = yes; then
-         oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
-         rmfiles="$rmfiles $dir/$oldobj"
-       fi
-       ;;
-
-      *)
-       # Do a test to see if this is a libtool program.
-       if test $mode = clean &&
-          (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-         relink_command=
-         . $dir/$file
-
-         rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
-         if test "$fast_install" = yes && test -n "$relink_command"; then
-           rmfiles="$rmfiles $objdir/lt-$name"
-         fi
-       fi
-       ;;
-      esac
-      $show "$rm $rmfiles"
-      $run $rm $rmfiles || exit_status=1
-    done
-
-    # Try to remove the ${objdir}s in the directories where we deleted files
-    for dir in $rmdirs; do
-      if test -d "$dir"; then
-       $show "rmdir $dir"
-       $run rmdir $dir >/dev/null 2>&1
-      fi
-    done
-
-    exit $exit_status
-    ;;
-
-  "")
-    $echo "$modename: you must specify a MODE" 1>&2
-    $echo "$generic_help" 1>&2
-    exit 1
-    ;;
-  esac
-
-  if test -z "$exec_cmd"; then
-    $echo "$modename: invalid operation mode \`$mode'" 1>&2
-    $echo "$generic_help" 1>&2
-    exit 1
-  fi
-fi # test -z "$show_help"
-
-if test -n "$exec_cmd"; then
-  eval exec $exec_cmd
-  exit 1
-fi
-
-# We need to display help for each of the modes.
-case $mode in
-"") $echo \
-"Usage: $modename [OPTION]... [MODE-ARG]...
-
-Provide generalized library-building support services.
-
-    --config          show all configuration variables
-    --debug           enable verbose shell tracing
--n, --dry-run         display commands without modifying any files
-    --features        display basic configuration information and exit
-    --finish          same as \`--mode=finish'
-    --help            display this help message and exit
-    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
-    --quiet           same as \`--silent'
-    --silent          don't print informational messages
-    --version         print version information
-
-MODE must be one of the following:
-
-      clean           remove files from the build directory
-      compile         compile a source file into a libtool object
-      execute         automatically set library path, then run a program
-      finish          complete the installation of libtool libraries
-      install         install libraries or executables
-      link            create a library or an executable
-      uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE."
-  exit 0
-  ;;
-
-clean)
-  $echo \
-"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
-
-Remove files from the build directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, object or program, all the files associated
-with it are deleted. Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-compile)
-  $echo \
-"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
-  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
-  -prefer-pic       try to building PIC objects only
-  -prefer-non-pic   try to building non-PIC objects only
-  -static           always build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
-  ;;
-
-execute)
-  $echo \
-"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
-  -dlopen FILE      add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
-  ;;
-
-finish)
-  $echo \
-"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges.  Use
-the \`--dry-run' option if you just want to see what would be executed."
-  ;;
-
-install)
-  $echo \
-"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command.  The first component should be
-either the \`install' or \`cp' program.
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
-  ;;
-
-link)
-  $echo \
-"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
-  -all-static       do not do any dynamic linking at all
-  -avoid-version    do not add a version suffix if possible
-  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
-  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
-  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-  -export-symbols SYMFILE
-                   try to export only the symbols listed in SYMFILE
-  -export-symbols-regex REGEX
-                   try to export only the symbols matching REGEX
-  -LLIBDIR          search LIBDIR for required installed libraries
-  -lNAME            OUTPUT-FILE requires the installed library libNAME
-  -module           build a library that can dlopened
-  -no-fast-install  disable the fast-install mode
-  -no-install       link a not-installable executable
-  -no-undefined     declare that a library does not refer to external symbols
-  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -release RELEASE  specify package release information
-  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
-  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
-  -static           do not do any dynamic linking of libtool libraries
-  -version-info CURRENT[:REVISION[:AGE]]
-                   specify library version info [each variable defaults to 0]
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename.  Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
-  ;;
-
-uninstall)
-  $echo \
-"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
-
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-*)
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$help" 1>&2
-  exit 1
-  ;;
-esac
-
-echo
-$echo "Try \`$modename --help' for more information about other modes."
-
-exit 0
-
-# Local Variables:
-# mode:shell-script
-# sh-indentation:2
-# End:
diff --git a/support/makedepend b/support/makedepend
deleted file mode 100755 (executable)
index 8157885..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#! /bin/sh
-
-##  $Id: makedepend 5787 2002-09-29 23:32:52Z rra $
-##
-##  Generate dependencies for INN makefiles
-##
-##  This shell script automates the process of updating the dependencies in
-##  INN's Makefiles.  It uses gcc -MM to do this, since only the maintainers
-##  should normally have to do this and using a compiler to parse include
-##  directives is more reliable than more ad hoc methods.  It takes compiler
-##  flags as its first argument and then a list of all source files to
-##  process.
-##
-##  The Makefile is updated in place, and everything after "DO NOT DELETE
-##  THIS LINE" is removed and replaced by the dependencies.
-
-flags="$1"
-shift
-sed '1,/DO NOT DELETE THIS LINE/!d' < Makefile > .makefile.tmp
-for source in "$@" ; do
-    case $source in
-    */*)
-        base=`echo "$source" | sed 's/\..*//'`
-        gcc -MM $flags "$source" | sed "s%^[^.: ][^.: ]*%$base%" \
-            >> .makefile.tmp
-        ;;
-    *)
-        gcc -MM $flags "$source" >> .makefile.tmp
-        ;;
-    esac
-    if [ $? != 0 ] ; then
-        rm .makefile.tmp
-        exit
-    fi
-done
-mv -f .makefile.tmp Makefile
diff --git a/support/mkchangelog b/support/mkchangelog
deleted file mode 100755 (executable)
index 7010078..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#! /usr/bin/perl -w
-
-##  $Id: mkchangelog 7473 2005-12-24 21:29:22Z eagle $
-##
-##  Generate a ChangeLog from svn log using svn2cl.
-##
-##  This script prompts the user for a date from which to pull log entries
-##  and the prefix to strip from file names and generates a ChangeLog file
-##  by running svn2cl.
-
-$| = 1;
-
-print "Enter prefix to strip from file names: ";
-my $prefix = <STDIN>;
-chomp $prefix;
-
-print "Enter date to start log at (YYYY-MM-DD): ";
-my $date = <STDIN>;
-chomp $date;
-
-print "\nRunning svn2cl....\n";
-system ("svn2cl --strip-prefix=$prefix --group-by-day -r 'HEAD:{$date}'") == 0
-    or die "svn2cl exited with status " . ($? >> 8) . "\n";
diff --git a/support/mkmanifest b/support/mkmanifest
deleted file mode 100755 (executable)
index 3d87a44..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#! /usr/bin/perl -w
-
-##  $Id: mkmanifest 7307 2005-06-11 08:38:15Z eagle $
-##
-##  Generate a filename-only manifest from an INN tree.
-##
-##  This script generates a filename-only manifest from an INN tree, excluding
-##  certain files according to .cvsignore files and several built-in rules.
-##  It is intended to be used to support make check-manifest from the top
-##  level of the INN tree.
-
-require 5.005;
-
-use strict;
-use vars qw(%CVSIGNORE @FILES @IGNORE);
-
-use File::Find qw(find);
-
-# The following regex patterns match files to be ignored wherever they are
-# in the tree.  This is intended to handle files that CVS ignores by default
-# or files that are present in the tree and in CVS but which are not included
-# in releases.
-@IGNORE = (qr%(\A|/)\.cvsignore\Z%, qr/\.[ao]\Z/, qr%(\A|/)CVS(/|\Z)%,
-           qr%(\A|/)\.?\#%, qr/\.(old|bak|orig|rej)$/, qr%(\A|/)core\Z%,
-           qr/~$/, qr%(\A|/)\.pure%, qr%(\A|/)\.svn(/|\Z)%);
-
-# Build a list of all the files ignored by rules in .cvsignore files.  Meant
-# to be run as the wanted sub of a call to File::Find.  Stuff in .cvsignore
-# that contains wildcards needs to be lifted into the list of @IGNORE regexes.
-sub find_cvsignore {
-    return unless $_ eq '.cvsignore';
-    return unless -f;
-    my $file = $_;
-    $file =~ s%^\./%%;
-    my @ignored;
-    my $dir = $File::Find::dir;
-    $dir =~ s%^\./?%%;
-    if ($dir) {
-        $dir .= '/';
-    }
-    open (CVSIGNORE, $_) or die "Cannot open $File::Find::name: $!\n";
-    @ignored = map { $dir . $_ } map { split (' ', $_) } <CVSIGNORE>;
-    close CVSIGNORE;
-    for (@ignored) {
-        if (/\*/) {
-            my $pattern = $_;
-            $pattern =~ s/\./\\./g;
-            $pattern =~ s/\*/.*/g;
-            push (@IGNORE, qr/\A$pattern\Z/);
-        } else {
-            $CVSIGNORE{$_}++;
-        }
-    }
-}
-
-# Build a list of all files in the tree that aren't ignored by .cvsignore
-# files or listed in ignore regexes.
-sub find_files {
-    return if $_ eq '.';
-    my $name = $File::Find::name;
-    $name =~ s%^./%%;
-    if ($CVSIGNORE{$name}) {
-        $File::Find::prune = 1;
-        return;
-    }
-    for my $pattern (@IGNORE) {
-        return if $name =~ /$pattern/;
-    }
-    push (@FILES, $name);
-}
-
-find (\&find_cvsignore, '.');
-find (\&find_files, '.');
-print join ("\n", (sort @FILES), '');
diff --git a/support/mksnapshot b/support/mksnapshot
deleted file mode 100755 (executable)
index a1e1631..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /bin/sh
-
-##  $Id: mksnapshot 7308 2005-06-11 08:39:54Z eagle $
-##
-##  Build a snapshot of the current tree.
-##
-##  Meant to be run on a fresh Subversion checkout, this script does the
-##  necessary work to generate a snapshot.  It expects to be invoked from the
-##  top level of the source tree and leaves the generated snapshot in that
-##  same directory as a .tar.gz file.
-##
-##  Snapshot generation will fail if the tree will not compile or if make test
-##  fails.  In either case, the output is left in snapshot.log.
-##
-##  This script takes one argument, a string representing what tree the
-##  snapshot is being taken from.  Generally this string is either CURRENT or
-##  STABLE.
-
-set -e
-
-date=`date -u +%Y%m%d`
-tree="$1"
-if [ -z "$tree" ] ; then
-    echo "$0: no tree name specified" >&2
-    exit 1
-fi
-
-exec > snapshot.log 2>&1
-
-./configure
-make warnings
-make test
-make check-manifest
-
-cat > README.snapshot <<EOF
-This is a snapshot of the current development version of INN, pulled
-automatically from the Subversion repository.  It was made on:
-
-    `date -u +"%B %e, %Y @ %I:%M %p %Z"`
-
-This code should be considered experimental.  Only a default compile and
-automated testing is done before it is made available.  If it breaks, we'd
-like to know at inn-bugs@isc.org, but if it causes your system to explode,
-don't blame us.
-
-If you are using this code, it's highly recommended that you be on the
-inn-workers@isc.org mailing list.  See README for more information.
-EOF
-
-make snapshot SNAPSHOT="$tree" SNAPDATE="$date"
diff --git a/support/mksystem b/support/mksystem
deleted file mode 100755 (executable)
index 6195451..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /bin/sh
-
-##  $Id: mksystem 6397 2003-07-12 19:14:58Z rra $
-##
-##  Create include/inn/system.h from include/config.h.
-##
-##  include/config.h is generated by autoconf and contains all of the test
-##  results for a platform.  Most of these are only used when building INN,
-##  but some of them are needed for various definitions in the header files
-##  for INN's libraries.  We want to be able to install those header files
-##  and their prerequisites, but we don't want to define the normal symbols
-##  defined by autoconf since they're too likely to conflict with other
-##  packages.
-##
-##  This script takes the path to awk as its first argument and the path to
-##  include/config.h as its second argument and generates a file suitable
-##  for being included as <inn/system.h>.  It contains only the autoconf
-##  results needed for INN's API, and the symbols that might conflict with
-##  autoconf results in other packages have INN_ prepended.
-
-cat <<EOF
-/* Automatically generated by mksystem from config.h; do not edit. */
-
-/* This header contains information obtained by INN at configure time that
-   is needed by INN headers.  Autoconf results that may conflict with the
-   autoconf results of another package have INN_ prepended to the
-   preprocessor symbols. */
-
-#ifndef INN_SYSTEM_H
-#define INN_SYSTEM_H 1
-
-EOF
-
-$1 '
-
-/^#define HAVE_C99_VAMACROS/    { print save $1 " INN_" $2 " " $3 "\n" }
-/^#define HAVE_GNU_VAMACROS/    { print save $1 " INN_" $2 " " $3 "\n" }
-/^#define HAVE_INTTYPES_H/      { print save $1 " INN_" $2 " " $3 "\n" }
-/^#define HAVE_MSYNC_3_ARG/     { print save $1 " INN_" $2 " " $3 "\n" }
-/^#define HAVE_STDBOOL_H/       { print save $1 " INN_" $2 " " $3 "\n" }
-/^#define HAVE_SYS_BITTYPES_H/  { print save $1 " INN_" $2 " " $3 "\n" }
-
-{ save = $0 "\n" }' $2
-
-cat <<EOF
-#endif /* INN_SYSTEM_H */
-EOF
diff --git a/support/mkversion b/support/mkversion
deleted file mode 100755 (executable)
index a32db90..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#! /bin/sh
-
-##  $Id: mkversion 7345 2005-07-02 05:04:05Z eagle $
-##
-##  Create version.h from INN version information.
-##
-##  Makefile.global contains the INN version number and extra version
-##  information (if any).  This is passed to use by lib/Makefile as our
-##  first and second arguments.  Print a header file suitable for use
-##  as inn/version.h on stdout.
-
-version="$1"
-extra="$2"
-string="INN $version"
-if [ x"$extra" = x"prerelease" ] ; then
-    date=`date +%Y%m%d`
-    extra="$date $extra"
-fi
-if [ -n "$extra" ] ; then
-    string="$string ($extra)"
-fi
-major=`echo "$version" | cut -d. -f1`
-minor=`echo "$version" | cut -d. -f2`
-patch=`echo "$version" | cut -d. -f3`
-
-cat <<EOF
-/* Automatically generated by mkversion, edit Makefile.global to change. */
-
-#ifndef INN_VERSION_H
-#define INN_VERSION_H 1
-
-#define INN_VERSION_MAJOR $major
-#define INN_VERSION_MINOR $minor
-#define INN_VERSION_PATCH $patch
-#define INN_VERSION_EXTRA "$extra"
-#define INN_VERSION_STRING "$string"
-
-#endif /* INN_VERSION_H */
-EOF
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644 (file)
index 97022e0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-##  $Id: Makefile 7494 2006-03-19 23:19:30Z eagle $
-
-include ../Makefile.global
-
-top    = ..
-CFLAGS = $(GCFLAGS) -I.
-
-##  The tests that need to be built.  Tests in the form of shell scripts
-##  or some other form that doesn't require compiling shouldn't be in this
-##  list.  If they need other things compiled, those other things should be
-##  added to EXTRA.
-
-TESTS  = lib/buffer.t lib/concat.t lib/confparse.t lib/date.t lib/hash.t \
-       lib/hashtab.t lib/hstrerror.t lib/inet_aton.t lib/inet_ntoa.t \
-       lib/innconf.t lib/list.t lib/md5.t lib/memcmp.t lib/messages.t \
-       lib/mkstemp.t lib/pread.t lib/pwrite.t lib/qio.t lib/snprintf.t \
-       lib/strerror.t lib/strlcat.t lib/strlcpy.t lib/tst.t lib/uwildmat.t \
-       lib/vector.t lib/wire.t lib/xwrite.t overview/tradindexed.t
-
-##  Extra stuff that needs to be built before tests can be run.
-
-EXTRA  = runtests lib/setenv.tr lib/xmalloc
-
-all check test: $(TESTS) $(EXTRA)
-       ./runtests TESTS
-
-build: $(TESTS) $(EXTRA)
-
-warnings:
-       $(MAKE) COPT='$(WARNINGS)' build
-
-clean clobber distclean:
-       rm -f *.o *.lo */*.o */*.lo .pure */.pure $(TESTS) $(EXTRA)
-       rm -rf .libs */.libs
-
-.c.o: $*.c
-       $(CC) $(CFLAGS) -c -o $@ $*.c
-
-LINK           = $(LIBTOOL) $(CC) $(LDFLAGS) -o $@
-STORAGEDEPS    = $(LIBSTORAGE) $(LIBHIST) $(LIBINN)
-STORAGELIBS    = $(STORAGEDEPS) $(EXTSTORAGELIBS)
-
-runtests: runtests.o
-       $(LINK) runtests.o
-
-lib/buffer.t: lib/buffer-t.o libtest.o $(LIBINN)
-       $(LINK) lib/buffer-t.o libtest.o $(LIBINN)
-
-lib/concat.t: lib/concat-t.o libtest.o $(LIBINN)
-       $(LINK) lib/concat-t.o libtest.o $(LIBINN)
-
-lib/confparse.t: lib/confparse-t.o libtest.o $(LIBINN)
-       $(LINK) lib/confparse-t.o libtest.o $(LIBINN)
-
-lib/date.t: lib/date-t.o libtest.o $(LIBINN)
-       $(LINK) lib/date-t.o libtest.o $(LIBINN)
-
-lib/hash.t: lib/hash-t.o libtest.o $(LIBINN)
-       $(LINK) lib/hash-t.o libtest.o $(LIBINN)
-
-lib/hashtab.t: lib/hashtab-t.o libtest.o $(LIBINN)
-       $(LINK) lib/hashtab-t.o libtest.o $(LIBINN)
-
-lib/hstrerror.o: ../lib/hstrerror.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/hstrerror.c
-
-lib/hstrerror.t: lib/hstrerror.o lib/hstrerror-t.o libtest.o
-       $(LINK) lib/hstrerror.o lib/hstrerror-t.o libtest.o $(LIBINN)
-
-lib/inet_aton.o: ../lib/inet_aton.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/inet_aton.c
-
-lib/inet_aton.t: lib/inet_aton.o lib/inet_aton-t.o
-       $(LINK) lib/inet_aton.o lib/inet_aton-t.o
-
-lib/inet_ntoa.o: ../lib/inet_ntoa.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/inet_ntoa.c
-
-lib/inet_ntoa.t: lib/inet_ntoa.o lib/inet_ntoa-t.o libtest.o
-       $(LINK) lib/inet_ntoa.o lib/inet_ntoa-t.o libtest.o $(LIBINN)
-
-lib/innconf.t: lib/innconf-t.o libtest.o $(LIBINN)
-       $(LINK) lib/innconf-t.o libtest.o $(LIBINN) $(LIBS)
-
-lib/list.t: lib/list-t.o libtest.o $(LIBINN)
-       $(LINK) lib/list-t.o libtest.o $(LIBINN) $(LIBS)
-
-lib/md5.t: lib/md5-t.o libtest.o $(LIBINN)
-       $(LINK) lib/md5-t.o libtest.o $(LIBINN)
-
-lib/memcmp.o: ../lib/memcmp.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/memcmp.c
-
-lib/memcmp.t: lib/memcmp.o lib/memcmp-t.o libtest.o
-       $(LINK) lib/memcmp.o lib/memcmp-t.o libtest.o $(LIBINN)
-
-lib/messages.o: ../lib/messages.c
-       $(CC) $(CFLAGS) -DDEBUG -c -o $@ ../lib/messages.c
-
-lib/messages-t.o: lib/messages-t.c
-       $(CC) $(CFLAGS) -DDEBUG -c -o $@ lib/messages-t.c
-
-lib/messages.t: lib/messages.o lib/messages-t.o $(LIBINN)
-       $(LINK) lib/messages-t.o lib/messages.o $(LIBINN)
-
-lib/mkstemp.o: ../lib/mkstemp.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/mkstemp.c
-
-lib/mkstemp.t: lib/mkstemp.o lib/mkstemp-t.o libtest.o
-       $(LINK) lib/mkstemp.o lib/mkstemp-t.o libtest.o $(LIBINN)
-
-lib/pread.o: ../lib/pread.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/pread.c
-
-lib/pread.t: lib/pread.o lib/pread-t.o libtest.o $(LIBINN)
-       $(LINK) lib/pread.o lib/pread-t.o libtest.o $(LIBINN)
-
-lib/pwrite.o: ../lib/pwrite.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/pwrite.c
-
-lib/pwrite.t: lib/pwrite.o lib/pwrite-t.o libtest.o $(LIBINN)
-       $(LINK) lib/pwrite.o lib/pwrite-t.o libtest.o $(LIBINN)
-
-lib/qio.t: lib/qio-t.o libtest.o $(LIBINN)
-       $(LINK) lib/qio-t.o libtest.o $(LIBINN)
-
-lib/setenv.o: ../lib/setenv.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/setenv.c
-
-lib/setenv.tr: lib/setenv.o lib/setenv-t.o libtest.o $(LIBINN)
-       $(LINK) lib/setenv.o lib/setenv-t.o libtest.o $(LIBINN)
-
-lib/snprintf.o: ../lib/snprintf.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/snprintf.c
-
-lib/snprintf.t: lib/snprintf.o lib/snprintf-t.o libtest.o
-       $(LINK) lib/snprintf.o lib/snprintf-t.o libtest.o $(LIBINN)
-
-lib/strerror.o: ../lib/strerror.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/strerror.c
-
-lib/strerror.t: lib/strerror.o lib/strerror-t.o libtest.o
-       $(LINK) lib/strerror.o lib/strerror-t.o libtest.o $(LIBINN)
-
-lib/strlcat.o: ../lib/strlcat.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/strlcat.c
-
-lib/strlcat.t: lib/strlcat.o lib/strlcat-t.o libtest.o
-       $(LINK) lib/strlcat.o lib/strlcat-t.o libtest.o $(LIBINN)
-
-lib/strlcpy.o: ../lib/strlcpy.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/strlcpy.c
-
-lib/strlcpy.t: lib/strlcpy.o lib/strlcpy-t.o libtest.o
-       $(LINK) lib/strlcpy.o lib/strlcpy-t.o libtest.o $(LIBINN)
-
-lib/tst.t: lib/tst-t.o $(LIBINN)
-       $(LINK) lib/tst-t.o libtest.o $(LIBINN)
-
-lib/uwildmat.t: lib/uwildmat-t.o $(LIBINN)
-       $(LINK) lib/uwildmat-t.o $(LIBINN)
-
-lib/vector.t: lib/vector-t.o libtest.o $(LIBINN)
-       $(LINK) lib/vector-t.o libtest.o $(LIBINN)
-
-lib/wire.t: lib/wire-t.o libtest.o $(LIBINN)
-       $(LINK) lib/wire-t.o libtest.o $(LIBINN)
-
-lib/xmalloc: lib/xmalloc.o $(LIBINN)
-       $(LINK) lib/xmalloc.o $(LIBINN)
-
-lib/xwrite.o: ../lib/xwrite.c
-       $(CC) $(CFLAGS) -DTESTING -c -o $@ ../lib/xwrite.c
-
-lib/xwrite.t: lib/xwrite-t.o lib/xwrite.o lib/fakewrite.o $(LIBINN)
-       $(LINK) lib/xwrite-t.o lib/xwrite.o lib/fakewrite.o $(LIBINN)
-
-overview/tradindexed.t: overview/tradindexed-t.o libtest.o $(STORAGEDEPS)
-       $(LINK) overview/tradindexed-t.o libtest.o $(STORAGELIBS) $(LIBS)
diff --git a/tests/TESTS b/tests/TESTS
deleted file mode 100644 (file)
index 5e09a11..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-authprogs/ckpasswd
-authprogs/domain
-lib/buffer
-lib/concat
-lib/confparse
-lib/date
-lib/hash
-lib/hashtab
-lib/inet_aton
-lib/inet_ntoa
-lib/innconf
-lib/list
-lib/md5
-lib/memcmp
-lib/messages
-lib/mkstemp
-lib/pread
-lib/pwrite
-lib/qio
-lib/setenv
-lib/snprintf
-lib/strerror
-lib/strlcat
-lib/strlcpy
-lib/tst
-lib/uwildmat
-lib/vector
-lib/wire
-lib/xmalloc
-lib/xwrite
-overview/tradindexed
-util/convdate
diff --git a/tests/authprogs/ckpasswd.t b/tests/authprogs/ckpasswd.t
deleted file mode 100755 (executable)
index 95c9680..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#! /bin/sh
-# $Id: ckpasswd.t 5572 2002-08-12 06:01:09Z rra $
-#
-# Test suite for ckpasswd.
-
-# The count starts at 1 and is updated each time ok is printed.  printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
-    echo "$1 $count $2"
-    count=`expr $count + 1`
-}
-
-# Run ckpasswd, expecting it to succeed.  Takes a username, a password, any
-# additional options, and the expected output string.
-runsuccess () {
-    output=`$ckpasswd -u "$1" -p "$2" $3 2>&1`
-    status=$?
-    if test $status = 0 && test x"$output" = x"$4" ; then
-        printcount "ok"
-    else
-        printcount "not ok"
-        echo "  saw: $output"
-        echo "  not: $4"
-    fi
-}
-
-# Run ckpasswd, feeding it the username and password on stdin in the same way
-# that nnrpd would.  Takes a username, a password, any additional options, and
-# the expected output string.
-runpipe () {
-    output=`( echo ClientAuthname: $1 ; echo ClientPassword: $2 ) \
-                | $ckpasswd $3 2>&1`
-    status=$?
-    if test $status = 0 && test x"$output" = x"$4" ; then
-        printcount "ok"
-    else
-        printcount "not ok"
-        echo "  saw: $output"
-        echo "  not: $4"
-    fi
-}
-
-# Run ckpasswd, expecting it to fail, and make sure it fails with status 1 and
-# prints out the right error message.  Takes a username, a password, any
-# additional options, and the expected output string.
-runfailure () {
-    output=`$ckpasswd -u "$1" -p "$2" $3 2>&1`
-    status=$?
-    if test $status = 1 && test x"$output" = x"$4" ; then
-        printcount "ok"
-    else
-        printcount "not ok"
-        echo "  saw: $output"
-        echo "  not: $4"
-    fi
-}
-
-# Make sure we're in the right directory.
-for dir in . authprogs tests/authprogs ; do
-    test -f "$dir/passwd" && cd $dir
-done
-ckpasswd=../../authprogs/ckpasswd
-
-# Print the test count.
-echo 7
-
-# First, run the tests that we expect to succeed.
-runsuccess "foo" "foopass" "-f passwd" "User:foo"
-runsuccess "bar" "barpass" "-f passwd" "User:bar"
-runsuccess "baz" ""        "-f passwd" "User:baz"
-runpipe "foo" "foopass" "-f passwd" "User:foo"
-
-# Now, run the tests that we expect to fail.
-runfailure "foo" "barpass" "-f passwd" \
-    "ckpasswd: invalid password for user foo"
-runfailure "who" "foopass" "-f passwd" \
-    "ckpasswd: user who unknown"
-runfailure "" "foopass" "-f passwd" \
-    "ckpasswd: null username"
diff --git a/tests/authprogs/domain.t b/tests/authprogs/domain.t
deleted file mode 100755 (executable)
index 205c70f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#! /bin/sh
-# $Id: domain.t 5948 2002-12-08 04:20:46Z rra $
-#
-# Test suite for domain.
-
-# The count starts at 1 and is updated each time ok is printed.  printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
-    echo "$1 $count $2"
-    count=`expr $count + 1`
-}
-
-# Run domain, expecting it to succeed.  Feed it the client host the way that
-# nnrpd would.  Takes the client host, the domain to check it against, and the
-# user expected.
-runsuccess () {
-    output=`( echo ClientHost: $1 ; echo ClientIP: 127.0.0.1 ; \
-              echo ClientPort: 0 ; echo LocalIP: 127.0.0.1 ; \
-              echo LocalPort: 119) | $domain $2 2>&1`
-    status=$?
-    if test $status = 0 && test x"$output" = x"$3" ; then
-        printcount "ok"
-    else
-        printcount "not ok"
-        echo "  saw: $output"
-        echo "  not: $3"
-    fi
-}
-
-# Run domain, expecting it to fail, and make sure it fails with status 1 and
-# prints out the right error message.  Takes the client host, the domain to
-# check it against, and the expected output string.
-runfailure () {
-    output=`( echo ClientHost: $1 ; echo ClientIP: 127.0.0.1 ; \
-              echo ClientPort: 0 ; echo LocalIP: 127.0.0.1 ; \
-              echo LocalPort: 119) | $domain $2 2>&1`
-    status=$?
-    if test $status = 1 && test x"$output" = x"$3" ; then
-        printcount "ok"
-    else
-        printcount "not ok"
-        echo "  saw: $output"
-        echo "  not: $3"
-    fi
-}
-
-# Make sure we're in the right directory.
-domain=domain
-for dir in authprogs ../authprogs ../../authprogs ; do
-    test -x "$dir/domain" && domain="$dir/domain"
-done
-
-# Print the test count.
-echo 8
-
-# First, run the tests that we expect to succeed.
-runsuccess "foo.example.com"     ".example.com" "User:foo"
-runsuccess "foo.example.com"     "example.com"  "User:foo"
-runsuccess "foo.bar.example.com" ".example.com" "User:foo.bar"
-runsuccess "foo.bar.example.com" "example.com"  "User:foo.bar"
-runsuccess "foo.example.com"     "com"          "User:foo.example"
-
-# Now, run the tests that we expect to fail.
-runfailure "example.com"     "example.com" \
-    "domain: host example.com matches the domain exactly"
-runfailure "foo.example.com" "example.net" \
-    "domain: host foo.example.com didn't match domain example.net"
-runfailure "fooexample.com"  "example.com" \
-    "domain: host fooexample.com didn't match domain example.com"
diff --git a/tests/authprogs/passwd b/tests/authprogs/passwd
deleted file mode 100644 (file)
index fefd476..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is a comment.
-foo:bZukvB.43WoX.:5:5:Foo Bar:/home/foo:/bin/sh
-
-# This is another comment.
-
-This is just some random text that someone put in this file for no good
-reason.
-
-bar:9oV.zhEh2nexE
-baz:qq2C4zterbO2k::::::::::::::::::::::
diff --git a/tests/lib/articles/no-body b/tests/lib/articles/no-body
deleted file mode 100644 (file)
index 5187f88..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Path: foo!bar\r
-From: example@example.com\r
-Subject: Test\r
-Date: Mon, 23 Dec 2002 16:00:04 -0700\r
-Message-ID: <id1@example.com>\r
diff --git a/tests/lib/articles/strange b/tests/lib/articles/strange
deleted file mode 100644 (file)
index 3c0731a..0000000
Binary files a/tests/lib/articles/strange and /dev/null differ
diff --git a/tests/lib/articles/truncated b/tests/lib/articles/truncated
deleted file mode 100644 (file)
index 24f301a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Path: foo!bar\r
-From: example@example.com\r
-Subject: Test\r
-Message-ID: <id1@example.com>\r
-Date: Mon, 23 Dec 2002 16:00:04
\ No newline at end of file
diff --git a/tests/lib/buffer-t.c b/tests/lib/buffer-t.c
deleted file mode 100644 (file)
index 50ca96d..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $Id: buffer-t.c 5469 2002-05-20 12:50:57Z alexk $ */
-/* buffer test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/buffer.h"
-#include "libtest.h"
-
-static const char test_string1[] = "This is a test";
-static const char test_string2[] = " of the buffer system";
-static const char test_string3[] = "This is a test\0 of the buffer system";
-
-int
-main(void)
-{
-    struct buffer one = { 0, 0, 0, NULL };
-    struct buffer two = { 0, 0, 0, NULL };
-    struct buffer *three;
-
-    puts("26");
-
-    buffer_set(&one, test_string1, sizeof(test_string1));
-    ok_int(1, 1024, one.size);
-    ok_int(2, 0, one.used);
-    ok_int(3, sizeof(test_string1), one.left);
-    ok_string(4, test_string1, one.data);
-    buffer_append(&one, test_string2, sizeof(test_string2));
-    ok_int(5, 1024, one.size);
-    ok_int(6, 0, one.used);
-    ok_int(7, sizeof(test_string3), one.left);
-    ok(8, memcmp(one.data, test_string3, sizeof(test_string3)) == 0);
-    one.left -= sizeof(test_string1);
-    one.used += sizeof(test_string1);
-    buffer_append(&one, test_string1, sizeof(test_string1));
-    ok_int(9, 1024, one.size);
-    ok_int(10, sizeof(test_string1), one.used);
-    ok_int(11, sizeof(test_string3), one.left);
-    ok(12,
-       memcmp(one.data + one.used, test_string2, sizeof(test_string2)) == 0);
-    ok(13,
-       memcmp(one.data + one.used + sizeof(test_string2), test_string1,
-              sizeof(test_string1)) == 0);
-    buffer_set(&one, test_string1, sizeof(test_string1));
-    buffer_set(&two, test_string2, sizeof(test_string2));
-    buffer_swap(&one, &two);
-    ok_int(14, 1024, one.size);
-    ok_int(15, 0, one.used);
-    ok_int(16, sizeof(test_string2), one.left);
-    ok_string(17, test_string2, one.data);
-    ok_int(18, 1024, two.size);
-    ok_int(19, 0, two.used);
-    ok_int(20, sizeof(test_string1), two.left);
-    ok_string(21, test_string1, two.data);
-
-    three = buffer_new();
-    ok(22, three != NULL);
-    ok_int(23, 0, three->size);
-    buffer_set(three, test_string1, sizeof(test_string1));
-    ok_int(24, 1024, three->size);
-    buffer_resize(three, 512);
-    ok_int(25, 1024, three->size);
-    buffer_resize(three, 1025);
-    ok_int(26, 2048, three->size);
-    free(three->data);
-    free(three);
-
-    return 0;
-}
diff --git a/tests/lib/concat-t.c b/tests/lib/concat-t.c
deleted file mode 100644 (file)
index 9d18adb..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id: concat-t.c 5054 2001-12-12 09:15:24Z rra $ */
-/* concat test suite. */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "libinn.h"
-#include "libtest.h"
-
-#define END     (char *) 0
-
-int
-main(void)
-{
-    printf("11\n");
-
-    ok_string( 1, "a",     concat("a",                   END));
-    ok_string( 2, "ab",    concat("a", "b",              END));
-    ok_string( 3, "ab",    concat("ab", "",              END));
-    ok_string( 4, "ab",    concat("", "ab",              END));
-    ok_string( 5, "",      concat("",                    END));
-    ok_string( 6, "abcde", concat("ab", "c", "", "de",   END));
-    ok_string( 7, "abcde", concat("abc", "de", END, "f", END));
-
-    ok_string( 8, "/foo",             concatpath("/bar", "/foo"));
-    ok_string( 9, "/foo/bar",         concatpath("/foo", "bar"));
-    ok_string(10, "./bar",            concatpath("/foo", "./bar"));
-    ok_string(11, "/bar/baz/foo/bar", concatpath("/bar/baz", "foo/bar"));
-
-    return 0;
-}
diff --git a/tests/lib/config/errors b/tests/lib/config/errors
deleted file mode 100644 (file)
index fde6d17..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-foo bar
-===
-config/tmp:1: parse error: saw string, expecting parameter
-===
-parameter: value with spaces
-===
-config/tmp:1: parse error: saw string, expecting semicolon or newline
-===
-parameter: escape\tvalue
-===
-config/tmp:1: invalid character '\' in unquoted string
-===
-parameter:: value
-===
-config/tmp:1: invalid character ':' in unquoted string
-===
-parameter: "value
-===
-config/tmp:1: no close quote seen for quoted string
-===
-parameter: value ; value
-===
-config/tmp:1: parse error: saw string, expecting parameter
-===
-parameter: # value
-value
-===
-config/tmp:1: parse error: saw string, expecting semicolon or newline
-===
-"foo bar"
-===
-config/tmp:1: parse error: saw quoted string, expecting parameter
-===
-first: second
-third: fourth
-parameter: "value \
-===
-config/tmp:4: end of file encountered while parsing quoted string
-===
-parameter:value
-===
-config/tmp:1: invalid character ':' in unquoted string
-===
-parameter: value # this is a comment
-===
-config/tmp:1: parse error: saw string, expecting semicolon or newline
-===
-parameter: "value
-value"
-===
-config/tmp:1: no close quote seen for quoted string
-===
diff --git a/tests/lib/config/line-endings b/tests/lib/config/line-endings
deleted file mode 100644 (file)
index 399cff0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is a leading comment.
-param1: on
-param2:  true
-param3: yes
-# this is a comment \
-param4: off
-  # this is another
-int1: 0
-
-int2: -3
diff --git a/tests/lib/config/no-newline b/tests/lib/config/no-newline
deleted file mode 100644 (file)
index b72eaf4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Test a lack of newline at the end of the configuration file.
-parameter: value
\ No newline at end of file
diff --git a/tests/lib/config/null b/tests/lib/config/null
deleted file mode 100644 (file)
index ebd35f4..0000000
Binary files a/tests/lib/config/null and /dev/null differ
diff --git a/tests/lib/config/simple b/tests/lib/config/simple
deleted file mode 100644 (file)
index 6f21e65..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-foo: baz
-bar: baz
diff --git a/tests/lib/config/valid b/tests/lib/config/valid
deleted file mode 100644 (file)
index 44d78dd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# This is a leading comment.
-param1: on
-
-       param2:  true
-
-
-param3: yes
-# this is a comment \
-param4: off
-  # this is another
-# comment
-         # on several lines
-  param5: false ; param6: no
-
-int1: 0                ;       int2: -3
-  # int3: 5000
-  int4: 5000
-int5: 2147483647
-int6: -2147483648
-
-string1: foo; string2: bar
-string3: "this is a test"
-string4: "this is \
-a test"
-string5: "this is \a\b\f\n\r\t\v a test \' of \" escapes \?\\"
-string6: "\
-# this is not a comment\
-"; string7: "lost \
-\nyet?"
diff --git a/tests/lib/config/warn-bool b/tests/lib/config/warn-bool
deleted file mode 100644 (file)
index add8c08..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-parameter: "yes"
-===
-config/tmp:1: parameter is not a boolean
-===
-parameter: False
-===
-config/tmp:1: parameter is not a boolean
-===
-foo: bar
-parameter: 0
-===
-config/tmp:2: parameter is not a boolean
-===
diff --git a/tests/lib/config/warn-int b/tests/lib/config/warn-int
deleted file mode 100644 (file)
index bf7beae..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-parameter: "foo"
-===
-config/tmp:1: parameter is not an integer
-===
-# Check that line numbers are right.
-key: value; parameter: foobar
-===
-config/tmp:2: parameter is not an integer
-===
-parameter: 999999999999999999999999999999999999999999999999999999999999
-===
-config/tmp:1: parameter doesn't convert to an integer
-===
diff --git a/tests/lib/config/warnings b/tests/lib/config/warnings
deleted file mode 100644 (file)
index facfd6b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Make sure line numbering copes with a leading comment.
-parameter: value
-parameter: value
-===
-config/tmp:3: duplicate parameter parameter
-===
-# Line numbering and Macs.
-parameter: value
-parameter: value
-===
-config/tmp:3: duplicate parameter parameter
-===
-# Line numbering and Windows.
-parameter: value
-parameter: value
-===
-config/tmp:3: duplicate parameter parameter
-===
diff --git a/tests/lib/confparse-t.c b/tests/lib/confparse-t.c
deleted file mode 100644 (file)
index a4b4762..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/* $Id: confparse-t.c 5955 2002-12-08 09:28:32Z rra $ */
-/* confparse test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <unistd.h>
-
-#include "inn/confparse.h"
-#include "inn/messages.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "libtest.h"
-
-/* Given a FILE *, read from that file, putting the results into a newly
-   allocated buffer, until encountering a line consisting solely of "===".
-   Returns the buffer, NULL on end of file, dies on error. */
-static char *
-read_section(FILE *file)
-{
-    char buf[1024] = "";
-    char *data = NULL;
-    char *status;
-
-    status = fgets(buf, sizeof(buf), file);
-    if (status == NULL)
-        return false;
-    while (1) {
-        if (status == NULL)
-            die("Unexpected end of file while reading tests");
-        if (strcmp(buf, "===\n") == 0)
-            break;
-        if (data == NULL) {
-            data = xstrdup(buf);
-        } else {
-            char *new_data;
-
-            new_data = concat(data, buf, (char *) 0);
-            free(data);
-            data = new_data;
-        }
-        status = fgets(buf, sizeof(buf), file);
-    }
-    return data;
-}
-
-/* Read from the given file a configuration file and write it out to
-   config/tmp.  Returns true on success, false on end of file, and dies on
-   any error. */
-static bool
-write_test_config(FILE *file)
-{
-    FILE *tmp;
-    char *config;
-
-    config = read_section(file);
-    if (config == NULL)
-        return false;
-    tmp = fopen("config/tmp", "w");
-    if (tmp == NULL)
-        sysdie("Cannot create config/tmp");
-    if (fputs(config, tmp) == EOF)
-        sysdie("Write error while writing to config/tmp");
-    fclose(tmp);
-    free(config);
-    return true;
-}
-
-/* Parse a given config file with errors, setting the appropriate error
-   handler for the duration of the parse to save errors into the errors
-   global.  Returns the resulting config_group. */
-static struct config_group *
-parse_error_config(const char *filename)
-{
-    struct config_group *group;
-
-    errors_capture();
-    group = config_parse_file(filename);
-    errors_uncapture();
-    return group;
-}
-
-/* Read in a configuration file from the provided FILE *, write it to disk,
-   parse the temporary config file, and return the resulting config_group in
-   the pointer passed as the second parameter.  Returns true on success,
-   false on end of file. */
-static bool
-parse_test_config(FILE *file, struct config_group **group)
-{
-    if (!write_test_config(file))
-        return false;
-    *group = parse_error_config("config/tmp");
-    unlink("config/tmp");
-    return true;
-}
-
-/* Test the error test cases in config/errors, ensuring that they all fail
-   to parse and match the expected error messages.  Takes the current test
-   count and returns the new test count. */
-static int
-test_errors(int n)
-{
-    FILE *errfile;
-    char *expected;
-    struct config_group *group;
-
-    errfile = fopen("config/errors", "r");
-    if (errfile == NULL)
-        sysdie("Cannot open config/errors");
-    while (parse_test_config(errfile, &group)) {
-        expected = read_section(errfile);
-        if (expected == NULL)
-            die("Unexpected end of file while reading error tests");
-        ok(n++, group == NULL);
-        ok_string(n++, expected, errors);
-        free(expected);
-    }
-    fclose(errfile);
-    return n;
-}
-
-/* Test the warning test cases in config/warningss, ensuring that they all
-   parse successfully and match the expected error messages.  Takes the
-   current test count and returns the new test count. */
-static int
-test_warnings(int n)
-{
-    FILE *warnfile;
-    char *expected;
-    struct config_group *group;
-
-    warnfile = fopen("config/warnings", "r");
-    if (warnfile == NULL)
-        sysdie("Cannot open config/warnings");
-    while (parse_test_config(warnfile, &group)) {
-        expected = read_section(warnfile);
-        if (expected == NULL)
-            die("Unexpected end of file while reading error tests");
-        ok(n++, group != NULL);
-        ok_string(n++, expected, errors);
-        free(expected);
-    }
-    fclose(warnfile);
-    return n;
-}
-
-/* Test the warning test cases in config/warn-bool, ensuring that they all
-   parse successfully and produce the expected error messages when retrieved
-   as bools.  Takes the current test count and returns the new test count. */
-static int
-test_warnings_bool(int n)
-{
-    FILE *warnfile;
-    char *expected;
-    struct config_group *group;
-    bool b_value = false;
-
-    warnfile = fopen("config/warn-bool", "r");
-    if (warnfile == NULL)
-        sysdie("Cannot open config/warn-bool");
-    while (parse_test_config(warnfile, &group)) {
-        expected = read_section(warnfile);
-        if (expected == NULL)
-            die("Unexpected end of file while reading error tests");
-        ok(n++, group != NULL);
-        ok(n++, errors == NULL);
-        errors_capture();
-        ok(n++, !config_param_boolean(group, "parameter", &b_value));
-        ok_string(n++, expected, errors);
-        errors_uncapture();
-        free(expected);
-    }
-    fclose(warnfile);
-    return n;
-}
-
-/* Test the warning test cases in config/warn-int, ensuring that they all
-   parse successfully and produce the expected error messages when retrieved
-   as bools.  Takes the current test count and returns the new test count. */
-static int
-test_warnings_int(int n)
-{
-    FILE *warnfile;
-    char *expected;
-    struct config_group *group;
-    long l_value = 1;
-
-    warnfile = fopen("config/warn-int", "r");
-    if (warnfile == NULL)
-        sysdie("Cannot open config/warn-int");
-    while (parse_test_config(warnfile, &group)) {
-        expected = read_section(warnfile);
-        if (expected == NULL)
-            die("Unexpected end of file while reading error tests");
-        ok(n++, group != NULL);
-        ok(n++, errors == NULL);
-        errors_capture();
-        ok(n++, !config_param_integer(group, "parameter", &l_value));
-        ok_string(n++, expected, errors);
-        errors_uncapture();
-        free(expected);
-    }
-    fclose(warnfile);
-    return n;
-}
-
-int
-main(void)
-{
-    struct config_group *group;
-    bool b_value = false;
-    long l_value = 1;
-    const char *s_value;
-    struct vector *v_value;
-    char *long_param, *long_value;
-    size_t length;
-    int n;
-    FILE *tmpconfig;
-
-    puts("125");
-
-    if (access("config/valid", F_OK) < 0)
-        if (access("lib/config/valid", F_OK) == 0)
-            chdir("lib");
-    group = config_parse_file("config/valid");
-    ok(1, group != NULL);
-    if (group == NULL)
-        exit(1);
-
-    /* Booleans. */
-    ok(2, config_param_boolean(group, "param1", &b_value));
-    ok(3, b_value);
-    b_value = false;
-    ok(4, config_param_boolean(group, "param2", &b_value));
-    ok(5, b_value);
-    b_value = false;
-    ok(6, config_param_boolean(group, "param3", &b_value));
-    ok(7, b_value);
-    ok(8, config_param_boolean(group, "param4", &b_value));
-    ok(9, !b_value);
-    b_value = true;
-    ok(10, config_param_boolean(group, "param5", &b_value));
-    ok(11, !b_value);
-    b_value = true;
-    ok(12, config_param_boolean(group, "param6", &b_value));
-    ok(13, !b_value);
-
-    /* Integers. */
-    ok(14, config_param_integer(group, "int1", &l_value));
-    ok(15, l_value == 0);
-    ok(16, config_param_integer(group, "int2", &l_value));
-    ok(17, l_value == -3);
-    ok(18, !config_param_integer(group, "int3", &l_value));
-    ok(19, l_value == -3);
-    ok(20, config_param_integer(group, "int4", &l_value));
-    ok(21, l_value == 5000);
-    ok(22, config_param_integer(group, "int5", &l_value));
-    ok(23, l_value == 2147483647L);
-    ok(24, config_param_integer(group, "int6", &l_value));
-    ok(25, l_value == (-2147483647L - 1));
-
-    /* Strings. */
-    ok(26, config_param_string(group, "string1", &s_value));
-    ok_string(27, "foo", s_value);
-    ok(28, config_param_string(group, "string2", &s_value));
-    ok_string(29, "bar", s_value);
-    ok(30, config_param_string(group, "string3", &s_value));
-    ok_string(31, "this is a test", s_value);
-    ok(32, config_param_string(group, "string4", &s_value));
-    ok_string(33, "this is a test", s_value);
-    ok(34, config_param_string(group, "string5", &s_value));
-    ok_string(35, "this is \a\b\f\n\r\t\v a test \' of \" escapes \?\\",
-              s_value);
-    ok(36, config_param_string(group, "string6", &s_value));
-    ok_string(37, "# this is not a comment", s_value);
-    ok(38, config_param_string(group, "string7", &s_value));
-    ok_string(39, "lost \nyet?", s_value);
-
-    config_free(group);
-
-    /* Missing newline. */
-    group = config_parse_file("config/no-newline");
-    ok(40, group != NULL);
-    if (group == NULL) {
-        ok(41, false);
-        ok(42, false);
-    } else {
-        ok(41, config_param_string(group, "parameter", &s_value));
-        ok_string(42, "value", s_value);
-        config_free(group);
-    }
-
-    /* Extremely long parameter and value. */
-    tmpconfig = fopen("config/tmp", "w");
-    if (tmpconfig == NULL)
-        sysdie("cannot create config/tmp");
-    long_param = xcalloc(20001, 1);
-    memset(long_param, 'a', 20000);
-    long_value = xcalloc(64 * 1024 + 1, 1);
-    memset(long_value, 'b', 64 * 1024);
-    fprintf(tmpconfig, "%s: \"%s\"; two: %s", long_param, long_value,
-            long_value);
-    fclose(tmpconfig);
-    group = config_parse_file("config/tmp");
-    ok(43, group != NULL);
-    if (group == NULL) {
-        ok(44, false);
-        ok(45, false);
-        ok(46, false);
-        ok(47, false);
-    } else {
-        ok(44, config_param_string(group, long_param, &s_value));
-        ok_string(45, long_value, s_value);
-        ok(46, config_param_string(group, "two", &s_value));
-        ok_string(47, long_value, s_value);
-        config_free(group);
-    }
-    unlink("config/tmp");
-    free(long_param);
-    free(long_value);
-
-    /* Parsing problems exactly on the boundary of a buffer.  This test
-       catches a bug in the parser that caused it to miss the colon at the end
-       of a parameter because the colon was the first character read in a new
-       read of the file buffer. */
-    tmpconfig = fopen("config/tmp", "w");
-    if (tmpconfig == NULL)
-        sysdie("cannot create config/tmp");
-    length = 16 * 1024 - strlen(": baz\nfoo:");
-    long_param = xcalloc(length + 1, 1);
-    memset(long_param, 'c', length);
-    fprintf(tmpconfig, "%s: baz\nfoo: bar\n", long_param);
-    fclose(tmpconfig);
-    group = config_parse_file("config/tmp");
-    ok(48, group != NULL);
-    if (group == NULL) {
-        ok(49, false);
-        ok(50, false);
-        ok(51, false);
-        ok(52, false);
-    } else {
-        ok(49, config_param_string(group, long_param, &s_value));
-        ok_string(50, "baz", s_value);
-        ok(51, config_param_string(group, "foo", &s_value));
-        ok_string(52, "bar", s_value);
-        config_free(group);
-    }
-    unlink("config/tmp");
-    free(long_param);
-
-    /* Alternate line endings. */
-    group = config_parse_file("config/line-endings");
-    ok(53, group != NULL);
-    if (group == NULL)
-        exit(1);
-    ok(54, config_param_boolean(group, "param1", &b_value));
-    ok(55, b_value);
-    b_value = false;
-    ok(56, config_param_boolean(group, "param2", &b_value));
-    ok(57, b_value);
-    b_value = false;
-    ok(58, config_param_boolean(group, "param3", &b_value));
-    ok(59, b_value);
-    ok(60, config_param_boolean(group, "param4", &b_value));
-    ok(61, !b_value);
-    ok(62, config_param_integer(group, "int1", &l_value));
-    ok(63, l_value == 0);
-    ok(64, config_param_integer(group, "int2", &l_value));
-    ok(65, l_value == -3);
-    config_free(group);
-
-    /* Listing parameters. */
-    group = config_parse_file("config/simple");
-    ok(66, group != NULL);
-    if (group == NULL)
-        exit(1);
-    v_value = config_params(group);
-    ok_int(67, 2, v_value->count);
-    ok_int(68, 2, v_value->allocated);
-    if (strcmp(v_value->strings[0], "foo") == 0)
-        ok_string(69, "bar", v_value->strings[1]);
-    else if (strcmp(v_value->strings[0], "bar") == 0)
-        ok_string(69, "foo", v_value->strings[1]);
-    else
-        ok(69, false);
-    vector_free(v_value);
-    config_free(group);
-
-    /* Errors. */
-    group = parse_error_config("config/null");
-    ok(70, group == NULL);
-    ok_string(71, "config/null: invalid NUL character found in file\n",
-              errors);
-    n = test_errors(72);
-    n = test_warnings(n);
-    n = test_warnings_bool(n);
-    n = test_warnings_int(n);
-
-    return 0;
-}
diff --git a/tests/lib/date-t.c b/tests/lib/date-t.c
deleted file mode 100644 (file)
index d60de15..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* $Id: date-t.c 7495 2006-03-19 23:21:38Z eagle $ */
-/* makedate test suite */
-
-#include "config.h"
-#include "clibrary.h"
-#include <time.h>
-
-#include "libinn.h"
-#include "libtest.h"
-
-static const time_t test_times[] = {
-    28800UL,                    /* Thu,  1 Jan 1970 00:00:00 -0800 (PST) */
-    362762400UL,                /* Tue, 30 Jun 1981 15:20:00 +0000 (UTC) */
-    396977449UL,                /* Sat, 31 Jul 1982 15:30:49 +0000 (UTC) */
-    825597049UL,                /* Thu, 29 Feb 1996 12:30:49 +0000 (UTC) */
-    850435199UL,                /* Thu, 12 Dec 1996 23:59:59 +0000 (UTC) */
-    852101999UL,                /* Wed,  1 Jan 1997 06:59:59 +0000 (UTC) */
-    934288249UL,                /* Tue, 10 Aug 1999 12:30:49 +0000 (UTC) */
-    946684800UL,                /* Sat,  1 Jan 2000 00:00:00 +0000 (UTC) */
-    946713599UL,                /* Fri, 31 Dec 1999 23:59:59 -0800 (PST) */
-    946713600UL,                /* Sat,  1 Jan 2000 00:00:00 -0800 (PST) */
-    951827449UL,                /* Tue, 29 Feb 2000 12:30:49 +0000 (UTC) */
-    954669599UL,                /* Sun,  2 Apr 2000 01:59:59 -0800 (PST) */
-    954669600UL,                /* Sun,  2 Apr 2000 03:00:00 -0700 (PDT) */
-    967707668UL,                /* Thu, 31 Aug 2000 07:41:08 +0000 (UTC) */
-    972813600UL                 /* Sun, 29 Oct 2000 02:00:00 -0800 (PST) */
-};
-
-static void
-ok_time(int n, time_t right, const char *date, const char *hour, bool local)
-{
-    time_t seen;
-
-    seen = parsedate_nntp(date, hour, local);
-    if (right == seen)
-        printf("ok %d\n", n);
-    else
-        printf("not ok %d\n  wanted %lu seen %lu\n  %s %s %d\n", n,
-               (unsigned long) right, (unsigned long) seen, date, hour,
-               local);
-}
-
-static void
-check_nntp(int *n, time_t timestamp)
-{
-    char date[9], hour[7];
-    struct tm *tmp_tm, tm;
-
-    tmp_tm = localtime(&timestamp);
-    tm = *tmp_tm;
-    sprintf(date, "%02d%02d%02d", tm.tm_year % 100, tm.tm_mon + 1,
-            tm.tm_mday);
-    sprintf(hour, "%02d%02d%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
-    ok_time((*n)++, timestamp, date, hour, true);
-    sprintf(date, "%04d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1,
-            tm.tm_mday);
-    ok_time((*n)++, timestamp, date, hour, true);
-    tmp_tm = gmtime(&timestamp);
-    tm = *tmp_tm;
-    sprintf(date, "%04d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1,
-            tm.tm_mday);
-    sprintf(hour, "%02d%02d%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
-    ok_time((*n)++, timestamp, date, hour, false);
-}
-
-int
-main(void)
-{
-    char buff[64] = "";
-    bool status;
-    time_t now, result;
-    double diff = 0;
-    int n;
-    unsigned int i;
-
-    char PST8PDT[] = "TZ=PST8PDT";
-    char Newfoundland[] = "TZ=Canada/Newfoundland";
-
-    printf("%d\n", 44 + ARRAY_SIZE(test_times) * 3 + 3);
-
-    now = time(NULL);
-    status = makedate(-1, false, buff, sizeof(buff));
-    if (status) {
-        result = parsedate(buff, NULL);
-        diff = difftime(result, now);
-    }
-    ok(1, status && diff >= 0 && diff < 10);
-    now = time(NULL);
-    status = makedate(-1, true, buff, sizeof(buff));
-    if (status) {
-        result = parsedate(buff, NULL);
-        diff = difftime(result, now);
-    }
-    ok(2, status && diff >= 0 && diff < 10);
-
-    putenv(PST8PDT);
-    tzset();
-
-    status = makedate(100000000UL, false, buff, sizeof(buff));
-    ok(3, status);
-    ok_string(4, "Sat, 3 Mar 1973 09:46:40 +0000 (UTC)", buff);
-    status = makedate(100000000UL, true, buff, sizeof(buff));
-    ok(5, status);
-    ok_string(6, "Sat, 3 Mar 1973 01:46:40 -0800 (PST)", buff);
-    status = makedate(300000000UL, false, buff, sizeof(buff));
-    ok(7, status);
-    ok_string(8, "Thu, 5 Jul 1979 05:20:00 +0000 (UTC)", buff);
-    status = makedate(300000000UL, true, buff, sizeof(buff));
-    ok(9, status);
-    ok_string(10, "Wed, 4 Jul 1979 22:20:00 -0700 (PDT)", buff);
-
-    status = makedate(300000000UL, false, buff, 31);
-    ok(11, !status);
-    status = makedate(300000000UL, false, buff, 32);
-    ok(12, status);
-    ok_string(13, "Thu, 5 Jul 1979 05:20:00 +0000", buff);
-    status = makedate(300000000UL, true, buff, 32);
-    ok(14, status);
-    ok_string(15, "Wed, 4 Jul 1979 22:20:00 -0700", buff);
-
-    putenv(Newfoundland);
-    tzset();
-
-    status = makedate(900000045UL, true, buff, sizeof(buff));
-    ok(16, status);
-    if (memcmp(buff, "Thu, 9 Jul 1998 16:00:45 +0000", 30) == 0)
-        printf("ok 17 # skip - Newfoundland time zone not installed\n");
-    else
-        ok_string(17, "Thu, 9 Jul 1998 13:30:45 -0230 (NDT)", buff);
-
-    putenv(PST8PDT);
-    tzset();
-
-    ok_time(18, (time_t) -1, "20000132", "000000", false);
-    ok_time(19, (time_t) -1, "20000132", "000000", true);
-    ok_time(20, (time_t) -1, "20000230", "000000", false);
-    ok_time(21, (time_t) -1, "20000230", "000000", true);
-    ok_time(22, (time_t) -1, "19990229", "000000", false);
-    ok_time(23, (time_t) -1, "19990229", "000000", true);
-    ok_time(24, (time_t) -1, "19990020", "000000", false);
-    ok_time(25, (time_t) -1, "19990120", "240000", false);
-    ok_time(26, (time_t) -1, "19990120", "146000", false);
-    ok_time(27, (time_t) -1, "19990120", "145961", false);
-    ok_time(28, (time_t) -1,   "691231", "235959", false);
-    ok_time(29, (time_t) -1, "19691231", "235959", false);
-    ok_time(30, (time_t) -1, "19700100", "000000", false);
-    ok_time(31,           0, "19700101", "000000", false);
-    ok_time(32,           0,   "700101", "000000", false);
-    ok_time(33, (time_t) -1, "2000010101", "000000", false);
-    ok_time(34, (time_t) -1,    "00101", "000000", false);
-    ok_time(35, (time_t) -1, "20000101",  "11111", false);
-    ok_time(36, (time_t) -1, "20000101", "1111111", false);
-    ok_time(37, (time_t) -1, "200001a1", "000000", false);
-    ok_time(38, (time_t) -1, "20000101", "00a000", false);
-
-    /* Times around the fall daylight savings change are ambiguous; accept
-       either of the possible interpretations, but make sure we get one or
-       the other. */
-    result = parsedate_nntp("20001029", "010000", true);
-    ok(39, result == 972806400UL || result == 972810000UL);
-    result = parsedate_nntp("001029", "013000", true);
-    ok(40, result == 972808200UL || result == 972811800UL);
-    result = parsedate_nntp("20001029", "013000", true);
-    ok(41, result == 972808200UL || result == 972811800UL);
-    result = parsedate_nntp("001029", "013000", true);
-    ok(42, result == 972808200UL || result == 972811800UL);
-    result = parsedate_nntp("20001029", "015959", true);
-    ok(43, result == 972809999UL || result == 972813599UL);
-    result = parsedate_nntp("001029", "015959", true);
-    ok(44, result == 972809999UL || result == 972813599UL);
-
-    n = 45;
-    for (i = 0; i < ARRAY_SIZE(test_times); i++)
-        check_nntp(&n, test_times[i]);
-    check_nntp(&n, time(NULL));
-
-    return 0;
-}
diff --git a/tests/lib/fakewrite.c b/tests/lib/fakewrite.c
deleted file mode 100644 (file)
index 7661e28..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* $Id: fakewrite.c 5417 2002-04-15 08:40:20Z rra $ */
-/* Fake write and writev functions for testing xwrite and xwritev. */
-
-#include "config.h"
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-
-#include "libinn.h"
-
-ssize_t fake_write(int, const void *, size_t);
-ssize_t fake_pwrite(int, const void *, size_t, off_t);
-ssize_t fake_writev(int, const struct iovec *, int);
-
-/* All the data is actually written into this buffer.  We use write_offset
-   to track how far we've written. */
-char write_buffer[256];
-size_t write_offset = 0;
-
-/* If write_interrupt is non-zero, then half of the calls to write or writev
-   will fail, returning -1 with errno set to EINTR. */
-int write_interrupt = 0;
-
-/* If write_fail is non-zero, all writes or writevs will return 0,
-   indicating no progress in writing out the buffer. */
-int write_fail = 0;
-
-/* Accept a write request and write only the first 32 bytes of it into
-   write_buffer (or as much as will fit), returning the amount written. */
-ssize_t
-fake_write(int fd UNUSED, const void *data, size_t n)
-{
-    size_t total;
-
-    if (write_fail)
-        return 0;
-    if (write_interrupt && (write_interrupt++ % 2) == 0) {
-        errno = EINTR;
-        return -1;
-    }
-    total = (n < 32) ? n : 32;
-    if (256 - write_offset < total)
-        total = 256 - write_offset;
-    memcpy(write_buffer + write_offset, data, total);
-    write_offset += total;
-    return total;
-}
-
-/* Accept a pwrite request and write only the first 32 bytes of it into
-   write_buffer at the specified offset (or as much as will fit), returning
-   the amount written. */
-ssize_t
-fake_pwrite(int fd UNUSED, const void *data, size_t n, off_t offset)
-{
-    size_t total;
-
-    if (write_fail)
-        return 0;
-    if (write_interrupt && (write_interrupt++ % 2) == 0) {
-        errno = EINTR;
-        return -1;
-    }
-    total = (n < 32) ? n : 32;
-    if (offset > 256) {
-        errno = ENOSPC;
-        return -1;
-    }
-    if ((size_t) (256 - offset) < total)
-        total = 256 - offset;
-    memcpy(write_buffer + offset, data, total);
-    return total;
-}
-
-/* Accept an xwrite request and write only the first 32 bytes of it into
-   write_buffer (or as much as will fit), returning the amount written. */
-ssize_t
-fake_writev(int fd UNUSED, const struct iovec *iov, int iovcnt)
-{
-    int total, i;
-    size_t left, n;
-
-    if (write_fail)
-        return 0;
-    if (write_interrupt && (write_interrupt++ % 2) == 0) {
-        errno = EINTR;
-        return -1;
-    }
-    left = 256 - write_offset;
-    if (left > 32)
-        left = 32;
-    total = 0;
-    for (i = 0; i < iovcnt && left != 0; i++) {
-        n = ((size_t) iov[i].iov_len < left) ? iov[i].iov_len : left;
-        memcpy(write_buffer + write_offset, iov[i].iov_base, n);
-        write_offset += n;
-        total += n;
-        left -= n;
-    }
-    return total;
-}
diff --git a/tests/lib/hash-t.c b/tests/lib/hash-t.c
deleted file mode 100644 (file)
index c8bd9bc..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id: hash-t.c 5623 2002-08-21 19:35:37Z alexk $ */
-/* hash test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "libinn.h"
-#include "libtest.h"
-
-int
-main(void)
-{
-    HASH h1, h2;
-
-    puts("12");
-
-    h1 = HashMessageID("<lhs@test.invalid>");
-    h2 = HashMessageID("<lhs@TEST.invalid>");
-    ok(1, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<lhs@test.INVALID>");
-    ok(2, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<Lhs@test.invalid>");
-    ok(3, HashCompare(&h1, &h2) != 0);
-    h2 = HashMessageID("<lhS@test.invalid>");
-    ok(4, HashCompare(&h1, &h2) != 0);
-    h1 = HashMessageID("<test.invalid>");
-    h2 = HashMessageID("<TEST.invalid>");
-    ok(5, HashCompare(&h1, &h2) != 0);
-    h2 = HashMessageID("<test.INVALID>");
-    ok(6, HashCompare(&h1, &h2) != 0);
-    h1 = HashMessageID("<postmaster@test.invalid>");
-    h2 = HashMessageID("<POSTMASTER@test.invalid>");
-    ok(7, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<PostMaster@test.invalid>");
-    ok(8, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<postmasteR@test.invalid>");
-    ok(9, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<postmaster@TEST.invalid>");
-    ok(10, HashCompare(&h1, &h2) == 0);
-    h2 = HashMessageID("<postmaster@test.INVALID>");
-    ok(11, HashCompare(&h1, &h2) == 0);
-    h1 = HashMessageID("<postmaster.test.invalid>");
-    h2 = HashMessageID("<POSTMASTER.test.invalid>");
-    ok(12, HashCompare(&h1, &h2) != 0);
-
-    return 0;
-}
diff --git a/tests/lib/hashtab-t.c b/tests/lib/hashtab-t.c
deleted file mode 100644 (file)
index 9f818ff..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/* $Id: hashtab-t.c 6026 2002-12-24 05:02:51Z rra $ */
-/* Test suite for lib/hashtab.c. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <sys/stat.h>
-
-#include "inn/hashtab.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "libtest.h"
-
-struct wordref {
-    const char *word;
-    int count;
-};
-
-static const void *
-string_key(const void *entry)
-{
-    return entry;
-}
-
-static bool
-string_equal(const void *key, const void *entry)
-{
-    const char *p, *q;
-
-    p = key;
-    q = entry;
-    return !strcmp(p, q);
-}
-
-static void
-string_delete(void *entry)
-{
-    free(entry);
-}
-
-static void
-string_traverse(void *entry, void *data)
-{
-    int i;
-    struct wordref *wordrefs = data;
-
-    for (i = 0; wordrefs[i].word != NULL; i++)
-        if (!strcmp(entry, wordrefs[i].word)) {
-            wordrefs[i].count++;
-            return;
-        }
-    wordrefs[3].count++;
-}
-
-int
-main(void)
-{
-    struct hash *hash;
-    FILE *words;
-    int reported, i;
-    char buffer[1024];
-    char *word;
-    char *test, *testing, *strange, *change, *foo, *bar;
-
-    struct wordref wordrefs[4] = {
-        { "test", 0 }, { "testing", 0 }, { "change", 0 }, { NULL, 0 }
-    };
-
-    test = xstrdup("test");
-    testing = xstrdup("testing");
-    strange = xstrdup("strange");
-    change = xstrdup("change");
-
-    puts("38");
-    hash = hash_create(4, hash_string, string_key, string_equal,
-                       string_delete);
-    ok(1, hash != NULL);
-    if (hash == NULL)
-        die("Unable to create hash, cannot continue");
-
-    ok(2, hash_insert(hash, "test", test));
-    ok(3, hash_collisions(hash) == 0);
-    ok(4, hash_expansions(hash) == 0);
-    ok(5, hash_searches(hash) == 1);
-    ok(6, hash_count(hash) == 1);
-    word = hash_lookup(hash, "test");
-    ok(7, word != NULL && !strcmp("test", word));
-    ok(8, hash_delete(hash, "test"));
-    test = xstrdup("test");
-    ok(9, hash_lookup(hash, "test") == NULL);
-    ok(10, !hash_delete(hash, "test"));
-    ok(11, !hash_replace(hash, "test", testing));
-    ok(12, hash_count(hash) == 0);
-    ok(13, hash_insert(hash, "test", test));
-    ok(14, hash_insert(hash, "testing", testing));
-    ok(15, hash_insert(hash, "strange", strange));
-    ok(16, hash_expansions(hash) == 0);
-    ok(17, hash_insert(hash, "change", change));
-    ok(18, hash_expansions(hash) == 1);
-    ok(19, hash_count(hash) == 4);
-    word = hash_lookup(hash, "testing");
-    ok(20, word != NULL && !strcmp("testing", word));
-    word = hash_lookup(hash, "strange");
-    ok(21, word != NULL && !strcmp("strange", word));
-    ok(22, hash_lookup(hash, "thingie") == NULL);
-    ok(23, !hash_delete(hash, "thingie"));
-    ok(24, hash_delete(hash, "strange"));
-    ok(25, hash_lookup(hash, "strange") == NULL);
-    ok(26, hash_count(hash) == 3);
-
-    hash_traverse(hash, string_traverse, &wordrefs[0]);
-    reported = 0;
-    for (i = 0; wordrefs[i].word != NULL; i++)
-        if (wordrefs[i].count != 1 && !reported) {
-            printf("not ");
-            reported = 1;
-        }
-    puts("ok 27");
-    ok(28, wordrefs[3].count == 0);
-
-    hash_free(hash);
-
-    /* Test hash creation with an odd size.  This previously could result
-       in the wrong table size being allocated. */
-    test = xstrdup("test");
-    testing = xstrdup("testing");
-    strange = xstrdup("strange");
-    change = xstrdup("change");
-    foo = xstrdup("foo");
-    bar = xstrdup("bar");
-    hash = hash_create(5, hash_string, string_key, string_equal,
-                       string_delete);
-    ok(29, hash != NULL);
-    if (hash == NULL)
-        die("Unable to create hash, cannot continue");
-    ok(30, hash_insert(hash, "test", test));
-    ok(31, hash_insert(hash, "testing", testing));
-    ok(32, hash_insert(hash, "strange", strange));
-    ok(33, hash_insert(hash, "change", change));
-    ok(34, hash_insert(hash, "foo", foo));
-    ok(35, hash_insert(hash, "bar", bar));
-    ok(36, hash_count(hash) == 6);
-    hash_free(hash);
-
-    words = fopen("/usr/dict/words", "r");
-    if (words == NULL)
-        words = fopen("/usr/share/dict/words", "r");
-    if (words == NULL) {
-        puts("ok 37 # skip\nok 38 # skip");
-        exit(0);
-    }
-
-    hash = hash_create(4, hash_string, string_key, string_equal,
-                       string_delete);
-    reported = 0;
-    if (hash == NULL)
-        printf("not ");
-    else {
-        while (fgets(buffer, sizeof(buffer), words)) {
-            buffer[strlen(buffer) - 1] = '\0';
-            word = xstrdup(buffer);
-            if (!hash_insert(hash, word, word)) {
-                if (!reported)
-                    printf("not ");
-                reported = 1;
-            }
-        }
-    }
-    puts("ok 37");
-
-    if (fseek(words, 0, SEEK_SET) < 0)
-        sysdie("Unable to rewind words file");
-    reported = 0;
-    if (hash == NULL)
-        printf("not ");
-    else {
-        while (fgets(buffer, sizeof(buffer), words)) {
-            buffer[strlen(buffer) - 1] = '\0';
-            word = hash_lookup(hash, buffer);
-            if (!word || strcmp(word, buffer) != 0) {
-                if (!reported)
-                    printf("not ");
-                reported = 1;
-            }
-        }
-    }
-    puts("ok 38");
-
-    hash_free(hash);
-
-    return 0;
-}
diff --git a/tests/lib/hstrerror-t.c b/tests/lib/hstrerror-t.c
deleted file mode 100644 (file)
index 64163a4..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $Id: hstrerror-t.c 5060 2001-12-12 09:20:10Z rra $ */
-/* hstrerror test suite. */
-
-#include "config.h"
-#include <netdb.h>
-#include <stdio.h>
-
-#include "libtest.h"
-
-const char *test_hstrerror(int);
-
-static void
-test_error(int n, const char *expected, int error)
-{
-    ok_string(n, expected, test_hstrerror(error));
-}
-
-int
-main(void)
-{
-    puts("7");
-
-    test_error(1, "Internal resolver error", -1);
-    test_error(2, "No resolver error", 0);
-    test_error(3, "No address associated with name", NO_ADDRESS);
-    test_error(4, "Resolver error 777777", 777777);
-    test_error(5, "Resolver error -99999", -99999);
-    test_error(6, "", 1000000);
-    test_error(7, "", -100000);
-
-    return 0;
-}
diff --git a/tests/lib/inet_aton-t.c b/tests/lib/inet_aton-t.c
deleted file mode 100644 (file)
index 59b0e75..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $Id: inet_aton-t.c 5061 2001-12-12 09:21:17Z rra $ */
-/* inet_aton test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <netinet/in.h>
-
-int test_inet_aton(const char *, struct in_addr *);
-
-static void
-test_addr(int n, const char *string, unsigned long addr)
-{
-    bool success, okay;
-    struct in_addr in;
-
-    success = test_inet_aton(string, &in);
-    okay = (success && in.s_addr == htonl(addr));
-    
-    printf("%sok %d\n", okay ? "" : "not ", n);
-    if (!okay && !success) printf("  success: %d\n", success);
-    if (!okay && in.s_addr != htonl(addr))
-        printf("  want: %lx\n   saw: %lx\n", (unsigned long) htonl(addr),
-               (unsigned long) in.s_addr);
-}
-
-static void
-test_fail(int n, const char *string)
-{
-    struct in_addr in;
-    int success;
-
-    in.s_addr = htonl(0x01020304UL);
-    success = test_inet_aton(string, &in);
-    success = (success == 0 && in.s_addr == htonl(0x01020304UL));
-    printf("%sok %d\n", success ? "" : "not ", n);
-}
-
-int
-main(void)
-{
-    puts("46");
-
-    test_addr( 1,             "0.0.0.0", 0);
-    test_addr( 2,      "127.0.0.000000", 0x7f000000UL);
-    test_addr( 3,     "255.255.255.255", 0xffffffffUL);
-    test_addr( 4,     "172.200.232.199", 0xacc8e8c7UL);
-    test_addr( 5,             "1.2.3.4", 0x01020304UL);
-
-    test_addr( 6,     "0x0.0x0.0x0.0x0", 0);
-    test_addr( 7, "0x7f.0x000.0x0.0x00", 0x7f000000UL);
-    test_addr( 8, "0xff.0xFf.0xFF.0xff", 0xffffffffUL);
-    test_addr( 9, "0xAC.0xc8.0xe8.0xC7", 0xacc8e8c7UL);
-    test_addr(10, "0xAa.0xbB.0xCc.0xdD", 0xaabbccddUL);
-    test_addr(11, "0xEe.0xfF.0.0x00000", 0xeeff0000UL);
-    test_addr(12, "0x1.0x2.0x00003.0x4", 0x01020304UL);
-
-    test_addr(13,    "000000.00.000.00", 0);
-    test_addr(14,              "0177.0", 0x7f000000UL);
-    test_addr(15, "0377.0377.0377.0377", 0xffffffffUL);
-    test_addr(16, "0254.0310.0350.0307", 0xacc8e8c7UL);
-    test_addr(17, "00001.02.3.00000004", 0x01020304UL);
-
-    test_addr(18,            "16909060", 0x01020304UL);
-    test_addr(19,       "172.062164307", 0xacc8e8c7UL);
-    test_addr(20,     "172.0xc8.0xe8c7", 0xacc8e8c7UL);
-    test_addr(21,               "127.1", 0x7f000001UL);
-    test_addr(22,          "0xffffffff", 0xffffffffUL);
-    test_addr(23,        "127.0xffffff", 0x7fffffffUL);
-    test_addr(24,      "127.127.0xffff", 0x7f7fffffUL);
-
-    test_fail(25,                  "");
-    test_fail(26,      "Donald Duck!");
-    test_fail(27,        "a127.0.0.1");
-    test_fail(28,          "aaaabbbb");
-    test_fail(29,       "0x100000000");
-    test_fail(30,       "0xfffffffff");
-    test_fail(31,     "127.0xfffffff");
-    test_fail(32,     "127.376926742");
-    test_fail(33,  "127.127.01452466");
-    test_fail(34, "127.127.127.0x100");
-    test_fail(35,             "256.0");
-    test_fail(36,  "127.0378.127.127");
-    test_fail(37, "127.127.0x100.127");
-    test_fail(38,         "127.0.o.1");
-    test_fail(39,  "127.127.127.127v");
-    test_fail(40,    "ef.127.127.127");
-    test_fail(41,  "0128.127.127.127");
-    test_fail(42,          "0xeg.127");
-    test_fail(43,          ".127.127");
-    test_fail(44,          "127.127.");
-    test_fail(45,          "127..127");
-    test_fail(46,       "de.ad.be.ef");
-
-    return 0;
-}
diff --git a/tests/lib/inet_ntoa-t.c b/tests/lib/inet_ntoa-t.c
deleted file mode 100644 (file)
index 46aee06..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $Id: inet_ntoa-t.c 5061 2001-12-12 09:21:17Z rra $ */
-/* inet_ntoa test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <netinet/in.h>
-
-#include "libtest.h"
-
-const char *test_inet_ntoa(const struct in_addr);
-
-static void
-test_addr(int n, const char *expected, unsigned long addr)
-{
-    struct in_addr in;
-
-    in.s_addr = htonl(addr);
-    ok_string(n, expected, test_inet_ntoa(in));
-}
-
-int
-main(void)
-{
-    puts("5");
-
-    test_addr(1,         "0.0.0.0", 0x0);
-    test_addr(2,       "127.0.0.0", 0x7f000000UL);
-    test_addr(3, "255.255.255.255", 0xffffffffUL);
-    test_addr(4, "172.200.232.199", 0xacc8e8c7UL);
-    test_addr(5,         "1.2.3.4", 0x01020304UL);
-
-    return 0;
-}
diff --git a/tests/lib/innconf-t.c b/tests/lib/innconf-t.c
deleted file mode 100644 (file)
index 0442901..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id: innconf-t.c 7748 2008-04-06 13:49:56Z iulius $ */
-/* innconf test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libtest.h"
-
-static const char grep[] =
-"egrep 'mta|organization|ovmethod|hismethod|path|pgpverify'\
- ../../samples/inn.conf > config/tmp";
-
-int
-main(void)
-{
-    struct innconf *standard;
-    FILE *config;
-
-    if (access("config/valid", F_OK) < 0)
-        if (access("lib/config/valid", F_OK) == 0)
-            chdir("lib");
-
-    puts("9");
-
-    ok(1, innconf_read("../../samples/inn.conf"));
-    standard = innconf;
-    innconf = NULL;
-    if (system(grep) != 0)
-        die("Unable to create stripped configuration file");
-    ok(2, innconf_read("config/tmp"));
-    unlink("config/tmp");
-    ok(3, innconf_compare(standard, innconf));
-    innconf_free(standard);
-    innconf_free(innconf);
-    innconf = NULL;
-    ok(4, true);
-
-    /* Checking inn.conf. */
-    errors_capture();
-    if (system(grep) != 0)
-        die("Unable to create stripped configuration file");
-    ok(5, innconf_check("config/tmp"));
-    ok(6, errors == NULL);
-    innconf_free(innconf);
-    innconf = NULL;
-    config = fopen("config/tmp", "a");
-    if (config == NULL)
-        sysdie("Unable to open stripped configuration file for append");
-    fputs("foo: bar\n", config);
-    fclose(config);
-    ok(7, !innconf_check("config/tmp"));
-    unlink("config/tmp");
-    ok_string(8, "config/tmp:26: unknown parameter foo\n", errors);
-    errors_uncapture();
-    free(errors);
-    errors = NULL;
-    innconf_free(innconf);
-    innconf = NULL;
-    ok(9, true);
-
-    return 0;
-}
diff --git a/tests/lib/list-t.c b/tests/lib/list-t.c
deleted file mode 100644 (file)
index 5ad4d14..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $Id: list-t.c 6294 2003-04-15 03:43:45Z rra $ */
-/* Test suite for list routines. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "inn/list.h"
-#include "libinn.h"
-#include "libtest.h"
-
-int
-main(void)
-{
-    struct list list;
-    struct node a, b, c;
-
-    puts("28");
-
-    list_new(&list);
-    ok(1, list_isempty(&list));
-
-    ok(2, list_addhead(&list, &a) == &a);
-    ok(3, !list_isempty(&list));
-    ok(4, list_head(&list) == &a);
-    ok(5, list_tail(&list) == &a);
-    ok(6, list_remhead(&list) == &a);
-    ok(7, list_isempty(&list));
-
-    ok(8, list_addhead(&list, &a) == &a);
-    ok(9, list_remtail(&list) == &a);
-    ok(10, list_isempty(&list));
-
-    ok(11, list_addtail(&list, &a) == &a);
-    ok(12, !list_isempty(&list));
-    ok(13, list_head(&list) == &a);
-    ok(14, list_tail(&list) == &a);
-    ok(15, list_remhead(&list) == &a);
-    ok(16, list_isempty(&list));
-
-    list_addtail(&list, &a);
-    ok(17, list_remtail(&list) == &a);
-    ok(18, list_isempty(&list));
-
-    list_addhead(&list, &a);
-    ok(19, list_remove(&a) == &a);
-    ok(20, list_isempty(&list));
-
-    list_addtail(&list, &a);
-    list_addtail(&list, &b);
-    list_insert(&list, &c, &a);
-    ok(21, list_succ(&c) == &b);
-    ok(22, list_pred(&c) == &a);
-    list_remove(&c);
-    list_insert(&list, &c, &b);
-    ok(23, list_succ(&c) == NULL);
-    ok(24, list_pred(&c) == &b);
-    list_remove(&c);
-    list_insert(&list, &c, NULL);
-    ok(25, list_succ(&c) == &a);
-    ok(26, list_pred(&c) == NULL);
-    list_remove(&c);
-    ok(27, list_head(&list) == &a);
-    ok(28, list_tail(&list) == &b);
-
-    return 0;
-}
diff --git a/tests/lib/md5-t.c b/tests/lib/md5-t.c
deleted file mode 100644 (file)
index 0a411be..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* $Id: md5-t.c 6128 2003-01-18 22:26:49Z rra $ */
-/* MD5 hashing test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include "inn/md5.h"
-#include "libinn.h"
-#include "libtest.h"
-
-/* Used to initialize strings of unsigned characters. */
-#define U       (const unsigned char *)
-
-/* An unsigned char version of strlen. */
-#define ustrlen(s)      strlen((const char *) s)
-
-/* Used for converting digests to hex to make them easier to deal with. */
-static const char hex[] = "0123456789abcdef";
-
-/* A set of data strings and resulting digests to check.  It's not easy to
-   get nulls into this data structure, so data containing nulls should be
-   checked separately. */
-static const unsigned char * const testdata[] = {
-    /* First five tests of the MD5 test suite from RFC 1321. */
-    U"",
-    U"a",
-    U"abc",
-    U"message digest",
-    U"abcdefghijklmnopqrstuvwxyz",
-
-    /* Three real message IDs to ensure compatibility with old INN versions;
-       the corresponding MD5 hashes were taken directly out of the history
-       file of a server running INN 2.3. */
-    U"<J3Ds5.931$Vg6.7556@news01.chello.no>",
-    U"<sr5v7ooea6e17@corp.supernews.com>",
-    U"<cancel.Y2Ds5.26391$oH5.540535@news-east.usenetserver.com>",
-
-    /* Other random stuff, including high-bit characters. */
-    U"example.test",
-    U"||",
-    U"|||",
-    U"\375\277\277\277\277\276",
-    U"\377\277\277\277\277\277"
-};
-
-/* The hashes corresonding to the above data. */
-static const char * const testhash[] = {
-    "d41d8cd98f00b204e9800998ecf8427e",
-    "0cc175b9c0f1b6a831c399e269772661",
-    "900150983cd24fb0d6963f7d28e17f72",
-    "f96b697d7cb7938d525a2f31aaf161d0",
-    "c3fcd3d76192e4007dfb496cca67e13b",
-    "c4a70fb19af37bed6b7c77f1e1187f00",
-    "7f70531c7027c20b0ddba0a649cf8691",
-    "9d9f0423f38b731c9bf69607cea6be76",
-    "09952be409a7d6464cd7661beeeb966e",
-    "7d010443693eec253a121e2aa2ba177c",
-    "2edf2958166561c5c08cd228e53bbcdc",
-    "c18293a6fe0a09720e841c8ebc697b97",
-    "ce23eb027c63215b999b9f86d6a4f9cb"
-};
-
-static void
-digest2hex(const unsigned char *digest, char *result)
-{
-    const unsigned char *p;
-    unsigned int i;
-
-    for (p = digest, i = 0; i < 32; i += 2, p++) {
-        result[i] = hex[(*p & 0xf0) >> 4];
-        result[i + 1] = hex[*p & 0x0f];
-    }
-    result[32] = '\0';
-}
-
-static void
-test_md5(int n, const char *expected, const unsigned char *data,
-         size_t length)
-{
-    unsigned char digest[16];
-    char hexdigest[33];
-
-    md5_hash(data, length, digest);
-    digest2hex(digest, hexdigest);
-    ok_string(n, expected, hexdigest);
-}
-
-int
-main(void)
-{
-    unsigned int i;
-    int j, n;
-    unsigned char *data;
-    struct md5_context context;
-    char hexdigest[33];
-
-    printf("%d\n", 12 + ARRAY_SIZE(testdata));
-
-    test_md5(1, "93b885adfe0da089cdf634904fd59f71", U"\0", 1);
-    test_md5(2, "e94a053c3fbfcfb22b4debaa11af7718", U"\0ab\n", 4);
-
-    data = xmalloc(64 * 1024);
-    memset(data, 0, 64 * 1024);
-    test_md5(3, "fcd6bcb56c1689fcef28b57c22475bad", data, 64 * 1024);
-    memset(data, 1, 32 * 1024);
-    test_md5(4, "3d8897b14254c9f86fbad3fe22f62edd", data, 64 * 1024);
-    test_md5(5, "25364962aa23b187942a24ae736c4e8c", data, 65000);
-    test_md5(6, "f9816b5d5363d15f14bb98d548309dcc", data, 55);
-    test_md5(7, "5e99dfddfb51c18cfc55911dee24ae7b", data, 56);
-    test_md5(8, "0871ffa021e2bc4da87eb93ac22d293c", data, 63);
-    test_md5(9, "784d68ba9112308689114a6816c628ce", data, 64);
-
-    /* Check the individual functions. */
-    md5_init(&context);
-    md5_update(&context, data, 32 * 1024);
-    md5_update(&context, data + 32 * 1024, 32 * 1024 - 42);
-    md5_update(&context, data + 64 * 1024 - 42, 42);
-    md5_final(&context);
-    digest2hex(context.digest, hexdigest);
-    ok_string(10, "3d8897b14254c9f86fbad3fe22f62edd", hexdigest);
-
-    /* Part of the MD5 test suite from RFC 1321. */
-    for (i = 0, n = 'A'; n <= 'Z'; i++, n++)
-        data[i] = n;
-    for (i = 26, n = 'a'; n <= 'z'; i++, n++)
-        data[i] = n;
-    for (i = 52, n = '0'; n <= '9'; i++, n++)
-        data[i] = n;
-    test_md5(11, "d174ab98d277d9f5a5611c2c9f419d9f", data, 62);
-    for (i = 0, j = 0; j < 8; j++) {
-        for (n = '1'; n <= '9'; i++, n++)
-            data[i] = n;
-        data[i++] = '0';
-    }
-    test_md5(12, "57edf4a22be3c955ac49da2e2107b67a", data, 80);
-
-    n = 13;
-    for (i = 0; i < ARRAY_SIZE(testdata); i++)
-        test_md5(n++, testhash[i], testdata[i], ustrlen(testdata[i]));
-
-    return 0;
-}
diff --git a/tests/lib/memcmp-t.c b/tests/lib/memcmp-t.c
deleted file mode 100644 (file)
index 2b59789..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id: memcmp-t.c 5054 2001-12-12 09:15:24Z rra $ */
-/* memcmp test suite. */
-
-#include "config.h"
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "libtest.h"
-
-int test_memcmp(const void *, const void *, size_t);
-
-int
-main(void)
-{
-    puts("15");
-
-    ok( 1, test_memcmp("",             "",             0) == 0);
-    ok( 2, test_memcmp("",             "",             1) == 0);
-    ok( 3, test_memcmp("alpha",        "alpha",        6) == 0);
-    ok( 4, test_memcmp("alpha",        "beta",         5)  < 0);
-    ok( 5, test_memcmp("beta",         "alpha",        5)  > 0);
-    ok( 6, test_memcmp("alpha",        "apple",        1) == 0);
-    ok( 7, test_memcmp("alpha",        "apple",        2)  < 0);
-    ok( 8, test_memcmp("\0v",          "\0w",          2)  < 0);
-    ok( 9, test_memcmp("\200\201\202", "\200\201\202", 4) == 0);
-    ok(10, test_memcmp("\200\201\202", "\200\201\203", 4)  < 0);
-    ok(11, test_memcmp("\200\201\203", "\200\201\202", 4)  > 0);
-    ok(12, test_memcmp("al\0po",       "al\0pha",      6)  > 0);
-    ok(13, test_memcmp("\100",         "\201",         1)  < 0);
-    ok(14, test_memcmp("\200",         "\201",         1)  < 0);
-    ok(15, test_memcmp("a",            "b",            0) == 0);
-
-    return 0;
-}
diff --git a/tests/lib/messages-t.c b/tests/lib/messages-t.c
deleted file mode 100644 (file)
index 2da71d2..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/* $Id: messages-t.c 5638 2002-08-23 22:52:53Z rra $ */
-/* Test suite for error handling routines. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-#define END     (char *) 0
-
-/* Test function type. */
-typedef void (*test_function_t)(void);
-
-/* Fork and execute the provided function, connecting stdout and stderr to a
-   pipe.  Captures the output into the provided buffer and returns the exit
-   status as a waitpid status value. */
-static int
-run_test(test_function_t function, char *buf, size_t buflen)
-{
-    int fds[2];
-    pid_t child;
-    ssize_t count, status;
-
-    /* Flush stdout before we start to avoid odd forking issues. */
-    fflush(stdout);
-
-    /* Set up the pipe and call the function, collecting its output. */
-    if (pipe(fds) == -1)
-        sysdie("can't create pipe");
-    child = fork();
-    if (child == (pid_t) -1) {
-        sysdie("can't fork");
-    } else if (child == 0) {
-        /* In child.  Set up our stdout and stderr. */
-        close(fds[0]);
-        if (dup2(fds[1], 1) == -1)
-            _exit(255);
-        if (dup2(fds[1], 2) == -1)
-            _exit(255);
-
-        /* Now, run the function and exit successfully if it returns. */
-        (*function)();
-        fflush(stdout);
-        _exit(0);
-    } else {
-        /* In the parent; close the extra file descriptor, read the output
-           if any, and then collect the exit status. */
-        close(fds[1]);
-        count = 0;
-        do {
-            status = read(fds[0], buf + count, buflen - count - 1);
-            if (status > 0)
-                count += status;
-        } while (status > 0);
-        buf[count < 0 ? 0 : count] = '\0';
-        if (waitpid(child, &status, 0) == (pid_t) -1)
-            sysdie("waitpid failed");
-    }
-    return status;
-}
-
-/* Test functions. */
-static void test1(void) { warn("warning"); }
-static void test2(void) { die("fatal"); }
-static void test3(void) { errno = EPERM; syswarn("permissions"); }
-static void test4(void) { errno = EACCES; sysdie("fatal access"); }
-static void test5(void) {
-    message_program_name = "test5";
-    warn("warning");
-}
-static void test6(void) {
-    message_program_name = "test6";
-    die("fatal");
-}
-static void test7(void) {
-    message_program_name = "test7";
-    errno = EPERM;
-    syswarn("perms %d", 7);
-}
-static void test8(void) {
-    message_program_name = "test8";
-    errno = EACCES;
-    sysdie("%st%s", "fa", "al");
-}
-
-static int return10(void) { return 10; }
-
-static void test9(void) {
-    message_fatal_cleanup = return10;
-    die("fatal");
-}
-static void test10(void) {
-    message_program_name = 0;
-    message_fatal_cleanup = return10;
-    errno = EPERM;
-    sysdie("fatal perm");
-}
-static void test11(void) {
-    message_program_name = "test11";
-    message_fatal_cleanup = return10;
-    errno = EPERM;
-    fputs("1st ", stdout);
-    sysdie("fatal");
-}
-
-static void log(int len, const char *format, va_list args, int error) {
-    fprintf(stderr, "%d %d ", len, error);
-    vfprintf(stderr, format, args);
-    fprintf(stderr, "\n");
-}
-
-static void test12(void) {
-    message_handlers_warn(1, log);
-    warn("warning");
-}
-static void test13(void) {
-    message_handlers_die(1, log);
-    die("fatal");
-}
-static void test14(void) {
-    message_handlers_warn(2, log, log);
-    errno = EPERM;
-    syswarn("warning");
-}
-static void test15(void) {
-    message_handlers_die(2, log, log);
-    message_fatal_cleanup = return10;
-    errno = EPERM;
-    sysdie("fatal");
-}
-static void test16(void) {
-    message_handlers_warn(2, message_log_stderr, log);
-    message_program_name = "test16";
-    errno = EPERM;
-    syswarn("warning");
-}
-static void test17(void) { notice("notice"); }
-static void test18(void) {
-    message_program_name = "test18";
-    notice("notice");
-}
-static void test19(void) { trace(TRACE_PROGRAM, "tracing"); }
-static void test20(void) { debug("debug"); }
-static void test21(void) {
-    message_handlers_notice(1, log);
-    notice("foo");
-}
-static void test22(void) {
-    message_handlers_trace(1, log);
-    message_trace_enable(TRACE_PROGRAM, true);
-    trace(TRACE_PROGRAM, "foo");
-    trace(TRACE_NETWORK, "bar");
-}
-static void test23(void) {
-    message_handlers_debug(1, message_log_stdout);
-    message_program_name = "test23";
-    debug("baz");
-}
-static void test24(void) {
-    message_handlers_die(0);
-    die("hi mom!");
-}
-static void test25(void) {
-    message_handlers_warn(0);
-    warn("this is a test");
-}
-static void test26(void) {
-    notice("first");
-    message_handlers_notice(0);
-    notice("second");
-    message_handlers_notice(1, message_log_stdout);
-    notice("third");
-}
-
-/* Given the test number, intended exit status and message, and the function
-   to run, print ok or not ok. */
-static void
-test_error(int n, int status, const char *output, test_function_t function)
-{
-    int real_status;
-    char buf[256];
-    int succeeded = 1;
-
-    real_status = run_test(function, buf, sizeof(buf));
-    if (!WIFEXITED(real_status) || status != WEXITSTATUS(real_status)) {
-        printf("  unexpected exit status %d\n", real_status);
-        succeeded = 0;
-    }
-    if (strcmp(output, buf)) {
-        printf("  unexpected output: %s", buf);
-        printf("    expected output: %s", output);
-        succeeded = 0;
-    }
-    printf("%sok %d\n", succeeded ? "" : "not ", n);
-}
-
-/* Given the test number, intended status, intended message sans the
-   appended strerror output, errno, and the function to run, print ok or not
-   ok. */
-static void
-test_strerror(int n, int status, const char *output, int error,
-              test_function_t function)
-{
-    char *full_output;
-
-    full_output = concat(output, ": ", strerror(error), "\n", END);
-    test_error(n, status, full_output, function);
-    free(full_output);
-}
-
-/* Run the tests. */
-int
-main(void)
-{
-    char buff[32];
-
-    puts("26");
-
-    test_error(1, 0, "warning\n", test1);
-    test_error(2, 1, "fatal\n", test2);
-    test_strerror(3, 0, "permissions", EPERM, test3);
-    test_strerror(4, 1, "fatal access", EACCES, test4);
-    test_error(5, 0, "test5: warning\n", test5);
-    test_error(6, 1, "test6: fatal\n", test6);
-    test_strerror(7, 0, "test7: perms 7", EPERM, test7);
-    test_strerror(8, 1, "test8: fatal", EACCES, test8);
-    test_error(9, 10, "fatal\n", test9);
-    test_strerror(10, 10, "fatal perm", EPERM, test10);
-    test_strerror(11, 10, "1st test11: fatal", EPERM, test11);
-    test_error(12, 0, "7 0 warning\n", test12);
-    test_error(13, 1, "5 0 fatal\n", test13);
-
-    sprintf(buff, "%d", EPERM);
-
-    test_error(14, 0,
-               concat("7 ", buff, " warning\n7 ", buff, " warning\n", END),
-               test14);
-    test_error(15, 10,
-               concat("5 ", buff, " fatal\n5 ", buff, " fatal\n", END),
-               test15);
-    test_error(16, 0,
-               concat("test16: warning: ", strerror(EPERM), "\n7 ", buff,
-                      " warning\n", END),
-               test16);
-
-    test_error(17, 0, "notice\n", test17);
-    test_error(18, 0, "test18: notice\n", test18);
-    test_error(19, 0, "", test19);
-    test_error(20, 0, "", test20);
-    test_error(21, 0, "3 0 foo\n", test21);
-    test_error(22, 0, "3 0 foo\n", test22);
-    test_error(23, 0, "test23: baz\n", test23);
-
-    /* Make sure that it's possible to turn off a message type entirely. */ 
-    test_error(24, 1, "", test24);
-    test_error(25, 0, "", test25);
-    test_error(26, 0, "first\nthird\n", test26);
-
-    return 0;
-}
diff --git a/tests/lib/mkstemp-t.c b/tests/lib/mkstemp-t.c
deleted file mode 100644 (file)
index 203d326..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $Id: mkstemp-t.c 5329 2002-03-17 07:39:14Z rra $ */
-/* mkstemp test suite */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "libtest.h"
-
-int test_mkstemp(char *template);
-
-int
-main(void)
-{
-    int fd;
-    char template[] = "tsXXXXXXX";
-    char tooshort[] = "XXXXX";
-    char bad1[] = "/foo/barXXXXX";
-    char bad2[] = "/foo/barXXXXXX.out";
-    char buffer[256];
-    struct stat st1, st2;
-    ssize_t length;
-
-    puts("20");
-
-    /* First, test a few error messages. */
-    errno = 0;
-    ok_int(1, -1, test_mkstemp(tooshort));
-    ok(2, errno == EINVAL);
-    ok_string(3, "XXXXX", tooshort);
-    errno = 0;
-    ok_int(4, -1, test_mkstemp(bad1));
-    ok(5, errno == EINVAL);
-    ok_string(6, "/foo/barXXXXX", bad1);
-    errno = 0;
-    ok_int(7, -1, test_mkstemp(bad2));
-    ok(8, errno == EINVAL);
-    ok_string(9, "/foo/barXXXXXX.out", bad2);
-    errno = 0;
-
-    /* Now try creating a real file. */
-    fd = test_mkstemp(template);
-    ok(10, fd >= 0);
-    ok(11, strcmp(template, "tsXXXXXXX") != 0);
-    ok(12, strncmp(template, "tsX", 3) == 0);
-    ok(13, access(template, F_OK) == 0);
-
-    /* Make sure that it's the same file as template refers to now. */
-    ok(14, stat(template, &st1) == 0);
-    ok(15, fstat(fd, &st2) == 0);
-    ok(16, st1.st_ino == st2.st_ino);
-    unlink(template);
-
-    /* Make sure the open mode is correct. */
-    length = strlen(template);
-    ok(17, write(fd, template, length) == length);
-    ok(18, lseek(fd, 0, SEEK_SET) == 0);
-    ok(19, read(fd, buffer, length) == length);
-    buffer[length] = '\0';
-    ok_string(20, template, buffer);
-    close(fd);
-
-    return 0;
-}
diff --git a/tests/lib/pread-t.c b/tests/lib/pread-t.c
deleted file mode 100644 (file)
index b977215..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $Id: pread-t.c 5379 2002-03-31 21:45:12Z rra $ */
-/* pread test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "libtest.h"
-
-ssize_t test_pread(int fd, void *buf, size_t nbyte, off_t offset);
-
-int
-main(void)
-{
-    unsigned char buf[256], result[256];
-    unsigned char c;
-    int i, fd;
-    ssize_t status;
-    off_t position;
-
-    for (c = 0, i = 0; i < 256; i++, c++)
-        buf[i] = c;
-    fd = open(".testout", O_RDWR | O_CREAT | O_TRUNC, 0644);
-    if (fd < 0)
-        sysdie("Can't create .testout");
-    if (unlink(".testout") < 0)
-        sysdie("Can't unlink .testout");
-    if (xwrite(fd, buf, 256) < 0)
-        sysdie("Can't write to .testout");
-    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
-        sysdie("Can't rewind .testout");
-    memset(result, 0, sizeof(result));
-
-    puts("6");
-
-    status = test_pread(fd, result, 128, 128);
-    ok(1, (status == 128) && !memcmp(result, buf + 128, 128));
-    status = read(fd, result, 64);
-    ok(2, (status == 64) && !memcmp(result, buf, 64));
-    status = test_pread(fd, result, 1, 256);
-    ok(3, status == 0);
-    status = test_pread(fd, result, 256, 0);
-    ok(4, (status == 256) && !memcmp(result, buf, 256));
-    position = lseek(fd, 0, SEEK_CUR);
-    ok(5, position == 64);
-
-    close(20);
-    errno = 0;
-    status = test_pread(20, result, 1, 0);
-    ok(6, (status == -1) && (errno == EBADF));
-
-    return 0;
-}
diff --git a/tests/lib/pwrite-t.c b/tests/lib/pwrite-t.c
deleted file mode 100644 (file)
index d329042..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id: pwrite-t.c 5379 2002-03-31 21:45:12Z rra $ */
-/* pwrite test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-#include "libtest.h"
-
-ssize_t test_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
-
-int
-main(void)
-{
-    unsigned char buf[256], result[256];
-    unsigned char c;
-    int i, fd;
-    ssize_t status;
-
-    for (c = 0, i = 0; i < 256; i++, c++)
-        buf[i] = c;
-    fd = open(".testout", O_RDWR | O_CREAT | O_TRUNC, 0644);
-    if (fd < 0)
-        sysdie("Can't create .testout");
-    if (unlink(".testout") < 0)
-        sysdie("Can't unlink .testout");
-    memset(result, 0, sizeof(result));
-
-    puts("6");
-
-    ok(1, test_pwrite(fd, buf + 129, 127, 129) == 127);
-    ok(2, write(fd, buf, 64) == 64);
-    ok(3, test_pwrite(fd, buf + 64, 65, 64) == 65);
-    status = read(fd, result, 64);
-    ok(4, (status == 64) && !memcmp(result, buf + 64, 64));
-        
-    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
-        sysdie("Can't rewind .testout");
-    status = read(fd, result, 256);
-    ok(5, (status == 256) && !memcmp(result, buf, 256));
-
-    close(20);
-    errno = 0;
-    status = test_pwrite(20, result, 1, 0);
-    ok(6, (status == -1) && (errno == EBADF));
-
-    return 0;
-}
diff --git a/tests/lib/qio-t.c b/tests/lib/qio-t.c
deleted file mode 100644 (file)
index b357fd5..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $Id: qio-t.c 6939 2004-06-10 22:04:58Z hkehoe $ */
-/* Test suite for the Quick I/O library */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-#include "inn/qio.h"
-#include "libinn.h"
-#include "libtest.h"
-
-static void
-output(int fd, const void *data, size_t size)
-{
-    if (xwrite(fd, data, size) < 0)
-        sysdie("Can't write to .testout");
-}
-
-int
-main(void)
-{
-    unsigned char data[256], line[256], out[256];
-    unsigned char c;
-    char *result;
-    int i, count, fd;
-    size_t size = 8192;
-    QIOSTATE *qio;
-    bool success;
-
-#if HAVE_ST_BLKSIZE
-    struct stat st;
-#endif
-
-    for (c = 1, i = 0; i < 255; i++, c++)
-        data[i] = c;
-    data[9] = ' ';
-    data[255] = '\255';
-    memcpy(line, data, 255);
-    line[255] = '\n';
-    memcpy(out, data, 255);
-    out[255] = '\0';
-    fd = open(".testout", O_RDWR | O_CREAT | O_TRUNC, 0644);
-    if (fd < 0) sysdie("Can't create .testout");
-
-#if HAVE_ST_BLKSIZE
-    /* Mostly duplicate the code from qio.c so that we can test with lines
-       exactly as large as the buffer. */
-    if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
-        size = st.st_blksize;
-        if (size > 4 * 8192)
-            size = 8192;
-       else
-           while(size < 8192)
-               size += st.st_blksize;
-    }
-#endif /* HAVE_ST_BLKSIZE */
-
-    /* Start with small, equally sized lines exactly equal to the buffer.
-       Then a line equal in size to the buffer, then a short line and
-       another line equal in size to the buffer, then a half line and lines
-       repeated to fill another buffer, then a line that's one character too
-       long. */
-    count = size / 256;
-    for (i = 0; i < count; i++)
-        output(fd, line, 256);
-    for (i = 0; i < count - 1; i++)
-        output(fd, data, 256);
-    output(fd, line, 256);
-    output(fd, "\n", 1);
-    for (i = 0; i < count - 1; i++)
-        output(fd, data, 256);
-    output(fd, line, 256);
-    output(fd, data, 127);
-    output(fd, "\n", 1);
-    for (i = 0; i < count; i++)
-        output(fd, line, 256);
-    for (i = 0; i < count; i++)
-        output(fd, data, 256);
-    output(fd, "\n", 1);
-    close(fd);
-
-    puts("30");
-
-    /* Now make sure we can read all that back correctly. */
-    qio = QIOopen(".testout");
-    ok(1, qio != NULL);
-    ok(2, !QIOerror(qio));
-    ok(3, QIOfileno(qio) > 0);
-    if (unlink(".testout") < 0)
-        sysdie("Can't unlink .testout");
-    for (success = true, i = 0; i < count; i++) {
-        result = QIOread(qio);
-        success = (success && !QIOerror(qio) && (QIOlength(qio) == 255)
-                   && !strcmp(result, (char *) out));
-    }
-    ok(4, success);
-    ok(5, QIOtell(qio) == (off_t) size);
-    result = QIOread(qio);
-    if (strlen(result) < size - 1) {
-        ok(6, false);
-    } else {
-        for (success = true, i = 0; i < count - 1; i++)
-            success = success && !memcmp(result + i * 256, data, 256);
-        success = success && !memcmp(result + i * 256, data, 255);
-        ok(6, success);
-    }
-    ok(7, QIOtell(qio) == (off_t) (2 * size));
-    result = QIOread(qio);
-    ok(8, !QIOerror(qio));
-    ok(9, QIOlength(qio) == 0);
-    ok(10, *result == 0);
-    result = QIOread(qio);
-    if (strlen(result) < size - 1) {
-        ok(11, false);
-    } else {
-        for (success = true, i = 0; i < count - 1; i++)
-            success = success && !memcmp(result + i * 256, data, 256);
-        success = success && !memcmp(result + i * 256, data, 255);
-        ok(11, success);
-    }
-    ok(12, QIOtell(qio) == (off_t) (3 * size + 1));
-    result = QIOread(qio);
-    ok(13, !QIOerror(qio));
-    ok(14, QIOlength(qio) == 127);
-    ok(15, strlen(result) == 127);
-    ok(16, !memcmp(result, data, 127));
-    for (success = true, i = 0; i < count; i++) {
-        result = QIOread(qio);
-        success = (success && !QIOerror(qio) && (QIOlength(qio) == 255)
-                   && !strcmp(result, (char *) out));
-    }
-    ok(17, success);
-    ok(18, QIOtell(qio) == (off_t) (4 * size + 129));
-    result = QIOread(qio);
-    ok(19, !result);
-    ok(20, QIOerror(qio));
-    ok(21, QIOtoolong(qio));
-    ok(22, QIOrewind(qio) == 0);
-    ok(23, QIOtell(qio) == 0);
-    result = QIOread(qio);
-    ok(24, !QIOerror(qio));
-    ok(25, QIOlength(qio) == 255);
-    ok(26, strlen(result) == 255);
-    ok(27, !strcmp(result, (char *) out));
-    ok(28, QIOtell(qio) == 256);
-    fd = QIOfileno(qio);
-    QIOclose(qio);
-    ok(29, close(fd) < 0);
-    ok(30, errno == EBADF);
-
-    return 0;
-}
diff --git a/tests/lib/setenv-t.c b/tests/lib/setenv-t.c
deleted file mode 100644 (file)
index a710fb7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: setenv-t.c 7492 2006-03-19 23:07:34Z eagle $ */
-/* setenv test suite. */
-
-#include "config.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "libtest.h"
-
-int test_setenv(const char *name, const char *value, int overwrite);
-
-static const char test_var[] = "SETENV_TEST";
-static const char test_value1[] = "Do not taunt Happy Fun Ball.";
-static const char test_value2[] = "Do not use Happy Fun Ball on concrete.";
-
-int
-main(void)
-{
-    char *value;
-    int status;
-
-    if (getenv(test_var))
-        die("%s already in the environment!", test_var);
-
-    puts("12");
-
-    ok(1, test_setenv(test_var, test_value1, 0) == 0);
-    ok_string(2, test_value1, getenv(test_var));
-    ok(3, test_setenv(test_var, test_value2, 0) == 0);
-    ok_string(4, test_value1, getenv(test_var));
-    ok(5, test_setenv(test_var, test_value2, 1) == 0);
-    ok_string(6, test_value2, getenv(test_var));
-    ok(7, test_setenv(test_var, "", 1) == 0);
-    ok_string(8, "", getenv(test_var));
-
-    /* We're run by a shell script wrapper that sets resource limits such
-       that we can allocate one string of this size but not two.  Note that
-       Linux doesn't support data limits, so skip if we get an unexpected
-       success here. */
-    value = xmalloc(100 * 1024);
-    memset(value, 'A', 100 * 1024 - 1);
-    value[100 * 1024 - 1] = 0;
-    ok(9, test_setenv(test_var, value, 0) == 0);
-    ok_string(10, "", getenv(test_var));
-    status = test_setenv(test_var, value, 1);
-    if (status == 0) {
-        puts("ok 11 # skip - no data limit support");
-        puts("ok 12 # skip - no data limit support");
-    } else {
-        ok(11, (status == -1) && (errno == ENOMEM));
-        ok_string(12, "", getenv(test_var));
-    }
-
-    return 0;
-}
diff --git a/tests/lib/setenv.t b/tests/lib/setenv.t
deleted file mode 100755 (executable)
index 64d445a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#! /bin/sh
-# $Id: setenv.t 7492 2006-03-19 23:07:34Z eagle $
-#
-# Wrapper around the setenv test suite to set a resource limit low enough
-# that two strings over 100KB can't both be allocated, allowing the memory
-# allocation failure code in setenv to be exercised.  Done with this
-# wrapper because ulimit is more easily portable than the corresponding C
-# code.
-
-# Find where the test suite is.
-setenv=setenv.tr
-for file in ./setenv.tr lib/setenv.tr tests/lib/setenv.tr ; do
-    [ -x $file ] && setenv=$file
-done
-
-ulimit -d 150
-exec $setenv
diff --git a/tests/lib/snprintf-t.c b/tests/lib/snprintf-t.c
deleted file mode 100644 (file)
index 6979e48..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* $Id: snprintf-t.c 7510 2006-04-02 18:31:51Z eagle $ */
-/* snprintf test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "libtest.h"
-
-int test_snprintf(char *str, size_t count, const char *fmt, ...);
-int test_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
-
-static const char string[] = "abcdefghijklmnopqrstuvwxyz0123456789";
-
-static const char *const fp_formats[] = {
-    "%-1.5f",   "%1.5f",    "%31.9f",   "%10.5f",   "% 10.5f",  "%+22.9f",
-    "%+4.9f",   "%01.3f",   "%3.1f",    "%3.2f",    "%.0f",     "%.1f",
-    "%f",       NULL
-};
-static const char *const int_formats[] = {
-    "%-1.5d",   "%1.5d",    "%31.9d",   "%5.5d",    "%10.5d",   "% 10.5d",
-    "%+22.30d", "%01.3d",   "%4d",      "%d",       "%ld",      NULL
-};
-static const char *const uint_formats[] = {
-    "%-1.5lu",  "%1.5lu",   "%31.9lu",  "%5.5lu",   "%10.5lu",  "% 10.5lu",
-    "%+6.30lu", "%01.3lu",  "%4lu",     "%lu",      "%4lx",     "%4lX",
-    "%01.3lx",  "%1lo",     NULL
-};
-static const char *const llong_formats[] = {
-    "%lld",     "%-1.5lld",  "%1.5lld",    "%123.9lld",  "%5.5lld",
-    "%10.5lld", "% 10.5lld", "%+22.33lld", "%01.3lld",   "%4lld",
-    NULL
-};
-static const char *const ullong_formats[] = {
-    "%llu",     "%-1.5llu",  "%1.5llu",    "%123.9llu",  "%5.5llu",
-    "%10.5llu", "% 10.5llu", "%+22.33llu", "%01.3llu",   "%4llu",
-    "%llx",     "%llo",      NULL
-};
-
-static const double fp_nums[] = {
-    -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996,
-    4.136, 0
-};
-static long int_nums[] = {
-    -1, 134, 91340, 341, 0203, 0
-};
-static unsigned long uint_nums[] = {
-    (unsigned long) -1, 134, 91340, 341, 0203, 0
-};
-static long long llong_nums[] = {
-    ~(long long) 0,                     /* All-1 bit pattern. */
-    (~(unsigned long long) 0) >> 1,     /* Largest signed long long. */
-    -150, 134, 91340, 341,
-    0
-};
-static unsigned long long ullong_nums[] = {
-    ~(unsigned long long) 0,            /* All-1 bit pattern. */
-    (~(unsigned long long) 0) >> 1,     /* Largest signed long long. */
-    134, 91340, 341,
-    0
-};
-
-static void
-test_format(int n, bool truncate, const char *expected, int count,
-            const char *format, ...)
-{
-    char buf[128];
-    int result;
-    va_list args;
-
-    va_start(args, format);
-    result = test_vsnprintf(buf, truncate ? 32 : sizeof(buf), format, args);
-    va_end(args);
-    if (!strcmp(buf, expected) && result == count) {
-        printf("ok %d\n", n);
-    } else {
-        printf("not ok %d\n", n);
-        printf("  format: %s\n", format);
-        if (strcmp(buf, expected))
-            printf("   saw: %s\n  want: %s\n", buf, expected);
-        if (result != count) printf("  %d != %d\n", result, count);
-    }
-}
-
-int
-main(void)
-{
-    int n, i, count;
-    unsigned int j;
-    long lcount;
-    char lgbuf[128];
-
-    printf("%d\n",
-           (25 + (ARRAY_SIZE(fp_formats) - 1) * ARRAY_SIZE(fp_nums)
-            + (ARRAY_SIZE(int_formats) - 1) * ARRAY_SIZE(int_nums)
-            + (ARRAY_SIZE(uint_formats) - 1) * ARRAY_SIZE(uint_nums)
-            + (ARRAY_SIZE(llong_formats) - 1) * ARRAY_SIZE(llong_nums)
-            + (ARRAY_SIZE(ullong_formats) - 1) * ARRAY_SIZE(ullong_nums)));
-
-    ok(1, test_snprintf(NULL, 0, "%s", "abcd") == 4);
-    ok(2, test_snprintf(NULL, 0, "%d", 20) == 2);
-    ok(3, test_snprintf(NULL, 0, "Test %.2s", "abcd") == 7);
-    ok(4, test_snprintf(NULL, 0, "%c", 'a') == 1);
-    ok(5, test_snprintf(NULL, 0, "") == 0);
-
-    test_format(6, true, "abcd", 4, "%s", "abcd");
-    test_format(7, true, "20", 2, "%d", 20);
-    test_format(8, true, "Test ab", 7, "Test %.2s", "abcd");
-    test_format(9, true, "a", 1, "%c", 'a');
-    test_format(10, true, "", 0, "");
-    test_format(11, true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%s",
-                string);
-    test_format(12, true, "abcdefghij", 10, "%.10s", string);
-    test_format(13, true, "  abcdefghij", 12, "%12.10s", string);
-    test_format(14, true, "    abcdefghijklmnopqrstuvwxyz0", 40, "%40s",
-                string);
-    test_format(15, true, "abcdefghij    ", 14, "%-14.10s", string);
-    test_format(16, true, "              abcdefghijklmnopq", 50, "%50s",
-                string);
-    test_format(17, true, "%abcd%", 6, "%%%0s%%", "abcd");
-    test_format(18, true, "", 0, "%.0s", string);
-    test_format(19, true, "abcdefghijklmnopqrstuvwxyz  444", 32, "%.26s  %d",
-                string, 4444);
-    test_format(20, true, "abcdefghijklmnopqrstuvwxyz  -2.", 32,
-                "%.26s  %.1f", string, -2.5);
-    test_format(21, true, "abcdefghij4444", 14, "%.10s%n%d", string, &count,
-                4444);
-    ok(22, count == 10);
-    test_format(23, true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%n%s%ln",
-                &count, string, &lcount);
-    ok(24, count == 0);
-    ok(25, lcount == 31);
-
-    n = 25;
-    for (i = 0; fp_formats[i] != NULL; i++)
-        for (j = 0; j < ARRAY_SIZE(fp_nums); j++) {
-            count = sprintf(lgbuf, fp_formats[i], fp_nums[j]);
-            test_format(++n, false, lgbuf, count, fp_formats[i], fp_nums[j]);
-        }
-    for (i = 0; int_formats[i] != NULL; i++)
-        for (j = 0; j < ARRAY_SIZE(int_nums); j++) {
-            count = sprintf(lgbuf, int_formats[i], int_nums[j]);
-            test_format(++n, false, lgbuf, count, int_formats[i],
-                        int_nums[j]);
-        }
-    for (i = 0; uint_formats[i] != NULL; i++)
-        for (j = 0; j < ARRAY_SIZE(uint_nums); j++) {
-            count = sprintf(lgbuf, uint_formats[i], uint_nums[j]);
-            test_format(++n, false, lgbuf, count, uint_formats[i],
-                        uint_nums[j]);
-        }
-    for (i = 0; llong_formats[i] != NULL; i++)
-        for (j = 0; j < ARRAY_SIZE(llong_nums); j++) {
-            count = sprintf(lgbuf, llong_formats[i], llong_nums[j]);
-            test_format(++n, false, lgbuf, count, llong_formats[i],
-                        llong_nums[j]);
-        }
-    for (i = 0; ullong_formats[i] != NULL; i++)
-        for (j = 0; j < ARRAY_SIZE(ullong_nums); j++) {
-            count = sprintf(lgbuf, ullong_formats[i], ullong_nums[j]);
-            test_format(++n, false, lgbuf, count, ullong_formats[i],
-                        ullong_nums[j]);
-        }
-
-    return 0;
-}
diff --git a/tests/lib/strerror-t.c b/tests/lib/strerror-t.c
deleted file mode 100644 (file)
index 014d055..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $Id: strerror-t.c 5559 2002-08-11 23:43:48Z rra $ */
-/* strerror test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-
-#include "libtest.h"
-
-const char *test_strerror(int);
-
-int
-main(void)
-{
-    puts("5");
-
-#if HAVE_STRERROR
-    ok_string(1, strerror(EACCES), test_strerror(EACCES));
-    ok_string(2, strerror(0), test_strerror(0));
-#else
-    ok(1, strerror(EACCES) != NULL);
-    ok(2, strerror(0) != NULL);
-#endif
-    ok_string(3, "Error code 77777", test_strerror(77777));
-    ok_string(4, "Error code -4000", test_strerror(-4000));
-    ok_string(5, "Error code -100000", test_strerror(-100000));
-
-    return 0;
-}
diff --git a/tests/lib/strlcat-t.c b/tests/lib/strlcat-t.c
deleted file mode 100644 (file)
index 454eb1a..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* $Id: strlcat-t.c 5656 2002-08-25 21:54:57Z rra $ */
-/* strlcat test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "libtest.h"
-
-size_t test_strlcat(char *, const char *, size_t);
-
-int
-main(void)
-{
-    char buffer[10] = "";
-
-    puts("27");
-
-    ok_int(1, 3, test_strlcat(buffer, "foo", sizeof(buffer)));
-    ok_string(2, "foo", buffer);
-    ok_int(3, 7, test_strlcat(buffer, " bar", sizeof(buffer)));
-    ok_string(4, "foo bar", buffer);
-    ok_int(5, 9, test_strlcat(buffer, "!!", sizeof(buffer)));
-    ok_string(6, "foo bar!!", buffer);
-    ok_int(7, 10, test_strlcat(buffer, "!", sizeof(buffer)));
-    ok_string(8, "foo bar!!", buffer);
-    ok(9, buffer[9] == '\0');
-    buffer[0] = '\0';
-    ok_int(10, 11, test_strlcat(buffer, "hello world", sizeof(buffer)));
-    ok_string(11, "hello wor", buffer);
-    ok(12, buffer[9] == '\0');
-    buffer[0] = '\0';
-    ok_int(13, 7, test_strlcat(buffer, "sausage", 5));
-    ok_string(14, "saus", buffer);
-    ok_int(15, 14, test_strlcat(buffer, "bacon eggs", sizeof(buffer)));
-    ok_string(16, "sausbacon", buffer);
-
-    /* Make sure that with a size of 0, the destination isn't changed. */
-    ok_int(17, 11, test_strlcat(buffer, "!!", 0));
-    ok_string(18, "sausbacon", buffer);
-
-    /* Now play with empty strings. */
-    ok_int(19, 9, test_strlcat(buffer, "", 0));
-    ok_string(20, "sausbacon", buffer);
-    buffer[0] = '\0';
-    ok_int(21, 0, test_strlcat(buffer, "", sizeof(buffer)));
-    ok_string(22, "", buffer);
-    ok_int(23, 3, test_strlcat(buffer, "foo", 2));
-    ok_string(24, "f", buffer);
-    ok(25, buffer[1] == '\0');
-    ok_int(26, 1, test_strlcat(buffer, "", sizeof(buffer)));
-    ok(27, buffer[1] == '\0');
-
-    return 0;
-}
diff --git a/tests/lib/strlcpy-t.c b/tests/lib/strlcpy-t.c
deleted file mode 100644 (file)
index 1d03a77..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $Id: strlcpy-t.c 5568 2002-08-12 02:06:44Z rra $ */
-/* strlcpy test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "libtest.h"
-
-size_t test_strlcpy(char *, const char *, size_t);
-
-int
-main(void)
-{
-    char buffer[10];
-
-    puts("23");
-
-    ok_int(1, 3, test_strlcpy(buffer, "foo", sizeof(buffer)));
-    ok_string(2, "foo", buffer);
-    ok_int(3, 9, test_strlcpy(buffer, "hello wor", sizeof(buffer)));
-    ok_string(4, "hello wor", buffer);
-    ok_int(5, 10, test_strlcpy(buffer, "world hell", sizeof(buffer)));
-    ok_string(6, "world hel", buffer);
-    ok(7, buffer[9] == '\0');
-    ok_int(8, 11, test_strlcpy(buffer, "hello world", sizeof(buffer)));
-    ok_string(9, "hello wor", buffer);
-    ok(10, buffer[9] == '\0');
-
-    /* Make sure that with a size of 0, the destination isn't changed. */
-    ok_int(11, 3, test_strlcpy(buffer, "foo", 0));
-    ok_string(12, "hello wor", buffer);
-
-    /* Now play with empty strings. */
-    ok_int(13, 0, test_strlcpy(buffer, "", 0));
-    ok_string(14, "hello wor", buffer);
-    ok_int(15, 0, test_strlcpy(buffer, "", sizeof(buffer)));
-    ok_string(16, "", buffer);
-    ok_int(17, 3, test_strlcpy(buffer, "foo", 2));
-    ok_string(18, "f", buffer);
-    ok(19, buffer[1] == '\0');
-    ok_int(20, 0, test_strlcpy(buffer, "", 1));
-    ok(21, buffer[0] == '\0');
-
-    /* Finally, check using strlcpy as strlen. */
-    ok_int(22, 3, test_strlcpy(NULL, "foo", 0));
-    ok_int(23, 11, test_strlcpy(NULL, "hello world", 0));
-
-    return 0;
-}
diff --git a/tests/lib/tst-t.c b/tests/lib/tst-t.c
deleted file mode 100644 (file)
index 76dcada..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $Id: tst-t.c 7262 2005-06-06 04:45:48Z eagle $ */
-/* Test suite for ternary search tries. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "inn/tst.h"
-#include "libinn.h"
-#include "libtest.h"
-
-/* Used for strings of unsigned characters. */
-#define U (const unsigned char *)
-
-/* An unsigned char version of strlen. */
-#define ustrlen(s) strlen((const char *) s)
-
-int
-main(void)
-{
-    struct tst *tst;
-    FILE *words;
-    unsigned char buffer[1024];
-    bool reported;
-    void *existing;
-    unsigned char *word;
-
-    char test[] = "test";
-    char t[] = "t";
-    char foo[] = "foo";
-    char testing[] = "testing";
-    char Strange[] = "Strange";
-    char change[] = "çhange";
-
-    puts("38");
-
-    tst = tst_init(2);
-    ok(1, tst != NULL);
-    ok(2, tst_insert(tst, U"test", test, 0, NULL) == TST_OK);
-    ok_string(3, "test", tst_search(tst, U"test"));
-    ok(4, tst_insert(tst, U"test", foo, 0, &existing) == TST_DUPLICATE_KEY);
-    ok_string(5, "test", existing);
-    ok(6, tst_insert(tst, U"test", foo, TST_REPLACE, &existing) == TST_OK);
-    ok_string(7, "test", existing);
-    ok_string(8, "foo", tst_search(tst, U"test"));
-    ok(9, tst_insert(tst, U"testing", testing, 0, NULL) == TST_OK);
-    ok(10, tst_insert(tst, U"t", t, 0, NULL) == TST_OK);
-    ok(11, tst_insert(tst, U"Strange", Strange, 0, NULL) == TST_OK);
-    ok(12, tst_insert(tst, U"çhange", change, 0, NULL) == TST_OK);
-    ok(13, tst_insert(tst, U"", foo, 0, NULL) == TST_NULL_KEY);
-    ok(14, tst_insert(tst, NULL, foo, 0, NULL) == TST_NULL_KEY);
-    ok_string(15, "testing", tst_search(tst, U"testing"));
-    ok_string(16, "t", tst_search(tst, U"t"));
-    ok_string(17, "Strange", tst_search(tst, U"Strange"));
-    ok_string(18, "çhange", tst_search(tst, U"çhange"));
-    ok_string(19, "foo", tst_search(tst, U"test"));
-    ok(20, tst_search(tst, U"") == NULL);
-    ok(21, tst_search(tst, U"Peter") == NULL);
-    ok(22, tst_search(tst, U"foo") == NULL);
-    ok(23, tst_search(tst, U"te") == NULL);
-    ok_string(24, "Strange", tst_delete(tst, U"Strange"));
-    ok(25, tst_search(tst, U"Strange") == NULL);
-    ok_string(26, "t", tst_delete(tst, U"t"));
-    ok(27, tst_search(tst, U"t") == NULL);
-    ok_string(28, "testing", tst_search(tst, U"testing"));
-    ok_string(29, "foo", tst_search(tst, U"test"));
-    ok_string(30, "testing", tst_delete(tst, U"testing"));
-    ok_string(31, "foo", tst_search(tst, U"test"));
-    ok_string(32, "çhange", tst_delete(tst, U"çhange"));
-    ok_string(33, "foo", tst_delete(tst, U"test"));
-    ok(34, tst_search(tst, NULL) == NULL);
-    ok(35, tst_delete(tst, NULL) == NULL);
-    tst_cleanup(tst);
-    ok(36, true);
-
-    words = fopen("/usr/dict/words", "r");
-    if (words == NULL)
-        words = fopen("/usr/share/dict/words", "r");
-    if (words == NULL) {
-        puts("ok 37 # skip\nok 38 # skip");
-        exit(0);
-    }
-
-    tst = tst_init(1000);
-    reported = false;
-    if (tst == NULL)
-        printf("not ");
-    else {
-        while (fgets((char *) buffer, sizeof(buffer), words)) {
-            buffer[ustrlen(buffer) - 1] = '\0';
-            if (buffer[0] == '\0')
-                continue;
-            word = (unsigned char *) xstrdup((char *) buffer);
-            if (tst_insert(tst, buffer, word, 0, NULL) != TST_OK) {
-                if (!reported)
-                    printf("not ");
-                reported = true;
-            }
-        }
-    }
-    puts("ok 37");
-
-    if (fseek(words, 0, SEEK_SET) < 0)
-        sysdie("Unable to rewind words file");
-    reported = false;
-    if (tst == NULL)
-        printf("not ");
-    else {
-        while (fgets((char *) buffer, sizeof(buffer), words)) {
-            buffer[ustrlen(buffer) - 1] = '\0';
-            if (buffer[0] == '\0')
-                continue;
-            word = tst_search(tst, buffer);
-            if (word == NULL || strcmp((char *) word, buffer) != 0) {
-                if (!reported)
-                    printf("not ");
-                reported = true;
-            }
-            word = tst_delete(tst, buffer);
-            if (word == NULL || strcmp((char *) word, buffer) != 0) {
-                if (!reported)
-                    printf("not ");
-                reported = true;
-            }
-            free(word);
-        }
-    }
-    tst_cleanup(tst);
-    puts("ok 38");
-
-    return 0;
-}
diff --git a/tests/lib/uwildmat-t.c b/tests/lib/uwildmat-t.c
deleted file mode 100644 (file)
index fdad296..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*  $Id: uwildmat-t.c 7262 2005-06-06 04:45:48Z eagle $
-**
-**  wildmat test suite.
-**
-**  As of March 11, 2001, this test suite achieves 100% coverage of the
-**  wildmat source code at that time.
-*/
-
-#include "clibrary.h"
-#include "libinn.h"
-
-static void
-test_r(int n, const char *text, const char *pattern, bool matches)
-{
-    bool matched;
-
-    matched = uwildmat(text, pattern);
-    printf("%sok %d\n", matched == matches ? "" : "not ", n);
-    if (matched != matches)
-        printf("  %s\n  %s\n  expected %d\n", text, pattern, matches);
-}
-
-static void
-test_p(int n, const char *text, const char *pattern, enum uwildmat matches)
-{
-    enum uwildmat matched;
-
-    matched = uwildmat_poison(text, pattern);
-    printf("%sok %d\n", matched == matches ? "" : "not ", n);
-    if (matched != matches)
-        printf("  %s\n  %s\n  expected %d got %d\n", text, pattern,
-               (int) matches, (int) matched);
-}
-
-static void
-test_s(int n, const char *text, const char *pattern, bool matches)
-{
-    bool matched;
-
-    matched = uwildmat_simple(text, pattern);
-    printf("%sok %d\n", matched == matches ? "" : "not ", n);
-    if (matched != matches)
-        printf("  %s\n  %s\n  expected %d\n", text, pattern, matches);
-}
-
-int
-main(void)
-{
-    puts("166");
-
-    /* Basic wildmat features. */
-    test_r(  1, "foo",            "foo",               true);
-    test_r(  2, "foo",            "bar",               false);
-    test_r(  3, "",               "",                  true);
-    test_r(  4, "foo",            "???",               true);
-    test_r(  5, "foo",            "??",                false);
-    test_r(  6, "foo",            "*",                 true);
-    test_r(  7, "foo",            "f*",                true);
-    test_r(  8, "foo",            "*f",                false);
-    test_r(  9, "foo",            "*foo*",             true);
-    test_r( 10, "foobar",         "*ob*a*r*",          true);
-    test_r( 11, "aaaaaaabababab", "*ab",               true);
-    test_r( 12, "foo*",           "foo\\*",            true);
-    test_r( 13, "foobar",         "foo\\*bar",         false);
-    test_r( 14, "\\",             "\\\\",              true);
-    test_r( 15, "ball",           "*[al]?",            true);
-    test_r( 16, "ten",            "[ten]",             false);
-    test_r( 17, "ten",            "**[^te]",           true);
-    test_r( 18, "ten",            "**[^ten]",          false);
-    test_r( 19, "ten",            "t[a-g]n",           true);
-    test_r( 20, "ten",            "t[^a-g]n",          false);
-    test_r( 21, "ton",            "t[^a-g]n",          true);
-    test_r( 22, "]",              "]",                 true);
-    test_r( 23, "a]b",            "a[]]b",             true);
-    test_r( 24, "a-b",            "a[]-]b",            true);
-    test_r( 25, "a]b",            "a[]-]b",            true);
-    test_r( 26, "aab",            "a[]-]b",            false);
-    test_r( 27, "aab",            "a[]a-]b",           true);
-
-    /* Multiple and negation. */
-    test_r( 28, "foo",            "!foo",              false);
-    test_r( 29, "foo",            "!bar",              false);
-    test_r( 30, "foo",            "*,!foo",            false);
-    test_r( 31, "foo",            "*,!bar",            true);
-    test_r( 32, "foo",            "foo,bar",           true);
-    test_r( 33, "bar",            "foo,bar",           true);
-    test_r( 34, "baz",            "foo,bar",           false);
-    test_r( 35, "baz",            "foo,ba?",           true);
-    test_r( 36, "",               "!",                 false);
-    test_r( 37, "foo",            "!",                 false);
-    test_r( 38, "a",              "a,!b,c",            true);
-    test_r( 39, "b",              "a,!b,c",            false);
-    test_r( 40, "c",              "a,!b,c",            true);
-    test_r( 41, "ab",             "a*,!ab",            false);
-    test_r( 42, "abc",            "a*,!ab",            true);
-    test_r( 43, "dabc",           "a*,!ab",            false);
-    test_r( 44, "abc",            "a*,!ab*,abc",       true);
-    test_r( 45, "",               ",",                 true);
-    test_r( 46, "a",              ",a",                true);
-    test_r( 47, "a",              "a,,,",              true);
-    test_r( 48, "b",              ",a",                false);
-    test_r( 49, "b",              "a,,,",              false);
-    test_r( 50, "a,b",            "a\\,b",             true);
-    test_r( 51, "a,b",            "a\\\\,b",           false);
-    test_r( 52, "a\\",            "a\\\\,b",           true);
-    test_r( 53, "a\\,b",          "a\\\\,b",           false);
-    test_r( 54, "a\\,b",          "a\\\\\\,b",         true);
-    test_r( 55, ",",              "\\,",               true);
-    test_r( 56, ",\\",            "\\,",               false);
-    test_r( 57, ",\\",            "\\,\\\\,",          true);
-    test_r( 58, "",               "\\,\\\\,",          true);
-    test_r( 59, "",               "\\,,!",             false);
-    test_r( 60, "",               "\\,!,",             true);
-
-    /* Various additional tests. */
-    test_r( 61, "acrt",           "a[c-c]st",          false);
-    test_r( 62, "]",              "[^]-]",             false);
-    test_r( 63, "a",              "[^]-]",             true);
-    test_r( 64, "",               "\\",                false);
-    test_r( 65, "\\",             "\\",                false);
-    test_r( 66, "foo",            "*,@foo",            true);
-    test_r( 67, "@foo",           "@foo",              true);
-    test_r( 68, "foo",            "@foo",              false);
-    test_r( 69, "[ab]",           "\\[ab]",            true);
-    test_r( 70, "?a?b",           "\\??\\?b",          true);
-    test_r( 71, "abc",            "\\a\\b\\c",         true);
-
-    /* Poison negation. */
-    test_p( 72, "abc",            "*",                 UWILDMAT_MATCH);
-    test_p( 73, "abc",            "def",               UWILDMAT_FAIL);
-    test_p( 74, "abc",            "*,!abc",            UWILDMAT_FAIL);
-    test_p( 75, "a",              "*,@a",              UWILDMAT_POISON);
-    test_p( 76, "ab",             "*,@a*,ab",          UWILDMAT_MATCH);
-    test_p( 77, "ab",             "*,@a**,!ab",        UWILDMAT_FAIL);
-    test_p( 78, "@ab",            "\\@ab",             UWILDMAT_MATCH);
-    test_p( 79, "@ab",            "@\\@ab",            UWILDMAT_POISON);
-
-    /* UTF-8 characters. */
-    test_r( 80, "S\303\256ne",    "S\303\256ne",       true);
-    test_r( 81, "S\303\256ne",    "S\303\257ne",       false);
-    test_r( 82, "S\303\256ne",    "S?ne",              true);
-    test_r( 83, "S\303\256ne",    "S*e",               true);
-    test_r( 84, "S\303\256ne",    "S[a-\330\200]ne",   true);
-    test_r( 85, "S\303\256ne",    "S[a-\300\256]ne",   false);
-    test_r( 86, "S\303\256ne",    "S[^\1-\177]ne",     true);
-    test_r( 87, "S\303\256ne",    "S[0\303\256$]ne",   true);
-    test_r( 88, "\2",             "[\1-\3]",           true);
-    test_r( 89, "\330\277",     "[\330\276-\331\200]", true);
-    test_r( 90, "\337\277", "[\337\276-\350\200\200]", true);
-    test_r( 91, "\357\277\277", "[\357\277\276-\364\200\200\200]", true);
-    test_r( 92, "\357\276\277", "[\357\277\276-\364\200\200\200]", false);
-    test_r( 93, "\367\277\277\277",
-                    "[\310\231-\372\200\200\200\200]", true);
-    test_r( 94, "\373\277\277\277\277",
-                      "[\1-\375\200\200\200\200\200]", true);
-    test_r( 95, "\375\200\200\200\200\200",
-                      "[\5-\375\200\200\200\200\200]", true);
-    test_r( 96, "\375\277\277\277\277\276",
-           "[\375\277\277\277\277\275-\375\277\277\277\277\277]", true);
-    test_r( 97, "b\357\277\277a", "b?a",               true);
-    test_r( 98, "b\367\277\277\277a", "b?a",           true);
-    test_r( 99, "b\373\277\277\277\277a", "b?a",       true);
-    test_r(100, "b\375\277\277\277\277\276a", "b?a",   true);
-    test_r(101, "\357\240\275S\313\212\375\206\203\245\260\211",
-                                               "????", true);
-    test_r(102, "S\303\256ne",    "S\\\303\256ne",     true);
-    test_r(103, "s", "[^\330\277-\375\277\277\277\277\277]", true);
-    test_r(104, "\367\277\277\277",
-               "[^\330\277-\375\277\277\277\277\277]", false);
-
-    /* Malformed UTF-8. */
-    test_r(105, "S\303\256ne",    "S?\256ne",          false);
-    test_r(106, "\303\303",       "?",                 false);
-    test_r(107, "\303\303",       "??",                true);
-    test_r(108, "\200",           "[\177-\201]",       true);
-    test_r(109, "abc\206d",       "*\206d",            true);
-    test_r(110, "\303\206",       "*\206",             false);
-    test_r(111, "\40",            "\240",              false);
-    test_r(112, "\323",           "[a-\377]",          true);
-    test_r(113, "\376\277\277\277\277\277", "?",       false);
-    test_r(114, "\376\277\277\277\277\277", "??????",  true);
-    test_r(115, "\377\277\277\277\277\277", "?",       false);
-    test_r(116, "\377\277\277\277\277\277", "??????",  true);
-    test_r(117, "\303\323\206",   "??",                true);
-    test_r(118, "\206",           "[\341\206f]",       true);
-    test_r(119, "f",              "[\341\206f]",       true);
-    test_r(120, "\207",           "[\341\206-\277]",   true);
-    test_r(121, "\207",           "[\341\206\206-\277]", false);
-    test_r(122, "\300",           "[\277-\341\206]",   true);
-    test_r(123, "\206",           "[\277-\341\206]",   true);
-    test_r(124, "\341\206",       "[\341\206-\277]?",  true);
-
-    /* Additional tests, including some malformed wildmats. */
-    test_r(125, "ab",             "a[]b",              false);
-    test_r(126, "a[]b",           "a[]b",              false);
-    test_r(127, "ab[",            "ab[",               false);
-    test_r(128, "ab",             "[^",                false);
-    test_r(129, "ab",             "[-",                false);
-    test_r(130, "-",              "[-]",               true);
-    test_r(131, "-",              "[a-",               false);
-    test_r(132, "-",              "[^a-",              false);
-    test_r(133, "-",              "[--A]",             true);
-    test_r(134, "5",              "[--A]",             true);
-    test_r(135, "\303\206",       "[--A]",             false);
-    test_r(136, " ",              "[ --]",             true);
-    test_r(137, "$",              "[ --]",             true);
-    test_r(138, "-",              "[ --]",             true);
-    test_r(139, "0",              "[ --]",             false);
-    test_r(140, "-",              "[---]",             true);
-    test_r(141, "-",              "[------]",          true);
-    test_r(142, "j",              "[a-e-n]",           false);
-    test_r(143, "a",              "[^------]",         true);
-    test_r(144, "[",              "[]-a]",             false);
-    test_r(145, "^",              "[]-a]",             true);
-    test_r(146, "^",              "[^]-a]",            false);
-    test_r(147, "[",              "[^]-a]",            true);
-    test_r(148, "^",              "[a^bc]",            true);
-    test_r(149, "-b]",            "[a-]b]",            true);
-    test_r(150, "\\]",            "[\\]]",             true);
-    test_r(151, "]",              "[\\-^]",            true);
-    test_r(152, "[",              "[\\-^]",            false);
-    test_r(153, "G",              "[A-\\]",            true);
-    test_r(154, "aaabbb",         "b*a",               false);
-    test_r(155, "aabcaa",         "*ba*",              false);
-    test_r(156, ",",              "[,]",               true);
-    test_r(157, ",",              "[\\,]",             true);
-    test_r(158, "\\",             "[\\,]",             true);
-    test_r(159, "-",              "[,-.]",             true);
-    test_r(160, "+",              "[,-.]",             false);
-    test_r(161, "-.]",            "[,-.]",             false);
-
-    /* Tests for the wildmat_simple interface. */
-    test_s(162, "ab,cd",          "ab,cd",             true);
-    test_s(163, "ab",             "ab,cd",             false);
-    test_s(164, "!aaabbb",        "!a*b*",             true);
-    test_s(165, "ccc",            "*,!a*",             false);
-    test_s(166, "foo",            "*",                 true);
-
-    return 0;
-}
diff --git a/tests/lib/vector-t.c b/tests/lib/vector-t.c
deleted file mode 100644 (file)
index 8e424c4..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* $Id: vector-t.c 5678 2002-08-28 23:21:32Z rra $ */
-/* vector test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/vector.h"
-#include "libinn.h"
-#include "libtest.h"
-
-int
-main(void)
-{
-    struct vector *vector;
-    struct cvector *cvector;
-    const char cstring[] = "This is a\ttest.  ";
-    const char tabs[] = "test\t\ting\t";
-    static const char nulls1[] = "This\0is\0a\0test.";
-    static const char nulls2[] = "This is a\t\0es\0.  ";
-    char empty[] = "";
-    char *string;
-    char *p;
-
-    puts("87");
-
-    vector = vector_new();
-    ok(1, vector != NULL);
-    vector_add(vector, cstring);
-    ok_int(2, 1, vector->count);
-    ok(3, vector->strings[0] != cstring);
-    vector_resize(vector, 4);
-    ok_int(4, 4, vector->allocated);
-    vector_add(vector, cstring);
-    vector_add(vector, cstring);
-    vector_add(vector, cstring);
-    ok_int(5, 4, vector->allocated);
-    ok_int(6, 4, vector->count);
-    ok(7, vector->strings[1] != vector->strings[2]);
-    ok(8, vector->strings[2] != vector->strings[3]);
-    ok(9, vector->strings[3] != vector->strings[0]);
-    ok(10, vector->strings[0] != cstring);
-    vector_clear(vector);
-    ok_int(11, 0, vector->count);
-    ok_int(12, 4, vector->allocated);
-    string = xstrdup(cstring);
-    vector_add(vector, cstring);
-    vector_add(vector, string);
-    ok_int(13, 2, vector->count);
-    ok(14, vector->strings[1] != string);
-    vector_resize(vector, 1);
-    ok_int(15, 1, vector->count);
-    ok(16, vector->strings[0] != cstring);
-    vector_free(vector);
-    free(string);
-
-    cvector = cvector_new();
-    ok(17, cvector != NULL);
-    cvector_add(cvector, cstring);
-    ok_int(18, 1, cvector->count);
-    ok(19, cvector->strings[0] == cstring);
-    cvector_resize(cvector, 4);
-    ok_int(20, 4, cvector->allocated);
-    cvector_add(cvector, cstring);
-    cvector_add(cvector, cstring);
-    cvector_add(cvector, cstring);
-    ok_int(21, 4, cvector->allocated);
-    ok_int(22, 4, cvector->count);
-    ok(23, cvector->strings[1] == cvector->strings[2]);
-    ok(24, cvector->strings[2] == cvector->strings[3]);
-    ok(25, cvector->strings[3] == cvector->strings[0]);
-    ok(26, cvector->strings[0] == cstring);
-    cvector_clear(cvector);
-    ok_int(27, 0, cvector->count);
-    ok_int(28, 4, cvector->allocated);
-    string = xstrdup(cstring);
-    cvector_add(cvector, cstring);
-    cvector_add(cvector, string);
-    ok_int(29, 2, cvector->count);
-    ok(30, cvector->strings[1] == string);
-    cvector_resize(cvector, 1);
-    ok_int(31, 1, cvector->count);
-    ok(32, cvector->strings[0] == cstring);
-    cvector_free(cvector);
-    free(string);
-
-    vector = vector_split_space("This is a\ttest.  ", NULL);
-    ok_int(33, 4, vector->count);
-    ok_int(34, 4, vector->allocated);
-    ok_string(35, "This", vector->strings[0]);
-    ok_string(36, "is", vector->strings[1]);
-    ok_string(37, "a", vector->strings[2]);
-    ok_string(38, "test.", vector->strings[3]);
-    vector_add(vector, cstring);
-    ok_string(39, cstring, vector->strings[4]);
-    ok(40, vector->strings[4] != cstring);
-    ok_int(41, 5, vector->allocated);
-    vector = vector_split(cstring, 't', vector);
-    ok_int(42, 3, vector->count);
-    ok_int(43, 5, vector->allocated);
-    ok_string(44, "This is a\t", vector->strings[0]);
-    ok_string(45, "es", vector->strings[1]);
-    ok_string(46, ".  ", vector->strings[2]);
-    ok(47, vector->strings[0] != cstring);
-    p = vector_join(vector, "fe");
-    ok_string(48, "This is a\tfeesfe.  ", p);
-    free(p);
-    vector_free(vector);
-
-    string = xstrdup(cstring);
-    cvector = cvector_split_space(string, NULL);
-    ok_int(49, 4, cvector->count);
-    ok_int(50, 4, cvector->allocated);
-    ok_string(51, "This", cvector->strings[0]);
-    ok_string(52, "is", cvector->strings[1]);
-    ok_string(53, "a", cvector->strings[2]);
-    ok_string(54, "test.", cvector->strings[3]);
-    ok(55, memcmp(string, nulls1, 16) == 0);
-    cvector_add(cvector, cstring);
-    ok(56, cvector->strings[4] == cstring);
-    ok_int(57, 5, cvector->allocated);
-    free(string);
-    string = xstrdup(cstring);
-    cvector = cvector_split(string, 't', cvector);
-    ok_int(58, 3, cvector->count);
-    ok_int(59, 5, cvector->allocated);
-    ok_string(60, "This is a\t", cvector->strings[0]);
-    ok_string(61, "es", cvector->strings[1]);
-    ok_string(62, ".  ", cvector->strings[2]);
-    ok(63, cvector->strings[0] == string);
-    ok(64, memcmp(string, nulls2, 18) == 0);
-    p = cvector_join(cvector, "oo");
-    ok_string(65, "This is a\tooesoo.  ", p);
-    free(p);
-    cvector_free(cvector);
-    free(string);
-
-    vector = vector_split("", ' ', NULL);
-    ok_int(66, 1, vector->count);
-    ok_string(67, "", vector->strings[0]);
-    vector_free(vector);
-    cvector = cvector_split(empty, ' ', NULL);
-    ok_int(68, 1, cvector->count);
-    ok_string(69, "", vector->strings[0]);
-    cvector_free(cvector);
-
-    vector = vector_split_space("", NULL);
-    ok_int(70, 0, vector->count);
-    vector_free(vector);
-    cvector = cvector_split_space(empty, NULL);
-    ok_int(71, 0, cvector->count);
-    cvector_free(cvector);
-
-    vector = vector_split(tabs, '\t', NULL);
-    ok_int(72, 4, vector->count);
-    ok_string(73, "test", vector->strings[0]);
-    ok_string(74, "", vector->strings[1]);
-    ok_string(75, "ing", vector->strings[2]);
-    ok_string(76, "", vector->strings[3]);
-    p = vector_join(vector, "");
-    ok_string(77, "testing", p);
-    free(p);
-    vector_free(vector);
-
-    string = xstrdup(tabs);
-    cvector = cvector_split(string, '\t', NULL);
-    ok_int(78, 4, cvector->count);
-    ok_string(79, "test", cvector->strings[0]);
-    ok_string(80, "", cvector->strings[1]);
-    ok_string(81, "ing", cvector->strings[2]);
-    ok_string(82, "", cvector->strings[3]);
-    p = cvector_join(cvector, "");
-    ok_string(83, "testing", p);
-    free(p);
-    cvector_free(cvector);
-    free(string);
-
-    vector = vector_split_space("foo\nbar", NULL);
-    ok_int(84, 1, vector->count);
-    ok_string(85, "foo\nbar", vector->strings[0]);
-    vector_free(vector);
-
-    string = xstrdup("foo\nbar");
-    cvector = cvector_split_space(string, NULL);
-    ok_int(86, 1, cvector->count);
-    ok_string(87, "foo\nbar", cvector->strings[0]);
-    cvector_free(cvector);
-
-    return 0;
-}
diff --git a/tests/lib/wire-t.c b/tests/lib/wire-t.c
deleted file mode 100644 (file)
index 66116ee..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $Id: wire-t.c 6084 2002-12-27 07:24:55Z rra $ */
-/* wire test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "inn/messages.h"
-#include "inn/wire.h"
-#include "libinn.h"
-#include "libtest.h"
-
-/* Read in a file and return the contents in newly allocated memory.  Fills in
-   the provided stat buffer. */
-static char *
-read_file(const char *name, struct stat *st)
-{
-    int fd;
-    char *article;
-    ssize_t count;
-
-    if (stat(name, st) < 0)
-        sysdie("cannot stat %s", name);
-    article = xmalloc(st->st_size);
-    fd = open(name, O_RDONLY);
-    if (fd < 0)
-        sysdie("cannot open %s", name);
-    count = read(fd, article, st->st_size);
-    if (count < st->st_size)
-        die("unable to read all of %s", name);
-    close(fd);
-    return article;
-}
-
-
-/* Test article for wire_findbody. */
-const char ta[] = "Path: \r\nFrom: \r\n\r\n";
-
-int
-main(void)
-{
-    const char *p, *end;
-    char *article;
-    struct stat st;
-
-    puts("34");
-
-    end = ta + sizeof(ta) - 1;
-    p = end - 4;
-    ok(1, wire_findbody(ta, sizeof(ta) - 1) == end);
-    ok(2, wire_findbody(ta, sizeof(ta) - 2) == NULL);
-    ok(3, wire_findbody(ta, sizeof(ta) - 3) == NULL);
-    ok(4, wire_findbody(ta, sizeof(ta) - 4) == NULL);
-    ok(5, wire_findbody(ta, sizeof(ta) - 5) == NULL);
-    ok(6, wire_findbody(p, 4) == end);
-    ok(7, wire_findbody(p, 3) == NULL);
-    ok(8, wire_findbody(p, 2) == NULL);
-    ok(9, wire_findbody(p, 1) == NULL);
-    ok(10, wire_findbody(p, 0) == NULL);
-
-    if (access("articles/strange", F_OK) < 0)
-        if (access("lib/articles/strange", F_OK) == 0)
-            chdir("lib");
-    article = read_file("articles/strange", &st);
-
-    p = wire_findbody(article, st.st_size);
-    ok(11, strncmp(p, "Path: This is", strlen("Path: This is")) == 0);
-    p = wire_nextline(p, article + st.st_size - 1);
-    ok(12, strncmp(p, "Second: Not", strlen("Second: Not")) == 0);
-    p = wire_nextline(p, article + st.st_size - 1);
-    ok(13, p == NULL);
-    p = wire_findheader(article, st.st_size, "Path");
-    ok(14, p == article + 6);
-    p = wire_findheader(article, st.st_size, "From");
-    ok(15, strncmp(p, "This is the real", strlen("This is the real")) == 0);
-    p = wire_findheader(article, st.st_size, "SUMMARY");
-    ok(16, strncmp(p, "First text", strlen("First text")) == 0);
-    p = wire_findheader(article, st.st_size, "Header");
-    ok(17, strncmp(p, "This one is real", strlen("This one is real")) == 0);
-    p = wire_findheader(article, st.st_size, "message-id");
-    ok(18, strncmp(p, "<foo@example.com>", strlen("<foo@example.com>")) == 0);
-    p = wire_findheader(article, st.st_size, "Second");
-    ok(19, p == NULL);
-    p = wire_findheader(article, st.st_size, "suBJect");
-    ok(20, strncmp(p, "This is\rnot", strlen("This is\rnot")) == 0);
-    end = wire_endheader(p, article + st.st_size - 1);
-    ok(21, strncmp(end, "\nFrom: This is", strlen("\nFrom: This is")) == 0);
-    p = wire_findheader(article, st.st_size, "keywordS");
-    ok(22, strncmp(p, "this is --", strlen("this is --")) == 0);
-    end = wire_endheader(p, article + st.st_size - 1);
-    ok(23, strncmp(end, "\nSummary: ", strlen("\nSummary: ")) == 0);
-    p = wire_findheader(article, st.st_size, "strange");
-    ok(24, strncmp(p, "This is\n\nnot", strlen("This is\n\nnot")) == 0);
-    end = wire_endheader(p, article + st.st_size - 1);
-    ok(25, strncmp(end, "\nMessage-ID: ", strlen("\nMessage-ID: ")) == 0);
-    p = wire_findheader(article, st.st_size, "Message");
-    ok(26, p == NULL);
-
-    free(article);
-    article = read_file("articles/no-body", &st);
-
-    ok(27, wire_findbody(article, st.st_size) == NULL);
-    p = wire_findheader(article, st.st_size, "message-id");
-    ok(28, strncmp(p, "<id1@example.com>\r\n",
-                   strlen("<id1@example.com>\r\n")) == 0);
-    end = wire_endheader(p, article + st.st_size - 1);
-    ok(29, end == article + st.st_size - 1);
-    ok(30, wire_nextline(p, article + st.st_size - 1) == NULL);
-
-    free(article);
-    article = read_file("articles/truncated", &st);
-
-    ok(31, wire_findbody(article, st.st_size) == NULL);
-    p = wire_findheader(article, st.st_size, "date");
-    ok(32, strncmp(p, "Mon, 23 Dec", strlen("Mon, 23 Dec")) == 0);
-    ok(33, wire_endheader(p, article + st.st_size - 1) == NULL);
-    ok(34, wire_nextline(p, article + st.st_size - 1) == NULL);
-
-    free(article);
-
-    return 0;
-}
diff --git a/tests/lib/xmalloc.c b/tests/lib/xmalloc.c
deleted file mode 100644 (file)
index 4c951e2..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $Id: xmalloc.c 5379 2002-03-31 21:45:12Z rra $ */
-/* Test suite for xmalloc and family. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-
-/* Linux requires sys/time.h be included before sys/resource.h. */
-#if HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#include <sys/resource.h>
-
-#include "inn/messages.h"
-#include "libinn.h"
-
-/* A customized error handler for checking xmalloc's support of them.
-   Prints out the error message and exits with status 1. */
-static void
-test_handler(const char *function, size_t size, const char *file, int line)
-{
-    die("%s %lu %s %d", function, (unsigned long) size, file, line);
-}
-
-/* Allocate the amount of memory given and write to all of it to make sure
-   we can, returning true if that succeeded and false on any sort of
-   detectable error. */
-static int
-test_malloc(size_t size)
-{
-    char *buffer;
-    size_t i;
-
-    buffer = xmalloc(size);
-    if (buffer == NULL)
-        return 0;
-    if (size > 0)
-        memset(buffer, 1, size);
-    for (i = 0; i < size; i++)
-        if (buffer[i] != 1)
-            return 0;
-    free(buffer);
-    return 1;
-}
-
-/* Allocate half the memory given, write to it, then reallocate to the
-   desired size, writing to the rest and then checking it all.  Returns true
-   on success, false on any failure. */
-static int
-test_realloc(size_t size)
-{
-    char *buffer;
-    size_t i;
-
-    buffer = xmalloc(size / 2);
-    if (buffer == NULL)
-        return 0;
-    if (size / 2 > 0)
-        memset(buffer, 1, size / 2);
-    buffer = xrealloc(buffer, size);
-    if (buffer == NULL)
-        return 0;
-    if (size > 0)
-        memset(buffer + size / 2, 2, size - size / 2);
-    for (i = 0; i < size / 2; i++)
-        if (buffer[i] != 1)
-            return 0;
-    for (i = size / 2; i < size; i++)
-        if (buffer[i] != 2)
-            return 0;
-    free(buffer);
-    return 1;
-}
-
-/* Generate a string of the size indicated, call xstrdup on it, and then
-   ensure the result matches.  Returns true on success, false on any
-   failure. */
-static int
-test_strdup(size_t size)
-{
-    char *string, *copy;
-    int match;
-
-    string = xmalloc(size);
-    if (string == NULL)
-        return 0;
-    memset(string, 1, size - 1);
-    string[size - 1] = '\0';
-    copy = xstrdup(string);
-    if (copy == NULL)
-        return 0;
-    match = strcmp(string, copy);
-    free(string);
-    free(copy);
-    return (match == 0);
-}
-
-/* Generate a string of the size indicated plus some, call xstrndup on it, and
-   then ensure the result matches.  Returns true on success, false on any
-   failure. */
-static int
-test_strndup(size_t size)
-{
-    char *string, *copy;
-    int match, toomuch;
-
-    string = xmalloc(size + 1);
-    if (string == NULL)
-        return 0;
-    memset(string, 1, size - 1);
-    string[size - 1] = 2;
-    string[size] = '\0';
-    copy = xstrndup(string, size - 1);
-    if (copy == NULL)
-        return 0;
-    match = strncmp(string, copy, size - 1);
-    toomuch = strcmp(string, copy);
-    free(string);
-    free(copy);
-    return (match == 0 && toomuch != 0);
-}
-
-/* Allocate the amount of memory given and check that it's all zeroed,
-   returning true if that succeeded and false on any sort of detectable
-   error. */
-static int
-test_calloc(size_t size)
-{
-    char *buffer;
-    size_t i, nelems;
-
-    nelems = size / 4;
-    if (nelems * 4 != size)
-        return 0;
-    buffer = xcalloc(nelems, 4);
-    if (buffer == NULL)
-        return 0;
-    for (i = 0; i < size; i++)
-        if (buffer[i] != 0)
-            return 0;
-    free(buffer);
-    return 1;
-}
-
-/* Take the amount of memory to allocate in bytes as a command-line argument
-   and call test_malloc with that amount of memory. */
-int
-main(int argc, char *argv[])
-{
-    size_t size, max;
-    size_t limit = 0;
-    int willfail = 0;
-    unsigned char code;
-    struct rlimit rl;
-
-    if (argc < 3)
-        die("Usage error.  Type, size, and limit must be given.");
-    errno = 0;
-    size = strtol(argv[2], 0, 10);
-    if (size == 0 && errno != 0)
-        sysdie("Invalid size");
-    errno = 0;
-    limit = strtol(argv[3], 0, 10);
-    if (limit == 0 && errno != 0)
-        sysdie("Invalid limit");
-
-    /* If a memory limit was given and we can set memory limits, set it.
-       Otherwise, exit 2, signalling to the driver that the test should be
-       skipped.  We do this here rather than in the driver due to some
-       pathological problems with Linux (setting ulimit in the shell caused
-       the shell to die). */
-    if (limit > 0) {
-#if HAVE_SETRLIMIT && defined(RLIMIT_DATA)
-        rl.rlim_cur = limit;
-        rl.rlim_max = limit;
-        if (setrlimit(RLIMIT_DATA, &rl) < 0) {
-            syswarn("Can't set data limit to %lu", (unsigned long) limit);
-            exit(2);
-        }
-#else
-        warn("Data limits aren't supported.");
-        exit(2);
-#endif
-    }
-
-    /* If the code is capitalized, install our customized error handler. */
-    code = argv[1][0];
-    if (isupper(code)) {
-        xmalloc_error_handler = test_handler;
-        code = tolower(code);
-    }
-
-    /* Decide if the allocation should fail.  If it should, set willfail to
-       2, so that if it unexpectedly succeeds, we exit with a status
-       indicating that the test should be skipped. */
-    max = size;
-    if (code == 's' || code == 'n')
-        max *= 2;
-    if (limit > 0 && max > limit)
-        willfail = 2;
-
-    switch (code) {
-    case 'c': exit(test_calloc(size) ? willfail : 1);
-    case 'm': exit(test_malloc(size) ? willfail : 1);
-    case 'r': exit(test_realloc(size) ? willfail : 1);
-    case 's': exit(test_strdup(size) ? willfail : 1);
-    case 'n': exit(test_strndup(size) ? willfail : 1);
-    default:
-        die("Unknown mode %c", argv[1][0]);
-        break;
-    }
-    exit(1);
-}
diff --git a/tests/lib/xmalloc.t b/tests/lib/xmalloc.t
deleted file mode 100755 (executable)
index 4fb2ebd..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-#! /bin/sh
-# $Id: xmalloc.t 5379 2002-03-31 21:45:12Z rra $
-#
-# Test suite for xmalloc and friends.
-
-# The count starts at 1 and is updated each time ok is printed.  printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
-    echo "$1 $count $2"
-    count=`expr $count + 1`
-}
-
-# Run a program expected to succeed, and print ok if it does.
-runsuccess () {
-    output=`$xmalloc "$1" "$2" "$3" 2>&1 >/dev/null`
-    status=$?
-    if test $status = 0 && test -z "$output" ; then
-        printcount "ok"
-    else
-        if test $status = 2 ; then
-            printcount "ok" "# skip - no data limit support"
-        else
-            printcount "not ok"
-            echo "  $output"
-        fi
-    fi
-}
-
-# Run a program expected to fail and make sure it fails with an exit status
-# of 2 and the right failure message.  Strip the colon and everything after
-# it off the error message since it's system-specific.
-runfailure () {
-    output=`$xmalloc "$1" "$2" "$3" 2>&1 >/dev/null`
-    status=$?
-    output=`echo "$output" | sed 's/:.*//'`
-    if test $status = 1 && test x"$output" = x"$4" ; then
-        printcount "ok"
-    else
-        if test $status = 2 ; then
-            printcount "ok" "# skip - no data limit support"
-        else
-            printcount "not ok"
-            echo "  saw: $output"
-            echo "  not: $4"
-        fi
-    fi
-}
-
-# Find where the helper program is.
-xmalloc=xmalloc
-for file in ./xmalloc lib/xmalloc ../xmalloc ; do
-    [ -x $file ] && xmalloc=$file
-done
-
-# Total tests.
-echo 26
-
-# First run the tests expected to succeed.
-runsuccess "m" "21"     "0"
-runsuccess "m" "128000" "0"
-runsuccess "m" "0"      "0"
-runsuccess "r" "21"     "0"
-runsuccess "r" "128000" "0"
-runsuccess "s" "21"     "0"
-runsuccess "s" "128000" "0"
-runsuccess "n" "21"     "0"
-runsuccess "n" "128000" "0"
-runsuccess "c" "24"     "0"
-runsuccess "c" "128000" "0"
-
-# Now limit our memory to 96KB and then try the large ones again, all of
-# which should fail.
-runfailure "m" "128000" "96000" \
-    "failed to malloc 128000 bytes at lib/xmalloc.c line 36"
-runfailure "r" "128000" "96000" \
-    "failed to realloc 128000 bytes at lib/xmalloc.c line 62"
-runfailure "s" "64000"  "96000" \
-    "failed to strdup 64000 bytes at lib/xmalloc.c line 91"
-runfailure "n" "64000"  "96000" \
-    "failed to strndup 64000 bytes at lib/xmalloc.c line 115"
-runfailure "c" "128000" "96000" \
-    "failed to calloc 128000 bytes at lib/xmalloc.c line 137"
-
-# Check our custom error handler.
-runfailure "M" "128000" "96000" "malloc 128000 lib/xmalloc.c 36"
-runfailure "R" "128000" "96000" "realloc 128000 lib/xmalloc.c 62"
-runfailure "S" "64000"  "96000" "strdup 64000 lib/xmalloc.c 91"
-runfailure "N" "64000"  "96000" "strndup 64000 lib/xmalloc.c 115"
-runfailure "C" "128000" "96000" "calloc 128000 lib/xmalloc.c 137"
-
-# Check the smaller ones again just for grins.
-runsuccess "m" "21" "96000"
-runsuccess "r" "32" "96000"
-runsuccess "s" "64" "96000"
-runsuccess "n" "20" "96000"
-runsuccess "c" "24" "96000"
diff --git a/tests/lib/xwrite-t.c b/tests/lib/xwrite-t.c
deleted file mode 100644 (file)
index e8506f6..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $Id: xwrite-t.c 5790 2002-09-30 01:05:09Z rra $ */
-/* Test suite for xwrite and xwritev. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <sys/uio.h>
-
-#include "libinn.h"
-
-/* The data array we'll use to do testing. */
-char data[256];
-
-/* These come from fakewrite. */
-extern char write_buffer[];
-extern size_t write_offset;
-extern int write_interrupt;
-extern int write_fail;
-
-static void
-test_write(int n, int status, int total)
-{
-    int success;
-
-    success = (status == total && memcmp(data, write_buffer, 256) == 0);
-    printf("%sok %d\n", success ? "" : "not ", n);
-    if (!success && status != total)
-        printf("  status %d, total %d\n", status, total);
-}
-
-int
-main(void)
-{
-    int i;
-    struct iovec iov[4];
-
-    puts("19");
-
-    /* Test xwrite. */
-    for (i = 0; i < 256; i++)
-        data[i] = i;
-    test_write(1, xwrite(0, data, 256), 256);
-    write_offset = 0;
-    write_interrupt = 1;
-    memset(data, 0, 256);
-    test_write(2, xwrite(0, data, 256), 256);
-    write_offset = 0;
-    for (i = 0; i < 32; i++)
-        data[i] = i * 2;
-    test_write(3, xwrite(0, data, 32), 32);
-    for (i = 32; i < 65; i++)
-        data[i] = i * 2;
-    test_write(4, xwrite(0, data + 32, 33), 33);
-    write_offset = 0;
-    write_interrupt = 0;
-
-    /* Test xwritev. */
-    memset(data, 0, 256);
-    iov[0].iov_base = data;
-    iov[0].iov_len = 256;
-    test_write(5, xwritev(0, iov, 1), 256);
-    write_offset = 0;
-    for (i = 0; i < 256; i++)
-        data[i] = i;
-    iov[0].iov_len = 128;
-    iov[1].iov_base = &data[128];
-    iov[1].iov_len = 16;
-    iov[2].iov_base = &data[144];
-    iov[2].iov_len = 112;
-    test_write(6, xwritev(0, iov, 3), 256);
-    write_offset = 0;
-    write_interrupt = 1;
-    memset(data, 0, 256);
-    iov[0].iov_len = 32;
-    iov[1].iov_base = &data[32];
-    iov[1].iov_len = 224;
-    test_write(7, xwritev(0, iov, 2), 256);
-    for (i = 0; i < 32; i++)
-        data[i] = i * 2;
-    write_offset = 0;
-    test_write(8, xwritev(0, iov, 1), 32);
-    for (i = 32; i < 65; i++)
-        data[i] = i * 2;
-    iov[0].iov_base = &data[32];
-    iov[0].iov_len = 16;
-    iov[1].iov_base = &data[48];
-    iov[1].iov_len = 1;
-    iov[2].iov_base = &data[49];
-    iov[2].iov_len = 8;
-    iov[3].iov_base = &data[57];
-    iov[3].iov_len = 8;
-    test_write(9, xwritev(0, iov, 4), 33);
-    write_offset = 0;
-    write_interrupt = 0;
-
-    /* Test xpwrite. */
-    for (i = 0; i < 256; i++)
-        data[i] = i;
-    test_write(10, xpwrite(0, data, 256, 0), 256);
-    write_interrupt = 1;
-    memset(data + 1, 0, 255);
-    test_write(11, xpwrite(0, data + 1, 255, 1), 255);
-    for (i = 0; i < 32; i++)
-        data[i + 32] = i * 2;
-    test_write(12, xpwrite(0, data + 32, 32, 32), 32);
-    for (i = 32; i < 65; i++)
-        data[i + 32] = i * 2;
-    test_write(13, xpwrite(0, data + 64, 33, 64), 33);
-    write_interrupt = 0;
-
-    /* Test failures. */
-    write_fail = 1;
-    test_write(14, xwrite(0, data + 1, 255), -1);
-    iov[0].iov_base = data + 1;
-    iov[0].iov_len = 255;
-    test_write(15, xwritev(0, iov, 1), -1);
-    test_write(16, xpwrite(0, data + 1, 255, 0), -1);
-
-    /* Test zero-length writes. */
-    test_write(17, xwrite(0, "   ", 0), 0);
-    test_write(18, xpwrite(0, "   ", 0, 2), 0);
-    iov[0].iov_base = data + 1;
-    iov[0].iov_len = 2;
-    test_write(19, xwritev(0, iov, 0), 0);
-
-    return 0;
-}
diff --git a/tests/libtest.c b/tests/libtest.c
deleted file mode 100644 (file)
index 2a2fe7e..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*  $Id: libtest.c 5955 2002-12-08 09:28:32Z rra $
-**
-**  Some utility routines for writing tests.
-**
-**  Herein are a variety of utility routines for writing tests.  All
-**  routines of the form ok*() take a test number and some number of
-**  appropriate arguments, check to be sure the results match the expected
-**  output using the arguments, and print out something appropriate for that
-**  test number.  Other utility routines help in constructing more complex
-**  tests.
-*/
-
-#include "config.h"
-#include "clibrary.h"
-
-#include "inn/messages.h"
-#include "libinn.h"
-#include "libtest.h"
-
-/* A global buffer into which message_log_buffer stores error messages. */
-char *errors = NULL;
-
-
-/*
-**  Takes a boolean success value and assumes the test passes if that value
-**  is true and fails if that value is false.
-*/
-void
-ok(int n, int success)
-{
-    printf("%sok %d\n", success ? "" : "not ", n);
-}
-
-
-/*
-**  Takes an expected integer and a seen integer and assumes the test passes
-**  if those two numbers match.
-*/
-void
-ok_int(int n, int wanted, int seen)
-{
-    if (wanted == seen)
-        printf("ok %d\n", n);
-    else
-        printf("not ok %d\n  wanted: %d\n    seen: %d\n", n, wanted, seen);
-}
-
-
-/*
-**  Takes a string and what the string should be, and assumes the test
-**  passes if those strings match (using strcmp).
-*/
-void
-ok_string(int n, const char *wanted, const char *seen)
-{
-    if (wanted == NULL)
-        wanted = "(null)";
-    if (seen == NULL)
-        seen = "(null)";
-    if (strcmp(wanted, seen) != 0)
-        printf("not ok %d\n  wanted: %s\n    seen: %s\n", n, wanted, seen);
-    else
-        printf("ok %d\n", n);
-}
-
-
-/*
-**  An error handler that appends all errors to the errors global.  Used by
-**  error_capture.
-*/
-static void
-message_log_buffer(int len, const char *fmt, va_list args, int error UNUSED)
-{
-    char *message;
-
-    message = xmalloc(len + 1);
-    vsnprintf(message, len + 1, fmt, args);
-    if (errors == NULL) {
-        errors = concat(message, "\n", (char *) 0);
-    } else {
-        char *new_errors;
-
-        new_errors = concat(errors, message, "\n", (char *) 0);
-        free(errors);
-        errors = new_errors;
-    }
-    free(message);
-}
-
-
-/*
-**  Turn on the capturing of errors.  Errors will be stored in the global
-**  errors variable where they can be checked by the test suite.  Capturing is
-**  turned off with errors_uncapture.
-*/
-void
-errors_capture(void)
-{
-    if (errors != NULL) {
-        free(errors);
-        errors = NULL;
-    }
-    message_handlers_warn(1, message_log_buffer);
-}
-
-
-/*
-**  Turn off the capturing of errors again.
-*/
-void
-errors_uncapture(void)
-{
-    message_handlers_warn(1, message_log_stderr);
-}
diff --git a/tests/libtest.h b/tests/libtest.h
deleted file mode 100644 (file)
index 5e6e445..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*  $Id: libtest.h 5955 2002-12-08 09:28:32Z rra $
-**
-**  Some utility routines for writing tests.
-*/
-
-#ifndef TESTLIB_H
-#define TESTLIB_H 1
-
-#include "config.h"
-#include <inn/defines.h>
-
-/* A global buffer into which errors_capture stores errors. */
-extern char *errors;
-
-BEGIN_DECLS
-
-void ok(int n, int success);
-void ok_int(int n, int wanted, int seen);
-void ok_string(int n, const char *wanted, const char *seen);
-
-/* Turn on capturing of errors with errors_capture.  Errors reported by warn
-   will be stored in the global errors variable.  Turn this off again with
-   errors_uncapture.  Caller is responsible for freeing errors when done. */
-void errors_capture(void);
-void errors_uncapture(void);
-
-END_DECLS
-
-#endif /* TESTLIB_H */
diff --git a/tests/overview/data/basic b/tests/overview/data/basic
deleted file mode 100644 (file)
index c59b4d3..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-news.groups:1  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 15:30:16 -0800 <ylvgdgye47.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com>  3124    58      Xref: inn.example.com news.groups:1
-news.groups:2  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 15:32:03 -0800 <ylofj8ye18.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3eep7$q6r$1@samba.rahul.net> <a3epeq$rt$1@gw.retro.com> <a3f201$n8$1@samba.rahul.net> <a3f7v9$3kg$1@gw.retro.com>   448     11      Xref: inn.example.com news.groups:2
-news.groups:7  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 16:34:02 -0800 <ylhep0vi11.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com>      2834    55      Xref: inn.example.com news.groups:7
-news.groups:8  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 17:10:47 -0800 <yladusu1rc.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <3ndm5u8fgomord7vmh164ce7pcteh496sp@4ax.com>  2363    47      Xref: inn.example.com news.groups:8
-news.groups:12 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 17:20:57 -0800 <yl4rl0u1ae.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com>  1651    36      Xref: inn.example.com news.groups:12
-news.groups:13 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 18:10:18 -0800 <ylu1t03a7p.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <v1hm5u4mrhllm98ng1jhp5gco7sflbm4jq@4ax.com>      902     27      Xref: inn.example.com news.groups:13
-news.groups:14 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:08:02 -0800 <ylg04k37jh.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3fgk302sdn@enews1.newsguy.com>      808     18      Xref: inn.example.com news.groups:14
-news.groups:15 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:12:32 -0800 <yladus37bz.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <i8jm5u4l8bt7lk93mramtmbouhtg58tpnb@4ax.com>      643     14      Xref: inn.example.com news.groups:15
-news.groups:16 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:35:38 -0800 <yl4rl0369h.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <Xns91A8BC08432FEpeskyirritantcom@209.155.56.83>  326     12      Xref: inn.example.com news.groups:16
-news.groups:17 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 10:20:43 -0800 <ylg04j7nk4.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3g0i9$6ch$1@samba.rahul.net>     680     16      Xref: inn.example.com news.groups:17
-news.groups:18 Re: The beer truck (was Re: Pre-RFD - Exec Board Newsgroup Creation)    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 10:23:15 -0800 <yladur7nfw.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3h7be$dec$1@panix2.panix.com>    375     11      Xref: inn.example.com news.groups:18
-news.groups:19 Re: The beer truck (was Re: Pre-RFD - Exec Board Newsgroup Creation)    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <yl8zab38v3.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylhep0vi11.fsf@windlord.stanford.edu> <a3h7be$dec$1@panix2.panix.com> <yladur7nfw.fsf@windlord.stanford.edu> <a3hd8t$sin$1@panix2.panix.com> 481     16      Xref: inn.example.com news.groups:19
-news.groups:21 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 17:38:39 -0800 <ylwuxvwdi8.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <20020202150653$4dbb@babylon.ks.uiuc.edu> <fo1o5uoo90uh1qreh20u6n1ci70jt28mmg@4ax.com> <1f6z4v6.1fbjkdq18w29f4N%kmorgan@aptalaska.net> <lqto5u0p5sblo0ui9hal0nil52e3nlbssm@4ax.com>     316     9       Xref: inn.example.com news.groups:21
-news.groups:22 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 17:42:27 -0800 <ylr8o3wdbw.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <08_68.11847$gW4.9091001@news1.rdc1.mi.home.com>        1405    29      Xref: inn.example.com news.groups:22
-news.groups:23 Re: [History] Re: A Chronology of Usenet Newsgroups:  Start Post        Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 09:34:04 -0800 <yl665e4ghf.fsf@windlord.stanford.edu>  <3c4a31e3$0$95685$892e7fe2@authen.puce.readfreenews.net> <a301ve02s1r@enews2.newsguy.com> <dbc8daca.0201280231.791aeb03@posting.google.com> <8I07QDHHw-B@khms.westfalen.de> <3c5d3981$0$36784$892e7fe2@authen.puce.readfreenews.net>    617     15      Xref: inn.example.com news.groups:23
-news.groups:24 Re: Guidelines for Big Eight Newsgroup Creation Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 09:38:27 -0800 <ylzo2q31po.fsf@windlord.stanford.edu>  <big-eight-faq-1012550404$22697@windlord.stanford.edu> <vvjq5u8l1dnrdankh4q7l2d043ud8kt11o@4ax.com>     971     22      Xref: inn.example.com news.groups:24
-news.admin.net-abuse.policy:1  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 10:22:36 -0800 <ylelk21l3n.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com>   1448    31      Xref: inn.example.com news.admin.net-abuse.policy:1
-news.groups:25 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 13:21:34 -0800 <ylwuxuz2g1.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <20020202150653$4dbb@babylon.ks.uiuc.edu> <FRRtIeAzyYX8Ewxl@merlyn.demon.co.uk> 668     15      Xref: inn.example.com news.groups:25
-news.admin.net-abuse.policy:4  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 13:23:54 -0800 <ylr8o2z2c5.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> 533     12      Xref: inn.example.com news.admin.net-abuse.policy:4
-gnu.misc.discuss:1     Re: want to learn perl from free sources        Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 09:51:12 -0800 <yln0yp87an.fsf@windlord.stanford.edu>  <m2r8o1iu11.fsf@dan.jacobson.tw>        641     15      Xref: inn.example.com gnu.misc.discuss:1
-comp.lang.perl.misc:1  Re: want to learn perl from free sources        Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 09:51:12 -0800 <yln0yp87an.fsf@windlord.stanford.edu>  <m2r8o1iu11.fsf@dan.jacobson.tw>        641     15      Xref: inn.example.com comp.lang.perl.misc:1
-csd.bboard:1   comp.doc.techreports submissions from Stanford  Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 10:28:11 -0800 <yl4rkx3xvo.fsf@windlord.stanford.edu>          672     18      Xref: inn.example.com csd.bboard:1
-news.admin.net-abuse.policy:5  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 12:09:24 -0800 <ylr8o1xb4b.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com>       1751    38      Xref: inn.example.com news.admin.net-abuse.policy:5
-csd.bboard:2   Re: comp.doc.techreports submissions from Stanford      Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 12:31:16 -0800 <yl3d0hxa3v.fsf@windlord.stanford.edu>  <yl4rkx3xvo.fsf@windlord.stanford.edu>  794     16      Xref: inn.example.com csd.bboard:2
-gnu.utils.bug:1        Re: let's beef up the tsort info page   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 14:03:41 -0800 <yl4rkwx5tu.fsf@windlord.stanford.edu>  <m2wuxtj3gh.fsf@dan.jacobson.tw>        2409    73      Xref: inn.example.com gnu.utils.bug:1
-news.groups:26 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 15:31:18 -0800 <yl4rkwu8mx.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com>    578     15      Xref: inn.example.com news.groups:26
-news.groups:27 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 16:37:55 -0800 <ylofj4rcf0.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com> <yl4rkwu8mx.fsf@windlord.stanford.edu> <a3n74c026se@enews4.newsguy.com>    899     22      Xref: inn.example.com news.groups:27
-news.admin.net-abuse.policy:6  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 17:56:53 -0800 <ylk7tsofmi.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com> <ylr8o1xb4b.fsf@windlord.stanford.edu> <Gr1CnE.Iny@world.std.com>     961     18      Xref: inn.example.com news.admin.net-abuse.policy:6
-news.groups:32 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 19:02:56 -0800 <yln0yobpgf.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com> <yl4rkwu8mx.fsf@windlord.stanford.edu> <a3n74c026se@enews4.newsguy.com> <ylofj4rcf0.fsf@windlord.stanford.edu> <a3nbva02f0r@enews4.newsguy.com>    1280    26      Xref: inn.example.com news.groups:32
-news.groups:33 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 19:04:16 -0800 <ylheowbpe7.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net>  851     17      Xref: inn.example.com news.groups:33
-news.admin.net-abuse.policy:7  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 08:52:18 -0800 <yl4rkvx459.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com> <ylr8o1xb4b.fsf@windlord.stanford.edu> <Gr1CnE.Iny@world.std.com> <ylk7tsofmi.fsf@windlord.stanford.edu> <Gr1LLx.6xF@world.std.com>   3618    69      Xref: inn.example.com news.admin.net-abuse.policy:7
-news.software.nntp:1   Re: peering under the storage API       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:04:13 -0800 <ylit9bl8tu.fsf@windlord.stanford.edu>  <slrna60q6l.3fo.br@panix2.panix.com>    546     14      Xref: inn.example.com news.software.nntp:1
-news.groups:34 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:46:28 -0800 <ylofj3jsaz.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net> <m2k7trcxes.fsf@dan.jacobson.tw> <3C6077F5.AE1C5ED8@sfo.com>     882     22      Xref: inn.example.com news.groups:34
-news.groups:36 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:51:33 -0800 <ylit9bjs2i.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <Xns91AD188E6226grahamdrabblelineone@ID-77355.user.dfncis.de>   1067    21      Xref: inn.example.com news.groups:36
-news.admin.technical:1 Re: nnrpd       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:53:18 -0800 <yld6zjjrzl.fsf@windlord.stanford.edu>  <a3psen$7p4$1@quasar.ctc.edu>   543     13      Xref: inn.example.com news.admin.technical:1
-news.admin.hierarchies:1       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:54:47 -0800 <yl7kprjrx4.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain>      877     21      Xref: inn.example.com news.admin.hierarchies:1
-news.groups:37 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 18:07:55 -0800 <ylvgdbicqs.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net> <3C608D3D.C87E3610@diogenes.sacramento.ca.us>    623     13      Xref: inn.example.com news.groups:37
-news.software.nntp:2   Re: INN on another user/group   Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 19:14:03 -0800 <ylg04fs3no.fsf@windlord.stanford.edu>  <3c609757$0$20968$afc38c87@news.optusnet.com.au>        593     15      Xref: inn.example.com news.software.nntp:2
-news.admin.hierarchies:2       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 21:56:17 -0800 <yl665bqhku.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain>    828     19      Xref: inn.example.com news.admin.hierarchies:2
-news.admin.net-abuse.policy:8  Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 08:42:16 -0800 <ylr8ny7eaf.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com>       740     18      Xref: inn.example.com news.admin.net-abuse.policy:8
-news.software.nntp:3   Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 08:45:04 -0800 <yllme67e5r.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net>      852     21      Xref: inn.example.com news.software.nntp:3
-news.software.nntp:4   Re: first > last        Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:50:15 -0800 <yly9i6uvoo.fsf@windlord.stanford.edu>  <3C61951F.8080606@gemal.dk>     850     19      Xref: inn.example.com news.software.nntp:4
-news.admin.net-abuse.policy:9  Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:57:38 -0800 <ylk7tqtgrx.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com> <ylr8ny7eaf.fsf@windlord.stanford.edu> <878za6o8h5.fsf@erlenstar.demon.co.uk> 578     16      Xref: inn.example.com news.admin.net-abuse.policy:9
-news.admin.net-abuse.policy:10 Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:58:09 -0800 <yleljytgr2.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com> <ylr8ny7eaf.fsf@windlord.stanford.edu> <1013015167.535798@ok-corral.gunslinger.net>   548     13      Xref: inn.example.com news.admin.net-abuse.policy:10
-news.admin.hierarchies:3       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 14:00:23 -0800 <yl8za6tgnc.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain> <yl665bqhku.fsf@windlord.stanford.edu> <m3lme68jz6.fsf@defun.localdomain>  478     17      Xref: inn.example.com news.admin.hierarchies:3
-news.admin.hierarchies:4       Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 14:09:30 -0800 <yllme6s1np.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3ptk7.3vuai51.1@mid.glglgl.de> <a3qmdq$1akiad$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> 972     20      Xref: inn.example.com news.admin.hierarchies:4
-news.admin.hierarchies:7       Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 16:19:10 -0800 <ylk7tqp2ip.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3ptk7.3vuai51.1@mid.glglgl.de> <a3qmdq$1akiad$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> <yllme6s1np.fsf@windlord.stanford.edu> <a3sbmu$1ao4a2$1@ID-80930.news.dfncis.de>        421     11      Xref: inn.example.com news.admin.hierarchies:7
-news.admin.hierarchies:11      Re: control.ctl maintenance (was: [INFO] bc.* and van.*)        Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 16:20:13 -0800 <yleljyp2gy.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> <yllme6s1np.fsf@windlord.stanford.edu> <EKi88.17124$gW4.11422684@news1.rdc1.mi.home.com>   688     18      Xref: inn.example.com news.admin.hierarchies:11
-news.groups:38 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 22:21:34 -0800 <yl8za5n769.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <1j6l5u499l6ru00rn6ibje0cgsv32jkrk1@4ax.com> <a3f1oq02gd2@enews3.newsguy.com> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com>   1093    26      Xref: inn.example.com news.groups:38
-news.groups:39 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Thu, 07 Feb 2002 00:46:46 -0800 <yl3d0dn0g9.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com> <yl8za5n769.fsf@windlord.stanford.edu> <a3tb6q$i69$1@gw.retro.com>      5108    96      Xref: inn.example.com news.groups:39
-news.software.nntp:5   Re: innd and Microsoft Exchange Russ Allbery <rra@stanford.edu> Thu, 07 Feb 2002 10:01:40 -0800 <yleljx41dn.fsf@windlord.stanford.edu>  <623f5703.0202070541.2b943211@posting.google.com>       1013    21      Xref: inn.example.com news.software.nntp:5
-news.software.nntp:6   Re: innd and Microsoft Exchange Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 11:04:25 -0800 <ylofiz23t2.fsf@windlord.stanford.edu>  <623f5703.0202070541.2b943211@posting.google.com> <yleljx41dn.fsf@windlord.stanford.edu> <3C63AD90.492F3C00@eproduction.ch>     541     14      Xref: inn.example.com news.software.nntp:6
-news.software.nntp:9   Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 11:05:28 -0800 <ylit9723rb.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net>    556     16      Xref: inn.example.com news.software.nntp:9
-news.software.nntp:10  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 12:15:43 -0800 <ylsn8bwx00.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <ylit9723rb.fsf@windlord.stanford.edu> <C2W88.119862$i3.977629@news.easynews.com>  749     19      Xref: inn.example.com news.software.nntp:10
-news.groups:40 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 18:11:54 -0800 <ylsn8b76ad.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3tb6q$i69$1@gw.retro.com> <a3uq5f$n81$1@news.orst.edu> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> 1995    40      Xref: inn.example.com news.groups:40
-news.admin.hierarchies:12      Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 20:42:25 -0800 <ylu1srclla.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain>    505     14      Xref: inn.example.com news.admin.hierarchies:12
-news.groups:41 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 23:24:31 -0800 <yllme3azio.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net>    1282    26      Xref: inn.example.com news.groups:41
-news.admin.hierarchies:13      Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:00:56 -0800 <yl8za2a0hz.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de>       905     23      Xref: inn.example.com news.admin.hierarchies:13
-news.groups:42 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:20:01 -0800 <yl1yfu9zm6.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3uq5f$n81$1@news.orst.edu> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <3c651972$0$67480$892e7fe2@authen.puce.readfreenews.net>    990     19      Xref: inn.example.com news.groups:42
-news.admin.hierarchies:18      Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:25:07 -0800 <ylvgd68kt8.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain> <ylu1srclla.fsf@windlord.stanford.edu> <m37kpmdayt.fsf@defun.localdomain>  580     18      Xref: inn.example.com news.admin.hierarchies:18
-comp.lang.perl.moderated:1     Re: perldoc vs man why so much slower   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:47:26 -0800 <yl8za28js1.fsf@windlord.stanford.edu>  <m1d6zfnl9h.fsf@reader.newsguy.com> <20020209180911.23756.qmail@plover.com>     799     20      Xref: inn.example.com comp.lang.perl.moderated:1
-news.software.nntp:11  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 13:18:51 -0800 <yl3d0a8ibo.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <ylit9723rb.fsf@windlord.stanford.edu> <2504c.922202@archiver.winews.net>  1075    27      Xref: inn.example.com news.software.nntp:11
-news.groups:43 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 23:47:28 -0800 <yln0yh22y7.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com>      2306    45      Xref: inn.example.com news.groups:43
-news.groups:44 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 23:49:43 -0800 <ylheop22ug.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <a44mu80urn@enews2.newsguy.com>     810     16      Xref: inn.example.com news.groups:44
-news.software.nntp:12  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 09:32:55 -0800 <yl8za1kzso.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <yl3d0a8ibo.fsf@windlord.stanford.edu> <21049.a22200@archiver.winews.net>  1915    40      Xref: inn.example.com news.software.nntp:12
-news.groups:46 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 10:47:13 -0800 <ylpu3dgoni.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yllme3azio.fsf@windlord.stanford.edu> <a44mu80urn@enews2.newsguy.com> <ylheop22ug.fsf@windlord.stanford.edu> <a46ec6$lee$1@samba.rahul.net> 1052    28      Xref: inn.example.com news.groups:46
-news.groups:47 Re: 2nd RFD: sci.space.moderated moderated      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 10:54:24 -0800 <ylk7tlgobj.fsf@windlord.stanford.edu>  <1010713186.32070@isc.org> <3N898.13340$Zu6.55955@news-server.bigpond.net.au> <u6argep8r8l2c2@corp.supernews.com> <Xns91B0C720E8590grahamdrabblelineone@ID-77355.user.dfncis.de> <a440uv$r73$2@dent.deepthot.org> <u6b36tthfaecfb@corp.supernews.com>   1235    23      Xref: inn.example.com news.groups:47
-news.groups:48 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 11:48:18 -0800 <yly9i1f799.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylheop22ug.fsf@windlord.stanford.edu> <a46ec6$lee$1@samba.rahul.net> <ylpu3dgoni.fsf@windlord.stanford.edu> <a46i88$m4m$1@samba.rahul.net>  1563    32      Xref: inn.example.com news.groups:48
-news.groups:49 Re: 2nd RFD: sci.space.moderated moderated      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 12:12:17 -0800 <ylsn89f65a.fsf@windlord.stanford.edu>  <1010713186.32070@isc.org> <a440uv$r73$2@dent.deepthot.org> <u6b36tthfaecfb@corp.supernews.com> <a448lr$il$1@dent.deepthot.org> <3c65d1dc$0$67479$892e7fe2@authen.puce.readfreenews.net>        3599    70      Xref: inn.example.com news.groups:49
-news.groups:50 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 14:31:08 -0800 <yly9i1as0j.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com>       1723    38      Xref: inn.example.com news.groups:50
-gnu.emacs.gnus:1       Re: Gnus, Postings, and Anti-spam?      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 14:37:51 -0800 <ylheoparpc.fsf@windlord.stanford.edu>  <ubsezbqfg.fsf@synopsys.com> <geg.y1ysn8apwb0.fsf@fly.verified.de> <eljuvgy6.fsf@ichimusai.org> <geg.y1y3d0apg8z.fsf@fly.verified.de> <vgd52d4a.fsf@ichimusai.org>      862     23      Xref: inn.example.com gnu.emacs.gnus:1
-news.groups:53 Re: Professional practice (was Re: RESULT: sci.military.nuclear-bio-chem fails 73:25)   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 18:37:01 -0800 <yl8za0agmq.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com> <yly9i1as0j.fsf@windlord.stanford.edu> <a474cg$qou$1@panix2.panix.com>        1274    30      Xref: inn.example.com news.groups:53
-news.groups:56 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 20:01:15 -0800 <yleljs8y5w.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com> <yly9i1as0j.fsf@windlord.stanford.edu> <a47aeg01e39@enews3.newsguy.com>       1482    35      Xref: inn.example.com news.groups:56
-news.admin.technical:2 Re: Maximum Length of Newsgroup Description field       Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 13:05:47 -0800 <ylit9391as.fsf@windlord.stanford.edu>  <Xns91B278CC1107Djaydejaydenet@157.54.3.22>     526     12      Xref: inn.example.com news.admin.technical:2
-gnu.emacs.gnus:2       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 15:55:01 -0800 <ylheon7ewa.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <m0it9339nj.fsf@k2.onsight.com>      175     8       Xref: inn.example.com gnu.emacs.gnus:2
-gnu.emacs.gnus:6       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 15:56:50 -0800 <ylbsev7et9.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> 1021    23      Xref: inn.example.com gnu.emacs.gnus:6
-news.software.nntp:13  Re: rebuilding overview with makehistory        Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 18:14:40 -0800 <ylofiv5tv3.fsf@windlord.stanford.edu>  <slrna6gcn5.nmf.br@panix2.panix.com>    687     20      Xref: inn.example.com news.software.nntp:13
-news.software.nntp:14  Re: rebuilding overview with makehistory        Russ Allbery <rra@stanford.edu> Tue, 12 Feb 2002 11:15:20 -0800 <yladuefr5j.fsf@windlord.stanford.edu>  <slrna6gcn5.nmf.br@panix2.panix.com> <ylofiv5tv3.fsf@windlord.stanford.edu> <slrna6ig0n.qig.br@panix2.panix.com>        505     13      Xref: inn.example.com news.software.nntp:14
-gnu.emacs.gnus:7       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Tue, 12 Feb 2002 12:07:06 -0800 <ylwuxia2hh.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> <ylbsev7et9.fsf@windlord.stanford.edu> <ilu665235iy.fsf@extundo.com>    426     11      Xref: inn.example.com gnu.emacs.gnus:7
-gnu.emacs.gnus:8       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Wed, 13 Feb 2002 13:46:55 -0800 <yl3d05awc0.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> <ylbsev7et9.fsf@windlord.stanford.edu> <ilu665235iy.fsf@extundo.com> <ylwuxia2hh.fsf@windlord.stanford.edu> <1yfpzc36.fsf@hschmi22.userfqdn.rz-online.de>       326     11      Xref: inn.example.com gnu.emacs.gnus:8
-news.software.nntp:15  Re: chan.c problem with INN 2.3.[012] on AIX 4.2        Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 11:49:28 -0800 <yl7kpfq1x3.fsf@windlord.stanford.edu>  <fa8727e8.0202141109.7875ddc@posting.google.com>        1449    42      Xref: inn.example.com news.software.nntp:15
-news.groups:57 Re: comp.distributed again?     Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 13:43:52 -0800 <ylu1sjkacn.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a4co04$d94$1@slb2.atl.mindspring.net> <a4edc2$uds$5@dent.deepthot.org> <a4frn0$71f$1@slb3.atl.mindspring.net> <a4frot$inj$8@dent.deepthot.org>      360     10      Xref: inn.example.com news.groups:57
-news.groups:58 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 21:40:08 -0800 <ylvgczi9qf.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com> <3c6038d6.774936@news.storm.ca> <a3pg75$3vk$1@gw.retro.com> <3c604f11.3004891@news.storm.ca> <3n516u0ahojobsdiknc99l00f0euoujb60@4ax.com> <3C60A31C.A5D832F7@elepar.com> <slrna6lpis.6k8.dbt@pianosa.catch22.org> <3C6B5EA3.4A10@mcimail.com> <slrna6p6q1.4c8.dbt@pianosa.catch22.org>  718     17      Xref: inn.example.com news.groups:58
-news.groups:59 Re: Professional practice (was Re: RESULT: sci.military.nuclear-bio-chem fails 73:25)   Russ Allbery <rra@stanford.edu> Fri, 15 Feb 2002 19:59:06 -0800 <ylofiq6prp.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yly9i1as0j.fsf@windlord.stanford.edu> <a474cg$qou$1@panix2.panix.com> <yl8za0agmq.fsf@windlord.stanford.edu> <a4jcua$nqo$1@panix2.panix.com>        500     12      Xref: inn.example.com news.groups:59
-news.groups:260        Re: [History] The Guidelines:  a preliminary revision history   Russ Allbery <rra@stanford.edu> Sat, 16 Feb 2002 12:47:46 -0800 <yleljlnogd.fsf@windlord.stanford.edu>  <dbc8daca.0202161159.4c0a1eee@posting.google.com>       7082    173     Xref: inn.example.com news.groups:60
-news.groups:464        Re: [History] The Guidelines:  a preliminary revision history   Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 00:05:02 -0800 <ylbseoh6tt.fsf@windlord.stanford.edu>  <dbc8daca.0202161159.4c0a1eee@posting.google.com> <yleljlnogd.fsf@windlord.stanford.edu> <dbc8daca.0202162324.1ce3b411@posting.google.com>      845     22      Xref: inn.example.com news.groups:64
-news.admin.net-abuse.policy:11 Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 13:58:51 -0800 <yllmdrdb38.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <87pu3mj826.fsf@erlenstar.demon.co.uk> <3mqs5us2puq2ov9gpqn7cqn8hhstojsesj@4ax.com> <b2059324.0202170829.47a7abce@posting.google.com> <3C7022DC.2F2E87DF@trin.ity> 546     11      Xref: inn.example.com news.admin.net-abuse.policy:11
-news.software.nntp:16  Re: [yEnc] some newbie questions        Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 15:43:07 -0800 <ylpu33brp0.fsf@windlord.stanford.edu>  <3c6e6798.9093644@news> <a4kc41$ou1$2@pegasus.csx.cam.ac.uk> <3c702e8c.7007252@news>    1000    24      Xref: inn.example.com news.software.nntp:16
-news.software.nntp:17  Re: RFC 977 extensions? Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 13:46:21 -0800 <ylvgcu31le.fsf@windlord.stanford.edu>  <Xns91B9E610EE161M8@62.2.16.82> 786     21      Xref: inn.example.com news.software.nntp:17
-gnu.misc.discuss:2     Re: Money matters       Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 18:27:36 -0800 <yl3czyyzmv.fsf@windlord.stanford.edu>  <1629dcd9.0202160842.36e8bdab@posting.google.com> <C4cc8.17$X5.109616@burlma1-snr2> <87heoek2h5.fsf@toncho.dhh.gt.org> <Rvhc8.29$X5.122317@burlma1-snr2>        1014    21      Xref: inn.example.com gnu.misc.discuss:2
-gnu.misc.discuss:3     Re: Money matters       Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 20:12:07 -0800 <ylr8nixg88.fsf@windlord.stanford.edu>  <1629dcd9.0202160842.36e8bdab@posting.google.com> <C4cc8.17$X5.109616@burlma1-snr2> <87heoek2h5.fsf@toncho.dhh.gt.org> <Rvhc8.29$X5.122317@burlma1-snr2> <yl3czyyzmv.fsf@windlord.stanford.edu> <slrna73glj.9cp.jmaynard@thebrain.conmicro.cx>  1896    35      Xref: inn.example.com gnu.misc.discuss:3
-news.software.nntp:18  Re: [yEnc] some newbie questions        Russ Allbery <rra@stanford.edu> Tue, 19 Feb 2002 10:34:36 -0800 <yleljh722r.fsf@windlord.stanford.edu>  <3c6e6798.9093644@news> <a4kc41$ou1$2@pegasus.csx.cam.ac.uk> <3c702e8c.7007252@news> <a4pknt$4pg$2@pegasus.csx.cam.ac.uk> <53488.j22209@archiver.winews.net>    872     21      Xref: inn.example.com news.software.nntp:18
-news.software.nntp:19  Re: Usefor: Message/external-body - any experiences ?   Russ Allbery <rra@stanford.edu> Tue, 19 Feb 2002 10:36:56 -0800 <yl8z9p71yv.fsf@windlord.stanford.edu>  <5955a.j22200@archiver.winews.net>      921     22      Xref: inn.example.com news.software.nntp:19
-news.software.nntp:20  Re: "Recomended Format of Usenet Articles with 8-bit Attachements" (yEnc)       Russ Allbery <rra@stanford.edu> Wed, 20 Feb 2002 13:49:54 -0800 <ylwux7su0t.fsf@windlord.stanford.edu>  <3c7615d0.11232095@news>        1280    30      Xref: inn.example.com news.software.nntp:20
-news.software.nntp:21  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 16:40:59 -0800 <yleljecpr8.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com>  1560    35      Xref: inn.example.com news.software.nntp:21
-news.software.nntp:22  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 21:35:01 -0800 <ylr8ne6pve.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com>    1560    38      Xref: inn.example.com news.software.nntp:22
-news.software.nntp:23  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 23:57:04 -0800 <ylvgcq3q5r.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com> <ylr8ne6pve.fsf@windlord.stanford.edu> <20020222021334.828$pl@newsreader.com>      2024    48      Xref: inn.example.com news.software.nntp:23
-news.software.nntp:24  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Fri, 22 Feb 2002 10:24:51 -0800 <ylu1s9nzm4.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com> <ylr8ne6pve.fsf@windlord.stanford.edu> <20020222021334.828$pl@newsreader.com> <ylvgcq3q5r.fsf@windlord.stanford.edu> <20020222120943.799$AG@newsreader.com>        1353    29      Xref: inn.example.com news.software.nntp:24
-news.admin.hierarchies:19      Re: Draft hierarchies intro for news.announce.newusers  Russ Allbery <rra@stanford.edu> Fri, 22 Feb 2002 12:35:43 -0800 <ylbsehjluo.fsf@windlord.stanford.edu>  <Grp0uH.Gop@presby.edu> <3ik45a.06k.ln@erik.selwerd.nl> <wVpd8.37121$gW4.19914136@news1.rdc1.mi.home.com> <duac7uk00n416m5vn6lo21qupuo9il6mtk@4ax.com>  888     23      Xref: inn.example.com news.admin.hierarchies:19
diff --git a/tests/overview/data/bogus b/tests/overview/data/bogus
deleted file mode 100644 (file)
index 934bb36..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-..foo..:7498   Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-1@example.com>            481     16      Xref: inn.example.com ..foo..:7498
-../..:7498     Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-2@example.com>            481     16      Xref: inn.example.com ../..:7498
-/:7498 Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-3@example.com>            481     16      Xref: inn.example.com /:7498
-bar..:7498     Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-4@example.com>            481     16      Xref: inn.example.com bar..:7498
-bar../:7498    Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-5@example.com>            481     16      Xref: inn.example.com bar../:7498
-/../foo:1      Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-6@example.com>            481     16      Xref: inn.example.com /../foo:1
-.:1    Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-7@example.com>            481     16      Xref: inn.example.com .:1
-////:7498      Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-8@example.com>            481     16      Xref: inn.example.com ////:7498
-foo..bar:1     Bogus newsgroup name    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-9@example.com>            481     16      Xref: inn.example.com foo..bar:1
diff --git a/tests/overview/data/high-numbered b/tests/overview/data/high-numbered
deleted file mode 100644 (file)
index 4365699..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-example.test:7498      High-numbered test article      Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-1@example.com>            481     16      Xref: inn.example.com example.test:7498
-example.test:7499      High-numbered test article      Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <test-2@example.com>    <test-1@example.com>    481     16      Xref: inn.example.com example.test:7499
diff --git a/tests/overview/data/reversed b/tests/overview/data/reversed
deleted file mode 100644 (file)
index aa7bd9c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-news.admin.hierarchies:19      Re: Draft hierarchies intro for news.announce.newusers  Russ Allbery <rra@stanford.edu> Fri, 22 Feb 2002 12:35:43 -0800 <ylbsehjluo.fsf@windlord.stanford.edu>  <Grp0uH.Gop@presby.edu> <3ik45a.06k.ln@erik.selwerd.nl> <wVpd8.37121$gW4.19914136@news1.rdc1.mi.home.com> <duac7uk00n416m5vn6lo21qupuo9il6mtk@4ax.com>  888     23      Xref: inn.example.com news.admin.hierarchies:19
-news.software.nntp:24  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Fri, 22 Feb 2002 10:24:51 -0800 <ylu1s9nzm4.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com> <ylr8ne6pve.fsf@windlord.stanford.edu> <20020222021334.828$pl@newsreader.com> <ylvgcq3q5r.fsf@windlord.stanford.edu> <20020222120943.799$AG@newsreader.com>        1353    29      Xref: inn.example.com news.software.nntp:24
-news.software.nntp:23  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 23:57:04 -0800 <ylvgcq3q5r.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com> <ylr8ne6pve.fsf@windlord.stanford.edu> <20020222021334.828$pl@newsreader.com>      2024    48      Xref: inn.example.com news.software.nntp:23
-news.software.nntp:22  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 21:35:01 -0800 <ylr8ne6pve.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com> <yleljecpr8.fsf@windlord.stanford.edu> <20020221224023.453$bg@newsreader.com>    1560    38      Xref: inn.example.com news.software.nntp:22
-news.software.nntp:21  Re: [yEnc] Survey time! (Compression or not?)   Russ Allbery <rra@stanford.edu> Thu, 21 Feb 2002 16:40:59 -0800 <yleljecpr8.fsf@windlord.stanford.edu>  <a504os$736$6@pegasus.csx.cam.ac.uk> <200220022141483852%planb@newsreaders.com> <20020220230116.405$a3@newsreader.com> <1014270020.729921@ok-corral.gunslinger.net> <20020221152617.647$FV@newsreader.com> <a53ut8$7i4$4@pegasus.csx.cam.ac.uk> <20020221183904.819$lz@newsreader.com>  1560    35      Xref: inn.example.com news.software.nntp:21
-news.software.nntp:20  Re: "Recomended Format of Usenet Articles with 8-bit Attachements" (yEnc)       Russ Allbery <rra@stanford.edu> Wed, 20 Feb 2002 13:49:54 -0800 <ylwux7su0t.fsf@windlord.stanford.edu>  <3c7615d0.11232095@news>        1280    30      Xref: inn.example.com news.software.nntp:20
-news.software.nntp:19  Re: Usefor: Message/external-body - any experiences ?   Russ Allbery <rra@stanford.edu> Tue, 19 Feb 2002 10:36:56 -0800 <yl8z9p71yv.fsf@windlord.stanford.edu>  <5955a.j22200@archiver.winews.net>      921     22      Xref: inn.example.com news.software.nntp:19
-news.software.nntp:18  Re: [yEnc] some newbie questions        Russ Allbery <rra@stanford.edu> Tue, 19 Feb 2002 10:34:36 -0800 <yleljh722r.fsf@windlord.stanford.edu>  <3c6e6798.9093644@news> <a4kc41$ou1$2@pegasus.csx.cam.ac.uk> <3c702e8c.7007252@news> <a4pknt$4pg$2@pegasus.csx.cam.ac.uk> <53488.j22209@archiver.winews.net>    872     21      Xref: inn.example.com news.software.nntp:18
-gnu.misc.discuss:3     Re: Money matters       Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 20:12:07 -0800 <ylr8nixg88.fsf@windlord.stanford.edu>  <1629dcd9.0202160842.36e8bdab@posting.google.com> <C4cc8.17$X5.109616@burlma1-snr2> <87heoek2h5.fsf@toncho.dhh.gt.org> <Rvhc8.29$X5.122317@burlma1-snr2> <yl3czyyzmv.fsf@windlord.stanford.edu> <slrna73glj.9cp.jmaynard@thebrain.conmicro.cx>  1896    35      Xref: inn.example.com gnu.misc.discuss:3
-gnu.misc.discuss:2     Re: Money matters       Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 18:27:36 -0800 <yl3czyyzmv.fsf@windlord.stanford.edu>  <1629dcd9.0202160842.36e8bdab@posting.google.com> <C4cc8.17$X5.109616@burlma1-snr2> <87heoek2h5.fsf@toncho.dhh.gt.org> <Rvhc8.29$X5.122317@burlma1-snr2>        1014    21      Xref: inn.example.com gnu.misc.discuss:2
-news.software.nntp:17  Re: RFC 977 extensions? Russ Allbery <rra@stanford.edu> Mon, 18 Feb 2002 13:46:21 -0800 <ylvgcu31le.fsf@windlord.stanford.edu>  <Xns91B9E610EE161M8@62.2.16.82> 786     21      Xref: inn.example.com news.software.nntp:17
-news.software.nntp:16  Re: [yEnc] some newbie questions        Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 15:43:07 -0800 <ylpu33brp0.fsf@windlord.stanford.edu>  <3c6e6798.9093644@news> <a4kc41$ou1$2@pegasus.csx.cam.ac.uk> <3c702e8c.7007252@news>    1000    24      Xref: inn.example.com news.software.nntp:16
-news.admin.net-abuse.policy:11 Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 13:58:51 -0800 <yllmdrdb38.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <87pu3mj826.fsf@erlenstar.demon.co.uk> <3mqs5us2puq2ov9gpqn7cqn8hhstojsesj@4ax.com> <b2059324.0202170829.47a7abce@posting.google.com> <3C7022DC.2F2E87DF@trin.ity> 546     11      Xref: inn.example.com news.admin.net-abuse.policy:11
-news.groups:464        Re: [History] The Guidelines:  a preliminary revision history   Russ Allbery <rra@stanford.edu> Sun, 17 Feb 2002 00:05:02 -0800 <ylbseoh6tt.fsf@windlord.stanford.edu>  <dbc8daca.0202161159.4c0a1eee@posting.google.com> <yleljlnogd.fsf@windlord.stanford.edu> <dbc8daca.0202162324.1ce3b411@posting.google.com>      845     22      Xref: inn.example.com news.groups:64
-news.groups:260        Re: [History] The Guidelines:  a preliminary revision history   Russ Allbery <rra@stanford.edu> Sat, 16 Feb 2002 12:47:46 -0800 <yleljlnogd.fsf@windlord.stanford.edu>  <dbc8daca.0202161159.4c0a1eee@posting.google.com>       7082    173     Xref: inn.example.com news.groups:60
-news.groups:59 Re: Professional practice (was Re: RESULT: sci.military.nuclear-bio-chem fails 73:25)   Russ Allbery <rra@stanford.edu> Fri, 15 Feb 2002 19:59:06 -0800 <ylofiq6prp.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yly9i1as0j.fsf@windlord.stanford.edu> <a474cg$qou$1@panix2.panix.com> <yl8za0agmq.fsf@windlord.stanford.edu> <a4jcua$nqo$1@panix2.panix.com>        500     12      Xref: inn.example.com news.groups:59
-news.groups:58 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 21:40:08 -0800 <ylvgczi9qf.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com> <3c6038d6.774936@news.storm.ca> <a3pg75$3vk$1@gw.retro.com> <3c604f11.3004891@news.storm.ca> <3n516u0ahojobsdiknc99l00f0euoujb60@4ax.com> <3C60A31C.A5D832F7@elepar.com> <slrna6lpis.6k8.dbt@pianosa.catch22.org> <3C6B5EA3.4A10@mcimail.com> <slrna6p6q1.4c8.dbt@pianosa.catch22.org>  718     17      Xref: inn.example.com news.groups:58
-news.groups:57 Re: comp.distributed again?     Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 13:43:52 -0800 <ylu1sjkacn.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a4co04$d94$1@slb2.atl.mindspring.net> <a4edc2$uds$5@dent.deepthot.org> <a4frn0$71f$1@slb3.atl.mindspring.net> <a4frot$inj$8@dent.deepthot.org>      360     10      Xref: inn.example.com news.groups:57
-news.software.nntp:15  Re: chan.c problem with INN 2.3.[012] on AIX 4.2        Russ Allbery <rra@stanford.edu> Thu, 14 Feb 2002 11:49:28 -0800 <yl7kpfq1x3.fsf@windlord.stanford.edu>  <fa8727e8.0202141109.7875ddc@posting.google.com>        1449    42      Xref: inn.example.com news.software.nntp:15
-gnu.emacs.gnus:8       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Wed, 13 Feb 2002 13:46:55 -0800 <yl3d05awc0.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> <ylbsev7et9.fsf@windlord.stanford.edu> <ilu665235iy.fsf@extundo.com> <ylwuxia2hh.fsf@windlord.stanford.edu> <1yfpzc36.fsf@hschmi22.userfqdn.rz-online.de>       326     11      Xref: inn.example.com gnu.emacs.gnus:8
-gnu.emacs.gnus:7       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Tue, 12 Feb 2002 12:07:06 -0800 <ylwuxia2hh.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> <ylbsev7et9.fsf@windlord.stanford.edu> <ilu665235iy.fsf@extundo.com>    426     11      Xref: inn.example.com gnu.emacs.gnus:7
-news.software.nntp:14  Re: rebuilding overview with makehistory        Russ Allbery <rra@stanford.edu> Tue, 12 Feb 2002 11:15:20 -0800 <yladuefr5j.fsf@windlord.stanford.edu>  <slrna6gcn5.nmf.br@panix2.panix.com> <ylofiv5tv3.fsf@windlord.stanford.edu> <slrna6ig0n.qig.br@panix2.panix.com>        505     13      Xref: inn.example.com news.software.nntp:14
-news.software.nntp:13  Re: rebuilding overview with makehistory        Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 18:14:40 -0800 <ylofiv5tv3.fsf@windlord.stanford.edu>  <slrna6gcn5.nmf.br@panix2.panix.com>    687     20      Xref: inn.example.com news.software.nntp:13
-gnu.emacs.gnus:6       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 15:56:50 -0800 <ylbsev7et9.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <uy9hzy4yp.fsf@synopsys.com> 1021    23      Xref: inn.example.com gnu.emacs.gnus:6
-gnu.emacs.gnus:2       Re: modifying Sender: to (valid) From: of gnus-posting-styles   Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 15:55:01 -0800 <ylheon7ewa.fsf@windlord.stanford.edu>  <m0it93yajy.fsf@k2.onsight.com> <vxkbsevzlcc.fsf@cinnamon.vanillaknot.com> <m0it9339nj.fsf@k2.onsight.com>      175     8       Xref: inn.example.com gnu.emacs.gnus:2
-news.admin.technical:2 Re: Maximum Length of Newsgroup Description field       Russ Allbery <rra@stanford.edu> Mon, 11 Feb 2002 13:05:47 -0800 <ylit9391as.fsf@windlord.stanford.edu>  <Xns91B278CC1107Djaydejaydenet@157.54.3.22>     526     12      Xref: inn.example.com news.admin.technical:2
-news.groups:56 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 20:01:15 -0800 <yleljs8y5w.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com> <yly9i1as0j.fsf@windlord.stanford.edu> <a47aeg01e39@enews3.newsguy.com>       1482    35      Xref: inn.example.com news.groups:56
-news.groups:53 Re: Professional practice (was Re: RESULT: sci.military.nuclear-bio-chem fails 73:25)   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 18:37:01 -0800 <yl8za0agmq.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com> <yly9i1as0j.fsf@windlord.stanford.edu> <a474cg$qou$1@panix2.panix.com>        1274    30      Xref: inn.example.com news.groups:53
-gnu.emacs.gnus:1       Re: Gnus, Postings, and Anti-spam?      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 14:37:51 -0800 <ylheoparpc.fsf@windlord.stanford.edu>  <ubsezbqfg.fsf@synopsys.com> <geg.y1ysn8apwb0.fsf@fly.verified.de> <eljuvgy6.fsf@ichimusai.org> <geg.y1y3d0apg8z.fsf@fly.verified.de> <vgd52d4a.fsf@ichimusai.org>      862     23      Xref: inn.example.com gnu.emacs.gnus:1
-news.groups:50 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 14:31:08 -0800 <yly9i1as0j.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com> <yln0yh22y7.fsf@windlord.stanford.edu> <3c68f0c2.3904908@supernews.seanet.com>       1723    38      Xref: inn.example.com news.groups:50
-news.groups:49 Re: 2nd RFD: sci.space.moderated moderated      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 12:12:17 -0800 <ylsn89f65a.fsf@windlord.stanford.edu>  <1010713186.32070@isc.org> <a440uv$r73$2@dent.deepthot.org> <u6b36tthfaecfb@corp.supernews.com> <a448lr$il$1@dent.deepthot.org> <3c65d1dc$0$67479$892e7fe2@authen.puce.readfreenews.net>        3599    70      Xref: inn.example.com news.groups:49
-news.groups:48 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 11:48:18 -0800 <yly9i1f799.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylheop22ug.fsf@windlord.stanford.edu> <a46ec6$lee$1@samba.rahul.net> <ylpu3dgoni.fsf@windlord.stanford.edu> <a46i88$m4m$1@samba.rahul.net>  1563    32      Xref: inn.example.com news.groups:48
-news.groups:47 Re: 2nd RFD: sci.space.moderated moderated      Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 10:54:24 -0800 <ylk7tlgobj.fsf@windlord.stanford.edu>  <1010713186.32070@isc.org> <3N898.13340$Zu6.55955@news-server.bigpond.net.au> <u6argep8r8l2c2@corp.supernews.com> <Xns91B0C720E8590grahamdrabblelineone@ID-77355.user.dfncis.de> <a440uv$r73$2@dent.deepthot.org> <u6b36tthfaecfb@corp.supernews.com>   1235    23      Xref: inn.example.com news.groups:47
-news.groups:46 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 10:47:13 -0800 <ylpu3dgoni.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <yllme3azio.fsf@windlord.stanford.edu> <a44mu80urn@enews2.newsguy.com> <ylheop22ug.fsf@windlord.stanford.edu> <a46ec6$lee$1@samba.rahul.net> 1052    28      Xref: inn.example.com news.groups:46
-news.software.nntp:12  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Sun, 10 Feb 2002 09:32:55 -0800 <yl8za1kzso.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <yl3d0a8ibo.fsf@windlord.stanford.edu> <21049.a22200@archiver.winews.net>  1915    40      Xref: inn.example.com news.software.nntp:12
-news.groups:44 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 23:49:43 -0800 <ylheop22ug.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <a44mu80urn@enews2.newsguy.com>     810     16      Xref: inn.example.com news.groups:44
-news.groups:43 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 23:47:28 -0800 <yln0yh22y7.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net> <yllme3azio.fsf@windlord.stanford.edu> <GrAr0y.AsA@world.std.com>      2306    45      Xref: inn.example.com news.groups:43
-news.software.nntp:11  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 13:18:51 -0800 <yl3d0a8ibo.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <ylit9723rb.fsf@windlord.stanford.edu> <2504c.922202@archiver.winews.net>  1075    27      Xref: inn.example.com news.software.nntp:11
-comp.lang.perl.moderated:1     Re: perldoc vs man why so much slower   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:47:26 -0800 <yl8za28js1.fsf@windlord.stanford.edu>  <m1d6zfnl9h.fsf@reader.newsguy.com> <20020209180911.23756.qmail@plover.com>     799     20      Xref: inn.example.com comp.lang.perl.moderated:1
-news.admin.hierarchies:18      Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:25:07 -0800 <ylvgd68kt8.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain> <ylu1srclla.fsf@windlord.stanford.edu> <m37kpmdayt.fsf@defun.localdomain>  580     18      Xref: inn.example.com news.admin.hierarchies:18
-news.groups:42 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:20:01 -0800 <yl1yfu9zm6.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3uq5f$n81$1@news.orst.edu> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <3c651972$0$67480$892e7fe2@authen.puce.readfreenews.net>    990     19      Xref: inn.example.com news.groups:42
-news.admin.hierarchies:13      Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Sat, 09 Feb 2002 12:00:56 -0800 <yl8za2a0hz.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de>       905     23      Xref: inn.example.com news.admin.hierarchies:13
-news.groups:41 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 23:24:31 -0800 <yllme3azio.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> <ylsn8b76ad.fsf@windlord.stanford.edu> <a42f8b$rfj$1@samba.rahul.net>    1282    26      Xref: inn.example.com news.groups:41
-news.admin.hierarchies:12      Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 20:42:25 -0800 <ylu1srclla.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain>    505     14      Xref: inn.example.com news.admin.hierarchies:12
-news.groups:40 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 18:11:54 -0800 <ylsn8b76ad.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3tb6q$i69$1@gw.retro.com> <a3uq5f$n81$1@news.orst.edu> <a3v87u$ihf$1@panix2.panix.com> <a409ek$qc8$1@gw.retro.com> 1995    40      Xref: inn.example.com news.groups:40
-news.software.nntp:10  Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 12:15:43 -0800 <ylsn8bwx00.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net> <ylit9723rb.fsf@windlord.stanford.edu> <C2W88.119862$i3.977629@news.easynews.com>  749     19      Xref: inn.example.com news.software.nntp:10
-news.software.nntp:9   Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 11:05:28 -0800 <ylit9723rb.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net> <a405vd$huq$1@newsread4.arcor-online.net>    556     16      Xref: inn.example.com news.software.nntp:9
-news.software.nntp:6   Re: innd and Microsoft Exchange Russ Allbery <rra@stanford.edu> Fri, 08 Feb 2002 11:04:25 -0800 <ylofiz23t2.fsf@windlord.stanford.edu>  <623f5703.0202070541.2b943211@posting.google.com> <yleljx41dn.fsf@windlord.stanford.edu> <3C63AD90.492F3C00@eproduction.ch>     541     14      Xref: inn.example.com news.software.nntp:6
-news.software.nntp:5   Re: innd and Microsoft Exchange Russ Allbery <rra@stanford.edu> Thu, 07 Feb 2002 10:01:40 -0800 <yleljx41dn.fsf@windlord.stanford.edu>  <623f5703.0202070541.2b943211@posting.google.com>       1013    21      Xref: inn.example.com news.software.nntp:5
-news.groups:39 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Thu, 07 Feb 2002 00:46:46 -0800 <yl3d0dn0g9.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com> <yl8za5n769.fsf@windlord.stanford.edu> <a3tb6q$i69$1@gw.retro.com>      5108    96      Xref: inn.example.com news.groups:39
-news.groups:38 Re: RESULT: sci.military.nuclear-bio-chem fails 73:25   Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 22:21:34 -0800 <yl8za5n769.fsf@windlord.stanford.edu>  <1012432821.79903@isc.org> <1j6l5u499l6ru00rn6ibje0cgsv32jkrk1@4ax.com> <a3f1oq02gd2@enews3.newsguy.com> <a3obho02a17@enews2.newsguy.com> <a3pcp9$3d8$1@gw.retro.com>   1093    26      Xref: inn.example.com news.groups:38
-news.admin.hierarchies:11      Re: control.ctl maintenance (was: [INFO] bc.* and van.*)        Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 16:20:13 -0800 <yleljyp2gy.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> <yllme6s1np.fsf@windlord.stanford.edu> <EKi88.17124$gW4.11422684@news1.rdc1.mi.home.com>   688     18      Xref: inn.example.com news.admin.hierarchies:11
-news.admin.hierarchies:7       Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 16:19:10 -0800 <ylk7tqp2ip.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3ptk7.3vuai51.1@mid.glglgl.de> <a3qmdq$1akiad$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> <yllme6s1np.fsf@windlord.stanford.edu> <a3sbmu$1ao4a2$1@ID-80930.news.dfncis.de>        421     11      Xref: inn.example.com news.admin.hierarchies:7
-news.admin.hierarchies:4       Re: [INFO] bc.* and van.*       Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 14:09:30 -0800 <yllme6s1np.fsf@windlord.stanford.edu>  <a36mup$160fpd$1@ID-80930.news.dfncis.de> <a3ptk7.3vuai51.1@mid.glglgl.de> <a3qmdq$1akiad$1@ID-80930.news.dfncis.de> <a3qseq.3vue8up.1@mid.glglgl.de> <a3qvtt$19gllq$1@ID-80930.news.dfncis.de> 972     20      Xref: inn.example.com news.admin.hierarchies:4
-news.admin.hierarchies:3       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 14:00:23 -0800 <yl8za6tgnc.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain> <yl665bqhku.fsf@windlord.stanford.edu> <m3lme68jz6.fsf@defun.localdomain>  478     17      Xref: inn.example.com news.admin.hierarchies:3
-news.admin.net-abuse.policy:10 Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:58:09 -0800 <yleljytgr2.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com> <ylr8ny7eaf.fsf@windlord.stanford.edu> <1013015167.535798@ok-corral.gunslinger.net>   548     13      Xref: inn.example.com news.admin.net-abuse.policy:10
-news.admin.net-abuse.policy:9  Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:57:38 -0800 <ylk7tqtgrx.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com> <ylr8ny7eaf.fsf@windlord.stanford.edu> <878za6o8h5.fsf@erlenstar.demon.co.uk> 578     16      Xref: inn.example.com news.admin.net-abuse.policy:9
-news.software.nntp:4   Re: first > last        Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 13:50:15 -0800 <yly9i6uvoo.fsf@windlord.stanford.edu>  <3C61951F.8080606@gemal.dk>     850     19      Xref: inn.example.com news.software.nntp:4
-news.software.nntp:3   Re: Trailing spaces in body  on  INN 2.3.3 ?    Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 08:45:04 -0800 <yllme67e5r.fsf@windlord.stanford.edu>  <52419.622207@archiver.winews.net>      852     21      Xref: inn.example.com news.software.nntp:3
-news.admin.net-abuse.policy:8  Re: [RETROMODERATION]    teenfem terrorists     Russ Allbery <rra@stanford.edu> Wed, 06 Feb 2002 08:42:16 -0800 <ylr8ny7eaf.fsf@windlord.stanford.edu>  <6f826u0dag3c5gosbps2elao0scnu38k0p@news-01.easynews.com>       740     18      Xref: inn.example.com news.admin.net-abuse.policy:8
-news.admin.hierarchies:2       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 21:56:17 -0800 <yl665bqhku.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain> <yl7kprjrx4.fsf@windlord.stanford.edu> <m3y9i7xluu.fsf@defun.localdomain>    828     19      Xref: inn.example.com news.admin.hierarchies:2
-news.software.nntp:2   Re: INN on another user/group   Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 19:14:03 -0800 <ylg04fs3no.fsf@windlord.stanford.edu>  <3c609757$0$20968$afc38c87@news.optusnet.com.au>        593     15      Xref: inn.example.com news.software.nntp:2
-news.groups:37 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 18:07:55 -0800 <ylvgdbicqs.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net> <3C608D3D.C87E3610@diogenes.sacramento.ca.us>    623     13      Xref: inn.example.com news.groups:37
-news.admin.hierarchies:1       Re: Are the active files at ftp.isc.org maintained?     Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:54:47 -0800 <yl7kprjrx4.fsf@windlord.stanford.edu>  <m3lme7zhep.fsf@defun.localdomain>      877     21      Xref: inn.example.com news.admin.hierarchies:1
-news.admin.technical:1 Re: nnrpd       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:53:18 -0800 <yld6zjjrzl.fsf@windlord.stanford.edu>  <a3psen$7p4$1@quasar.ctc.edu>   543     13      Xref: inn.example.com news.admin.technical:1
-news.groups:36 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:51:33 -0800 <ylit9bjs2i.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <Xns91AD188E6226grahamdrabblelineone@ID-77355.user.dfncis.de>   1067    21      Xref: inn.example.com news.groups:36
-news.groups:34 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:46:28 -0800 <ylofj3jsaz.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net> <m2k7trcxes.fsf@dan.jacobson.tw> <3C6077F5.AE1C5ED8@sfo.com>     882     22      Xref: inn.example.com news.groups:34
-news.software.nntp:1   Re: peering under the storage API       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 17:04:13 -0800 <ylit9bl8tu.fsf@windlord.stanford.edu>  <slrna60q6l.3fo.br@panix2.panix.com>    546     14      Xref: inn.example.com news.software.nntp:1
-news.admin.net-abuse.policy:7  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Tue, 05 Feb 2002 08:52:18 -0800 <yl4rkvx459.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com> <ylr8o1xb4b.fsf@windlord.stanford.edu> <Gr1CnE.Iny@world.std.com> <ylk7tsofmi.fsf@windlord.stanford.edu> <Gr1LLx.6xF@world.std.com>   3618    69      Xref: inn.example.com news.admin.net-abuse.policy:7
-news.groups:33 Re: CFV: sci.geo.cartography    Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 19:04:16 -0800 <ylheowbpe7.fsf@windlord.stanford.edu>  <1010622320.26971@isc.org> <1012843693.45036@isc.org> <3c5f4805$0$36783$892e7fe2@authen.puce.readfreenews.net>  851     17      Xref: inn.example.com news.groups:33
-news.groups:32 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 19:02:56 -0800 <yln0yobpgf.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com> <yl4rkwu8mx.fsf@windlord.stanford.edu> <a3n74c026se@enews4.newsguy.com> <ylofj4rcf0.fsf@windlord.stanford.edu> <a3nbva02f0r@enews4.newsguy.com>    1280    26      Xref: inn.example.com news.groups:32
-news.admin.net-abuse.policy:6  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 17:56:53 -0800 <ylk7tsofmi.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com> <ylr8o1xb4b.fsf@windlord.stanford.edu> <Gr1CnE.Iny@world.std.com>     961     18      Xref: inn.example.com news.admin.net-abuse.policy:6
-news.groups:27 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 16:37:55 -0800 <ylofj4rcf0.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com> <yl4rkwu8mx.fsf@windlord.stanford.edu> <a3n74c026se@enews4.newsguy.com>    899     22      Xref: inn.example.com news.groups:27
-news.groups:26 Re: [META RFD] Removal of low traffic groups.   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 15:31:18 -0800 <yl4rkwu8mx.fsf@windlord.stanford.edu>  <Xns91A5EF6DA9BCEgrahamdrabblelineone@ID-77355.user.dfncis.de> <3c5f0eb7$0$36784$892e7fe2@authen.puce.readfreenews.net> <3c5u5u08g2u5tva8i6gd1087ug4uma6051@4ax.com>    578     15      Xref: inn.example.com news.groups:26
-gnu.utils.bug:1        Re: let's beef up the tsort info page   Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 14:03:41 -0800 <yl4rkwx5tu.fsf@windlord.stanford.edu>  <m2wuxtj3gh.fsf@dan.jacobson.tw>        2409    73      Xref: inn.example.com gnu.utils.bug:1
-csd.bboard:2   Re: comp.doc.techreports submissions from Stanford      Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 12:31:16 -0800 <yl3d0hxa3v.fsf@windlord.stanford.edu>  <yl4rkx3xvo.fsf@windlord.stanford.edu>  794     16      Xref: inn.example.com csd.bboard:2
-news.admin.net-abuse.policy:5  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 12:09:24 -0800 <ylr8o1xb4b.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> <ylr8o2z2c5.fsf@windlord.stanford.edu> <Gr0r5x.M8y@world.std.com>       1751    38      Xref: inn.example.com news.admin.net-abuse.policy:5
-csd.bboard:1   comp.doc.techreports submissions from Stanford  Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 10:28:11 -0800 <yl4rkx3xvo.fsf@windlord.stanford.edu>          672     18      Xref: inn.example.com csd.bboard:1
-comp.lang.perl.misc:1  Re: want to learn perl from free sources        Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 09:51:12 -0800 <yln0yp87an.fsf@windlord.stanford.edu>  <m2r8o1iu11.fsf@dan.jacobson.tw>        641     15      Xref: inn.example.com comp.lang.perl.misc:1
-gnu.misc.discuss:1     Re: want to learn perl from free sources        Russ Allbery <rra@stanford.edu> Mon, 04 Feb 2002 09:51:12 -0800 <yln0yp87an.fsf@windlord.stanford.edu>  <m2r8o1iu11.fsf@dan.jacobson.tw>        641     15      Xref: inn.example.com gnu.misc.discuss:1
-news.admin.net-abuse.policy:4  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 13:23:54 -0800 <ylr8o2z2c5.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com> <ylelk21l3n.fsf@windlord.stanford.edu> <Gqz2AI.JH2@world.std.com> 533     12      Xref: inn.example.com news.admin.net-abuse.policy:4
-news.groups:25 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 13:21:34 -0800 <ylwuxuz2g1.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <20020202150653$4dbb@babylon.ks.uiuc.edu> <FRRtIeAzyYX8Ewxl@merlyn.demon.co.uk> 668     15      Xref: inn.example.com news.groups:25
-news.admin.net-abuse.policy:1  Re: [ALT hierarchy]  Anyone can newgroup and anyone can rmgroup ?       Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 10:22:36 -0800 <ylelk21l3n.fsf@windlord.stanford.edu>  <5Re78.4895$XS6.585609@news2-win.server.ntlworld.com>   1448    31      Xref: inn.example.com news.admin.net-abuse.policy:1
-news.groups:24 Re: Guidelines for Big Eight Newsgroup Creation Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 09:38:27 -0800 <ylzo2q31po.fsf@windlord.stanford.edu>  <big-eight-faq-1012550404$22697@windlord.stanford.edu> <vvjq5u8l1dnrdankh4q7l2d043ud8kt11o@4ax.com>     971     22      Xref: inn.example.com news.groups:24
-news.groups:23 Re: [History] Re: A Chronology of Usenet Newsgroups:  Start Post        Russ Allbery <rra@stanford.edu> Sun, 03 Feb 2002 09:34:04 -0800 <yl665e4ghf.fsf@windlord.stanford.edu>  <3c4a31e3$0$95685$892e7fe2@authen.puce.readfreenews.net> <a301ve02s1r@enews2.newsguy.com> <dbc8daca.0201280231.791aeb03@posting.google.com> <8I07QDHHw-B@khms.westfalen.de> <3c5d3981$0$36784$892e7fe2@authen.puce.readfreenews.net>    617     15      Xref: inn.example.com news.groups:23
-news.groups:22 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 17:42:27 -0800 <ylr8o3wdbw.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <08_68.11847$gW4.9091001@news1.rdc1.mi.home.com>        1405    29      Xref: inn.example.com news.groups:22
-news.groups:21 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 17:38:39 -0800 <ylwuxvwdi8.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <PE2$9TMo7+W8Ew43@merlyn.demon.co.uk> <20020202150653$4dbb@babylon.ks.uiuc.edu> <fo1o5uoo90uh1qreh20u6n1ci70jt28mmg@4ax.com> <1f6z4v6.1fbjkdq18w29f4N%kmorgan@aptalaska.net> <lqto5u0p5sblo0ui9hal0nil52e3nlbssm@4ax.com>     316     9       Xref: inn.example.com news.groups:21
-news.groups:19 Re: The beer truck (was Re: Pre-RFD - Exec Board Newsgroup Creation)    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 12:51:44 -0800 <yl8zab38v3.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylhep0vi11.fsf@windlord.stanford.edu> <a3h7be$dec$1@panix2.panix.com> <yladur7nfw.fsf@windlord.stanford.edu> <a3hd8t$sin$1@panix2.panix.com> 481     16      Xref: inn.example.com news.groups:19
-news.groups:18 Re: The beer truck (was Re: Pre-RFD - Exec Board Newsgroup Creation)    Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 10:23:15 -0800 <yladur7nfw.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3h7be$dec$1@panix2.panix.com>    375     11      Xref: inn.example.com news.groups:18
-news.groups:17 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Sat, 02 Feb 2002 10:20:43 -0800 <ylg04j7nk4.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3g0i9$6ch$1@samba.rahul.net>     680     16      Xref: inn.example.com news.groups:17
-news.groups:16 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:35:38 -0800 <yl4rl0369h.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <Xns91A8BC08432FEpeskyirritantcom@209.155.56.83>  326     12      Xref: inn.example.com news.groups:16
-news.groups:15 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:12:32 -0800 <yladus37bz.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <i8jm5u4l8bt7lk93mramtmbouhtg58tpnb@4ax.com>      643     14      Xref: inn.example.com news.groups:15
-news.groups:14 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 19:08:02 -0800 <ylg04k37jh.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <a3fgk302sdn@enews1.newsguy.com>      808     18      Xref: inn.example.com news.groups:14
-news.groups:13 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 18:10:18 -0800 <ylu1t03a7p.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com> <yl4rl0u1ae.fsf@windlord.stanford.edu> <v1hm5u4mrhllm98ng1jhp5gco7sflbm4jq@4ax.com>      902     27      Xref: inn.example.com news.groups:13
-news.groups:12 Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 17:20:57 -0800 <yl4rl0u1ae.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <1hem5uc8efskp0efdahvnpphg2qtrlt9pc@4ax.com>  1651    36      Xref: inn.example.com news.groups:12
-news.groups:8  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 17:10:47 -0800 <yladusu1rc.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com> <ylhep0vi11.fsf@windlord.stanford.edu> <3ndm5u8fgomord7vmh164ce7pcteh496sp@4ax.com>  2363    47      Xref: inn.example.com news.groups:8
-news.groups:7  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 16:34:02 -0800 <ylhep0vi11.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com> <ylvgdgye47.fsf@windlord.stanford.edu> <tuam5ug6iomvjscick3a2fftfs7d20rrfk@4ax.com>      2834    55      Xref: inn.example.com news.groups:7
-news.groups:2  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 15:32:03 -0800 <ylofj8ye18.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3eep7$q6r$1@samba.rahul.net> <a3epeq$rt$1@gw.retro.com> <a3f201$n8$1@samba.rahul.net> <a3f7v9$3kg$1@gw.retro.com>   448     11      Xref: inn.example.com news.groups:2
-news.groups:1  Re: Pre-RFD - Exec Board Newsgroup Creation     Russ Allbery <rra@stanford.edu> Fri, 01 Feb 2002 15:30:16 -0800 <ylvgdgye47.fsf@windlord.stanford.edu>  <20020131191005$5818@babylon.ks.uiuc.edu> <a3cdbm$dt3$1@samba.rahul.net> <a3coga$jiv$1@news.orst.edu> <3C5AE4E5.B0A79442@elepar.com> <a3f1o2$nvo$1@news.orst.edu> <3b7m5ug5lmovmhotuegmkq13jpmcubrh0n@4ax.com>  3124    58      Xref: inn.example.com news.groups:1
diff --git a/tests/overview/munge-data b/tests/overview/munge-data
deleted file mode 100755 (executable)
index 56d11ff..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/perl
-
-##  $Id: munge-data 5144 2002-02-24 06:24:55Z rra $
-##
-##  Munge .overview data into something suitable for test data.
-##
-##  This script isn't used regularly and is here only for the use of INN
-##  developers and other people needing to generate more overview test data.
-##  It expects overview data but possibly with extra fields at the end, snips
-##  off To: data (to avoid putting people's e-mail addresses into INN test
-##  data), and if Newsgroups: data is present, rewrites the Xref header to use
-##  it instead of keeping the Xref data (this is so that I can use .overview
-##  files from Gnus as test data).  It generates overview data but with the
-##  newsgroup name and a colon prepended to the article number so that it can
-##  be split apart into overview data for multiple groups.
-##
-##  Please don't include overview information for people's articles into INN's
-##  test suite without their permission.
-
-my %number;
-while (<>) {
-    s/\s+$//;
-    my @data = split /\t/;
-    @data = grep { !/^To:/ } @data;
-    my $group = pop @data;
-    my $xref = pop @data;
-    if ($group =~ s/^Newsgroups: //) {
-        my @groups = split (/\s*,\s*/, $group);
-        for (@groups) {
-            $number{$_} = 1 unless $number{$_};
-            $data[0] = $_ . ':' . $number{$_}++;
-            $number{$_} += int (rand 5) if rand (10) > 8;
-            print join ("\t", @data, "Xref: inn.example.com $data[0]"), "\n";
-        }
-    } else {
-        $xref =~ s/Xref:\s*\S+\s+//;
-        my @xref = split (' ', $xref);
-        for (@xref) {
-            $data[0] = $_;
-            print join ("\t", @data, "Xref: inn.example.com $xref"), "\n";
-        }
-    }
-}
diff --git a/tests/overview/tradindexed-t.c b/tests/overview/tradindexed-t.c
deleted file mode 100644 (file)
index c93882d..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/* $Id: tradindexed-t.c 6388 2003-07-12 19:07:56Z rra $ */
-/* tradindexed test suite. */
-
-#include "config.h"
-#include "clibrary.h"
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "inn/innconf.h"
-#include "inn/hashtab.h"
-#include "inn/messages.h"
-#include "inn/vector.h"
-#include "libinn.h"
-#include "libtest.h"
-#include "ov.h"
-#include "storage.h"
-
-#include "../storage/tradindexed/tradindexed.h"
-
-/* Used as the artificial token for all articles inserted into overview. */
-static const TOKEN faketoken = { 1, 1, "" };
-
-struct group {
-    char *group;
-    unsigned long count;
-    unsigned long low;
-    unsigned long high;
-};
-
-static const void *
-group_key(const void *entry)
-{
-    const struct group *group = (const struct group *) entry;
-    return group->group;
-}
-
-static bool
-group_eq(const void *key, const void *entry)
-{
-    const char *first = key;
-    const char *second;
-
-    second = ((const struct group *) entry)->group;
-    return !strcmp(first, second);
-}
-
-static void
-group_del(void *entry)
-{
-    struct group *group = (struct group *) entry;
-
-    free(group->group);
-    free(group);
-}
-
-/* Build a stripped-down innconf struct that contains only those settings that
-   the tradindexed overview method cares about. */
-static void
-fake_innconf(void)
-{
-    innconf = xmalloc(sizeof(*innconf));
-    innconf->pathoverview = xstrdup("tdx-tmp");
-    innconf->overcachesize = 20;
-    innconf->groupbaseexpiry = true;
-    innconf->tradindexedmmap = true;
-}
-
-/* Initialize the overview database. */
-static bool
-overview_init(void)
-{
-    fake_innconf();
-    if (access("data/basic", F_OK) < 0)
-        if (access("overview/data/basic", F_OK) == 0)
-            if (chdir("overview") != 0)
-                sysdie("Cannot cd to overview");
-    if (mkdir("tdx-tmp", 0755) != 0 && errno != EEXIST)
-        sysdie("Cannot mkdir tdx-tmp");
-    return tradindexed_open(OV_READ | OV_WRITE);
-}
-
-/* Check to be sure that the line wasn't too long, and then parse the
-   beginning of the line from one of our data files, setting the article
-   number (via the passed pointer) and returning a pointer to the beginning of
-   the real overview data.  This function nul-terminates the group name and
-   leaves it at the beginning of the buffer.  (Ugly interface, but it's just a
-   test suite.) */
-static char *
-overview_data_parse(char *data, unsigned long *artnum)
-{
-    char *start;
-
-    if (data[strlen(data) - 1] != '\n')
-        die("Line too long in input data");
-
-    start = strchr(data, ':');
-    if (start == NULL)
-        die("No colon found in input data");
-    *start = '\0';
-    start++;
-    *artnum = strtoul(start, NULL, 10);
-    if (artnum == 0)
-        die("Cannot parse article number in input data");
-    return start;
-}
-
-/* Load an empty overview database from a file, in the process populating a
-   hash table with each group, the high water mark, and the count of messages
-   that should be in the group.  Returns the hash table on success and dies on
-   failure.  Takes the name of the data file to load. */
-static struct hash *
-overview_load(const char *data)
-{
-    struct hash *groups;
-    struct group *group;
-    FILE *overview;
-    char buffer[4096];
-    char flag[] = "y";
-    char *start;
-    unsigned long artnum;
-
-    /* Run through the overview data.  Each time we see a group, we update our
-       stored information about that group, which we'll use for verification
-       later.  We store that in a local hash table. */
-    groups = hash_create(32, hash_string, group_key, group_eq, group_del);
-    if (groups == NULL)
-        die("Cannot create a hash table");
-    overview = fopen(data, "r");
-    if (overview == NULL)
-        sysdie("Cannot open %s for reading", data);
-    while (fgets(buffer, sizeof(buffer), overview) != NULL) {
-        start = overview_data_parse(buffer, &artnum);
-
-        /* See if we've already seen this group.  If not, create it in the
-           overview and the hash table; otherwise, update our local hash table
-           entry. */
-        group = hash_lookup(groups, buffer);
-        if (group == NULL) {
-            group = xmalloc(sizeof(struct group));
-            group->group = xstrdup(buffer);
-            group->count = 1;
-            group->low = artnum;
-            group->high = artnum;
-            if (!hash_insert(groups, group->group, group))
-                die("Cannot insert %s into hash table", group->group);
-            if (!tradindexed_groupadd(group->group, 0, 0, flag))
-                die("Cannot insert group %s into overview", group->group);
-        } else {
-            group->count++;
-            group->low = (artnum < group->low) ? artnum : group->low;
-            group->high = (artnum > group->high) ? artnum : group->high;
-        }
-
-        /* Do the actual insert of the data.  Note that we set the arrival
-           time and expires time in a deterministic fashion so that we can
-           check later if that data is being stored properly. */
-        if (!tradindexed_add(group->group, artnum, faketoken, start,
-                             strlen(start), artnum * 10,
-                             (artnum % 5 == 0) ? artnum * 100 : artnum))
-            die("Cannot insert %s:%lu into overview", group->group, artnum);
-    }
-    fclose(overview);
-    return groups;
-}
-
-/* Verify that all of the group data looks correct; this is low mark, high
-   mark, and article count.  Returns true if all the data is right, false
-   otherwise.  This function is meant to be called as a hash traversal
-   function, which means that it will be called for each element in our local
-   hash table of groups with the group struct as the first argument and a
-   pointer to a status as the second argument. */
-static void
-overview_verify_groups(void *data, void *cookie)
-{
-    struct group *group = (struct group *) data;
-    bool *status = (bool *) cookie;
-    int low, high, count, flag;
-
-    if (!tradindexed_groupstats(group->group, &low, &high, &count, &flag)) {
-        warn("Unable to get data for %s", group->group);
-        *status = false;
-        return;
-    }
-    if ((unsigned long) low != group->low) {
-        warn("Low article wrong for %s: %lu != %lu", group->group,
-             (unsigned long) low, group->low);
-        *status = false;
-    }
-    if ((unsigned long) high != group->high) {
-        warn("High article wrong for %s: %lu != %lu", group->group,
-             (unsigned long) high, group->high);
-        *status = false;
-    }
-    if ((unsigned long) count != group->count) {
-        warn("Article count wrong for %s: %lu != %lu", group->group,
-             (unsigned long) count, group->count);
-        *status = false;
-    }
-    if (flag != 'y') {
-        warn("Flag wrong for %s: %c != y", group->group, (char) flag);
-        *status = false;
-    }
-}
-
-/* Verify the components of the overview data for a particular entry. */
-static bool
-check_data(const char *group, unsigned long artnum, const char *expected,
-           const char *seen, int length, TOKEN token)
-{
-    bool status = true;
-
-    if (strlen(expected) != (size_t) length) {
-        warn("Length wrong for %s:%lu: %d != %lu", group, artnum, length,
-             (unsigned long) strlen(expected));
-        status = false;
-    }
-    if (memcmp(&token, &faketoken, sizeof(token)) != 0) {
-        warn("Token wrong for %s:%lu", group, artnum);
-        status = false;
-    }
-    if (memcmp(expected, seen, length) != 0) {
-        warn("Data mismatch for %s:%lu", group, artnum);
-        warn("====\n%s\n====\n%s\n====", expected, seen);
-        status = false;
-    }
-    return status;
-}
-
-/* Read through the data again, looking up each article as we go and verifying
-   that the data stored in overview is the same as the data we put there.  Do
-   this two ways each time, once via getartinfo and once via opensearch.
-   Return true if everything checks out, false otherwise.  Takes the path to
-   the data file. */
-static bool
-overview_verify_data(const char *data)
-{
-    FILE *overdata;
-    char buffer[4096];
-    char *start;
-    unsigned long artnum, overnum;
-    char *overview;
-    int length;
-    TOKEN token;
-    bool status = true;
-    void *search;
-    time_t arrived;
-
-    overdata = fopen(data, "r");
-    if (overdata == NULL)
-        sysdie("Cannot open %s for reading", data);
-    while (fgets(buffer, sizeof(buffer), overdata) != NULL) {
-        start = overview_data_parse(buffer, &artnum);
-
-        /* Now check that the overview data is correct for that group. */
-        if (!tradindexed_getartinfo(buffer, artnum, &token)) {
-            warn("No overview data found for %s:%lu", buffer, artnum);
-            status = false;
-            continue;
-        }
-        if (memcmp(&token, &faketoken, sizeof(token)) != 0) {
-            warn("Token wrong for %s:%lu", buffer, artnum);
-            status = false;
-        }
-
-        /* Do the same thing, except use search. */
-        search = tradindexed_opensearch(buffer, artnum, artnum);
-        if (search == NULL) {
-            warn("Unable to open search for %s:%lu", buffer, artnum);
-            status = false;
-            continue;
-        }
-        if (!tradindexed_search(search, &overnum, &overview, &length, &token,
-                                &arrived)) {
-            warn("No overview data found for %s:%lu", buffer, artnum);
-            status = false;
-            continue;
-        }
-        if (overnum != artnum) {
-            warn("Incorrect article number in search for %s:%lu: %lu != %lu",
-                 buffer, artnum, overnum, artnum);
-            status = false;
-        }
-        if (!check_data(buffer, artnum, start, overview, length, token))
-            status = false;
-        if ((unsigned long) arrived != artnum * 10) {
-            warn("Arrival time wrong for %s:%lu: %lu != %lu", buffer, artnum,
-                 (unsigned long) arrived, artnum * 10);
-            status = false;
-        }
-        if (tradindexed_search(search, &overnum, &overview, &length, &token,
-                               &arrived)) {
-            warn("Unexpected article found for %s:%lu", buffer, artnum);
-            status = false;
-        }
-        tradindexed_closesearch(search);
-    }
-    fclose(overdata);
-    return status;
-}
-
-/* Try an overview search and verify that all of the data is returned in the
-   right order.  The first group mentioned in the provided data file will be
-   the group the search is done in, and the search will cover all articles
-   from the second article to the second-to-the-last article in the group.
-   Returns true if everything checks out, false otherwise. */
-static bool
-overview_verify_search(const char *data)
-{
-    unsigned long artnum, overnum, i;
-    unsigned long start = 0;
-    unsigned long end = 0;
-    unsigned long last = 0;
-    struct vector *expected;
-    char *line, *group;
-    FILE *overview;
-    char buffer[4096];
-    int length;
-    TOKEN token;
-    void *search;
-    time_t arrived;
-    bool status = true;
-
-    overview = fopen(data, "r");
-    if (overview == NULL)
-        sysdie("Cannot open %s for reading", data);
-    expected = vector_new();
-    if (fgets(buffer, sizeof(buffer), overview) == NULL)
-        die("Unexpected end of file in %s", data);
-    overview_data_parse(buffer, &artnum);
-    group = xstrdup(buffer);
-    while (fgets(buffer, sizeof(buffer), overview) != NULL) {
-        line = overview_data_parse(buffer, &artnum);
-        if (strcmp(group, buffer) != 0)
-            continue;
-        vector_add(expected, line);
-        if (start == 0)
-            start = artnum;
-        end = last;
-        last = artnum;
-    }
-    search = tradindexed_opensearch(group, start, end);
-    if (search == NULL) {
-        warn("Unable to open search for %s:%lu", buffer, start);
-        free(group);
-        vector_free(expected);
-        return false;
-    }
-    i = 0;
-    while (tradindexed_search(search, &overnum, &line, &length, &token,
-                              &arrived)) {
-        if (!check_data(group, overnum, expected->strings[i], line, length,
-                        token))
-            status = false;
-        if ((unsigned long) arrived != overnum * 10) {
-            warn("Arrival time wrong for %s:%lu: %lu != %lu", group, overnum,
-                 (unsigned long) arrived, overnum * 10);
-            status = false;
-        }
-        i++;
-    }
-    tradindexed_closesearch(search);
-    if (overnum != end) {
-        warn("End of search in %s wrong: %lu != %lu", group, overnum, end);
-        status = false;
-    }
-    if (i != expected->count - 1) {
-        warn("Didn't see all expected entries in %s", group);
-        status = false;
-    }
-    free(group);
-    vector_free(expected);
-    return status;
-}
-
-/* Try an overview search and verify that all of the data is returned in the
-   right order.  The search will cover everything from article 1 to the
-   highest numbered article plus one.  There were some problems with a search
-   low-water mark lower than the base of the group.  Returns true if
-   everything checks out, false otherwise. */
-static bool
-overview_verify_full_search(const char *data)
-{
-    unsigned long artnum, overnum, i;
-    unsigned long end = 0;
-    struct vector *expected;
-    char *line;
-    char *group = NULL;
-    FILE *overview;
-    char buffer[4096];
-    int length;
-    TOKEN token;
-    void *search;
-    time_t arrived;
-    bool status = true;
-
-    overview = fopen(data, "r");
-    if (overview == NULL)
-        sysdie("Cannot open %s for reading", data);
-    expected = vector_new();
-    while (fgets(buffer, sizeof(buffer), overview) != NULL) {
-        line = overview_data_parse(buffer, &artnum);
-        if (group == NULL)
-            group = xstrdup(buffer);
-        vector_add(expected, line);
-        end = artnum;
-    }
-    search = tradindexed_opensearch(group, 1, end + 1);
-    if (search == NULL) {
-        warn("Unable to open full search for %s", group);
-        free(group);
-        vector_free(expected);
-        return false;
-    }
-    i = 0;
-    while (tradindexed_search(search, &overnum, &line, &length, &token,
-                              &arrived)) {
-        if (!check_data(group, overnum, expected->strings[i], line, length,
-                        token))
-            status = false;
-        if ((unsigned long) arrived != overnum * 10) {
-            warn("Arrival time wrong for %s:%lu: %lu != %lu", group, overnum,
-                 (unsigned long) arrived, overnum * 10);
-            status = false;
-        }
-        i++;
-    }
-    tradindexed_closesearch(search);
-    if (overnum != end) {
-        warn("End of search in %s wrong: %lu != %lu", group, overnum, end);
-        status = false;
-    }
-    if (i != expected->count) {
-        warn("Didn't see all expected entries in %s", group);
-        status = false;
-    }
-    free(group);
-    vector_free(expected);
-    return status;
-}
-
-int
-main(void)
-{
-    struct hash *groups;
-    bool status;
-
-    puts("21");
-
-    if (!overview_init())
-        die("Opening the overview database failed, cannot continue");
-    ok(1, true);
-
-    groups = overview_load("data/basic");
-    ok(2, true);
-    status = true;
-    hash_traverse(groups, overview_verify_groups, &status);
-    ok(3, status);
-    ok(4, overview_verify_data("data/basic"));
-    ok(5, overview_verify_search("data/basic"));
-    hash_free(groups);
-    tradindexed_close();
-    system("/bin/rm -r tdx-tmp");
-    ok(6, true);
-
-    if (!overview_init())
-        die("Opening the overview database failed, cannot continue");
-    ok(7, true);
-
-    groups = overview_load("data/reversed");
-    ok(8, true);
-    status = true;
-    hash_traverse(groups, overview_verify_groups, &status);
-    ok(9, status);
-    ok(10, overview_verify_data("data/basic"));
-    ok(11, overview_verify_search("data/basic"));
-    hash_free(groups);
-    tradindexed_close();
-    system("/bin/rm -r tdx-tmp");
-    ok(12, true);
-
-    if (!overview_init())
-        die("Opening the overview database failed, cannot continue");
-    ok(13, true);
-
-    groups = overview_load("data/high-numbered");
-    ok(14, true);
-    ok(15, overview_verify_data("data/high-numbered"));
-    ok(16, overview_verify_full_search("data/high-numbered"));
-    hash_free(groups);
-    tradindexed_close();
-    system("/bin/rm -r tdx-tmp");
-    ok(17, true);
-
-    if (!overview_init())
-        die("Opening the overview database failed, cannot continue");
-    ok(18, true);
-
-    groups = overview_load("data/bogus");
-    ok(19, true);
-    ok(20, overview_verify_data("data/bogus"));
-    hash_free(groups);
-    tradindexed_close();
-    system("/bin/rm -r tdx-tmp");
-    ok(21, true);
-
-    return 0;
-}
diff --git a/tests/runtests.c b/tests/runtests.c
deleted file mode 100644 (file)
index 5dca51f..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-/* $Id: runtests.c 7578 2006-09-11 23:03:12Z eagle $
-
-   Run a set of tests, reporting results.
-
-   Copyright 2000, 2001 Russ Allbery <rra@stanford.edu>
-
-   Please note that this file is maintained separately from INN by the above
-   author (which is why the coding style is slightly different).  Any fixes
-   added to the INN tree should also be reported to the above author if
-   necessary.
-
-   Permission is hereby granted, free of charge, to any person obtaining a
-   copy of this software and associated documentation files (the
-   "Software"), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-   Usage:
-
-        runtests <test-list>
-
-   Expects a list of executables located in the given file, one line per
-   executable.  For each one, runs it as part of a test suite, reporting
-   results.  Test output should start with a line containing the number of
-   tests (numbered from 1 to this number), and then each line should be in
-   the following format:
-
-        ok <number>
-        not ok <number>
-        ok <number> # skip
-
-   where <number> is the number of the test.  ok indicates success, not ok
-   indicates failure, and "# skip" indicates the test was skipped for some
-   reason (maybe because it doesn't apply to this platform).
-
-   This file is completely stand-alone by intention.  As stated more
-   formally in the license above, you are welcome to include it in your
-   packages as a test suite driver.  It requires ANSI C (__FILE__, __LINE__,
-   void, const, stdarg.h, string.h) and POSIX (fcntl.h, unistd.h, pid_t) and
-   won't compile out of the box on SunOS without adjustments to include
-   strings.h instead.  This is intentionally not fixed using autoconf so
-   that this file will not have a dependency on autoconf (although you're
-   welcome to fix it for your project if you want).  Since it doesn't matter
-   as much that the test suite for the software package be utterly portable
-   to older systems, this file should be portable enough for most purposes.
-
-   Any bug reports, bug fixes, and improvements are very much welcome and
-   should be sent to the e-mail address above. */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/wait.h"
-#include "portable/time.h"
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-
-/* sys/time.h must be included before sys/resource.h on some platforms. */
-#include <sys/resource.h>
-
-/* Test status codes. */
-enum test_status {
-    TEST_FAIL,
-    TEST_PASS,
-    TEST_SKIP,
-    TEST_INVALID
-};
-
-/* Error exit statuses for test processes. */
-#define CHILDERR_DUP    100     /* Couldn't redirect stderr or stdout. */
-#define CHILDERR_EXEC   101     /* Couldn't exec child process. */
-#define CHILDERR_STDERR 102     /* Couldn't open stderr file. */
-
-/* Structure to hold data for a set of tests. */
-struct testset {
-    const char *file;           /* The file name of the test. */
-    int count;                  /* Expected count of tests. */
-    int current;                /* The last seen test number. */
-    int passed;                 /* Count of passing tests. */
-    int failed;                 /* Count of failing lists. */
-    int skipped;                /* Count of skipped tests (passed). */
-    enum test_status *results;  /* Table of results by test number. */
-    int aborted;                /* Whether the set as aborted. */
-    int reported;               /* Whether the results were reported. */
-    int status;                 /* The exit status of the test. */
-};
-
-/* Structure to hold a linked list of test sets. */
-struct testlist {
-    struct testset *ts;
-    struct testlist *next;
-};
-
-/* Header used for test output.  %s is replaced by the file name of the list
-   of tests. */
-static const char banner[] = "\n\
-Running all tests listed in %s.  If any tests fail, run the failing\n\
-test program by hand to see more details.  The test program will have the\n\
-same name as the test set but with \".t\" appended.\n\n";
-
-/* Header for reports of failed tests. */
-static const char header[] = "\n\
-Failed Set                 Fail/Total (%) Skip Stat  Failing Tests\n\
--------------------------- -------------- ---- ----  ------------------------";
-
-/* Include the file name and line number in malloc failures. */
-#define xmalloc(size)   x_malloc((size), __FILE__, __LINE__)
-#define xstrdup(p)      x_strdup((p), __FILE__, __LINE__)
-
-/* Internal prototypes. */
-static void sysdie(const char *format, ...);
-static void *x_malloc(size_t, const char *file, int line);
-static char *x_strdup(const char *, const char *file, int line);
-static int test_analyze(struct testset *);
-static int test_batch(const char *testlist);
-static void test_checkline(const char *line, struct testset *);
-static void test_fail_summary(const struct testlist *);
-static int test_init(const char *line, struct testset *);
-static int test_print_range(int first, int last, int chars, int limit);
-static void test_summarize(struct testset *, int status);
-static pid_t test_start(const char *path, int *fd);
-static double tv_diff(const struct timeval *, const struct timeval *);
-static double tv_seconds(const struct timeval *);
-static double tv_sum(const struct timeval *, const struct timeval *);
-
-
-/* Report a fatal error, including the results of strerror, and exit. */
-static void
-sysdie(const char *format, ...)
-{
-    int oerrno;
-    va_list args;
-
-    oerrno = errno;
-    fflush(stdout);
-    fprintf(stderr, "runtests: ");
-    va_start(args, format);
-    vfprintf(stderr, format, args);
-    va_end(args);
-    fprintf(stderr, ": %s\n", strerror(oerrno));
-    exit(1);
-}
-
-
-/* Allocate memory, reporting a fatal error and exiting on failure. */
-static void *
-x_malloc(size_t size, const char *file, int line)
-{
-    void *p;
-
-    p = malloc(size);
-    if (!p)
-        sysdie("failed to malloc %lu bytes at %s line %d",
-               (unsigned long) size, file, line);
-    return p;
-}
-
-
-/* Copy a string, reporting a fatal error and exiting on failure. */
-static char *
-x_strdup(const char *s, const char *file, int line)
-{
-    char *p;
-    size_t len;
-
-    len = strlen(s) + 1;
-    p = malloc(len);
-    if (!p)
-        sysdie("failed to strdup %lu bytes at %s line %d",
-               (unsigned long) len, file, line);
-    memcpy(p, s, len);
-    return p;
-}
-
-
-/* Given a struct timeval, return the number of seconds it represents as a
-   double.  Use difftime() to convert a time_t to a double. */
-static double
-tv_seconds(const struct timeval *tv)
-{
-    return difftime(tv->tv_sec, 0) + tv->tv_usec * 1e-6;
-}
-
-/* Given two struct timevals, return the difference in seconds. */
-static double
-tv_diff(const struct timeval *tv1, const struct timeval *tv0)
-{
-    return tv_seconds(tv1) - tv_seconds(tv0);
-}
-
-/* Given two struct timevals, return the sum in seconds as a double. */
-static double
-tv_sum(const struct timeval *tv1, const struct timeval *tv2)
-{
-    return tv_seconds(tv1) + tv_seconds(tv2);
-}
-
-
-/* Read the first line of test output, which should contain the range of
-   test numbers, and initialize the testset structure.  Assume it was zeroed
-   before being passed in.  Return true if initialization succeeds, false
-   otherwise. */
-static int
-test_init(const char *line, struct testset *ts)
-{
-    int i;
-
-    /* Prefer a simple number of tests, but if the count is given as a range
-       such as 1..10, accept that too for compatibility with Perl's
-       Test::Harness. */
-    while (isspace((unsigned char)(*line))) line++;
-    if (!strncmp(line, "1..", 3)) line += 3;
-
-    /* Get the count, check it for validity, and initialize the struct. */
-    i = atoi(line);
-    if (i <= 0) {
-        puts("invalid test count");
-        ts->aborted = 1;
-        ts->reported = 1;
-        return 0;
-    }
-    ts->count = i;
-    ts->results = xmalloc(ts->count * sizeof(enum test_status));
-    for (i = 0; i < ts->count; i++) ts->results[i] = TEST_INVALID;
-    return 1;
-}
-
-
-/* Start a program, connecting its stdout to a pipe on our end and its
-   stderr to /dev/null, and storing the file descriptor to read from in the
-   two argument.  Returns the PID of the new process.  Errors are fatal. */
-static pid_t
-test_start(const char *path, int *fd)
-{
-    int fds[2], errfd;
-    pid_t child;
-
-    if (pipe(fds) == -1) sysdie("can't create pipe");
-    child = fork();
-    if (child == (pid_t) -1) {
-        sysdie("can't fork");
-    } else if (child == 0) {
-        /* In child.  Set up our stdout and stderr. */
-        errfd = open("/dev/null", O_WRONLY);
-        if (errfd < 0) _exit(CHILDERR_STDERR);
-        if (dup2(errfd, 2) == -1) _exit(CHILDERR_DUP);
-        close(fds[0]);
-        if (dup2(fds[1], 1) == -1) _exit(CHILDERR_DUP);
-
-        /* Now, exec our process. */
-        if (execl(path, path, (char *) 0) == -1) _exit(CHILDERR_EXEC);
-    } else {
-        /* In parent.  Close the extra file descriptor. */
-        close(fds[1]);
-    }
-    *fd = fds[0];
-    return child;
-}
-
-
-/* Given a single line of output from a test, parse it and return the
-   success status of that test.  Anything printed to stdout not matching the
-   form /^(not )?ok \d+/ is ignored.  Sets ts->current to the test number
-   that just reported status. */
-static void
-test_checkline(const char *line, struct testset *ts)
-{
-    enum test_status status = TEST_PASS;
-    int current;
-
-    /* If the given line isn't newline-terminated, it was too big for an
-       fgets(), which means ignore it. */
-    if (line[strlen(line) - 1] != '\n') return;
-
-    /* Parse the line, ignoring something we can't parse. */
-    if (!strncmp(line, "not ", 4)) {
-        status = TEST_FAIL;
-        line += 4;
-    }
-    if (strncmp(line, "ok ", 3)) return;
-    line += 3;
-    current = atoi(line);
-    if (current == 0) return;
-    if (current < 0 || current > ts->count) {
-        printf("invalid test number %d\n", current);
-        ts->aborted = 1;
-        ts->reported = 1;
-        return;
-    }
-    while (isspace((unsigned char)(*line))) line++;
-    while (isdigit((unsigned char)(*line))) line++;
-    while (isspace((unsigned char)(*line))) line++;
-    if (*line == '#') {
-        line++;
-        while (isspace((unsigned char)(*line))) line++;
-        if (!strncmp(line, "skip", 4)) status = TEST_SKIP;
-    }
-
-    /* Make sure that the test number is in range and not a duplicate. */
-    if (ts->results[current - 1] != TEST_INVALID) {
-        printf("duplicate test number %d\n", current);
-        ts->aborted = 1;
-        ts->reported = 1;
-        return;
-    }
-
-    /* Good results.  Increment our various counters. */
-    switch (status) {
-        case TEST_PASS: ts->passed++;   break;
-        case TEST_FAIL: ts->failed++;   break;
-        case TEST_SKIP: ts->skipped++;  break;
-        default:                        break;
-    }
-    ts->current = current;
-    ts->results[current - 1] = status;
-}
-
-
-/* Print out a range of test numbers, returning the number of characters it
-   took up.  Add a comma and a space before the range if chars indicates
-   that something has already been printed on the line, and print
-   ... instead if chars plus the space needed would go over the limit (use a
-   limit of 0 to disable this. */
-static int
-test_print_range(int first, int last, int chars, int limit)
-{
-    int needed = 0;
-    int out = 0;
-    int n;
-
-    if (chars > 0) {
-        needed += 2;
-        if (!limit || chars <= limit) out += printf(", ");
-    }
-    for (n = first; n > 0; n /= 10)
-        needed++;
-    if (last > first) {
-        for (n = last; n > 0; n /= 10)
-            needed++;
-        needed++;
-    }
-    if (limit && chars + needed > limit) {
-        if (chars <= limit) out += printf("...");
-    } else {
-        if (last > first) out += printf("%d-", first);
-        out += printf("%d", last);
-    }
-    return out;
-}
-
-
-/* Summarize a single test set.  The second argument is 0 if the set exited
-   cleanly, a positive integer representing the exit status if it exited
-   with a non-zero status, and a negative integer representing the signal
-   that terminated it if it was killed by a signal. */
-static void
-test_summarize(struct testset *ts, int status)
-{
-    int i;
-    int missing = 0;
-    int failed = 0;
-    int first = 0;
-    int last = 0;
-
-    if (ts->aborted) {
-        fputs("aborted", stdout);
-        if (ts->count > 0)
-            printf(", passed %d/%d", ts->passed, ts->count - ts->skipped);
-    } else {
-        for (i = 0; i < ts->count; i++) {
-            if (ts->results[i] == TEST_INVALID) {
-                if (missing == 0) fputs("MISSED ", stdout);
-                if (first && i == last) {
-                    last = i + 1;
-                } else {
-                    if (first) {
-                        test_print_range(first, last, missing - 1, 0);
-                    }
-                    missing++;
-                    first = i + 1;
-                    last = i + 1;
-                }
-            }
-        }
-        if (first) test_print_range(first, last, missing - 1, 0);
-        first = 0;
-        last = 0;
-        for (i = 0; i < ts->count; i++) {
-            if (ts->results[i] == TEST_FAIL) {
-                if (missing && !failed) fputs("; ", stdout);
-                if (failed == 0) fputs("FAILED ", stdout);
-                if (first && i == last) {
-                    last = i + 1;
-                } else {
-                    if (first) {
-                        test_print_range(first, last, failed - 1, 0);
-                    }
-                    failed++;
-                    first = i + 1;
-                    last = i + 1;
-                }
-            }
-        }
-        if (first) test_print_range(first, last, failed - 1, 0);
-        if (!missing && !failed) {
-            fputs(!status ? "ok" : "dubious", stdout);
-            if (ts->skipped > 0) printf(" (skipped %d tests)", ts->skipped);
-        }
-    }
-    if (status > 0) {
-        printf(" (exit status %d)", status);
-    } else if (status < 0) {
-        printf(" (killed by signal %d%s)", -status,
-               WCOREDUMP(ts->status) ? ", core dumped" : "");
-    }
-    putchar('\n');
-}
-
-
-/* Given a test set, analyze the results, classify the exit status, handle a
-   few special error messages, and then pass it along to test_summarize()
-   for the regular output. */
-static int
-test_analyze(struct testset *ts)
-{
-    if (ts->reported) return 0;
-    if (WIFEXITED(ts->status) && WEXITSTATUS(ts->status) != 0) {
-        switch (WEXITSTATUS(ts->status)) {
-        case CHILDERR_DUP:
-            if (!ts->reported) puts("can't dup file descriptors");
-            break;
-        case CHILDERR_EXEC:
-            if (!ts->reported) puts("execution failed (not found?)");
-            break;
-        case CHILDERR_STDERR:
-            if (!ts->reported) puts("can't open /dev/null");
-            break;
-        default:
-            test_summarize(ts, WEXITSTATUS(ts->status));
-            break;
-        }
-        return 0;
-    } else if (WIFSIGNALED(ts->status)) {
-        test_summarize(ts, -WTERMSIG(ts->status));
-        return 0;
-    } else {
-        test_summarize(ts, 0);
-        return (ts->failed == 0);
-    }
-}
-
-
-/* Runs a single test set, accumulating and then reporting the results.
-   Returns true if the test set was successfully run and all tests passed,
-   false otherwise. */
-static int
-test_run(struct testset *ts)
-{
-    pid_t testpid, child;
-    int outfd, i, status;
-    FILE *output;
-    char buffer[BUFSIZ];
-    char *file;
-
-    /* Initialize the test and our data structures, flagging this set in
-       error if the initialization fails. */
-    file = xmalloc(strlen(ts->file) + 3);
-    strcpy(file, ts->file);
-    strcat(file, ".t");
-    testpid = test_start(file, &outfd);
-    free(file);
-    output = fdopen(outfd, "r");
-    if (!output) sysdie("fdopen failed");
-    if (!fgets(buffer, sizeof(buffer), output)) ts->aborted = 1;
-    if (!ts->aborted && !test_init(buffer, ts)) {
-        while (fgets(buffer, sizeof(buffer), output))
-            ;
-        ts->aborted = 1;
-    }
-
-    /* Pass each line of output to test_checkline(). */
-    while (!ts->aborted && fgets(buffer, sizeof(buffer), output))
-        test_checkline(buffer, ts);
-    if (ferror(output)) ts->aborted = 1;
-
-    /* Close the output descriptor, retrieve the exit status, and pass that
-       information to test_analyze() for eventual output. */
-    fclose(output);
-    child = waitpid(testpid, &ts->status, 0);
-    if (child == (pid_t) -1)
-        sysdie("waitpid for %u failed", (unsigned int) testpid);
-    status = test_analyze(ts);
-
-    /* Convert missing tests to failed tests. */
-    for (i = 0; i < ts->count; i++) {
-        if (ts->results[i] == TEST_INVALID) {
-            ts->failed++;
-            ts->results[i] = TEST_FAIL;
-            status = 0;
-        }
-    }
-    return status;
-}
-
-
-/* Summarize a list of test failures. */
-static void
-test_fail_summary(const struct testlist *fails)
-{
-    struct testset *ts;
-    int i, chars, total, first, last;
-
-    puts(header);
-
-    /* Failed Set                 Fail/Total (%) Skip Stat  Failing (25)
-       -------------------------- -------------- ---- ----  -------------- */
-    for (; fails; fails = fails->next) {
-        ts = fails->ts;
-        total = ts->count - ts->skipped;
-        printf("%-26.26s %4d/%-4d %3.0f%% %4d ", ts->file, ts->failed,
-               total, total ? (ts->failed * 100.0) / total : 0,
-               ts->skipped);
-        if (WIFEXITED(ts->status)) {
-            printf("%4d  ", WEXITSTATUS(ts->status));
-        } else {
-            printf("  --  ");
-        }
-        if (ts->aborted) {
-            puts("aborted");
-            continue;
-        }
-        chars = 0;
-        first = 0;
-        last = 0;
-        for (i = 0; i < ts->count; i++) {
-            if (ts->results[i] == TEST_FAIL) {
-                if (first && i == last) {
-                    last = i + 1;
-                } else {
-                    if (first)
-                        chars += test_print_range(first, last, chars, 20);
-                    first = i + 1;
-                    last = i + 1;
-                }
-            }
-        }
-        if (first) test_print_range(first, last, chars, 20);
-        putchar('\n');
-    }
-}
-
-
-/* Run a batch of tests from a given file listing each test on a line by
-   itself.  The file must be rewindable.  Returns true iff all tests
-   passed. */
-static int
-test_batch(const char *testlist)
-{
-    FILE *tests;
-    size_t length, i;
-    size_t longest = 0;
-    char buffer[BUFSIZ];
-    int line;
-    struct testset ts, *tmp;
-    struct timeval start, end;
-    struct rusage stats;
-    struct testlist *failhead = 0;
-    struct testlist *failtail = 0;
-    int total = 0;
-    int passed = 0;
-    int skipped = 0;
-    int failed = 0;
-    int aborted = 0;
-
-    /* Open our file of tests to run and scan it, checking for lines that
-       are too long and searching for the longest line. */
-    tests = fopen(testlist, "r");
-    if (!tests) sysdie("can't open %s", testlist);
-    line = 0;
-    while (fgets(buffer, sizeof(buffer), tests)) {
-        line++;
-        length = strlen(buffer) - 1;
-        if (buffer[length] != '\n') {
-            fprintf(stderr, "%s:%d: line too long\n", testlist, line);
-            exit(1);
-        }
-        if (length > longest) longest = length;
-    }
-    if (fseek(tests, 0, SEEK_SET) == -1)
-        sysdie("can't rewind %s", testlist);
-
-    /* Add two to longest and round up to the nearest tab stop.  This is how
-       wide the column for printing the current test name will be. */
-    longest += 2;
-    if (longest % 8) longest += 8 - (longest % 8);
-
-    /* Start the wall clock timer. */
-    gettimeofday(&start, NULL);
-
-    /* Now, plow through our tests again, running each one.  Check line
-       length again out of paranoia. */
-    line = 0;
-    while (fgets(buffer, sizeof(buffer), tests)) {
-        line++;
-        length = strlen(buffer) - 1;
-        if (buffer[length] != '\n') {
-            fprintf(stderr, "%s:%d: line too long\n", testlist, line);
-            exit(1);
-        }
-        buffer[length] = '\0';
-        fputs(buffer, stdout);
-        for (i = length; i < longest; i++) putchar('.');
-        memset(&ts, 0, sizeof(ts));
-        ts.file = xstrdup(buffer);
-        if (!test_run(&ts)) {
-            tmp = xmalloc(sizeof(struct testset));
-            memcpy(tmp, &ts, sizeof(struct testset));
-            if (!failhead) {
-                failhead = xmalloc(sizeof(struct testset));
-                failhead->ts = tmp;
-                failhead->next = 0;
-                failtail = failhead;
-            } else {
-                failtail->next = xmalloc(sizeof(struct testset));
-                failtail = failtail->next;
-                failtail->ts = tmp;
-                failtail->next = 0;
-            }
-        }
-        aborted += ts.aborted;
-        total += ts.count;
-        passed += ts.passed;
-        skipped += ts.skipped;
-        failed += ts.failed;
-    }
-    total -= skipped;
-
-    /* Stop the timer and get our child resource statistics. */
-    gettimeofday(&end, NULL);
-    getrusage(RUSAGE_CHILDREN, &stats);
-
-    /* Print out our final results. */
-    if (failhead) test_fail_summary(failhead);
-    putchar('\n');
-    if (aborted) {
-        printf("Aborted %d test sets, passed %d/%d tests.\n", aborted,
-               passed, total);
-    } else if (failed == 0) {
-        fputs("All tests successful", stdout);
-        if (skipped) printf(", %d tests skipped", skipped);
-        puts(".");
-    } else {
-        printf("Failed %d/%d tests, %.2f%% okay.\n", failed, total,
-               (total - failed) * 100.0 / total);
-    }
-    printf("Files=%d,  Tests=%d", line, total);
-    printf(",  %.2f seconds", tv_diff(&end, &start));
-    printf(" (%.2f usr + %.2f sys = %.2f CPU)\n",
-           tv_seconds(&stats.ru_utime), tv_seconds(&stats.ru_stime),
-           tv_sum(&stats.ru_utime, &stats.ru_stime));
-    return !(failed || aborted);
-}
-
-
-/* Main routine.  Given a file listing tests, run each test listed. */
-int
-main(int argc, char *argv[])
-{
-    if (argc != 2) {
-        fprintf(stderr, "Usage: runtests <test-list>\n");
-        exit(1);
-    }
-    printf(banner, argv[1]);
-    exit(test_batch(argv[1]) ? 0 : 1);
-}
diff --git a/tests/util/convdate.t b/tests/util/convdate.t
deleted file mode 100755 (executable)
index 9389f1b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#! /bin/sh
-# $Id: convdate.t 5754 2002-09-09 00:48:21Z rra $
-#
-# Test suite for convdate.
-
-# The count starts at 1 and is updated each time ok is printed.  printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
-    echo "$1 $count $2"
-    count=`expr $count + 1`
-}
-
-# Given the output from convdate and the expected output, compare them.
-compare () {
-    status=$?
-    if [ $status = 0 ] && [ "$1" = "$2" ] ; then
-        printcount "ok"
-    else
-        echo "  $1"
-        echo "  $2"
-        printcount "not ok"
-    fi
-}
-
-# Find convdate.
-convdate=false
-for file in ../expire/convdate ../../expire/convdate expire/convdate ; do
-    [ -x $file ] && convdate=$file
-done
-if [ $convdate = "false" ] ; then
-    echo "Could not find convdate" >&2
-    exit 1
-fi
-
-# Print out the count of tests.
-echo 7
-
-# Run our tests.  These are all from the man page, but with time zones
-# added.
-TZ=EST5EDT; export TZ
-compare "`$convdate 'feb 10, 1991 10am EST'`" 'Sun Feb 10 10:00:00 1991'
-compare "`$convdate '12pm EST 12/13/91' '12am EDT 5/4/90'`" \
-    'Fri Dec 13 12:00:00 1991
-Fri May  4 00:00:00 1990'
-compare "`$convdate -n 'feb 10, 1991 10am-0500' '12am-0400 5/5/90'`" \
-    '666198000
-641880000'
-compare "`$convdate -c 666198000`" 'Sun Feb 10 10:00:00 1991'
-compare "`$convdate -dc 666198000`" 'Sun, 10 Feb 1991 15:00:00 +0000 (UTC)'
-compare "`env TZ=PST8PDT $convdate -dlc 666198000`" \
-    'Sun, 10 Feb 1991 07:00:00 -0800 (PST)'
-compare "`env TZ=EST5EDT $convdate -dlc 666198000`" \
-    'Sun, 10 Feb 1991 10:00:00 -0500 (EST)'